3 from optparse import OptionParser
5 from urllib import urlencode
8 from jinja2 import Environment, FileSystemLoader
10 from dirtag import Dirtag, Tree, dir_tree
14 """The web interface to Dirtag.
16 def __init__(self, dirtag, template_dir, repository_name='Dirtag'):
17 """Initialize the bug repository for this web interface."""
19 self.env = Environment(loader=FileSystemLoader(template_dir))
20 self.repository_name = repository_name
21 self.rdf_root = 'http://dirtag.com/'
25 template = self.env.get_template('dirtag.xul')
26 cherrypy.response.headers['Content-Type'] = \
27 'application/vnd.mozilla.xul+xml'
28 return template.render(repository_name=self.repository_name)
32 return self.tree_rdf(self.dirtag.raw_dir, 'raw')
36 return self.tree_rdf(self.dirtag.tag_dir, 'tag', with_files=False)
38 def tree_rdf(self, root_dir, name, with_files=True):
39 cherrypy.response.headers['Content-Type'] = \
41 tree = dir_tree(root_dir)
43 '<?xml version="1.0"?>',
45 '<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"',
46 ' xmlns:FILES="%srdf#">' % self.rdf_root,
48 if with_files == True:
49 nodes = tree.traverse(depth=1, dirtag=self.dirtag)
51 nodes = tree.traverse(depth=1, type='dirs', dirtag=self.dirtag)
54 ' <RDF:Description RDF:about="%s%s">'
55 % (self.rdf_root, '/'.join([name]+node)),
56 ' <FILES:name>%s</FILES:name>' % node[-1],
58 if node.type == 'file':
59 lines.append(' <FILES:tags>%s</FILES:tags>'
60 % ','.join(['/'.join(t) for t in node.tags]))
61 lines.append(' </RDF:Description>')
63 lines.append(' <RDF:Seq RDF:about="%s%s/files">'
64 % (self.rdf_root, name))
66 for node in tree.traverse(depth=1,):
67 while (len(stack) > 0 and
68 not self.list_startswith(stack[-1], node[:-1])):
70 ' '*(4*len(stack)+2) + '</RDF:Seq>',
71 ' '*(4*len(stack)) + '</RDF:li>',
74 assert len(node) == len(stack)+1, (
75 'Floating %s -> %s (%d -> %d)'
76 % (stack[-1], node, len(stack), len(node)))
78 if node.type == 'file':
79 raw_node = self.dirtag.raw_node(node)
80 lines.append(' '*(4*len(stack))
81 + '<RDF:li RDF:resource="%s%s"/>'
82 % (self.rdf_root, '/'.join(['raw']+raw_node)))
86 ' '*(4*len(stack)) + '<RDF:li>',
87 ' '*(4*len(stack)+2) + '<RDF:Seq RDF:about="%s%s">'
88 % (self.rdf_root, '/'.join([name]+node)),
92 ' '*(4*len(stack)+2) + '</RDF:Seq>',
93 ' '*(4*len(stack)) + '</RDF:li>',
102 return '\n'.join(lines)
104 def list_startswith(self, a, b):
106 >>> x = WebInterface(None, 'template')
107 >>> x.list_startswith([1, 2, 3], [1, 2, 3, 4])
109 >>> x.list_startswith([1, 2, 3], [1, 2, 3])
111 >>> x.list_startswith([1, 2, 3], [1, 2])
113 >>> x.list_startswith([1, 2, 3], [2, 2, 3])
116 return len([x for x,y in zip(a,b) if x==y]) == len(a)
118 #raise cherrypy.HTTPRedirect('/static/dirtag.xul', status=302)
120 if __name__ == '__main__':
121 parser = OptionParser('%prog [options]', epilog=WebInterface.__doc__)
122 parser.add_option('-r', '--raw-dir', dest='raw_dir', metavar='DIR',
124 help='Location of raw files (%default)')
125 parser.add_option('-t', '--tag-dir', dest='tag_dir', metavar='DIR',
127 help='Location of tag links (%default)')
128 parser.add_option('-T', '--template-dir', dest='template_dir',
129 metavar='DIR', default='template',
130 help='Location of template files (%default)')
131 parser.add_option('-s', '--static-dir', dest='static_dir', metavar='DIR',
133 help='Location of static files (%default)')
134 parser.add_option('-n', '--name', dest='name', metavar='STRING',
136 help='Name of the dirtag repository')
137 parser.add_option('--test', dest='test', default=False,
139 help='Run unittests and exit')
140 options,args = parser.parse_args()
147 d = Dirtag(raw_dir=options.raw_dir, tag_dir=options.tag_dir)
149 d, template_dir=options.template_dir, repository_name=options.name)
150 cherrypy.config.update({
151 'tools.encode.on': True,
152 'tools.encode.encoding': 'utf8',
156 'tools.staticdir.on': True,
157 'tools.staticdir.dir': path.abspath(options.static_dir),
160 cherrypy.quickstart(w, '/', app_config)