1. Sam Hart
  2. noink

Commits

Sam Hart  committed a54476c Merge

merge

  • Participants
  • Parent commits a603c36, 6026111
  • Branches noink

Comments (0)

Files changed (8)

File .hgignore

View file
 *.kate-swp
 tags
 *.pyc
+.directory

File src/noink/__init__.py

View file
+"""
+
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+
+"""
+
+from flask import Flask
+from flask.ext.sqlalchemy import SQLAlchemy
+
+mainApp = Flask("noink")
+mainApp.config.from_object('noink.defaultConfig')
+try:
+    mainApp.config.from_envvar('NOINK_CONFIGURATION')
+except:
+    pass
+
+mainDB = SQLAlchemy(mainApp)
+

File src/noink/dataModels.py

View file
+"""
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+"""
+
+from noink import mainDB
+
+class User(mainDB.Model):
+    '''
+    Basic user class.
+
+    Currently, we leave authentication and, indeed, user management up to an
+    external source. By the time a user hits Noink, we assume they are a real,
+    actual user that must be in the database. If they do *not* exist in Noink,
+    then we add it.
+    '''
+    __tablename__ = 'user'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    name = mainDB.Column(mainDB.String(60))
+    fullname = mainDB.Column(mainDB.String(80))
+    bio = mainDB.Column(mainDB.String(4000))
+
+    def __init__(self, name, fullname, bio):
+        self.name = name
+        self.fullname = fullname
+        self.bio = bio
+
+    def __repr__(self):
+        return "<User %s, id %s>" % (self.name, self.id)
+
+class Group(mainDB.Model):
+    __tablename__ = 'group'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    name = mainDB.Column(mainDB.String(60))
+
+    def __init__(self, name):
+        self.name = name
+
+    def __repr__(self):
+        return "<Group %s, id %s>" % (self.name, self.id)
+
+class GroupMapping(mainDB.Model):
+    __tablename__ = 'groupmap'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    group_id = mainDB.Column(mainDB.Integer, mainDB.ForeignKey("group.id"))
+    group = mainDB.relationship('Group')
+    user_id = mainDB.Column(mainDB.Integer, mainDB.ForeignKey("user.id"))
+    user = mainDB.relationship("User")
+
+    def __init__(self, group, user):
+        self.group = group
+        self.user = user
+
+    def __repr__(self):
+        return "<Group %s : User %s>" % (self.group, self.user)
+
+class Event(mainDB.Model):
+    __tablename__ = 'events'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    event = mainDB.Column(mainDB.String(40))
+    description = mainDB.Column(mainDB.String(500))
+    date = mainDB.Column(mainDB.DateTime())
+    user = mainDB.Column(mainDB.Integer)
+    processed = mainDB.Column(mainDB.Boolean())
+    processedDate = mainDB.Column(mainDB.DateTime())
+
+    def __init__(self, event, description, date, user):
+        self.event = event
+        self.description = description
+        self.date = date
+        self.user = user
+
+    def __repr__(self):
+        return "<Event %s>" % self.event
+
+class Tag(mainDB.Model):
+    __tablename__ = 'tags'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    tag = mainDB.Column(mainDB.String(20))
+
+    def __init__(self, tag):
+        self.tag = tag
+
+    def __repr__(self):
+        return "<Tag %s>" % self.tag
+
+class TagMapping(mainDB.Model):
+    __tablename__ = 'tagmap'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    tag_id = mainDB.Column(mainDB.Integer, mainDB.ForeignKey("tags.id"))
+    tag = mainDB.relationship("Tag")
+    entry_id = mainDB.Column(mainDB.Integer, mainDB.ForeignKey("entries.id"))
+    entry = mainDB.relationship("Entry")
+
+    def __init__(self, tag, entry):
+        self.tag = tag
+        self.entry = entry
+
+    def __repr__(self):
+        return "<Tag %s : Entry %s>" % (self.tag, self.entry)
+
+class DataType(mainDB.Model):
+    __tablename__ = 'datatype'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    name = mainDB.Column(mainDB.String(20))
+
+    def __init__(self, name):
+        self.name = name
+
+    def __repr__(self):
+        return "<Type %s, id %s>" % (self.name, self.id)
+
+class Entry(mainDB.Model):
+    __tablename__ = 'entries'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    date = mainDB.Column(mainDB.DateTime())
+    title = mainDB.Column(mainDB.String(256))
+    entry = mainDB.Column(mainDB.String(40000))
+    author_id = mainDB.Column(mainDB.Integer, mainDB.ForeignKey("user.id"))
+    author = mainDB.relationship("User")
+
+    def __init__(self, title, author, date, entry):
+        self.date = date
+        self.title = title
+        self.author = author
+        self.entry = entry
+
+    def __repr__(self):
+        return "<Entry ID: %s, Title %s>" % (self.id, self.title)
+
+class Activity(mainDB.Model):
+    __tablename__ = 'activities'
+
+    id = mainDB.Column(mainDB.Integer, primary_key=True)
+    activityType = mainDB.Column(mainDB.Integer)
+    parameter = mainDB.Column(mainDB.String(256))
+    dateAdded = mainDB.Column(mainDB.DateTime())
+
+    def __init__(self, activityType, parameter, dateAdded):
+        self.activityType = activityType
+        self.parameter = parameter
+        self.dateAdded = dateAdded
+
+    def __repre__(self):
+        return "<Type '%s', Param '%s'>" % (self.activityType, self.parameter)
+

File src/noink/defaultConfig.py

View file
+"""
+Default configuration for Noink.
+
+Sensible defaults should be set here, with any local overwrites occuring by
+setting the environmental variable "NOINK_CONFIGURATION".
+
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+
+"""
+
+# The database URI for whatever DB you would like to use
+SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/noink.db"
+
+# The name of the administrative user - Note that this field SHOULD NOT be
+# changed after the database has been created, as it will not update the admin
+# user in the database!
+ADMIN_USER = "admin"
+
+# The administrative user's fullname
+ADMIN_FULLNAME = "Administrator"
+
+# The name of the administrative group - Note that this field SHOULD NOT be
+# changed after the database has been created, as it will not update the admin
+# group in the database!
+ADMIN_GROUP = "admin"
+

File src/noink/eventLog.py

View file
+'''
+The main interface to the event log.
+
+Everything should use this to interact with the event log, Nothing should work
+with the log in the database directly but this.
+
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+'''
+
+import datetime
+
+from noink import mainDB
+from noink.dataModels import Event
+from noink.eventsTable import eventTable
+
+class EventLog:
+
+    __borg_state = {}
+
+    def __init__(self):
+        self.__dict__ = self.__borg_state
+
+    def add(self, name, user, processed=False, *args):
+        '''
+        Adds an event to the log.
+
+        @param name: The event name. Should correspond to entry in eventTable
+        @param user: The id of the user generating the event
+        @param processed: If the event should be marked as processed
+        '''
+
+        if eventTable.has_key(name):
+            now = datetime.datetime.now()
+            if len(args) > 0:
+                e = Event(name, eventTable[name] % args, now, user)
+            else:
+                e = Event(name, eventTable[name], now, user)
+
+            e.processed = processed
+            if processed:
+                e.processedDate = now
+
+            mainDB.session.add(e)
+            mainDB.session.commit()
+        else:
+            raise KeyError('%s not in eventTable!' % name)

File src/noink/eventsTable.py

View file
+'''
+Defines all the possible events that can be generated.
+
+Note- you can very easily go "off the rails" and come up with your own events
+to add to the event log, but I'd *strongly* recommend just sticking to these
+here (or updating this list as needed) as we reserve the right to actually use
+specific items here in future data parsing, searching, processing, etc.
+
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+
+'''
+
+eventTable = {
+    'db_setup' : 'Initial database creation',
+    'db_finish' : 'Database initialization complete',
+    'add_user' : "User '%s' added",
+    'add_group' : "Group '%s' added"
+}

File src/noink/userDB.py

View file
+'''
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+'''
+
+import datetime
+
+from noink import mainDB
+from noink.dataModels import User, Group, GroupMapping
+from noink.eventLog import EventLog
+
+class DuplicateUser(Exception):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return repr(self.value)
+
+class DuplicateGroup(Exception):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        `return repr(self.value)
+
+class UserNotFound(Exception):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return repr(self.value)
+
+class UserDB:
+    __borg_state = {}
+
+    def __init__(self):
+        self.__dict__ = self.__borg_state
+
+        self.eventLog = EventLog()
+
+    def add(self, username, fullname, bio=""):
+        '''
+        Adds a user to the database.
+
+        @param username: The username to add, must be unique.
+        @param fullname: The user's full name
+        @param bio: The user's bio (optional)
+
+        @return The user id for the user crated.
+        '''
+        exists = User.query.filter_by(name=username).first()
+
+        if exists:
+            raise DuplicateUser("%s already exists in database with id '%d'" % (username, exists.id))
+        else:
+            u = User(username, fullname, bio)
+            mainDB.session.add(u)
+            mainDB.session.commit()
+            self.eventLog.add('add_user', u.id, True, username)
+            return u.id
+
+    def addGroup(self, groupName, userId=None):
+        '''
+        Adds a new grou to the database.
+
+        @param groupName: The group name to add, must be unique.
+        @param userId: (Optional) Single or multiple user IDs to associate with this group.
+        '''
+
+        exists = Group.query.filter_by(name=groupName).first()
+
+        if exists:
+            raise DuplicateGroup("%s already exists in database with id '%s'" % (groupName, exists.id))
+        else:
+            g = Group(groupName)
+            mainDB.session.add(g)
+            if userId:
+                exists = User.query.filter_by(id=userId).first()
+                if exists:
+                    gm = GroupMapping(g.id, userId)
+                    mainDB.session.add(gm)
+                else:
+                    raise UserNotFound("%s not found in database to match with new group" % userId)
+
+            mainDB.session.commit()
+            self.eventLog.add('add_group', (groupName))

File src/setup_db.py

View file
+#!/usr/bin/env python
+
+'''
+setup_db.py
+-----------
+Initializes the database, setting any default values
+
+##BOILERPLATE_COPYRIGHT
+##BOILERPLATE_COPYRIGHT_END
+
+'''
+
+from noink import mainApp, mainDB
+from noink.eventLog import EventLog
+from noink.userDB import UserDB
+
+eventLog = EventLog()
+userDB = UserDB()
+mainDB.create_all()
+eventLog.add('db_setup', -1, True)
+id = userDB.add(mainApp.config['ADMIN_USER'], mainApp.config['ADMIN_FULLNAME'])
+userDB.addGroup(mainApp.config['ADMIN_GROUP'], id)
+
+eventLog.add('db_finish', -1, True)
+