Exemple #1
0
class Frame(db.Model):
    __tablename__ = 'frame'

    urn = db.Column(db.Unicode(), primary_key=True)
    hash = db.Column(db.Unicode(), index=True)
    service_id = db.Column(db.Integer(), db.ForeignKey('service.id'))
    event_id = db.Column(db.Integer(), db.ForeignKey('event.id'))
    action_at = db.Column(db.DateTime, index=True)
    submitted_at = db.Column(db.DateTime, index=True)

    matches = db.relationship('Match', backref='frame', lazy='dynamic',
                              cascade='all, delete-orphan', order_by='Match.created_at.desc()')

    @classmethod
    def create(cls, service, event, data):
        obj = cls()
        obj.urn = data.get('urn')
        obj.hash = data.get('hash')
        obj.submitted_at = data.get('submitted_at')
        obj.action_at = data.get('action_at')
        obj.service = service
        obj.event = event
        db.session.add(obj)
        return obj

    @classmethod
    def to_urn(cls, frame):
        uuid = make_token()
        instance = app.config.get('INSTANCE', 'dwre')
        return 'urn:%s:%s:%s:%s' % (instance, frame['service'],
                                    frame['event'], uuid)

    @classmethod
    def by_hash(cls, hash):
        q = db.session.query(cls).filter_by(hash=hash)
        return q.first()

    @classmethod
    def by_urn(cls, urn):
        q = db.session.query(cls).filter_by(urn=urn)
        return q.first()

    def to_ref(self):
        from datawire.store import frame_url
        return {
            'urn': self.urn,
            'api_uri': url_for('frames.get', urn=self.urn, _external=True),
            'store_uri': frame_url(self.urn),
            'action_at': self.action_at,
            'submitted_at': self.submitted_at
        }

    @classmethod
    def all(cls):
        return db.session.query(cls)
Exemple #2
0
class Match(db.Model, ModelCore):
    __tablename__ = 'match'

    urn = db.Column(db.Unicode(), db.ForeignKey('frame.urn'))
    field = db.Column(db.Unicode())
    entity_id = db.Column(db.Integer(), db.ForeignKey('entity.id'))

    @classmethod
    def create(cls, urn, field, entity_id):
        obj = cls()
        obj.urn = urn
        obj.field = field
        obj.entity_id = entity_id
        db.session.add(obj)
        return obj

    @classmethod
    def exists(cls, urn, entity_id):
        q = db.session.query(cls)
        q = q.filter_by(urn=urn)
        q = q.filter_by(entity_id=entity_id)
        return q.first()

    def to_ref(self):
        data = self.frame.to_ref()
        data.update({
            'id': self.id,
            'field': self.field,
            'matched_at': self.created_at,
            'entity_id': self.entity_id
        })
        return data

    def to_dict(self):
        data = self.to_ref()
        data.update({
            'entity': self.entity
        })
        return data
Exemple #3
0
class Collection(db.Model):
    id = db.Column(db.Unicode(50), primary_key=True)
    slug = db.Column(db.Unicode(250))
    public = db.Column(db.Boolean, default=False)

    owner_id = db.Column(db.Integer(), db.ForeignKey('user.id'), nullable=True)
    owner = db.relationship(User)

    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime,
                           default=datetime.utcnow,
                           onupdate=datetime.utcnow)

    def to_dict(self):
        return {
            'id': self.id,
            'api_url': url_for('collections.view', id=self.id),
            'entities_api_url': url_for('entities.index', list=self.id),
            'slug': self.slug,
            'public': self.public,
            'owner': self.owner,
            'created_at': self.created_at,
            'updated_at': self.updated_at
        }

    @classmethod
    def create(cls, data, user):
        lst = cls()
        lst.update(data, user)
        lst.owner = user
        db.session.add(lst)
        return lst

    def update(self, data, user):
        data = CollectionForm().deserialize(data)
        self.slug = data.get('slug')
        if data.get('public') is not None:
            self.public = data.get('public')

    def delete(self):
        # for entity in self.entities:
        #     entity.delete()
        db.session.delete(self)

    @classmethod
    def by_slug(cls, login, slug):
        q = db.session.query(cls).filter_by(slug=slug)
        q = q.filter(cls.owner.login == login)
        return q.first()

    @classmethod
    def by_id(cls, id):
        q = db.session.query(cls).filter_by(id=id)
        return q.first()

    @classmethod
    def user_ids(cls, user, include_public=True):
        logged_in = user is not None and user.is_authenticated()
        q = db.session.query(cls.id)
        conds = []
        if include_public:
            conds.append(cls.public == True)  # noqa
        if logged_in:
            conds.append(cls.owner_id == user.id)
        if not len(conds):
            return []
        if not (logged_in and user.is_admin):
            q = q.filter(or_(*conds))
        return [c.id for c in q.all()]

    @classmethod
    def all_by_user(cls, user):
        q = db.session.query(cls)
        q = q.filter(cls.id.in_(cls.user_ids(user)))
        q = q.order_by(cls.id.desc())
        return q

    @property
    def terms(self):
        from aleph.model.entity import Entity
        from aleph.model.selector import Selector
        q = db.session.query(Selector.normalized)
        q = q.join(Entity, Entity.id == Selector.entity_id)
        q = q.filter(Entity.watchlist_id == self.id)
        q = q.distinct()
        return set([r[0] for r in q])

    def __repr__(self):
        return '<Watchlist(%r, %r)>' % (self.id, self.slug)

    def __unicode__(self):
        return self.slug
Exemple #4
0
class Entity(db.Model):
    id = db.Column(db.Unicode(50), primary_key=True, default=make_textid)
    label = db.Column(db.Unicode)
    category = db.Column(db.Enum(*CATEGORIES, name='entity_categories'),
                         nullable=False)

    creator_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
    creator = db.relationship(User,
                              backref=db.backref('entities',
                                                 lazy='dynamic',
                                                 cascade='all, delete-orphan'))

    collection_id = db.Column(db.Unicode(50), db.ForeignKey('collection.id'))
    collection = db.relationship('Collection',
                                 backref=db.backref(
                                     'entities',
                                     lazy='dynamic',
                                     cascade='all, delete-orphan'))

    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime,
                           default=datetime.utcnow,
                           onupdate=datetime.utcnow)

    def to_dict(self):
        return {
            'id': self.id,
            'api_url': url_for('entities.view', id=self.id),
            'label': self.label,
            'category': self.category,
            'creator_id': self.creator_id,
            'selectors': [s.text for s in self.selectors],
            'collection_id': self.collection_id,
            'created_at': self.created_at,
            'updated_at': self.updated_at
        }

    def has_selector(self, text):
        normalized = Selector.normalize(text)
        for selector in self.selectors:
            if selector.normalized == normalized:
                return True
        return False

    def delete(self):
        db.session.delete(self)

    @classmethod
    def create(cls, data, user):
        ent = cls()
        ent.update(data)
        ent.creator = user
        db.session.add(ent)
        return ent

    def update(self, data):
        data = EntityForm().deserialize(data)
        self.label = data.get('label')
        self.collection = data.get('collection')
        self.category = data.get('category')

        selectors = set(data.get('selectors'))
        selectors.add(self.label)
        existing = list(self.selectors)
        for sel in list(existing):
            if sel.text in selectors:
                selectors.remove(sel.text)
                existing.remove(sel)
        for sel in existing:
            db.session.delete(sel)
        for text in selectors:
            sel = Selector()
            sel.entity = self
            sel.text = text
            db.session.add(sel)

    @classmethod
    def by_normalized_label(cls, label, collection):
        q = db.session.query(cls)
        q = q.filter_by(collection=collection)
        q = q.filter(db_compare(cls.label, label))
        return q.first()

    @classmethod
    def by_id(cls, id):
        q = db.session.query(cls).filter_by(id=id)
        return q.first()

    @classmethod
    def by_collections(cls, collections, prefix=None):
        q = db.session.query(cls)
        q = q.filter(cls.collection_id.in_(collections))
        if prefix is not None and len(prefix):
            q = q.join(Selector, cls.id == Selector.entity_id)
            q = cls.apply_filter(q, Selector.normalized, prefix)
        q = q.order_by(cls.label.asc())
        return q

    @classmethod
    def by_id_set(cls, ids):
        if not len(ids):
            return {}
        q = db.session.query(cls)
        q = q.filter(cls.id.in_(ids))
        entities = {}
        for ent in q:
            entities[ent.id] = ent
        return entities

    @classmethod
    def apply_filter(cls, q, col, prefix):
        prefix = Selector.normalize(prefix)
        return q.filter(
            or_(col.like('%s%%' % prefix), col.like('%% %s%%' % prefix)))

    @classmethod
    def suggest_prefix(cls, prefix, collections, limit=10):
        ent = aliased(Entity)
        sel = aliased(Selector)
        q = db.session.query(ent.id, ent.label, ent.category)
        q = q.join(sel, ent.id == sel.entity_id)
        q = q.filter(ent.collection_id.in_(collections))
        if prefix is None or not len(prefix):
            return []
        q = cls.apply_filter(q, sel.normalized, prefix)
        q = q.order_by(ent.label.asc())
        q = q.limit(limit)
        q = q.distinct()
        suggestions = []
        for entity_id, label, category in q.all():
            suggestions.append({
                'id': entity_id,
                'label': label,
                'category': category
            })
        return suggestions

    @property
    def terms(self):
        return set([s.normalized for s in self.selectors])

    def __repr__(self):
        return '<Entity(%r, %r)>' % (self.id, self.label)

    def __unicode__(self):
        return self.label
Exemple #5
0
class User(db.Model, ModelCore):
    __tablename__ = 'user'

    screen_name = db.Column(db.Unicode())
    name = db.Column(db.Unicode())
    email = db.Column(db.Unicode())
    twitter_id = db.Column(db.Unicode())
    facebook_id = db.Column(db.Unicode())
    api_key = db.Column(db.Unicode(), default=make_token)

    entities = db.relationship('Entity',
                               backref='user',
                               lazy='dynamic',
                               cascade='all, delete-orphan')

    @classmethod
    def create(cls, data):
        obj = cls()
        obj.screen_name = data.get('screen_name')
        obj.name = data.get('name')
        obj.twitter_id = data.get('twitter_id')
        obj.facebook_id = data.get('facebook_id')
        db.session.add(obj)
        return obj

    def update(self, data):
        data = UserSchema().to_python(data)
        self.name = data['name']
        self.email = data['email']
        db.session.add(self)

    @classmethod
    def by_screen_name(cls, screen_name):
        q = db.session.query(cls)
        q = q.filter_by(screen_name=screen_name)
        return q.first()

    @classmethod
    def by_api_key(cls, api_key):
        q = db.session.query(cls).filter_by(api_key=api_key)
        return q.first()

    @classmethod
    def by_twitter_id(cls, twitter_id):
        q = db.session.query(cls).filter_by(twitter_id=twitter_id)
        return q.first()

    @classmethod
    def by_facebook_id(cls, facebook_id):
        q = db.session.query(cls).filter_by(facebook_id=facebook_id)
        return q.first()

    def to_ref(self):
        return {
            'id': self.id,
            'screen_name': self.screen_name,
            'uri': url_for('users.get', id=self.id, _external=True),
            'name': self.name
        }

    def to_dict(self):
        # TODO: Do we want to expose entities?
        data = self.to_ref()
        data.update({
            'created_at': self.created_at,
            'updated_at': self.updated_at
        })
        return data
Exemple #6
0
class Event(db.Model, ModelCore):
    __tablename__ = 'event'

    key = db.Column(db.Unicode())
    label = db.Column(db.Unicode())
    description = db.Column(db.Unicode())
    template = db.Column(db.Unicode())
    service_id = db.Column(db.Integer(), db.ForeignKey('service.id'))

    frames = db.relationship('Frame',
                             backref='event',
                             lazy='dynamic',
                             cascade='all, delete-orphan',
                             order_by='Frame.action_at.desc()')

    @classmethod
    def create(cls, data):
        # TODO: ensure this is the only event on this service with
        # this key.
        obj = cls()
        obj.key = data.get('key')
        obj.label = data.get('label')
        obj.description = data.get('description')
        obj.template = data.get('template')
        obj.service = data.get('service')
        db.session.add(obj)
        return obj

    def update(self, data):
        self.label = data.get('label')
        self.description = data.get('description')
        self.template = data.get('template')
        db.session.add(self)

    @classmethod
    def by_key(cls, service, key):
        q = db.session.query(cls)
        q = q.filter_by(service=service).filter_by(key=key)
        return q.first()

    def to_ref(self):
        return {
            'id':
            self.id,
            'key':
            self.key,
            'uri':
            url_for('events.get',
                    service_key=self.service.key,
                    event_key=self.key,
                    _external=True),
            'template':
            self.template,
            'label':
            self.label
        }

    def to_dict(self):
        data = self.to_ref()
        data.update({
            'description': self.description,
            'created_at': self.created_at,
            'updated_at': self.updated_at
        })
        return data
Exemple #7
0
class Entity(db.Model, ModelCore):
    __tablename__ = 'entity'

    text = db.Column(db.Unicode())
    category = db.Column(db.Unicode())

    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))

    matches = db.relationship('Match', backref='entity', lazy='dynamic',
                              cascade='all, delete-orphan', order_by='Match.created_at.desc()')

    @classmethod
    def create(cls, data, user):
        obj = cls()
        data = EntitySchema().to_python(data)
        obj.user = user
        obj.text = data.get('text')
        obj.category = data.get('category')
        db.session.add(obj)
        return obj

    def update(self, data):
        data = EntitySchema().to_python(data)
        self.text = data.get('text')
        self.category = data.get('category')
        db.session.add(self)

    def delete(self):
        db.session.delete(self)

    @property
    def pattern(self):
        return re.compile(self.text, re.I | re.M)

    @classmethod
    def by_user_and_id(cls, user, id):
        q = db.session.query(cls).filter_by(user=user)
        q = q.filter_by(id=id)
        return q.first()

    @classmethod
    def by_text(cls, text):
        q = db.session.query(cls).filter_by(text=text)
        return q.first()

    @classmethod
    def by_category(cls, category):
        q = db.session.query(cls).filter_by(category=category)
        return q.first()

    def to_ref(self):
        return {
            'id': self.id,
            'text': self.text,
            'category': self.category,
            'user_id': self.user_id
        }

    def to_dict(self):
        data = self.to_ref()
        data.update({
            'user': self.user.to_ref(),
            'created_at': self.created_at,
            'updated_at': self.updated_at
        })
        return data
Exemple #8
0
class Service(db.Model, ModelCore):
    __tablename__ = 'service'

    key = db.Column(db.Unicode())
    label = db.Column(db.Unicode())
    description = db.Column(db.Unicode())
    url = db.Column(db.Unicode())

    frames = db.relationship('Frame',
                             backref='service',
                             lazy='dynamic',
                             cascade='all, delete-orphan',
                             order_by='Frame.action_at.desc()')
    events = db.relationship('Event',
                             backref='service',
                             lazy='dynamic',
                             cascade='all, delete-orphan',
                             order_by='Event.key.asc()')
    editors = db.relationship('User',
                              secondary=editors,
                              backref=db.backref('services', lazy='dynamic'))

    @classmethod
    def create(cls, data):
        # TODO: ensure this is the only service with this key.
        obj = cls()
        obj.key = data.get('key')
        obj.label = data.get('label')
        obj.description = data.get('description')
        obj.url = data.get('url')
        db.session.add(obj)
        return obj

    def update(self, data):
        self.label = data.get('label')
        self.description = data.get('description')
        self.url = data.get('url')
        db.session.add(self)

    @classmethod
    def by_key(cls, key):
        q = db.session.query(cls).filter_by(key=key)
        return q.first()

    def to_ref(self):
        return {
            'id': self.id,
            'key': self.key,
            'uri': url_for('services.get', key=self.key, _external=True),
            'label': self.label
        }

    def to_dict(self):
        data = self.to_ref()
        data.update({
            'created_at': self.created_at,
            'updated_at': self.updated_at,
            'description': self.description,
            'url': self.url,
            'events': [e.to_ref() for e in self.events],
            'editors': self.editors
        })
        return data
Exemple #9
0
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    login = db.Column(db.Unicode(255))
    email = db.Column(db.Unicode, nullable=True)
    oauth_id = db.Column(db.Unicode)
    api_key = db.Column(db.Unicode, default=make_token)

    is_admin = db.Column(db.Boolean, nullable=False, default=False)

    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow,
                           onupdate=datetime.utcnow)

    def is_active(self):
        return True

    def is_authenticated(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self.login

    def __repr__(self):
        return '<User(%r,%r)>' % (self.id, self.login)

    def __unicode__(self):
        return self.login

    def to_dict(self):
        return {
            'id': self.id,
            'login': self.login,
            'is_admin': self.is_admin,
            'created_at': self.created_at,
            'updated_at': self.updated_at,
            'api_url': url_for('users.view', login=self.login)
        }

    def update(self, data):
        data = UserForm().deserialize(data)
        self.email = data.get('email')

    @classmethod
    def load(cls, data):
        user = cls.by_oauth_id(data.get('oauth_id'))

        if user is None:
            user = cls()
            user.login = data.get('login')
            user.oauth_id = data.get('oauth_id')

        if data.get('email'):
            # FIXME: better to overwrite with upstream or keep?
            user.email = data.get('email')
        db.session.add(user)
        return user

    @classmethod
    def all(cls):
        q = db.session.query(cls)
        return q

    @classmethod
    def by_login(cls, login):
        q = db.session.query(cls).filter_by(login=login)
        return q.first()

    @classmethod
    def by_api_key(cls, api_key):
        q = db.session.query(cls).filter_by(api_key=api_key)
        return q.first()

    @classmethod
    def by_oauth_id(cls, oauth_id):
        q = db.session.query(cls).filter_by(oauth_id=unicode(oauth_id))
        return q.first()