alexandria.py
author Dmitriy Morozov <morozov@cs.duke.edu>
Wed, 30 Apr 2008 10:41:18 -0400
changeset 1 b139e134d94a
parent 0 c9d3e04bc196
child 2 b8013798cbfc
permissions -rwxr-xr-x
Added hash + actually recording path + authors can be comma-separated

#!/usr/bin/env python

import os, sys, os.path
import hashlib
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):
    path = args[0]
    if not os.path.exists(path):
        print "Path %s does not exist. Cannot add paper"
        return

    path = os.path.abspath(path)
    m = hashlib.md5()
    fd = open(path, 'r')
    m.update(fd.read())
    fd.close()
    p = Paper(title = unicode(options.title), path = path, md5 = m.hexdigest())

    for label in options.labels:
        t = Tag.get_by_or_init(name = unicode(label))
        t.papers.append(p)

    for author_with_commas in options.authors:
        authors = author_with_commas.split(',')
        for author in authors:
            author = author.strip()
            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 _sort_authors(authors):
    authors.sort()          # FIXME: deal with firstname lastname issues

def _show_paper(paper):
    print paper.title
    authors = [str(a) for a in paper.authors]
    _sort_authors(authors)
    for author in authors[:-1]:
        print '%s,' % author,
    print '%s' % authors[-1]
    print 'Labels:', 
    for tag in paper.tags:
        print tag,
    print
    print "Path:   %s" % paper.path

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 len(args) == 0: sys.exit()
    if args[0] == 'add':
        add(args[1:], options)
    elif args[0] == 'list':
        list(args[1:], options)
    elif args[0] == 'alias':
        alias(args[1:], options)