Skip to content

Instantly share code, notes, and snippets.

@thruflo
Created June 16, 2010 21:16
Show Gist options
  • Select an option

  • Save thruflo/441281 to your computer and use it in GitHub Desktop.

Select an option

Save thruflo/441281 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""We persist data in couchdb_ via Couchdbkit_.
.. _couchdb: http://couchdb.apache.org/
.. _Couchdbkit: http://couchdbkit.org/
"""
__all__ = [
'User',
'Repository',
'Document',
]
import logging
from os.path import dirname, join as join_path
from couchdbkit import Server, ResourceNotFound, ResourceConflict
from couchdbkit import Document as CouchDBKitDocument
from couchdbkit.exceptions import BulkSaveError
from couchdbkit.loaders import FileSystemDocsLoader
from couchdbkit.schema.properties import *
import config
class Couch(object):
"""Convenience wrapper around the ``couchdbkit``
``Server`` and ``FileSystemDocsLoader`` internals.
Provides the ``couchdbkit.Database`` called "thruflo"
as ``self.db``.
"""
def sync(self):
path = join_path(dirname(__file__), '_design')
self.loader = FileSystemDocsLoader(path)
self.loader.sync(self.db)
def __init__(self, sync=config.debug):
self.db = Server().get_or_create_db('thruflo')
if sync:
self.sync()
couch = Couch()
class BaseDocument(CouchDBKitDocument):
"""Tweak Couchdbkit a little and extends it to provide ``ver``
``mod`` and ``archived``.
"""
@classmethod
def get_or_create(cls, docid=None, db=None, dynamic_properties=True, **params):
"""There's a bug passing params to the original version
of this method. The only change made here is to not pass
``**params`` to ``cls._db.get()``.
"""
if db is not None:
cls._db = db
cls._allow_dynamic_properties = dynamic_properties
if cls._db is None:
raise TypeError("doc database required to save document")
if docid is None:
raise ValueError("why use ``get_or_create`` without a ``docid``?")
rev = params.pop('rev', None)
try:
return cls._db.get(docid, rev=rev, wrapper=cls.wrap)
except ResourceNotFound:
obj = cls()
obj._id = docid
obj.update(params)
obj.save()
return obj
def __getattr__(self, key):
"""We like using ``doc.id``.
"""
if key == 'id':
key = '_id'
return super(BaseDocument, self).__getattr__(key)
def update(self, data):
"""Convienience method for setting multiple properties
at once from a dictionary.
"""
for k, v in data.iteritems():
setattr(self, k, v)
ver = IntegerProperty(default=1)
mod = DateTimeProperty(auto_now=True)
archived = BooleanProperty(default=False)
BaseDocument.set_db(couch.db)
class User(BaseDocument):
"""``User``s can use the system.
"""
username = StringProperty(required=True)
password = StringProperty(required=True)
name = StringProperty(required=True)
email = StringProperty(required=True)
class Repository(BaseDocument):
"""``User``s can own and share access to ``Repository``s.
"""
name = StringProperty(required=True)
owner = StringProperty(required=True)
sharers = StringListProperty()
class Document(BaseDocument):
"""``Repository``s contain ``Document``s.
"""
repository = StringProperty(required=True)
path = StringProperty(required=True)
content = StringProperty()
def sync():
"""Syncs the couchdb views in the database with the
``./_design`` folder.
"""
couch.sync()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment