Initial commit
authorDmitriy Morozov <morozov@cs.duke.edu>
Mon, 28 Apr 2008 17:23:09 -0400
changeset 0 c9d3e04bc196
child 1 b139e134d94a
Initial commit
alexandria.py
models.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alexandria.py	Mon Apr 28 17:23:09 2008 -0400
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+import os, sys, os.path
+from optparse import OptionParser
+from models import Author, Paper, Tag, AuthorNickname, initDatabase, session
+
+db_filename = 'alexandria.db'
+
+def find_database(starting_path = None):
+    if not starting_path: starting_path = '.'
+
+    # Walk up until "alexandria.db" is found
+    # return (True, path) if found, (False, os.path.join(starting_path, 'alexandria.db')) otherwise
+    directory = starting_path
+    while os.path.abspath(directory) != '/':
+        if os.path.exists(os.path.join(directory, db_filename)):
+            break
+        directory = os.path.abspath(os.path.join(directory, '..'))
+    else:
+        return (False, os.path.join(starting_path, db_filename))
+    return (True, os.path.join(directory, db_filename))
+
+def add(args, options):
+    p = Paper(title = unicode(options.title))
+
+    for label in options.labels:
+        t = Tag.get_by_or_init(name = unicode(label))
+        t.papers.append(p)
+
+    for author in options.authors:
+        an = AuthorNickname.get_by(name = unicode(author))
+        if an: a = an.author
+        else:  a = Author.get_by_or_init(name = unicode(author))
+        a.papers.append(p)
+
+    session.flush()
+    _show_paper(p)
+
+def list(args, options):
+    papers = Paper.query.all()
+    for p in papers:
+        _show_paper(p)
+        print
+
+def alias(args, options):
+    if len(args) > 0 and len(options.authors) > 0:
+        a =  Author.get_by_or_init(name = unicode(options.authors[0]))
+        an = AuthorNickname.get_by_or_init(name = unicode(args[0]))
+        an.author = a
+        session.flush()
+
+    print "Nicknames:"
+    for an in AuthorNickname.query.all():
+        print '  %s: %s' % (an.name, an.author.name)
+
+def _show_paper(paper):
+    print paper.title
+    for author in paper.authors[:-1]:
+        print '%s,' % author,
+    print '%s' % paper.authors[-1]
+    print 'Labels:', 
+    for tag in paper.tags:
+        print tag,
+    print
+
+if __name__ == "__main__":
+    usage =  '%s COMMAND OPTIONS\n' % sys.argv[0]
+    usage += 'Commands:\n'
+    usage += '  add        - add a paper to the database\n'
+    usage += '  list       - list papers in the database\n'
+    usage += '  alias      - add or list author nicknames'
+    
+    # Parse options
+    parser = OptionParser(usage = usage)
+    parser.add_option('-a', '--author', action='append', dest='authors', help='author')
+    parser.add_option('-t', '--title', dest='title', help='title')
+    parser.add_option('-l', '--label', action='append', dest='labels', help='label')
+    parser.add_option('-D', '--database', dest='database', help='directory with the database')
+    (options, args) = parser.parse_args()
+    
+    # Find database
+    found, path = find_database(options.database)
+    initDatabase(path, not found)
+    
+    if args[0] == 'add':
+        add(args[1:], options)
+    elif args[0] == 'list':
+        list(args[1:], options)
+    elif args[0] == 'alias':
+        alias(args[1:], options)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/models.py	Mon Apr 28 17:23:09 2008 -0400
@@ -0,0 +1,51 @@
+from elixir import *
+import os.path
+
+class Author(Entity):
+    name =      Field(UnicodeText)
+    nicknames = OneToMany('AuthorNickname', inverse = 'author')
+    papers =    ManyToMany('Paper')
+
+    def __repr__(self): return self.name
+
+class AuthorNickname(Entity):
+    name =      Field(UnicodeText)
+    author =    ManyToOne('Author')
+
+    def __repr__(self): return self.name
+
+class Paper(Entity):
+    authors =   ManyToMany('Author')
+    title =     Field(UnicodeText)
+    abstract =  Field(UnicodeText)
+    tags =      ManyToMany('Tag')
+
+    path =      Field(Text)
+
+    def __repr__(self): return self.title
+
+class Tag(Entity):
+    name =      Field(UnicodeText)
+    papers =    ManyToMany('Paper')
+
+    def __repr__(self): return self.name
+
+def initDatabase(path, create_tables = True):
+    db_path = os.path.abspath(path)
+    metadata.bind = 'sqlite:///' + db_path
+    setup_all()
+    if create_tables:
+        create_all()
+
+def get_by_or_init(cls, if_new_set={}, **params):
+	"""Call get_by; if no object is returned, initialize an
+	object with the same parameters.  If a new object was
+	created, set any initial values."""
+	
+	result = cls.get_by(**params)
+	if not result:
+		result = cls(**params)
+		result.set(**if_new_set)
+	return result
+
+Entity.get_by_or_init = classmethod(get_by_or_init)