Hello,

I have made an experiment to show how LISFS could be used to navigate
and build classification. For this, I created a file hierarchy
corresponding to the current classification in the demo server[1] over a
LISFS real file system[2].

==AN EXAMPLE OF EXPLORATION==

So at LISFS root, I can do a 'ls':

[EMAIL PROTECTED]:~/pub/lisfs/mounted$ ls -F
00-pool/                                    propagande/    question 200/
admin/                                      question 104/  question 202/
aéroports/                                  question 108/  question 204/
âge limite/                                 question 113/  question 205/
agriculture/                                question 117/  question 206/
alimentation/                               question 118/  question 207/
anglais/                                    question 119/  question 208/
anglais-français/                           question 129/  question 209/
antonyme/                                   question 130/  question 21/
armée/                                      question 131/  question 210/
armes/                                      question 132/  question 211/
association/                                question 133/  question 212/
automobile/                                 question 134/  question 213/
[...output cut...]

I can navigate into a tag, to see question and other tags attached to
it:

[EMAIL PROTECTED]:~/pub/lisfs/mounted$ cd Rennes/

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes$ ls -F
association/                                                           
expérience démocratique/
demexp/                                                                
financement/
Doit-on créer une piste cyclable à contre-sens quai de la Prévalaye ?  
financement demexp/
élection/                                                              question 
179/
esthétique/

You can see two things:

 1. question "Doit-on ... Prévalaye ?" as only tag "Rennes", so no
    further exploration is possible and the question is presented as a
    file (see below);

 2. other sub-directories are shown, that show additional tags to make a
    research.

You can see the content of the question "Doit-on ... Prévalaye ?":

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes$ cat Doit-on\ créer\ une\ piste\ 
cyclable\ à\ contre-sens\ quai\ de\ la\ Prévalaye\ \? 
46: Doit-on créer une piste cyclable à contre-sens quai de la Prévalaye ?
Tags:['Rennes']
Responses:
   - Question rejected
   - non
   - oui, en supprimant le trotoire qui longe le quai
   - oui, en supprimant les places de stationnement
   - Oui, à condition que l'expérience démocratique détienne la majorité du 
conseil municipal de Rennes et en réduisant l'espace de circulation voitures

But you can also refine your search by 'cd' and 'ls' in the file
hierarchy:

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes$ cd expérience\ démocratique/

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes/expérience démocratique$ ls -F
association/  demexp/  élection/  financement/  financement demexp/

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes/expérience démocratique$ cd demexp/

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes/expérience démocratique/demexp$ ls 
-F
Dans quelle banque l'association de financement de demexp doit-elle ouvrir son 
compte ?

And we can show the content of the only question:

[EMAIL PROTECTED]:~/pub/lisfs/mounted/Rennes/expérience démocratique/demexp$ 
cat Dans\ quelle\ banque\ l\
'association\ de\ financement\ de\ demexp\ doit-elle\ ouvrir\ son\ compte\ \? 
50: Dans quelle banque l'association de financement de demexp doit-elle ouvrir 
son compte ?
Tags:['exp\xc3\xa9rience d\xc3\xa9mocratique', 'financement', 'financement 
demexp', 'demexp', 'association', 'Rennes']
Responses:
   - Question rejected
   - Le Crédit mutuel de Bretagne
   - La Nef (à l'agence du Crédit coopératif de Rennes)
   - Le Crédit coopératif (agence de Rennes)
   - La poste (ils exigent que ce soit dans le bureau de poste du siège social 
de l'association)
   - 2
   - Le Crédit Agricole

You can notice an important property of LISFS: question 50 has 6 tags
but only 3 are needed to reach the question. For example, tag
'financement' is no longer discriminatory as soon as we have entered the
"Rennes/expérience démocratique/demexp" directory, so it is not shown as
sub-directory.

LISFS theory and code allow also to modify the hierachy dynamically,
while searching. This is quite powerful: you can navigate, find that the
classification needs some modification and modify it lively!

Moreover, typed attributes can be attached. For example question
identifiers can be attached to a question and one could do:

 cd qid:>10/qid:<20/   # to see questions #11 to #19

LISFS also support classification hierarchy. So we could have a tag
"Cities" that contains "Rennes", "Bruxelles", ... At the upper level,
only Cities/ directory would be displayed.


==REMAINING WORK==

This is just an dummy example, the real server classification cannot be
explored and modified through this system. And some details need to be
worked out, like not displaying the "question NNN" tags. But all the
OCaml code is available, freely (GPL license), so this is "just" a
question of writing proper gluing code. ;)

What do you think of it? Do you find the system appealing or does it
seems to you too much complicated?

Regarding architecture, I'm wondering if putting such a system into the
server couldn't be very useful: every client (even Python scripts! ;)
could use this system.

Best wishes,
d.

PS: "[technology preview]": yes, I'm reading for the marketing
    department. :)

Footnotes: 
[1]  I have used a Python script (well, rather a hack) using Thomas'
     pydemexp toolkit for this. It's very useful Thomas!

     Here is the used pydemexp script:
#!/usr/bin/python

import sys
import socket
import DemexpRpc
import string
import os

# for debug
#count_max=2
count_max=10000

def check_return_code(c):
    if c != DemexpRpc.const.rt_ok:
        print "Error: " + DemexpRpc.const.return_code_t[c] \
              + " (" + str(c) + ")"
        sys.exit (1)

# Check arguments
if len(sys.argv) != 1:
    print "Usage: make-directories.py"
    sys.exit (1)

# Connect to the server
try:
    c = DemexpRpc.client.Demexp.V1("tuxinette.linux-france.org",50000)
except socket.error:
    print "Connexion failed to tuxinette.linux-france.org:50000"
    sys.exit (1)

# Login on the server
login_ret = c.login(DemexpRpc.const.PROTOCOL_VERSION, "demo", "demo")

# Check the protocol version returned by the server to see if it's the
# same as the one we implement
if login_ret.server_protocol_version != DemexpRpc.const.PROTOCOL_VERSION:
    print "Server has a different protocol version"
    sys.exit (1)

# Check that login was successful
check_return_code(login_ret.login_return_code)

cookie = login_ret.login_cookie

# Get the maximum tag ID
ret = c.max_tag_id(cookie)
check_return_code(ret.max_tag_id_rc)

# Get a hash of tags
tag_labels = {}
for i in range (0, min(count_max, ret.max_tag_id + 1)):
    ret = c.tag_info(cookie, i, 1)
    check_return_code(ret.tag_info_rc)
    tag_labels[i] = ret.tag_info[0].a_tag_label
    print str(i) + ". " + tag_labels[i]
    try:
        os.mkdir(tag_labels[i])
    except OSError:
        pass


# Get the maximum question ID
ret = c.max_question_id(cookie)
check_return_code(ret.max_question_id_rc)
max_question_id = ret.max_question_id

# Get the tags of a question
tags_of_question = {}
for i in range (0, min(count_max, max_question_id + 1)):
    ret = c.get_question_tags(cookie, i)
    tags_of_question[i] = ret
    print ("Tags question %d: " % i) + repr(tags_of_question[i])

# List the questions and their tags
for i in range (0, min(count_max, max_question_id + 1)):
    ret = c.question_info (cookie, i, 1)
    check_return_code(ret.question_info_rc)

    question = ret.question_info[0]

    #print str(i) + ". " + question.q_desc

    question_tags = []
    for t_id in tags_of_question[i]:
        question_tags.append(tag_labels[t_id])
    #print question_tags

    path = string.join(question_tags, "/") + "/" + question.q_desc
    print str(i) + ": " + path

    try:
        f = open(path,"w")
        f.write(str(i) + ": " + question.q_desc + "\n")
        f.write("Tags:" + repr(question_tags) + "\n")
        f.write("Responses:\n")
        for response in question.q_info_responses:
            f.write("   - " + response.r_info_desc + "\n")
        f.close()
    except (OSError, IOError):
        pass

# Disconnect
c.goodbye(cookie)

sys.exit(0)
[2]  I can provide LISFS code if needed.

-- 
pub  1024D/A3AD7A2A 2004-10-03 David MENTRE <[EMAIL PROTECTED]>
 5996 CC46 4612 9CA4 3562  D7AC 6C67 9E96 A3AD 7A2A
_______________________________________________
Demexp-dev mailing list
Demexp-dev@nongnu.org
http://lists.nongnu.org/mailman/listinfo/demexp-dev

Répondre à