Beispiel #1
0
class KVPair(db.Model):
    __tablename__ = 'kvpair'
    key = db.Column(db.String(64), primary_key=True)
    value = db.Column(db.Text)

    def __init__(self, key, value):
        self.key = key
        self.value = value
Beispiel #2
0
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True)
    password = db.Column(db.String(256))
    auth_token = db.Column(db.String(256))

    def __init__(self, username, password):
        self.username = username
        self.password = hash_password(password)
        self.auth_token = pwd_context.encrypt('{0}{1}'.format(
            username, app.config['SECRET_KEY']))

    def verify_password(self, password):
        return pwd_context.verify(password, self.password)

    def change_password(self, password):
        self.password = hash_password(password)
        self.auth_token = pwd_context.encrypt('{0}{1}'.format(
            self.username, app.config['SECRET_KEY']))

    @property
    def is_authenticated(self):
        return True

    @property
    def is_active(self):
        return True

    @property
    def is_anonymous(self):
        return False

    @property
    def is_admin(self):
        if self.username == 'admin':
            return True
        else:
            return False

    def get_id(self):
        try:
            return unicode(self.id)
        except NameError:
            return str(self.id)

    def __repr__(self):
        return '<User %r>' % self.username

    def get_auth_token(self):
        return self.auth_token
Beispiel #3
0
class Log(db.Model):
    __tablename__ = 'log'
    id = db.Column(db.Integer, primary_key=True)
    entity = db.Column(db.String(ID_MAX))
    user = db.Column(db.String(32))
    timestamp = db.Column(db.DateTime)
    data = db.Column(db.Text)

    def __init__(self, entity, user, data):
        self.entity = entity
        self.data = data
        self.user = user
        self.timestamp = datetime.now()

    def __repr__(self):
        return 'Entity `%s\', user `%s\' (%s): %s' %\
            (self.entity, self.user, self.timestamp, self.data)
Beispiel #4
0
class ImportLog(db.Model):
    __tablename__ = 'ImportLog'
    id = db.Column(db.Integer, primary_key=True)
    import_id = db.Column(db.String(ID_MAX))
    # XXX: Do not add a foreign key constraint referencing User
    user = db.Column(db.String(32))
    timestamp = db.Column(db.DateTime)
    data = db.Column(db.Text)

    def __init__(self, import_id, user, data):
        self.import_id = import_id
        self.data = data
        self.user = user
        self.timestamp = datetime.now()

    def __repr__(self):
        return 'Import `%s\', user `%s\' (%s): %s' %\
            (self.import_id, self.user, self.timestamp, self.data)
Beispiel #5
0
class DocumentHit(db.Model):
    __tablename__ = 'documenthit'
    id = db.Column(db.Integer, primary_key=True)
    ip = db.Column(db.String(15))
    document_id = db.Column(
        db.Integer,
        db.ForeignKey("document.id", onupdate='cascade', ondelete='cascade'))
    referrer = db.Column(db.String(128))
    timestamp = db.Column(db.DateTime)

    def __init__(self, document, ip, referrer):
        self.document_id = document
        self.ip = ip
        self.referrer = clean_url(referrer) if referrer else referrer
        self.timestamp = datetime.now()

    def __repr__(self):
        return '<DocumentHit, time=%s, document=%s, type=%s>' %\
            (self.timestamp, self.document_id, self.document.type)
Beispiel #6
0
class Data(Document):
    __tablename__ = 'data'
    id = db.Column(db.Integer,
                   db.ForeignKey('document.id',
                                 onupdate='cascade',
                                 ondelete='cascade'),
                   primary_key=True)
    _format = db.Column('format', db.Enum(*data_formats, name='Format'))

    __mapper_args__ = {'polymorphic_identity': 'data'}

    def __init__(self, entity, format, url=None, enabled=True, notes=None):
        super(Data, self).__init__(entity,
                                   url=url,
                                   enabled=enabled,
                                   notes=notes)
        if format in data_formats:
            self.format = format
        else:
            raise Exception("Incorrect data format")

    def __repr__(self):
        return '<Data(%s), entity=%s, format=%s, url=%s, enabled=%s>' %\
            (self.id, self.entity_id, self.format, self.url, self.enabled)

    @property
    def data_pid(self):
        url = '{base_url}/collection/{entity_type}/data/{entity_id}'.format(
            base_url=app.config['BASE_URL'],
            entity_type=self.entity.type,
            entity_id=self.entity_id)
        return url

    @property
    def persistent_uri(self):
        uri = app.config['BASE_URL']
        uri += '/collection/%s/data/%s/%s' % (self.entity.type, self.entity_id,
                                              self.format)

        p = urlparse.urlparse(uri, 'http')
        netloc = p.netloc or p.path
        path = p.path if p.netloc else ''
        p = urlparse.ParseResult('http', netloc, path, *p[3:])
        uri = p.geturl()

        uris = [uri]

        if kvstore.get('titles_enabled'):
            uris.append(uri + '/' + self.entity.slug)
        if self.format == 'html':
            uris.append(uri[:-5])

        return uris

    def to_dict(self):
        dict = super(Data, self).to_dict()
        dict['format'] = self.format
        return dict

    @property
    def format(self):
        return self._format

    @format.setter
    def format(self, value):
        if value not in data_formats:
            raise Exception("Incorrect data format")
        if self._format != value:
            log(
                self.entity_id, "Changed format from '%s' to '%s' for %s" %
                (self._format, value, self))

        self._format = value

    format = db.synonym('_format', descriptor=format)
Beispiel #7
0
class Entity(db.Model):
    __tablename__ = 'entity'
    _id = db.Column('id', db.String(ID_MAX), primary_key=True)
    original_id = db.Column(db.String(ID_MAX))
    _type = db.Column('type', db.Enum(*entity_types, name='EntityType'))
    _title = db.Column('title', db.String(TITLE_MAX))
    slug = db.Column(db.String(SLUG_MAX))

    _documents = db.relationship(
        "Document",
        #cascade='all,delete',
        cascade='all,delete-orphan',
        backref='entity',
        order_by='Document.type')

    def __init__(self, id, type='work', title=None):
        self.id = id
        self.type = type
        self.title = title

    def __repr__(self):
        return '<Entity(%s), id=%s (%s), title=%s>' %\
            (self.type, self.id, self.original_id, self.title)

    @property
    def persistent_uri(self):
        url = app.config['BASE_URL'] + '/collection/%s' % self.id

        p = urlparse.urlparse(url, 'http')
        netloc = p.netloc or p.path
        path = p.path if p.netloc else ''
        p = urlparse.ParseResult('http', netloc, path, *p[3:])
        url = p.geturl()

        if kvstore.get('titles_enabled'):
            return [url, url + '/%s' % self.slug]
        else:
            return [url]

    @property
    def work_pid(self):
        url = '{base_url}/collection/{entity_id}'.format(
            base_url=app.config['BASE_URL'], entity_id=self.id)
        return url

    @property
    def persistent_uris(self):
        uris = self.persistent_uri
        for doc in self.documents:
            uris += doc.persistent_uri

        return uris

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, value):
        if self._title != value:
            log(self.id,
                "Changed title from '%s' to '%s'" % (self._title, value))

        self._title = value
        self.slug = slugify(value)[:64] if value else SLUG_DEFAULT

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, value):
        new_id = cleanID(value)
        ent = Entity.query.filter(Entity.id == new_id).first()
        # check against self (in case we're changing an existing entity's PID)
        if ent and not ent == self:
            # PID already in DB. If the unclean PID is not equal to the existing
            # entity's original PID, this is probably a collision.
            if value == ent.original_id:
                raise EntityPIDExistsException()
            else:
                raise EntityCollisionException(ent.original_id)

        if self._id != new_id:
            log(self.id, "Changed id from '%s' to '%s'" % (self._id, new_id))

        self.original_id = value
        self._id = new_id

    @property
    def type(self):
        return self._type

    @type.setter
    def type(self, value):
        if value not in entity_types:
            raise Exception("Wrong entity type")

        if self._type != value:
            log(self.id,
                "Changed type from '%s' to '%s'" % (self._type, value))

        self._type = value

    @property
    def documents(self):
        def sort_help(a, b):
            # Helper function for sorting the documents list
            if (a.type == 'data') or (b.type == 'data'):
                return 0
            else:
                return -1 if a.order < b.order else 1

        docs = self._documents
        return sorted(docs, sort_help)

    @property
    def active_documents(self):
        count = 0
        for document in self.documents:
            if document.enabled and\
               (document.url != '' or document.url != None):
                count += 1

        return count

    id = db.synonym('_id', descriptor=id)
    title = db.synonym('_title', descriptor=title)
    type = db.synonym('_type', descriptor=type)
Beispiel #8
0
class Representation(Document):
    __tablename__ = 'representation'
    id = db.Column(db.Integer,
                   db.ForeignKey('document.id',
                                 onupdate='cascade',
                                 ondelete='cascade'),
                   primary_key=True)
    order = db.Column(db.Integer)
    _reference = db.Column('reference', db.Boolean)
    label = db.Column(db.String(LABEL_MAX))

    __mapper_args__ = {'polymorphic_identity': 'representation'}

    def __init__(self,
                 entity,
                 order,
                 label=None,
                 url=None,
                 enabled=True,
                 notes=None,
                 reference=False):
        super(Representation, self).__init__(entity,
                                             url=url,
                                             enabled=enabled,
                                             notes=notes)
        self.order = order
        self.reference = reference
        self.label = label

    def __repr__(self):
        if self.label:
            return '<Representation(%s), entity=%s, label=%s, url=%s, order=%s, ref=%s, enabled=%s>' %\
                (self.id, self.entity_id, self.label, self.url, self.order,
                 self.reference, self.enabled)
        else:
            return '<Representation(%s), entity=%s, url=%s, order=%s, ref=%s>' %\
                (self.id, self.entity_id, self.url, self.order, self.reference)

    @property
    def persistent_uri(self):
        uri = app.config['BASE_URL']
        uri += '/collection/%s/representation/%s/%s' % (
            self.entity.type, self.entity_id, self.order)

        p = urlparse.urlparse(uri, 'http')
        netloc = p.netloc or p.path
        path = p.path if p.netloc else ''
        p = urlparse.ParseResult('http', netloc, path, *p[3:])
        uri = p.geturl()

        uris = [uri]

        if kvstore.get('titles_enabled'):
            uris.append(uri + '/' + self.entity.slug)
        if self.reference:
            uri = app.config[
                'BASE_URL'] + '/collection/%s/representation/%s' % (
                    self.entity.type, self.entity_id)

            p = urlparse.urlparse(uri, 'http')
            netloc = p.netloc or p.path
            path = p.path if p.netloc else ''
            p = urlparse.ParseResult('http', netloc, path, *p[3:])
            uri = p.geturl()

            uris.append(uri)

        return uris

    def to_dict(self):
        dict = super(Representation, self).to_dict()
        dict['order'] = self.order
        dict['reference'] = self.reference
        dict['label'] = self.label
        return dict

    @property
    def reference(self):
        return self._reference

    @reference.setter
    def reference(self, value):
        value = bool(value)
        if self._reference and (not value):
            log(self.entity_id, "Removed as reference: %s" % self)
        elif (not self._reference) and value:
            log(self.entity_id, "Set as reference: %s" % self)

        self._reference = value

    reference = db.synonym('_reference', descriptor=reference)
Beispiel #9
0
class Document(db.Model):
    __tablename__ = 'document'
    id = db.Column(db.Integer, primary_key=True)
    entity_id = db.Column(db.String(64), db.ForeignKey("entity.id",
                                                       onupdate='cascade',
                                                       ondelete='cascade'))
    _enabled = db.Column('enabled', db.Boolean)
    notes = db.Column(db.Text)
    _url = db.Column('url', db.String(512))
    type = db.Column(db.String(50))
    hits = db.relationship('DocumentHit',
                           #cascade='all,delete',
                           cascade='all, delete-orphan',
                           backref='document')

    __mapper_args__ = {
        'polymorphic_identity': 'document',
        'polymorphic_on': type
    }

    def __init__(self, entity_id, url=None, enabled=True, notes=None):
        self.url = url
        self.entity_id = entity_id
        self.enabled = enabled
        self.notes = notes

    def __repr__(self):
        raise Exception("Implement me")

    def to_dict(self):
        return {'url':self.url if self.url else "",
                'enabled':self.enabled,
                'id':self.id,
                'type':self.type,
                'notes':self.notes,
                'resolves':self.resolves,
                'entity':self.entity_id}

    @property
    def persistent_uri(self):
        raise Exception("Implement me")

    @property
    def resolves(self):
        if self.url:
            try:
                r = requests.head(self.url, allow_redirects=True)
                if r.status_code == 200:
                    return True
                else:
                    return False
            except:
                return False
        else:
            return False

    @property
    def url(self):
        return self._url

    @url.setter
    def url(self, url):
        # TODO: URL validation here

        old = self._url
        if url:
            u = urlparse(url)
            if u.scheme:
                self._url = url
            else:
                self._url = urlunparse(('http',)+u[1:])
        else:
            self._url = None

        if old != self._url:
            log(self.entity_id, "Changed URL from '%s' to '%s' for %s" %
                (old, self._url, self))

    @property
    def enabled(self):
        return self._enabled

    @enabled.setter
    def enabled(self, value):
        value = bool(value)
        if self._enabled and (not value):
            log(self.entity_id, "Disabled document %s" % self)
        elif (not self._enabled) and value:
            log(self.entity_id, "Enabled document %s" % self)

        self._enabled = value

    enabled = db.synonym('_enabled', descriptor=enabled)
    url = db.synonym('_url', descriptor=url)