# -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 import json from oxflask.db import MutableDict import oxflask.query from changelog import Changelog import settings from settings import db import state class User(db.Model): created = db.Column(db.DateTime()) modified = db.Column(db.DateTime()) id = db.Column(db.String(43), primary_key=True) info = db.Column(MutableDict.as_mutable(db.PickleType(pickler=json))) #nickname = db.Column(db.String(256), unique=True) nickname = db.Column(db.String(256)) pending = db.Column(db.String(64)) # sent|received peered = db.Column(db.Boolean()) online = db.Column(db.Boolean()) def __repr__(self): return self.id @classmethod def get(cls, id): return cls.query.filter_by(id=id).first() @classmethod def get_or_create(cls, id): user = cls.get(id) if not user: user = cls(id=id, peered=False, online=False) user.info = {} user.save() return user def save(self): db.session.add(self) db.session.commit() def json(self): j = {} if self.info: j.update(self.info) j['id'] = self.id if self.pending: j['pending'] = self.pending j['peered'] = self.peered j['online'] = self.check_online() j['nickname'] = self.nickname return j def check_online(self): return state.nodes.check_online(self.id) def lists_json(self): return [l.json() for l in self.lists.order_by('position')] def update_peering(self, peered, username=None): if peered: self.pending = '' self.peered = True if username: self.info['username'] = username self.set_nickname(self.info.get('username', 'anonymous')) else: self.peered = False self.nickname = None for i in self.items: i.users.remove(self) if not i.users: print 'last user, remove' db.session.delete(i) else: i.update_lists() self.save() def set_nickname(self, nickname): username = nickname n = 2 while self.query.filter_by(nickname=nickname).filter(User.id!=self.id).first(): nickname = '%s [%d]' % (username, n) n += 1 self.nickname = nickname list_items = db.Table('listitem', db.Column('list_id', db.Integer(), db.ForeignKey('list.id')), db.Column('item_id', db.String(32), db.ForeignKey('item.id')) ) class List(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String()) position = db.Column(db.Integer()) type = db.Column(db.String(64)) _query = db.Column('query', MutableDict.as_mutable(db.PickleType(pickler=json))) user_id = db.Column(db.String(43), db.ForeignKey('user.id')) user = db.relationship('User', backref=db.backref('lists', lazy='dynamic')) items = db.relationship('Item', secondary=list_items, backref=db.backref('lists', lazy='dynamic')) @classmethod def get(cls, user_id, name=None): if not name: user_id, name = cls.get_user_name(user_id) return cls.query.filter_by(user_id=user_id, name=name).first() @classmethod def get_user_name(cls, user_id): l = user_id.split(':') nickname = l[0] name = ':'.join(l[1:]) if nickname: user = User.query.filter_by(nickname=nickname).first() user_id = user.id else: user_id = settings.USER_ID return user_id, name @classmethod def get_or_create(cls, user_id, name=None): if not name: user_id, name = cls.get_user_name(user_id) l = cls.get(user_id, name) if not l: l = cls(name=name, user_id=user_id) db.session.add(l) db.session.commit() return l @classmethod def create(cls, user_id, name, query=None): l = cls(name=name, user_id=user_id) l._query = query l.type = 'smart' if l._query else 'static' l.position = cls.query.filter_by(user_id=user_id).count() if user_id == settings.USER_ID: p = User.get(settings.USER_ID) if not l._query: Changelog.record(p, 'addlist', l.name) db.session.add(l) db.session.commit() return l def add_items(self, items): from item.models import Item for item_id in items: i = Item.get(item_id) self.items.add(i) db.session.add(self) db.session.commit() def remove_items(self, items): from item.models import Item for item_id in items: i = Item.get(item_id) self.items.remove(i) db.session.add(self) db.session.commit() def remove(self): if not self._query: for i in self.items: self.items.remove(i) if not self._query: print 'record change: removelist', self.user, self.name Changelog.record(self.user, 'removelist', self.name) db.session.delete(self) db.session.commit() @property def public_id(self): id = '' if self.user_id != settings.USER_ID: id += self.user_id id = '%s:%s' % (id, self.name) return id def items_count(self): from item.models import Item if self._query: data = self._query return oxflask.query.Parser(Item).find({'query': data}).count() else: return len(self.items) def json(self): r = { 'id': self.public_id, 'name': self.name, 'index': self.position, 'items': self.items_count(), 'type': self.type } if self.type == 'smart': r['query'] = self._query return r def save(self): db.session.add(self) db.session.commit()