[Assorted-commits] SF.net SVN: assorted: [890] simple-zdb
Brought to you by:
yangzhang
From: <yan...@us...> - 2008-07-16 05:04:15
|
Revision: 890 http://assorted.svn.sourceforge.net/assorted/?rev=890&view=rev Author: yangzhang Date: 2008-07-15 22:04:18 -0700 (Tue, 15 Jul 2008) Log Message: ----------- added initial version of simple-zdb, which has brain-dead objects and props, along with a simple parser for my silly little textual object description format/language Added Paths: ----------- simple-zdb/ simple-zdb/trunk/ simple-zdb/trunk/README simple-zdb/trunk/src/ simple-zdb/trunk/src/zdb.py Added: simple-zdb/trunk/README =================================================================== --- simple-zdb/trunk/README (rev 0) +++ simple-zdb/trunk/README 2008-07-16 05:04:18 UTC (rev 890) @@ -0,0 +1,11 @@ +Overview +-------- + +Combination of: + +- bookmark manager, contact manager, tasklist, calendar, notebook +- object graph database, like freebase +- blog, tumblelog: customizable feeds; very flexible since they're continuous + queries +- revision controlled wiki: history is maintained, feed of updates is provided + Added: simple-zdb/trunk/src/zdb.py =================================================================== --- simple-zdb/trunk/src/zdb.py (rev 0) +++ simple-zdb/trunk/src/zdb.py 2008-07-16 05:04:18 UTC (rev 890) @@ -0,0 +1,179 @@ +#!/usr/bin/env python + +from __future__ import with_statement + +from cPickle import load, dump +from cStringIO import StringIO +from commons.files import soft_makedirs +from commons.startup import run_main +from os import rename +from path import path +from re import match +from sys import stdin, stdout, stderr +from time import time +from unittest import TestCase, main as test_main + +dbdir = path( '~/.zdb/db-' ).expanduser() + +# +# fundamental classes +# + +class zdb_exception( Exception ): + pass + +class zdb( object ): + 'The actual DB.' + def __init__( self ): + self.name2obj = {} + def add( self, name, parents, props ): + self.name2obj[ name ] = obj( name, parents, props ) + def set( self, name, field, value ): + self.name2obj[ name ].props[ field ] = value + def rm( self, name ): + del self.name2obj[ name ] + def dump( self, path ): + with file( path, 'w' ) as f: + f.write( 'blah' ) + def load( self, path ): + with file( path ) as f: + parse( f.read() ) + +class obj( object ): + 'An object in the ZDB object database' + __slots__ = 'name parents props'.split() + def __eq__( self, other ): + return ( type( self ) == type( other ) and + self.name == other.name and + self.props == other.props and + self.parents == other.parents ) + def __init__( self, name, parents, props ): + global db + self.name = name + self.parents = parents + self.props = {} + for p in props: self.props[p] = [] + if name in db.name2obj: raise zdb_exception('already exists: ' + name) + db.name2obj[name] = self + +# +# DB files management +# + +def dbfiles(): return sorted( dbdir.glob('*'), key = dbnum ) +def dbnum(dbpath): return int( x.split('-')[-1] ) + +def loaddb(): + global db + dbs = dbfiles() + if dbs == []: + raise zdb_exception('no DB to load') + else: + with file(dbs[-1]) as f: tstamp, db = load(f) + +def savedb(): + global db + dbs = dbfiles() + newdb = dbdir + str( dbnum(dbs[-1]) + 1 if len( dbs ) > 0 else 0 ) + soft_makedirs( newdb.dirname() ) + with file(newdb, 'w') as f: dump( ( time(), db ), f ) + +# +# zdb +# + +def createdb(): + 'Initialize a new DB and set the `db` global to it.' + global db + db = zdb() + obj( 'concept', [], [ 'notes' ] ) + # some common types + obj( 'person', [ 'concept' ], [ 'cell', 'email', 'aim', 'msn', 'google', 'residence' ] ) +# obj( 'place', [ 'concept' ], [ 'yelp URL' ] ) +# obj( 'event', [ 'concept' ], [ 'date/time' ] ) +# obj( 'group', [ 'concept' ], [ 'cell' ] ) + +# +# parser +# + +def parse( s, parents ): + f = StringIO(s.strip()) + os = [] + while True: + name = f.readline().strip() + if name == '': break + o = obj( name, parents, [] ) + while True: + line = f.readline().strip() + if line == '': break + m = match( '^([^:]+)::$', line ) + if m is not None: + field = m.group(1) + buf = [] + while True: + line = f.readline().rstrip() + if line == '::': break + buf.append( line ) + value = '\n'.join( buf ).rstrip() + else: + [field, value] = line.split(': ', 1) + o.props[ field ] = value + os.append( o ) + return os + +# +# tests +# + +class parser_tests( TestCase ): + def setUp( self ): + createdb() + def test_simple( self ): + createdb() + [parsed] = parse( ''' +Yang Zhang +google: yaaang +notes:: +- rocks +- sucks +:: + ''', [ 'person' ] ) + createdb() + expected = obj( 'Yang Zhang', [ 'person' ], '' ) + expected.props[ 'google' ] = 'yaaang' + expected.props[ 'notes' ] = '- rocks\n- sucks' + self.assertEqual( parsed, expected ) + +# +# main +# + +def main( argv ): + global db + + try: loaddb() + except zdb_exception: createdb() + + while True: + stdout.write( '>>> ' ) + line = stdin.readline() + words = line.split() + params = words[1:] + if words != []: + cmd = words[0] + try: + if False: pass + elif cmd == 'add': db.add( *params ) + elif cmd == 'del': db.rm( *params ) + elif cmd == 'set': db.set( *params ) + elif cmd == 'edit': db.dump( *params ) + elif cmd == 'save': db.load( *params ) + elif cmd == 'quit': break + else: raise zdb_exception( 'bad command: ' + cmd ) + except BaseException, ex: + print >> stderr, ex + + savedb() + +run_main( handle_exceptions = True ) Property changes on: simple-zdb/trunk/src/zdb.py ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |