--- /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)