[svn r1530] Add and browse working.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.cvsignore Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,2 @@
+*.pyc
+*.tmplc
--- a/.htaccess Tue Sep 23 10:26:35 2003 -0400
+++ b/.htaccess Tue Sep 23 15:11:11 2003 -0400
@@ -1,8 +1,9 @@
-AuthType Basic
-AuthUserFile /home/fabien/.htpasswd
AddHandler cgi-script py
Options +ExecCGI
DirectoryIndex index.py
+AuthType Basic
+AuthName Fabien@TZoNE
+AuthUserFile /home/fabien/.htpasswd
<Limit GET POST>
require valid-user
</Limit>
--- a/add.py Tue Sep 23 10:26:35 2003 -0400
+++ b/add.py Tue Sep 23 15:11:11 2003 -0400
@@ -14,30 +14,17 @@
from htmltmpl import TemplateManager, TemplateProcessor
import my_db
import time
-import bkmark
-
-def main(msg):
- tmpl = TemplateManager().prepare("add.tmpl")
- tproc = TemplateProcessor()
- tproc.set("msg", msg)
+from bkmark import Bookmark
-# tproc.set("syntax", user.syntax)
-# for syntax in Tester.syntax_name:
-# tproc.set("syntax_" + syntax,
-# (Tester.syntax_name[user.syntax] == syntax))
-# tproc.set("id", user.id)
-# tproc.set("gender", user.gender);
-# tproc.set("age", user.age);
-# exp = []
-# for key in Tester.keys:
-# exp.append({ 'name' : key,
-# 'value' : user.experience[key] });
-# tproc.set('Exp', exp);
+def main(keywords):
+ tmpl = TemplateManager().prepare("add_bk.tmpl")
+ tproc = TemplateProcessor()
+ tproc.set('Keywords', keywords);
print tproc.process(tmpl)
if (__name__ == "__main__"):
- form = cgi.FieldStorage()
- cnx = my_db.connect()
- entry = bkmark.get_from_form(form)
- qry = entry.add_to_db(cnx)
- main(str(qry))
+ db = my_db.connect()
+ kw = db.get_all_keywords()[1:]
+ kw.sort(lambda l,r: cmp(l[1],r[1]))
+ kw = map(lambda elem: { 'id' : elem[0], 'keyword' : elem[1] }, kw)
+ main(kw)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/add_bk.tmpl Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <title>Add a bookmark</title>
+ </head>
+ <body>
+ <h1>Add a bookmark</h1>
+ <form action="add_result.py" method="post" name="add">
+ <fieldset class="bookmark">
+ <label>Nom: <input type="text" name="name"></label><br/>
+ <label>URL: <input type="text" name="url"></label><br/>
+ <label for="desc">Description: </label><br/>
+ <textarea name="desc" rows="5" cols="40"></textarea>
+ <button type="submit" name="submit">Soumettre</button>
+ </fieldset>
+ <fieldset class="keywords">
+ <legend>Mots clés:</legend>
+ <ul>
+ <TMPL_LOOP Keywords>
+ <li><input type="checkbox" name="kw" value="<TMPL_VAR id>"/><TMPL_VAR keyword></li>
+ </TMPL_LOOP>
+ </ul>
+ </form>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/add_result.py Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+
+import sys
+import traceback
+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
+from htmltmpl import TemplateManager, TemplateProcessor
+import my_db
+import time
+from bkmark import Bookmark
+
+def get_bk_from_form(form):
+ bk = Bookmark()
+ bk.url = form['url'].value
+ bk.name = form['name'].value
+ bk.desc = form['desc'].value
+ return bk
+
+def get_kw_from_form(form):
+ kw = form.getvalue("kw")
+ if not isinstance(kw, type([])):
+ if kw:
+ kw = [kw]
+ else:
+ kw = []
+ kw = map(int, kw)
+ return kw
+
+def main(bk, kw):
+ tmpl = TemplateManager().prepare("add_result.tmpl")
+ tproc = TemplateProcessor()
+ tproc.set("url", bk.url)
+ tproc.set("name", bk.name)
+ tproc.set("added", bk.added)
+ tproc.set("desc", bk.desc)
+ tproc.set("Keywords", kw)
+ print tproc.process(tmpl)
+
+if (__name__ == "__main__"):
+ form = cgi.FieldStorage()
+ db = my_db.connect()
+ bk = get_bk_from_form(form)
+ kw = get_kw_from_form(form)
+ id = db.add_bookmark(bk)
+ db.update_keywords(id, kw)
+ kw = map(lambda e: { 'keyword': e[1] }, db.get_keywords(id)[1:])
+ main(bk, kw)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/add_result.tmpl Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
+ <title>Bookmarker 3</title>
+ </head>
+ <body>
+ <h1>Bookmarker 3</h1>
+ <p>Welcome to bookmarker 3!</p>
+ <p>Bookmark successfully added:</p>
+ <p><a href="<TMPL_VAR url>"><TMPL_VAR name></a><p>
+ <p><TMPL_VAR desc></p>
+ <p>Keywords:</p>
+ <TMPL_INCLUDE NAME="keywords.tmpl">
+ </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:
+-->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/keywords.tmpl Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,6 @@
+<ul>
+<TMPL_LOOP Keywords>
+ <li><TMPL_VAR keyword></li>
+</TMPL_LOOP>
+</ul>
+
--- a/index.py Tue Sep 23 10:26:35 2003 -0400
+++ b/index.py Tue Sep 23 15:11:11 2003 -0400
@@ -14,27 +14,42 @@
from htmltmpl import TemplateManager, TemplateProcessor
import my_db
-def main(msg):
+def get_selection(form):
+ kw = form.getvalue("kw")
+ if not isinstance(kw, type([])):
+ if kw:
+ kw = [kw]
+ else:
+ kw = [0]
+ return map(int, kw)
+
+def set_selection(kw, sel):
+ res = []
+ for key in kw:
+ chk = key[0] in sel
+ res.append({'id':key[0],
+ 'keyword': key[1],
+ 'checked' : chk})
+ return res
+
+def main(bk, kw):
tmpl = TemplateManager().prepare("index.tmpl")
tproc = TemplateProcessor()
- tproc.set("msg", msg)
-
-# tproc.set("syntax", user.syntax)
-# for syntax in Tester.syntax_name:
-# tproc.set("syntax_" + syntax,
-# (Tester.syntax_name[user.syntax] == syntax))
-# tproc.set("id", user.id)
-# tproc.set("gender", user.gender);
-# tproc.set("age", user.age);
-# exp = []
-# for key in Tester.keys:
-# exp.append({ 'name' : key,
-# 'value' : user.experience[key] });
-# tproc.set('Exp', exp);
+ tproc.set("Bookmarks", bk)
+ tproc.set("Keywords", kw)
print tproc.process(tmpl)
if (__name__ == "__main__"):
form = cgi.FieldStorage()
- cnx = my_db.connect()
- qry = cnx.query('SELECT name FROM keywords;')
- main(str(qry.getresult()))
+ db = my_db.connect()
+ keywords = db.get_all_keywords()[1:]
+ selection = get_selection(form)
+ if selection[0] == 0:
+ exc = map(lambda e: int(e[0]), keywords)
+ bookmarks = db.select_bookmarks([0], exc)
+ else:
+ bookmarks = db.select_bookmarks(selection)
+ keywords = set_selection(keywords, selection)
+ bookmarks = db.get_bookmarks(map(lambda x: x[0], bookmarks))
+ bookmarks = map(lambda bk: bk.dict(), bookmarks)
+ main(bookmarks, keywords)
--- a/index.tmpl Tue Sep 23 10:26:35 2003 -0400
+++ b/index.tmpl Tue Sep 23 15:11:11 2003 -0400
@@ -7,7 +7,26 @@
<body>
<h1>Bookmarker 3</h1>
<p>Welcome to bookmarker 3!</p>
- <pre><TMPL_VAR msg></pre>
+ <dl>
+ <TMPL_LOOP Bookmarks>
+ <dt><a href="<TMPL_VAR url>"><TMPL_VAR name></a></dt>
+ <dd><p><TMPL_VAR desc></p></dd>
+ </TMPL_LOOP>
+ </ul>
+ <form action="index.py" method="post" name="keywords">
+ <fieldset class="keywords">
+ <legend>Keywords:</legend>
+ <ul>
+ <TMPL_LOOP Keywords>
+ <li><input type="checkbox" name="kw"
+ <TMPL_IF checked>checked</TMPL_IF>
+ value="<TMPL_VAR id>"/><TMPL_VAR keyword></li>
+ </TMPL_LOOP>
+ </ul>
+ </fieldset>
+ <button type="submit">Refresh</button>
+ </form>
+ <form type
</body>
</html>
<!-- Keep this comment at the end of the file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/.cvsignore Tue Sep 23 15:11:11 2003 -0400
@@ -0,0 +1,2 @@
+*.pyc
+*.tmplc
--- a/lib/bkmark.py Tue Sep 23 10:26:35 2003 -0400
+++ b/lib/bkmark.py Tue Sep 23 15:11:11 2003 -0400
@@ -4,9 +4,18 @@
class Bookmark:
def __init__(self):
+ self.id = -1
self.url = ''
self.name = ''
self.desc = ''
self.added = time.strftime('%Y-%m-%d')
+ def dict(self):
+ return {
+ 'id' : self.id,
+ 'url' : self.url,
+ 'name' : self.name,
+ 'desc' : self.desc,
+ 'added' : self.added
+ }
--- a/lib/my_db.py Tue Sep 23 10:26:35 2003 -0400
+++ b/lib/my_db.py Tue Sep 23 15:11:11 2003 -0400
@@ -1,116 +1,154 @@
#!/usr/bin/python
-import pg
+import pgdb
import config
+from bkmark import Bookmark
class MyDbConnexion:
def __init__(self):
- self.cnx = pg.connect(config.database, config.host,
- config.port, None, None, config.user, config.passwd)
+ self.cnx = pgdb.connect(database = config.database,
+ host = config.host+':%d'%config.port,
+ user = config.user, password = config.passwd)
+ self.crs = self.cnx.cursor();
def add_bookmark(self, bk):
id = self.get_next_id('bookmarks')
- res = self.cnx.query("""
+ self.crs.execute("""
INSERT INTO bookmarks(id, url, name, ldesc, added)
VALUES (%d, '%s', '%s', '%s', '%s');
- INSERT INTO bookmarks(bookmark, keyword)
+ INSERT INTO bookmarks_keywords(bookmark, keyword)
VALUES (%d, %d);
""" % (id, bk.url, bk.name, bk.desc, bk.added,
id, 0))
+ self.cnx.commit()
return id
- def get_bookmark(self, id):
- bk = Bookmark()
- res = self.cnx.query("""
- SELECT url, name, ldesc, added
+ def get_bookmarks(self, ids):
+ qry = """
+ SELECT id, url, name, ldesc, added
FROM bookmarks
- WHERE id = %d;
- """ % (id,))
- res = res.dictresult()[0]
- bk.url = res['url']
- bk.name = res['name']
- bk.desc = res['ldesc']
- bk.added = res['added']
- bk.id = id
- return bk
+ WHERE id = %d
+ """ % (ids.pop(),)
+ for id in ids:
+ qry = qry + " OR id = %d" % (id,)
+ qry = qry + ";"
+ self.crs.execute(qry)
+ bks = []
+ list = self.crs.fetchall()
+ for res in list:
+ bk = Bookmark()
+ bk.id = res[0]
+ bk.url = res[1]
+ bk.name = res[2]
+ bk.desc = res[3]
+ bk.added = res[4]
+ bks.append(bk)
+ return bks
def update_bookmark(self, bk):
- return self.cnx.query("""
+ self.crs.execute("""
UPDATE bookmarks
SET url = '%s', name = '%s',
ldesc = '%s', added = '%s'
WHERE id = %d;
""" % (bk.url, bk.name, bk.desc, bk.added, bk.id))
+ self.cnx.commit()
+ def update_keywords(self, id, keywords):
+ self.crs.execute("""
+ DELETE FROM bookmarks_keywords
+ WHERE bookmark = %d AND
+ keyword <> 0;""" % (id,))
+ for kw in keywords:
+ if kw == 0: continue
+ self.crs.execute("""
+ INSERT INTO
+ bookmarks_keywords(bookmark, keyword)
+ VALUES (%d, %d);""" % (id, kw))
+ self.cnx.commit()
def remove_bookmark(self, id):
- return self.cnx.query("""
+ self.crs.execute("""
DELETE FROM bookmarks_keywords
WHERE bookmark = %d;
DELETE FROM bookmarks
WHERE id = %d;
""" % (id, id))
+ self.cnx.commit()
def add_keyword(self, name):
id = self.get_next_id('keywords')
- res = self.cnx.query("""
+ self.crs.execute("""
INSERT INTO keywords(id, name)
VALUES (%d, '%s')'
""" % (id, name))
+ self.cnx.commit()
return id
def get_keyword(self, id):
- return self.cnx.query("""
+ self.crs.execute("""
SELECT name FROM keywords
WHERE keyword.id = %d;
- """ % (id,)).getresult()[0][0]
+ """ % (id,))
+ return self.crs.fetchone()[0]
def get_keywords(self, bk_id):
- return self.cnx.query("""
+ self.crs.execute("""
SELECT id, name FROM keywords, bookmarks_keywords
WHERE keywords.id = bookmarks_keywords.keyword
- AND bookmarks_keywords.bookmark = %d;
+ AND bookmarks_keywords.bookmark = %d
+ ORDER BY id;
""" % (bk_id,))
+ return self.crs.fetchall()
def update_keyword(self, id, name):
- return self.cnx.query("""
+ self.crs.execute("""
UPDATE keywords
SET name = '%s'
WHERE id = %d;
""" % (name, id))
+ self.cnx.commit()
def remove_keyword(self, id):
if id == 0:
raise "Can't remove default keyword!"
- return self.cnx.query("""
+ self.crs.execute("""
DELETE FROM bookmarks_keywords
WHERE keyword = %d;
DELETE FROM keywords
WHERE id = %d;
""" % (id, id))
+ self.cnx.commit()
def merge_keywords(self, merge_id, into_id):
- self.cnx.query("""
+ self.crs.execute("""
UPDATE bookmarks_keywords
SET keyword = %d
WHERE keyword = %d;
""" % (into_id, merge_id))
self.remove_keyword(merge_id)
def get_all_keywords(self):
- self.cnx.query("SELECT id, name FROM keywords;"
- def get_bookmarks(self, has_kw, except_kw):
+ """Return a list of pair-elements [id, keyword]."""
+ self.crs.execute("SELECT id, name FROM keywords ORDER BY id;")
+ return self.crs.fetchall()
+ def select_bookmarks(self, has_kw = [0], except_kw = []):
+ """
+Return a list of id bookmarks who has /has_kw/ set but not /except_kw/.
+"""
basic_qry = """
- SELECT id, name, url FROM bookmarks, bookmarks_keywords
+ SELECT id FROM bookmarks, bookmarks_keywords
WHERE bookmarks.id = bookmarks_keywords.bookmark
AND bookmarks_keywords.keyword = %d
"""
- has_kw.reverse()
- kw = has_kw.pop()
- qry = basic_qry % kw
- has_kw.reverse()
- for kw in has_kw:
- qry = qry + ("INTERCEPT " + basic_qry % kw)
+
+ qry = basic_qry % has_kw[0]
+ for kw in has_kw[1:]:
+ qry = qry + ("INTERSECT " + basic_qry % kw)
for kw in except_kw:
qry = qry + ("EXCEPT " + basic_qry % kw)
qry = qry + ';'
+ self.crs.execute(qry)
+ return self.crs.fetchall()
def get_next_id(self, seq_name):
- id = self.cnx.query("""
+ self.crs.execute("""
SELECT nextid FROM db_sequence WHERE
- db_sequence.seq_name = '%s';
- """ % (seq_name)).getresult()[0][0]
- self.cnx.query("""
+ db_sequence.seq_name = '%s' FOR UPDATE;
+ """ % (seq_name))
+ id = self.crs.fetchone()[0]
+ self.crs.execute("""
UPDATE db_sequence SET nextid = %d
WHERE seq_name = 'bookmarks';
""" % (id+1,))
+ return id
def connect():
return MyDbConnexion()