class FollowerId(db.Model): user = db.IMProperty(required=True) snooze = db.IMProperty(required=False) more_search = db.StringProperty(required=False) filter_user_rep = db.IntegerProperty(required=False) filter_user_rate = db.IntegerProperty(required=False) mute = db.BooleanProperty(required=False) domain = db.StringProperty(required=False) created = db.DateTimeProperty(auto_now_add=True) secret = db.StringProperty(required=False) @staticmethod def create(im_from): keyname = str(im_from) return FollowerId.get_or_insert(keyname, user=im_from)
class OAUTH_Client(model_plus.Model): """Applications using our data""" # oauth_key is the Model's key_name field client_secret = db.TextProperty() client_verifier = db.TextProperty() user = db.ReferenceProperty(User) name = db.TextProperty() description = db.TextProperty() image = db.IMProperty() callback = db.URLProperty(required=False) created = db.DateTimeProperty(auto_now_add=True) @classmethod def generate(cls, *args, **kwargs): def _generate_key(): #genera una cadena de numeros aleatoria, se codifica a base64 y se limpia para URLs u = uuid4() return base64.urlsafe_b64encode( u.bytes.encode("base64")).strip('=') kwargs['key_name'] = 'oclient_%s' % _generate_key() kwargs['client_secret'] = _generate_key() client = OAUTH_Client(*args, **kwargs) client.put() return client @classmethod def get_token(cls, key_name): return OAUTH_Client.get_by_key_name('oclient_%s' % key_name) @property def client_key(self): return self.key().name().split('oclient_')[:-1]
class AllPropertiesModel(db.Model): """Property names are ugly, yes.""" prop_string = db.StringProperty() prop_byte_string = db.ByteStringProperty() prop_boolean = db.BooleanProperty() prop_integer = db.IntegerProperty() prop_float = db.FloatProperty() prop_date_time = db.DateTimeProperty() prop_date = db.DateProperty() prop_time = db.TimeProperty() prop_list = db.ListProperty(int) prop_string_list = db.StringListProperty() prop_reference = db.ReferenceProperty() prop_self_refeference = db.SelfReferenceProperty() prop_user = db.UserProperty() prop_blob = db.BlobProperty() prop_text = db.TextProperty() prop_category = db.CategoryProperty() prop_link = db.LinkProperty() prop_email = db.EmailProperty() prop_geo_pt = db.GeoPtProperty() prop_im = db.IMProperty() prop_phone_number = db.PhoneNumberProperty() prop_postal_address = db.PostalAddressProperty() prop_rating = db.RatingProperty()
class UserSettings(db.Model): user = db.UserProperty() lastname = db.StringProperty(verbose_name=u'姓') firstname = db.StringProperty(verbose_name=u'名') gender = db.StringProperty(choices=( "M", "F", ), verbose_name=u'性别') profile = db.TextProperty(verbose_name=u'档案') language = db.IntegerProperty(verbose_name=u'语言') im = db.IMProperty() birthdate = db.DateProperty(verbose_name=u'生日') website = db.LinkProperty(verbose_name=u'网址') home_phone = db.PhoneNumberProperty(verbose_name=u'私人电话') work_phone = db.PhoneNumberProperty(verbose_name=u'工作电话') mobile = db.PhoneNumberProperty(verbose_name=u'手机') fax = db.PhoneNumberProperty(verbose_name=u'传真') address = db.PostalAddressProperty(verbose_name=u'地址') @staticmethod def getByUser(user): settings = UserSettings.all().filter('user =', user).get() if settings is None: settings = UserSettings(user=user) settings.put() return settings # q = db.GqlQuery("SELECT * FROM UserSettings WHERE user = :1", user) # return q.get() @staticmethod def getByCurrentUser(): user = users.get_current_user() return UserSettings.getByUser(user)
class Site(db.Model): # RPC private/protected properties: read-only for ALL _deleted = db.BooleanProperty(default=False) _dateCreated = db.DateTimeProperty(auto_now_add=True) _dateModified = db.DateTimeProperty(auto_now=True) _dateAccessed = db.DateTimeProperty() _userLastAccessed = db.UserProperty() _rating = db.RatingProperty() # RPC public properties: writable by creator/admin userCreator = db.UserProperty(required=True) # creator or admin may change creator name = db.StringProperty(required=True) latlng = db.GeoPtProperty(required=True) address = db.PostalAddressProperty() description = db.TextProperty() pay = db.BooleanProperty() # pay access only? restricted = db.BooleanProperty() # authorized access only? # List of Service entries in the DB services = db.ListProperty(db.Key) # List of keys to Service entities #db.BlobProperty() # images, etc #db.ListProperty() # images, history, ... # ReferenceProperty? # Related sites? contactName = db.StringProperty() contactAddress = db.PostalAddressProperty() contactPhone = db.PhoneNumberProperty() contactEmail = db.EmailProperty() contactURL = db.LinkProperty() contactIM = db.IMProperty() evcmid = db.StringProperty() # ID, if imported from EVChargerMaps.com
class Player(db.Model): # List players on the server account = db.IMProperty(required=True) is_ready = db.BooleanProperty(default=False, required=True) room = db.ReferenceProperty(Room, collection_name='players') # room:player = 1:* #name # Leave for future pass
class Follower(db.Model): follower = db.IMProperty(required=True) tag = db.ReferenceProperty(Tag, required=True) mute = db.BooleanProperty(required=False) filter_user_rep = db.IntegerProperty(required=False) filter_user_rate = db.IntegerProperty(required=False) snooze = db.IMProperty(required=False) domain = db.StringProperty(required=False) created = db.DateTimeProperty(auto_now_add=True) tag_name = db.StringProperty(required=False) @staticmethod def create(keyname, db_tag, domain, follower_id): Follower.get_or_insert(keyname, tag=db_tag, follower=follower_id.user, mute=follower_id.mute, tag_name=db_tag.tag.name, filter_user_rep=follower_id.filter_user_rep, filter_user_rate=follower_id.filter_user_rate, domain=domain, snooze=follower_id.snooze)
class Account(db.Model): user = db.UserProperty() jid = db.IMProperty() @classmethod def by_jid(cls, jid): return cls.get_or_insert(jid, jid=db.IM('xmpp', jid)) def delete(self): for prop in dir(self): if prop.endswith('_set'): db.delete(getattr(self, prop)) super(Account, self).delete()
class QuestionFollower(db.Model): follower = db.IMProperty(required=True) question = db.ReferenceProperty(Question, required=True, collection_name="followers") domain = db.StringProperty(required=False) question_id = db.IntegerProperty(required=False) created = db.DateTimeProperty(auto_now_add=True) @staticmethod def create(question, follower): keyname = "%s%d%s" % (follower.address, question.question_id, question.domain) return QuestionFollower.get_or_insert(keyname, follower=follower, question=question, question_id=question.question_id, domain=question.domain)
class Everything(db.Model): str = db.StringProperty() bool = db.BooleanProperty() int = db.IntegerProperty() float = db.FloatProperty() datetime = db.DateTimeProperty() date = db.DateProperty() time = db.TimeProperty() list = db.ListProperty(types.IntType) strlist = db.StringListProperty() user = db.UserProperty() blob = db.BlobProperty() text = db.TextProperty() category = db.CategoryProperty() link = db.LinkProperty() email = db.EmailProperty() geopt = db.GeoPtProperty() im = db.IMProperty() phonenumber = db.PhoneNumberProperty() postaladdress = db.PostalAddressProperty() rating = db.RatingProperty()
class Follower2(db.Model): follower = db.IMProperty(required=True) mute = db.BooleanProperty(required=False) filter_user_rep = db.IntegerProperty(required=False) filter_user_rate = db.IntegerProperty(required=False) snooze = db.IMProperty(required=False) domain = db.StringProperty(required=False) created = db.DateTimeProperty(auto_now_add=True) tag_name = db.StringProperty(required=False) #0 is, 1 contains, 2 startswith, 3 endswith matcher = db.IntegerProperty(required=False, default=0) @staticmethod def build_key_name(user, tag_name, domain): return "%s/%s/%s" % (user.address.lower(), tag_name.lower(), domain.lower()) @staticmethod def create(follower_id, domain, tag_name): tag_name = tag_name.lower() tag_name, matcher = Follower2.tag_without_wildcard(tag_name) key_name = Follower2.build_key_name(follower_id.user, tag_name, domain) def txn(*args, **kwds): logging.info("creating follow tag %s" % (key_name, )) entity = Follower2.get_by_key_name(key_name) if not entity: entity = Follower2(key_name=key_name, **kwds) else: entity.matcher = kwds.get('matcher') entity.put() return entity return db.run_in_transaction( txn, follower=follower_id.user, matcher=matcher, mute=follower_id.mute, tag_name=tag_name, filter_user_rep=follower_id.filter_user_rep, filter_user_rate=follower_id.filter_user_rate, domain=domain, snooze=follower_id.snooze) @staticmethod def create_multi(follower_id, domain, tags): for tag in tags: if not Follower2.is_valid_tag(tag): raise InvalidTag(tag) for tag in tags: Follower2.create(follower_id, domain, tag) @property def full_tag(self): return Follower2.tag_with_wildcard(self.tag_name, self.matcher) @staticmethod def tag_with_wildcard(tag, matcher): if matcher == 0: #is return tag elif matcher == 1: #contains return "*" + tag + "*" elif matcher == 2: #startswith return tag + "*" elif matcher == 3: #endswith return "*" + tag return tag @staticmethod def is_valid_tag(tag): if tag.find('*', 1, -1) > 0: return False if len(tag.strip('*')) < 2 and tag not in allowed_short_tags: return False return True def is_match(self, full_tag): if self.matcher == 0: #is return self.tag_name == full_tag elif self.matcher == 1: #contains return full_tag.index(self.tag_name) >= 0 elif self.matcher == 2: #startswith return full_tag.startswith(self.tag_name) elif self.matcher == 3: #endswith return full_tag.endswith(self.tag_name) return False @staticmethod def tag_without_wildcard(tag): if tag.find('*') < 0: return (tag, 0) #is elif tag[0] == '*' and tag[-1] == '*': return (tag[1:-1], 1) #contains elif tag[-1] == '*': return (tag[:-1], 2) #startswith elif tag[0] == '*': return (tag[1:], 3) #endswith return None
class Question(db.Model): question = db.TextProperty(required=True) asker = db.IMProperty(required=True) asked = db.DateTimeProperty(required=True, auto_now_add=True) assignees = db.ListProperty(db.IM) last_assigned = db.DateTimeProperty() answer = db.TextProperty() answerer = db.IMProperty() answered = db.DateTimeProperty() @staticmethod def _tryAssignTx(key, user, expiry): """Assigns and returns the question if it's not assigned already. Args: key: db.Key: The key of a Question to try and assign. user: db.IM: The user to assign the question to. Returns: The Question object. If it was already assigned, no change is made """ question = Question.get(key) if not question.last_assigned or question.last_assigned < expiry: question.assignees.append(user) question.last_assigned = datetime.datetime.now() question.put() return question @staticmethod def assignQuestion(user): """Gets an unanswered question and assigns it to a user to answer. Args: user: db.IM: The identity of the user to assign a question to. Returns: The Question entity assigned to the user, or None if there are no unanswered questions. """ question = None while question == None or user not in question.assignees: # Assignments made before this timestamp have expired. expiry = (datetime.datetime.now() - datetime.timedelta(seconds=MAX_ANSWER_TIME)) # Find a candidate question q = Question.all() q.filter("answerer =", None) q.filter("last_assigned <", expiry).order("last_assigned") # If a question has never been assigned, order by when it was asked q.order("asked") candidates = [x for x in q.fetch(2) if x.asker != user] if not candidates: # No valid questions in queue. break # Try and assign it question = db.run_in_transaction(Question._tryAssignTx, candidates[0].key(), user, expiry) # Expire the assignment after a couple of minutes return question def _unassignTx(self, user): question = Question.get(self.key()) if user in question.assignees: question.assignees.remove(user) question.put() def unassign(self, user): """Unassigns the given user to this question. Args: user: db.IM: The user who will no longer be answering this question. """ db.run_in_transaction(self._unassignTx, user)