[svn r1601] Add first try to get a folder's like view.
--- a/ChangeLog Fri Oct 17 15:05:17 2003 -0400
+++ b/ChangeLog Sat Oct 18 00:56:42 2003 -0400
@@ -1,6 +1,7 @@
xbelweb (0.1-5) unstable; urgency=low
* Add display name to Preferences.
+ * Add folders view with Add.
-- Fabien Ninoles <fabien@tzone.org> Fri, 17 Oct 2003 15:04:26 -0400
--- a/edit_prefs.py Fri Oct 17 15:05:17 2003 -0400
+++ b/edit_prefs.py Sat Oct 18 00:56:42 2003 -0400
@@ -23,8 +23,7 @@
prefs['keywords_box'] = int(form['kw_size'].value)
if form.has_key('kw_sort'):
prefs['keywords_sort'] = form['kw_sort'].value
- if form.has_key('kw_reverse'):
- prefs['keywords_reverse'] = form['kw_reverse'].value <> 0
+ prefs['keywords_reverse'] = form.has_key('kw_reverse')
if form.has_key('fullname'):
prefs['fullname'] = form['fullname'].value
db.set_preferences(prefs)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/folders.py Sat Oct 18 00:56:42 2003 -0400
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+import sys
+import traceback
+if (__name__ == '__main__'):
+ sys.path.insert(0, "/home/fabien/lib/python")
+ sys.path.insert(0, "./lib")
+ sys.stderr = sys.stdout
+
+ print "Content-type: text/html; charset=iso-8859-1;"
+ print
+
+# import cgitb; cgitb.enable()
+import cgi
+import my_db
+from os import environ
+from htmltmpl import TemplateManager
+from webutils import get_template_processor, set_selection, sort_keywords
+
+def output(prefs, folder, parents, children, bookmarks, keywords):
+ tmpl = TemplateManager().prepare("folders.tmpl")
+ tproc = get_template_processor(prefs)
+ tproc.set('Parents', parents)
+ tproc.set('folder', folder['id'])
+ tproc.set('name', folder['name'])
+ tproc.set('total', len(bookmarks))
+ bookmarks.sort(lambda l,r: cmp(l['name'],r['name']))
+ tproc.set('Bookmarks', bookmarks)
+ tproc.set('Subfolders', children)
+ keywords = sort_keywords(keywords[1:], prefs)
+ tproc.set('Keywords', keywords)
+ print tproc.process(tmpl)
+
+if (__name__ == "__main__"):
+ form = cgi.FieldStorage()
+ db = my_db.connect(environ["REMOTE_USER"])
+ if form.has_key('folder'):
+ folder = int(form['folder'].value)
+ else:
+ folder = 0
+ if form.has_key('action'):
+ if form['action'].value == 'add':
+ if form.has_key('sel'):
+ keyword = int(form['sel'].value)
+ db.add_folder(keyword, folder)
+ print "<em>Folder successfully add.</em>"
+ parents = db.get_folder_parents_and_self(folder)
+ children = db.get_subfolders(folder)
+ parents.reverse()
+ selection = map(lambda e: e['keyword'], parents)
+ exclusion = map(lambda e: e['keyword'], children)
+ bookmarks = db.select_bookmarks(selection, exclusion)
+ selected_keywords = set_selection(db,
+ map(lambda e: e[0], bookmarks),
+ selection, exclusion)
+ keywords = []
+ for keyword in selected_keywords:
+ if not keyword['id'] in exclusion:
+ keywords.append(keyword)
+ for child in children:
+ child['count'] = len(db.select_bookmarks(selection + [child['keyword']]))
+ bookmarks = db.get_bookmarks(map(lambda bk: bk[0], bookmarks))
+ bookmarks = map(lambda bk: bk.dict(), bookmarks)
+ output(db.get_preferences(), parents.pop(), parents, children, bookmarks, keywords)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/folders.tmpl Sat Oct 18 00:56:42 2003 -0400
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <TMPL_INCLUDE NAME="headers.tmpl">
+ <body>
+ <h1><TMPL_VAR remote_user>'s XBelWeb</h1>
+ <TMPL_UNLESS folder>
+ <p><TMPL_LOOP Parents><a href="?folder=<TMPL_VAR id>"><TMPL_VAR name></a>
+ : </TMPL_LOOP></p>
+ </TMPL_UNLESS>
+ <h2><TMPL_IF folder><TMPL_VAR name><TMPL_ELSE>Main Folder</TMPL_IF>
+ (<TMPL_VAR total>)</h2>
+ <DIV class="subfolders">
+ <ul>
+ <TMPL_LOOP Subfolders>
+ <li><a href="folders.py?folder=<TMPL_VAR id>"><TMPL_VAR name>
+ (<TMPL_VAR count>)</a>
+ <a href="delete_folders.py?folder=<TMPL_VAR id>">delete</a></li>
+ </TMPL_LOOP>
+ </ul>
+ </div>
+ <form action="folders.py" method="post" name="folders">
+ <input type="hidden" name="folder" value="<TMPL_VAR folder>"/>
+ <label>Add subfolder with keyword:
+ <select name="sel" size="1">
+ <TMPL_LOOP Keywords>
+ <option value="<TMPL_VAR id>"
+ ><TMPL_VAR keyword> (<TMPL_VAR count>)</option>
+ </TMPL_LOOP></select>
+ <button name="action" value="add">Add</button>
+ </form>
+ <hr>
+ <div class="bookmarks">
+ <dl>
+ <TMPL_LOOP Bookmarks>
+ <dt>
+ <a href="<TMPL_VAR url>"><TMPL_VAR name></a>
+ <a href="edit.py?id=<TMPL_VAR id>">edit</a>
+ </dt>
+ <dd><p><TMPL_VAR desc></p></dd>
+ </TMPL_LOOP>
+ </dl>
+ </div>
+ <hr>
+ </body>
+</html>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:nil
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vi: syntax=html
+-->
--- a/lib/create_db.sql Fri Oct 17 15:05:17 2003 -0400
+++ b/lib/create_db.sql Sat Oct 18 00:56:42 2003 -0400
@@ -59,6 +59,20 @@
CREATE INDEX index_bkkw_user ON bookmarks_keywords (userid);
CREATE INDEX index_bkkw_bkuser ON bookmarks_keywords (bookmark, userid);
+--
+-- Folders structure
+--
+
+CREATE TABLE folders (
+ id int DEFAULT '0' NOT NULL,
+ userid int DEFAULT '0' NOT NULL,
+ keyword int DEFAULT '0' NOT NULL,
+ parent int DEFAULT '0' NOT NULL,
+ PRIMARY KEY (id, userid)
+);
+
+CREATE INDEX index_folders_parent ON folders (userid, parent);
+
--
-- Table structure for table 'db_sequence'
--
--- a/lib/my_db.py Fri Oct 17 15:05:17 2003 -0400
+++ b/lib/my_db.py Sat Oct 18 00:56:42 2003 -0400
@@ -44,6 +44,14 @@
VALUES ('bookmarks', %d, 0);
""" %(id,))
self.crs.execute("""
+ INSERT INTO folders(id, keyword, parent, userid)
+ VALUES (0, 0, -1, %d);
+ """ %(id,))
+ self.crs.execute("""
+ INSERT INTO db_sequence(seq_name, userid, nextid)
+ VALUES ('folders', %d, 1);
+ """ %(id,))
+ self.crs.execute("""
INSERT INTO preferences(userid)
VALUES (%d);
""" %(id,))
@@ -261,6 +269,68 @@
qry = qry + ';'
self.crs.execute(qry)
return self.crs.fetchall()
+ def get_folder_keyword(self, id):
+ self.crs.execute("""
+ SELECT k.id, k.name
+ FROM keywords k, folders f
+ WHERE
+ f.userid = %d AND f.id = %d
+ AND k.userid = f.userid
+ AND k.id = f.keyword;
+ """ %(self.userid, id))
+ return self.crs.fetchone()
+ def get_subfolders(self, id):
+ self.crs.execute("""
+ SELECT f.id, k.id, k.name
+ FROM folders f, keywords k
+ WHERE f.userid = %d
+ AND f.parent = %d
+ AND k.userid = f.userid
+ AND k.id = f.keyword
+ ORDER BY k.name;
+ """ %(self.userid, id))
+ res = self.crs.fetchall()
+ return map(lambda e: {
+ 'id' : e[0],
+ 'name' : e[2],
+ 'keyword' : e[1] },
+ res)
+ def get_folder_parents_and_self(self, id):
+ """Return self and parents in descending order."""
+ if id < 0:
+ return []
+ self.crs.execute("""
+ SELECT f.id, k.id, k.name, f.parent
+ FROM folders f, keywords k
+ WHERE
+ f.id = %d AND f.userid = %d
+ AND k.userid = f.userid
+ AND k.id = f.keyword;
+ """ %(id, self.userid))
+ cur = self.crs.fetchone()
+ res = [{ 'id': cur[0],
+ 'name' : cur[2],
+ 'keyword': cur[1] }]
+ return res + self.get_folder_parents_and_self(cur[3])
+ def add_folder(self, keyword, parent):
+ id = self.get_next_id('folders')
+ self.crs.execute("""
+ INSERT INTO folders(userid, id, keyword, parent)
+ VALUES (%d, %d, %d, %d);
+ """ % (self.userid, id, keyword, parent))
+ self.cnx.commit()
+ def remove_folders(self, id, commit = 1):
+ if id == 0:
+ raise "Can't erase base folder!"
+ subs = self.get_subfolders(self, id)
+ for sub in subs:
+ self.remove_folder(sub[0], 0)
+ self.crs.execute("""
+ DELETE FROM folders
+ WHERE id = %d AND userid = %d;
+ """ % (id, self.userid))
+ if commit:
+ self.cnx.commit()
def get_next_id(self, seq_name):
if seq_name == 'users':
userid = -1
--- a/lib/webutils.py Fri Oct 17 15:05:17 2003 -0400
+++ b/lib/webutils.py Sat Oct 18 00:56:42 2003 -0400
@@ -88,4 +88,3 @@
tproc.set("total", len(bk))
print tproc.process(tmpl)
-
--- a/prefs.tmpl Fri Oct 17 15:05:17 2003 -0400
+++ b/prefs.tmpl Sat Oct 18 00:56:42 2003 -0400
@@ -3,7 +3,7 @@
<TMPL_INCLUDE NAME="headers.tmpl">
<body>
<h1><TMPL_VAR remote_user>'s Preferences</h1>
- <form action="edit_prefs.py" method="get" name="keywords">
+ <form action="edit_prefs.py" method="post" name="prefs">
<p><label>Display name:
<input type="text" name="fullname"
value="<TMPL_VAR remote_user>"/></label></p>
@@ -19,7 +19,7 @@
</TMPL_LOOP>
</select>
<input type="checkbox" name="kw_reverse"
- value="<TMPL_VAR kw_reverse>"/>
+ <TMPL_IF kw_reverse>checked</TMPL_IF>>
reversed</p>
<button>Submit</button>
</form>