Skip to content

Instantly share code, notes, and snippets.

@smallevilbeast
Created December 3, 2013 05:39
Show Gist options
  • Save smallevilbeast/7764413 to your computer and use it in GitHub Desktop.
Save smallevilbeast/7764413 to your computer and use it in GitHub Desktop.
import datetime
import peewee as pw
from playhouse.signals import Model
from dtalk.utils.contextdecorator import contextmanager
from dtalk.utils.xmpp import split_jid, get_email
db = pw.SqliteDatabase('test.db', check_same_thread=False, threadlocals=True)
DEFAULT_GROUP = "我的好友"
def check_update_data(obj, data):
change = False
for key, new_value in data.iteritems():
old_val = getattr(obj, key, None)
if old_val != new_value:
change = True
setattr(obj, key, new_value)
if change:
obj.save()
@contextmanager
def disable_auto_commit(*args, **kwargs):
db.set_autocommit(False)
try:
yield
except:
pass
else:
db.commit()
finally:
db.set_autocommit(True)
class BaseModel(Model):
class Meta:
database = db
class Group(BaseModel):
name = pw.CharField()
class Meta:
db_table = "dtalk_group"
class User(BaseModel):
jid = pw.CharField()
nickname = pw.CharField(null=True)
remark = pw.CharField(null=True)
subscription = pw.CharField(null=True)
group = pw.ForeignKeyField(Group, related_name="users", null=True)
approved = pw.BooleanField(default=False)
isSelf = pw.BooleanField(default=False)
class Meta:
db_table = "dtalk_user"
@classmethod
def create_or_update_roster(cls, roster):
with disable_auto_commit():
for item in roster:
data = dict()
data["jid"] = get_email(item.jid)
data["remark"] = item.name
data["subscription"] = item.subscription
data["approved"] = item.approved
if len(item.groups) >= 1:
group_name = list(item.groups)[0]
else:
group_name = DEFAULT_GROUP
data["group"] = Group.get_or_create(name=group_name)
try:
obj = cls.get(jid=data["jid"])
except cls.DoesNotExist:
cls.create(**data)
else:
check_update_data(obj, data)
class Resource(BaseModel):
user = pw.ForeignKeyField(User, related_name="resources")
resource = pw.CharField(null=True)
show = pw.CharField(null=True)
status = pw.TextField(null=True)
priority = pw.IntegerField(default=0)
class Meta:
db_table = "dtalk_resource"
@classmethod
def update_status(cls, stanza):
jid, resource = split_jid(stanza.from_jid)
data = dict()
try:
u = User.get(jid=jid)
except User.DoesNotExist:
print "TODO: async"
else:
obj = cls.get_or_create(user=u, resource=resource)
data["show"] = stanza.show
data["status"] = stanza.status
data["priority"] = stanza.priority
check_update_data(obj, data)
@classmethod
def update_presences(cls, presences):
with disable_auto_commit():
for stanza in presences:
cls.update_status(stanza)
@classmethod
def offline(cls, stanza):
jid, resource = split_jid(stanza.from_jid)
try:
u = User.get(jid=jid)
except User.DoesNotExist:
print "TODO: DoesNotExist"
else:
try:
obj = cls.get(user=u, resource=resource)
except cls.DoesNotExist:
print "TODO: offline"
else:
# with disable_auto_commit():
obj.delete_instance()
class Message(BaseModel):
fromUser = pw.ForeignKeyField(User, related_name="messages")
toUser = pw.ForeignKeyField(User)
body = pw.TextField()
created = pw.DateTimeField(default=datetime.datetime.now)
class Meta:
db_table = "dtalk_message"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment