class ResearchGroup (db.Model): people = db.ListProperty(db.Key) name = db.StringProperty(required = True)
class Group(BaseModel): roles = db.ListProperty(db.Key) org = db.StringProperty()
class User(db.Model): name = db.StringProperty() device = db.ReferenceProperty(UserDevice, default=None) location = db.ReferenceProperty(UserLocation, default=None) chat_id = db.StringProperty() photo = db.StringProperty() contact_id = db.StringProperty(default=None) description = db.TextProperty() first_name = db.StringProperty() last_name = db.StringProperty() email = db.StringProperty() phone = db.StringProperty() password = db.StringProperty() receive_emails = db.BooleanProperty() salt = db.StringProperty() activation_code = db.StringProperty(default=None) is_active = db.BooleanProperty() is_paid_user = db.BooleanProperty() is_superuser = db.BooleanProperty(default=False) permissions = db.ListProperty(db.Key) groups = db.ListProperty(db.Key) roles = db.ListProperty(db.Key) version = db.IntegerProperty(default=0) created = db.DateTimeProperty(auto_now_add=True) updated = db.DateTimeProperty(auto_now=True) _is_dirty = None _roles_list = {} _perms_list = {} _perms_map = {} def is_dirty(self): return self._is_dirty def set_dirty(self, dirty, org_name=None): if org_name: if hasattr(self._perms_list, org_name) and self._perms_list[org_name]: self._perms_list[org_name] = None if hasattr(self._perms_map, org_name) and self._perms_map[org_name]: self._perms_map[org_name] = None if hasattr(self._roles_list, org_name) and self._roles_list[org_name]: self._roles_list[org_name] = None self._is_dirty = dirty def roles_list(self, org_name): if hasattr(self._roles_list, org_name) and self._roles_list[org_name]: org_roles = self._roles_list[org_name] else: org_roles = self.fetch_user_roles(org_name) self._roles_list[org_name] = org_roles return org_roles def perms_list(self, org_name): if hasattr(self._perms_list, org_name) and self._perms_list[org_name]: org_perms = self._perms_list[org_name] else: org_perms = self.fetch_user_perms(org_name) self._perms_list[org_name] = org_perms return org_perms def perms_map(self, org_name): if hasattr(self._perms_map, org_name) and self._perms_map[org_name]: org_perms_map = self._perms_map[org_name] else: temp_perms_map = {} for p in self.perms_list(org_name): temp_perms_map[p.name] = p self._perms_map[org_name] = temp_perms_map org_perms_map = temp_perms_map self.set_dirty(True) return org_perms_map def format_perm(self, keys): return ".".join(keys) def has_perm(self, org_name, perm): if (not perm): return False if not self.is_active: return False if self.is_superuser: return True if isinstance(perm, Permission): perm_name = perm.name else: perm_name = perm if not isinstance(perm, str): perm_name = self.format_perm(perm) #logging.info(self.perms_map(org_name)) perm_obj = None if perm_name in self.perms_map(org_name): perm_obj = self.perms_map(org_name)[perm_name] if perm_obj: return True else: return False def fetch_user_roles(self, org=None): '''Get the roles for the user''' user_roles = set() if len(self.roles) > 0: user_roles = set([ r for r in db.get(self.roles) if r.org is None or r.org == org ]) #logging.info(self.groups) for group in Group.get(self.groups): if group and len(group.roles) > 0: user_roles.update([ r for r in db.get(group.roles) if r.org is None or r.org == org ]) self.set_dirty(True) return user_roles def fetch_user_perms(self, org=None): '''Get the permissions for the user''' user_roles = self.fetch_user_roles(org) all_perms = set() for role in user_roles: if len(role.permissions) > 0: role_perms = set([ p for p in db.get(role.permissions) if p.org is None or p.org == org ]) all_perms.update(role_perms) if len(self.permissions) > 0: user_perms = set([ p for p in db.get(self.permissions) if p.org is None or p.org == org ]) all_perms.update(user_perms) self.set_dirty(True) return all_perms def update_cache_if_dirty(self): if self.is_dirty(): memcache.set('userid_user:%s' % self.name, self) self.set_dirty(False) def __str__(self): return "%s:%s" % (self.__class__.__name__, self.name)
class Permission(db.Model): title = db.StringProperty() dj_list = db.ListProperty(db.Key)
class Metadata(BaseModel): major_version = db.IntegerProperty(default=0) depends_on = db.ListProperty(db.Key) em_map_ = {} def get_entity_metadata(self, req, em_name): if (not self.em_map_) or (not em_name in self.em_map_): for em in self.entity_metadatas(req): self.em_map_[em.name] = em return self.em_map_[em_name] def entity_metadatas(self, req=None): res = [em for em in self.entitymetadata_set if check_perm(req, em)] for m in self.depends_on: m = Metadata.get(m) for em in m.entitymetadata_set: if check_perm(req, em): res.append(em) return res def type_infos(self, req=None): res = [ti for ti in self.typeinfo_set if check_perm(req, ti)] for m in self.depends_on: m = Metadata.get(m) for ti in m.typeinfo_set: if check_perm(req, ti): res.append(ti) return res def enumerations(self, req=None): res = [e for e in self.enumeration_set if check_perm(req, e)] for m in self.depends_on: m = Metadata.get(m) for e in m.enumeration_set: if check_perm(req, e): res.append(e) return res def entity_relations(self, req=None): res = [er for er in self.entityrelation_set if check_perm(req, er)] for m in self.depends_on: m = Metadata.get(m) for er in m.entityrelation_set: if check_perm(req, er): res.append(er) return res def l10n_content(self, req=None): res = [l for l in self.l10n_set if check_perm(req, l)] for m in self.depends_on: m = Metadata.get(m) for l in m.l10n_set: if check_perm(req, l): res.append(l) return res def view_definitions(self, req=None): res = [l for l in self.viewdefinition_set if check_perm(req, l)] for m in self.depends_on: m = Metadata.get(m) for l in m.viewdefinition_set: if check_perm(req, l): res.append(l) return res def view_maps(self, req=None): res = [l for l in self.viewmap_set if check_perm(req, l)] for m in self.depends_on: m = Metadata.get(m) for l in m.viewmap_set: if check_perm(req, l): res.append(l) return res def data_queries(self, req=None): res = [l for l in self.dataquery_set if check_perm(req, l)] for m in self.depends_on: m = Metadata.get(m) for l in m.dataquery_set: if check_perm(req, l): res.append(l) return res
class UserSettings(db.Model): user = db.UserProperty(required=True) seen_example = db.BooleanProperty(default=False) seen_guiders = db.StringListProperty() # the last version (list of ints) this person has viewed the release notes for seen_version = db.ListProperty(int, default=None) locale = db.StringProperty(default=None) chimped = db.BooleanProperty(default=False) @staticmethod def has_seen_example(): user = gae_users.get_current_user() if not user or not user.user_id(): raise Exception("Logged in user expected") settings = UserSettings.get_or_insert(user.user_id(), user=user) return settings.seen_example @staticmethod def mark_example_as_seen(): user = gae_users.get_current_user() if not user or not user.user_id(): raise Exception("Logged in user expected") settings = UserSettings.get_or_insert(user.user_id(), user=user) settings.seen_example = True settings.put() @staticmethod def show_guider(guider_name): user = gae_users.get_current_user() if not user or not user.user_id(): return False settings = UserSettings.get_or_insert(user.user_id(), user=user) return (guider_name not in settings.seen_guiders) @staticmethod def mark_guider_as_seen(guider_name): user = gae_users.get_current_user() if not user or not user.user_id(): return settings = UserSettings.get_or_insert(user.user_id(), user=user) if not guider_name in settings.seen_guiders: settings.seen_guiders.append(guider_name) settings.put() @staticmethod def has_seen_version(version): user = gae_users.get_current_user() if not user or not user.user_id(): return True # don't bother displaying "new version available" to non-authenticated users settings = UserSettings.get_or_insert(user.user_id(), user=user) if not settings.seen_version: settings.seen_version = [0, 0, 0] settings.put() return settings.seen_version >= version @staticmethod def mark_version_as_seen(version): user = gae_users.get_current_user() if not user or not user.user_id(): return settings = UserSettings.get_or_insert(user.user_id(), user=user) settings.seen_version = version settings.put() @staticmethod def get_locale(): user = gae_users.get_current_user() if not user or not user.user_id(): return None settings = UserSettings.get_or_insert(user.user_id(), user=user) return settings.locale @staticmethod def set_locale(locale): user = gae_users.get_current_user() if not user or not user.user_id(): return settings = UserSettings.get_or_insert(user.user_id(), user=user) settings.locale = locale settings.put()
class Serie(db.Model): nombre = db.StringProperty(required=True) autor = db.StringProperty(required=True) descripcion = db.TextProperty(required=True) fecha = db.DateTimeProperty(auto_now=True) categorias = db.ListProperty(db.Key)
class Article(Content): featured = db.StringProperty() status = db.StringProperty() slug = db.StringProperty() images = db.ListProperty(db.Key) media = db.ListProperty(db.Key)
class Counselor(db.Model): first_name = db.StringProperty() last_name = db.StringProperty() name = db.StringProperty() # google account username groups = db.ListProperty(db.Key) events = db.ListProperty(db.Key)
class Post(db.Model): subject = db.StringProperty(required=True) content = db.TextProperty(required=True) created_at = db.DateTimeProperty(auto_now_add=True) posted_by_id = db.IntegerProperty(required=True) likes = db.ListProperty(item_type=int)
class UserPrefs(db.Model): user = db.UserProperty() money = db.IntegerProperty() isPlaying = db.BooleanProperty(default=False) user_coin_record = db.ListProperty(int)
class Client(db.Model): mac = db.IntegerProperty() first_seen = db.DateTimeProperty() last_seen = db.DateTimeProperty() base_stations = db.ListProperty(db.Key)
class WorkItems(db.Model): queue_name = db.StringProperty() item_ids = db.ListProperty(int) date = db.DateTimeProperty(auto_now_add=True)
class CrossieData(db.Model): crossienum = db.IntegerProperty(required=True) acl = db.ListProperty(users.User, required=True) characters = db.StringListProperty(required=True) updated = db.DateTimeProperty(required=True, auto_now=True) def getJSON(self): return simplejson.dumps(self.getData()) def getData(self): return { 'crossienum': self.crossienum, 'characters': self.getCharacters(), 'crossieid': self.key().id(), 'updated': self.updated.__str__(), 'acl': self.getACL() } def getACL(self): list = [] for usr in self.acl: list.append(usr.email()) return list def getCharacters(self): list = {} for i in range(0, len(self.characters)): if self.characters[i] != '': x, y = divmod(i, 15) list[x.__str__() + ',' + y.__str__()] = self.characters[i] return list def getCharactersAsUpdates(self): updates = [] for i in range(0, len(self.characters)): if self.characters[i] != '': x, y = divmod(i, 15) updates.append({ 'pos': x.__str__() + ',' + y.__str__(), 'char': self.characters[i] }) return updates @staticmethod def getAndUpdateCrossie(crossieid, user, updates): crossiedata = CrossieData.get_by_id(crossieid) if crossiedata is None: # Cannot proceed raise NoSuchCrossieException if user not in crossiedata.acl: raise PermissionDeniedException if len(crossiedata.characters) == 0: # Populate 15x15 characters with blanks. for i in range(0, 225): crossiedata.characters.append('') for update in updates: pos = update['pos'].split(',') intpos = int(pos[0]) * 15 + int(pos[1]) char = update['char'] crossiedata.characters[intpos] = char crossiedata.put() for usr in crossiedata.acl: if usr != user: try: channel.send_message( usr.user_id(), simplejson.dumps({ 'crossieupdate': { 'updates': updates, 'crossienum': crossiedata.crossienum } })) except: # Does not matter if all collabs don't get the message pass return crossiedata
class Book(db.Model): title = db.StringProperty() authors = db.ListProperty(db.Key)
class PortConfig(db.Model): """Stores port configurations for a machine.""" used_ports = db.ListProperty(int)
class UserGroup(db.Model): name = db.StringProperty(required=True) users = db.ListProperty(gae_users.User) admins = db.ListProperty(gae_users.User)
class Feedback(db.Model): author = db.UserProperty() author_nickname = db.StringProperty() content = db.TextProperty() date = db.DateTimeProperty(auto_now_add=True) deleted = db.BooleanProperty(default=False) targets = db.ListProperty(db.Key) # first element is video key. # optional second element is question key. types = db.StringListProperty() is_flagged = db.BooleanProperty(default=False) is_hidden_by_flags = db.BooleanProperty(default=False) flags = db.StringListProperty(default=None) flagged_by = db.StringListProperty(default=None) sum_votes = db.IntegerProperty(default=0) inner_score = db.FloatProperty(default=0.0) @staticmethod def cache_key_for_video(video): return "videofeedbackcache:%s" % video.key() def __init__(self, *args, **kwargs): db.Model.__init__(self, *args, **kwargs) self.children_cache = [ ] # For caching each question's answers during render def clear_cache_for_video(self): layer_cache.BlobCache.delete(Feedback.cache_key_for_video( self.video()), namespace=App.version) def delete(self): db.delete(self) self.clear_cache_for_video() def put(self): db.Model.put(self) self.clear_cache_for_video() def set_author(self, user_data): self.author = user_data.user self.author_nickname = user_data.nickname def authored_by(self, user_data): return user_data and self.author == user_data.user def is_visible_to_public(self): return (not self.deleted and not self.is_hidden_by_flags) def is_visible_to(self, user_data): """ Returns true if this post should be visible to user_data. If user_data is empty, true only if the post should be visible to the general public. If someone's post has been deleted or flagged, it's only visible to the original author and developers. """ return self.is_visible_to_public() or self.authored_by(user_data) or ( user_data and user_data.developer) def appears_as_deleted_to(self, user_data): """ Returns true if the post should appear as deleted to user_data. This should only be true for posts that are deleted and being viewed by developers. """ return user_data and (user_data.developer or user_data.moderator ) and not self.is_visible_to_public() @property def sum_votes_incremented(self): # Always add an extra vote when displaying vote counts to convey the author's implicit "vote" # and make the site a little more positive. return self.sum_votes + 1 def is_type(self, type): return type in self.types def question_key(self): if self.targets: return self.targets[-1] # last target is always the question return None def question(self): return db.get(self.question_key()) def children_keys(self): keys = db.Query(Feedback, keys_only=True) keys.filter("targets = ", self.key()) return keys def video_key(self): if self.targets: return self.targets[0] return None def video(self): video_key = self.video_key() if video_key: video = db.get(video_key) if video and video.has_topic(): return video return None def add_vote_by(self, vote_type, user_data): FeedbackVote.add_vote(self, vote_type, user_data) self.update_votes_and_score() def update_votes_and_score(self): self.recalculate_votes() self.recalculate_score() self.put() if self.is_type(FeedbackType.Answer): question = self.question() question.recalculate_score() question.put() def recalculate_votes(self): self.sum_votes = FeedbackVote.count_votes(self) def recalculate_score(self): score = float(self.sum_votes) if self.is_type(FeedbackType.Question): for answer in db.get(self.children_keys().fetch(1000)): score += 0.5 * float(answer.sum_votes) self.inner_score = float(score) def add_flag_by(self, flag_type, user_data): if user_data.key_email in self.flagged_by: return False self.flags.append(flag_type) self.flagged_by.append(user_data.key_email) self.recalculate_flagged() return True def clear_flags(self): self.flags = [] self.flagged_by = [] self.recalculate_flagged() def recalculate_flagged(self): self.is_flagged = len(self.flags or []) > 0 self.is_hidden_by_flags = len(self.flags or []) >= FeedbackFlag.HIDE_LIMIT
class Page(db.Model): name = db.StringProperty(required=True) url = db.LinkProperty(required=True) site = db.ReferenceProperty(Site) _styles = db.ListProperty(db.Key) channels = db.ListProperty(db.Key) preview_img = db.BlobProperty(required=False, default=None) preview_urls = db.ListProperty(db.Link, default=None) # *additional* preview urls import_state = db.IntegerProperty(default=0) on_cdn = db.BooleanProperty(default=False) _style_cache = None def _set_styles(self, styles): self._style_cache = styles self._styles = [style.key() for style in styles] def _get_styles(self): if not self._style_cache: self._style_cache = [Style.get(k) for k in self._styles] return self._style_cache styles = property(_get_styles, _set_styles) def delete(self): for key in self.channels: channel = PageChannel.get(key) if channel: channel.send_message({'cmd': 'lock'}) channel.delete() for style in self.styles: style.delete() db.delete(self) def clean_channels(self): stale = [] for key in self.channels: channel = PageChannel.get(key) if not channel or channel.is_stale(): stale.append(key) if stale: for key in stale: self.channels.remove(key) channel = PageChannel.get(key) if channel: # If the channel is still here, it's probably stale. # Send 'lock' and remove, so it can't clobber anyone else. channel.send_message({'cmd': 'lock'}) channel.delete() self.put() def get_channels(self): channels = [] stale = [] for key in self.channels: channel = PageChannel.get(key) if channel: channels.append(channel) else: stale.append(key) if stale: for key in stale: self.channels.remove(key) self.put() return channels def update_locks(self): owner = None channels = self.get_channels() if channels: owner_user = channels[0].user owner = dict(name=owner_user.nickname(), email=owner_user.email()) channels[0].send_message(dict(cmd='unlock', user=owner)) lock_msg = dict(cmd='lock', user=owner) for channel in channels[1:]: channel.send_message(lock_msg) def add_channel(self, channel): self.remove_channel(channel) self.channels.append(channel.key()) self.put() def add_channel_first(self, channel): self.remove_channel(channel) self.channels.insert(0, channel.key()) self.put() def remove_channel(self, channel, delete=False): if channel.key() in self.channels: self.channels.remove(channel.key()) self.put() if delete: channel.delete() def put(self, *args, **kwargs): self._set_styles(self.styles) super(Page, self).put(*args, **kwargs) def queue_preview(self): taskqueue.add(queue_name='fetch-preview', url=url_for('tasks.fetch_preview'), params={'page_key': self.key()}) def queue_upload(self): taskqueue.add(queue_name='upload-css', url=url_for('tasks.upload_style'), params={'page_key': self.key()}) def queue_refresh(self): self.queue_upload() self.queue_preview() def _css(self, preview, compress): css = StringIO() for style in self.styles: rev = style.preview_rev if ( preview and style.preview_rev) else style.published_rev if compress: css.write(rev.compressed) else: css.write(scss.Scss().compile('@option compress:no;' + rev.raw)) return css.getvalue() def compressed_css(self, preview): return self._css(preview, compress=True) def uncompressed_css(self, preview): return self._css(preview, compress=False) def last_modified(self, preview): max_last_edit = datetime.min for style in self.styles: rev = style.preview_rev if ( preview and style.preview_rev) else style.published_rev max_last_edit = max(max_last_edit, rev.dt_last_edit) return max_last_edit def styles_json(self): # NOTE: It is okay to return an array here because we only display this # to users via editor.html. If we ever return this directly as the # response, we'll want to wrap it to avoid the exploit described at # http://haacked.com/archive/2009/06/25/json-hijacking.aspx styles_obj = [style.json_obj() for style in self.styles] return json.dumps(styles_obj, default=dt_handler, sort_keys=True, indent=4 if settings.debug else None) def upload_to_cdn(self): if not settings.use_google_cloud_storage: return path = files.gs.create('/gs/%s/%s.css' % (settings.google_bucket, str(self.key())), mime_type='text/css', acl='public-read', cache_control='private,max-age=300') try: fd = files.open(path, 'a') fd.write(self.compressed_css(False).encode('utf-8')) self.on_cdn = True self.save() except Exception: self.on_cdn = False self.save() raise finally: fd.close() files.finalize(path) @staticmethod def get_or_404(key): page = None if isinstance(key, long) or isinstance( key, int) or (isinstance(key, basestring) and key.isdigit()): page = Page.get_by_id(int(key)) else: try: key_obj = db.Key(key) except BadKeyError: abort(404) if (key_obj.kind() == 'Style'): page = Page.gql('WHERE _styles=:1', key_obj).get() else: page = Page.get(key) if not page: abort(404) return page @staticmethod def get_edit_or_404(page_id): page = Page.get_or_404(page_id) if gae_users.get_current_user() not in page.site.users: abort(404) return page @staticmethod def get_admin_or_404(page_id): page = Page.get_or_404(page_id) site = page.site if not site or gae_users.get_current_user() not in site.admins: abort(404) return page @staticmethod def new_page(site, name, url): ''' Do all the work in adding a new page to a site. ''' style = Style(name=name, site=site) style.put() first_rev = StyleRevision(parent=style) first_rev.raw = render_template('first_run.css') first_rev.put() style.published_rev = first_rev style.put() page = Page(name=name, url=url, site=site, _styles=[style.key()]) page.put() page.queue_refresh() return page
class Player(db.Model): name = db.StringProperty() guilds = db.ListProperty(db.Key)
class BusStop(db.Model): stopId = db.StringProperty() stopPosition = db.ListProperty(str) stopDesc = db.StringProperty() reqDate = db.DateTimeProperty(auto_now_add=True) reqUser = db.UserProperty()
class Board(db.Model): dateTimeCreated = db.DateTimeProperty() dateTimeStarted = db.DateTimeProperty() dateTimeEnded = db.DateTimeProperty() gameKey = db.StringProperty() resources = db.StringListProperty() hexProduces = db.StringListProperty( ) # must be same dimension as resources playerColors = db.StringListProperty() dice = db.ListProperty(int) diceValues = db.ListProperty(int) owner = db.UserProperty() gamePhase = db.IntegerProperty() currentPlayerRef = db.IntegerProperty() turnPhase = db.IntegerProperty() playOrder = db.ListProperty(int) winner = db.UserProperty() minimumPlayers = db.IntegerProperty() resourceMap = None def save(self, callback): rpc = db.create_rpc(deadline=5, callback=callback) self.put(rpc) def getGamePhases(self): return db.Query(GamePhase).ancestor(self).order("order").fetch(100) def getGamePhase(self, order): return db.Query(GamePhase).ancestor(self).filter("order =", order).get() def getGamePhaseByName(self, phase): return db.Query(GamePhase).ancestor(self).filter("phase =", phase).get() def getCurrentGamePhase(self): if self.gamePhase is None: return None else: return self.getGamePhase(self.gamePhase) def getResourceByHexType(self, hexType): if self.resourceMap is None: self.resourceMap = dict() for i in range(len(self.hexProduces)): #TODO: error check this self.resourceMap[self.hexProduces[i]] = self.resources[i] return self.resourceMap.get(hexType, None) def getCurrentTurnPhase(self): if self.turnPhase is None: return None gp = self.getCurrentGamePhase() if gp is None: return None return db.Query(TurnPhase).ancestor(gp).filter("order =", self.turnPhase).get() def getCurrentPlayerColor(self): p = self.getCurrentPlayer() if p is None: return None return p.color def moveNextPlayer(self): players = self.getPlayers() self.currentPlayerRef += 1 if self.currentPlayerRef >= len(players): self.currentPlayerRef = self.currentPlayerRef % len(players) self.put() def movePrevPlayer(self): players = self.getPlayers() self.currentPlayerRef -= 1 if self.currentPlayerRef < 0: self.currentPlayerRef = self.currentPlayerRef % len(players) self.put() def getCurrentPlayer(self): if self.currentPlayerRef is None: return None else: return db.Query(Player).ancestor(self).filter( "order =", self.currentPlayerRef).get() #TODO: add all deck of development cards def getVertexes(self): return db.Query(Vertex).ancestor(self).fetch(1000) def getEdges(self): return db.Query(Edge).ancestor(self).fetch(1000) def getHexes(self): return db.Query(Hex).ancestor(self).fetch(1000) def getHexesByValue(self, value): return db.Query(Hex).ancestor(self).filter("value =", value).fetch(1000) def getVertex(self, x, y): return db.Query(Vertex).ancestor(self).filter('x =', x).filter('y =', y).get() def getEdge(self, x1, y1, x2, y2): return db.Query(Edge).ancestor(self).filter('x1 =', x1).filter( 'y1 =', y1).filter('x2 =', x2).filter('y2 =', y2).get() def getHex(self, x, y): return db.Query(Hex).ancestor(self).filter('x =', x).filter('y =', y).get() def addPlayer(self, color, user): p = Player(parent=self, color=color, user=user) p.put() logging.info("player added: %s" % (user, )) return p def addReservation(self, reservationKey, reservedFor, expirationDateTime): r = Reservation(parent=self, reservationKey=reservationKey, reservedFor=reservedFor, expirationDateTime=expirationDateTime) r.put() logging.info("reserved for: %s" % (reservedFor, )) return r def getPlayer(self, user): return db.Query(Player).ancestor(self).filter('user =', user).get() def getReservations(self): return db.Query(Reservation).ancestor(self).filter( "expirationDateTime <", datetime.datetime.now()).fetch(100) def getReservationCount(self): return db.Query(Reservation).ancestor(self).filter( "expirationDateTime <", datetime.datetime.now()).count(100) def getReservation(self, reservationKey): return db.Query(Reservation).ancestor(self).filter( "reservationKey =", reservationKey).get() def getReservationByUser(self, user): return db.Query(Reservation).ancestor(self).filter( "reservedFor = ", user).get() def getPlayers(self): return db.Query(Player).ancestor(self).fetch(1000) def getPlayerColorMap(self): ret = dict() players = self.getPlayers() for p in players: ret[p.color] = p return ret def getDevelopmentTypeCost(self, name): ret = dict() dt = db.Query(DevelopmentType).ancestor(self).filter("name =", name).get() if dt is None: return ret return dt.getCost() def getDevelopmentTypeMapByLocation(self, location): ret = dict() devTypes = db.Query(DevelopmentType).ancestor(self).filter( "location =", location).fetch(100) for dt in devTypes: ret[dt.name] = dt cost = db.Query(DevelopmentTypeCost).ancestor(dt).fetch(100) ret["cost"] = dict() for c in cost: ret["cost"][c.resource] = c.amount return ret def dump(self, fp): json.dump(self, fp, cls=BoardEncoder)
class _LogRecord(db.Model): """Representation of the logging information for a single web request.""" app_id = db.StringProperty() version_id = db.StringProperty() ip = db.StringProperty() nickname = db.StringProperty() request_id = db.StringProperty() start_time = db.IntegerProperty() end_time = db.IntegerProperty() latency = db.IntegerProperty() mcycles = db.IntegerProperty() method = db.StringProperty() resource = db.TextProperty() status = db.IntegerProperty() response_size = db.IntegerProperty() http_version = db.StringProperty() host = db.StringProperty() user_agent = db.StringProperty() finished = db.BooleanProperty() app_logs = db.ListProperty(db.Key) @classmethod def get_or_create(cls): """Returns the LogRecord for this request, creating it if needed.""" return cls.get_or_insert(str(_get_request_id())) def fill_in_log(self, request, log, app_logs): """Fills in fields in a given RequestLog from a LogReadRequest's fields. Application-level logs are stored in the Datastore as _LogLines, so this method also grabs those items, resolves them, and stores them in the given RequestLog. Args: request: A LogReadRequest, containing the filters that the user has specified to use for their request. log: A RequestLog whose fields will be overriden with those from request. app_logs: The application-level logs associated with the given log. """ log.set_app_id(self.app_id) log.set_version_id(self.version_id) log.set_ip(self.ip) log.set_nickname(self.nickname) log.set_request_id(str(self.key())) log.set_start_time(self.start_time) log.set_end_time(self.end_time) log.set_latency(self.latency) log.set_mcycles(self.mcycles) log.set_method(self.method) log.set_resource(self.resource) log.set_status(self.status) log.set_response_size(self.response_size) log.set_http_version(self.http_version) if self.host is not None: log.set_host(self.host) if self.user_agent is not None: log.set_user_agent(self.user_agent) log.set_finished(self.finished) log.set_url_map_entry('') time_seconds = (self.end_time or self.start_time) / 10**6 date_string = time.strftime('%d/%b/%Y:%H:%M:%S %z', time.localtime(time_seconds)) log.set_combined('%s - %s [%s] \"%s %s %s\" %d %d - \"%s\"' % (self.ip, self.nickname, date_string, self.method, self.resource, self.http_version, self.status or 0, self.response_size or 0, self.user_agent)) if request.include_app_logs(): for app_log in app_logs: log_line = log.add_line() log_line.set_time(app_log.time) log_line.set_level(app_log.level) log_line.set_log_message(app_log.message)
class User(db.Model): name = db.StringProperty(required=True) pw_hash = db.StringProperty(required=True) email = db.StringProperty() exist_key = db.StringProperty() liked_posts = db.ListProperty(int) # Returns actual username from id @classmethod def name_by_id(cls, uid): if uid: return cls.get_by_id(int(uid)).name else: return None # Returns User @classmethod def by_id(cls, uid): if uid: return cls.get_by_id(int(uid)) else: return None # Returns User @classmethod def by_name(cls, name): user = cls.all().filter('name =', name).get() return user # Returns Bool for existing name using exist_key @classmethod def exist(cls, name): exist = cls.all().filter('exist_key =', name.lower()).get() if exist: return True else: return False # Returns User class to register with @classmethod def register(cls, name, pw, email=None): pw_hash = make_pw_hash(name, pw) return User(name=name, pw_hash=pw_hash, exist_key=name.lower()) # Returns user if password matches @classmethod def login(cls, name, pw): user = cls.by_name(name) if user and valid_pw(name, pw, user.pw_hash): return user else: return None # Reads user-id and returns name @classmethod def current(cls): uid = self.read_cookie('user-id') return User.name_by_id(uid)
class ImportProfile(BaseModel): type_of = db.StringProperty() field_mapping = db.ListProperty(db.Key) org = db.StringProperty() _fields = []
class RunResult(db.Model): submission_nameserver = db.ReferenceProperty(SubmissionNameServer, collection_name='results') run_number = db.IntegerProperty() durations = db.ListProperty(float) answer_counts = db.ListProperty(int)
class Role(BaseModel): permissions = db.ListProperty(db.Key) org = db.StringProperty()
class Vote(db.Model): answer = db.StringProperty() number = db.IntegerProperty() count = db.IntegerProperty() users = db.ListProperty(db.Key)
class Event(db.Model): status = db.StringProperty(required=True, default='pending', choices=EVENT_STATUS) # If the member who created the event is now suspended, what the previous # event status was. original_status = db.StringProperty(default=None, choices=EVENT_STATUS) member = db.UserProperty(auto_current_user_add=True) name = db.StringProperty(required=True) start_time = db.DateTimeProperty(required=True) end_time = db.DateTimeProperty() staff = db.ListProperty(users.User) rooms = db.StringListProperty() #choices=set(ROOM_OPTIONS) details = db.TextProperty(required=True) admin_notes = db.TextProperty(default="") url = db.StringProperty(default="") fee = db.StringProperty(default="") notes = db.TextProperty(default="") type = db.StringProperty(required=True) estimated_size = db.StringProperty(required=True) reminded = db.BooleanProperty(default=False) contact_name = db.StringProperty(default="") contact_phone = db.StringProperty(default="") expired = db.DateTimeProperty() created = db.DateTimeProperty(auto_now_add=True) updated = db.DateTimeProperty(auto_now=True) # Teardown / setup to avoid double-bookings setup = db.IntegerProperty() teardown = db.IntegerProperty() # An alternate person that will be responsible for the event, that must be # specified for events 24 hours or longer. other_member = db.StringProperty(default="") # When the member who owns this event was suspended, if they are. owner_suspended_time = db.DateTimeProperty() wifi_password = db.StringProperty(default="") @classmethod def check_conflict(cls, proposed_start_time, proposed_end_time, setup, teardown, proposed_rooms, optional_existing_event_id = 0): # Figure out how long we need to pad the start and end times of the event. # This is more complicated that it seems, because setup and teardown can # overlap, but there still must be a minimum amount of time between # consecutive events. conf = Config() start_padding = max(int(setup), conf.MIN_EVENT_SPACING) end_padding = max(int(teardown), conf.MIN_EVENT_SPACING) proposed_start_time -= timedelta(minutes=start_padding) proposed_end_time += timedelta(minutes=end_padding) possible_conflicts = cls.all() \ .filter('end_time >', proposed_start_time) \ .filter('status IN', ['approved', 'pending', 'onhold']) conflicts = [] for e in possible_conflicts: if e.key().id() != optional_existing_event_id: if e.start_time < proposed_end_time: for r in e.rooms: if r in proposed_rooms: if e not in conflicts: conflicts.append(e) return conflicts @classmethod def get_future_events_by_member(cls, member): return cls.all() \ .filter('start_time >', local_today()) \ .filter('status IN', ['approved', 'not_approved', 'pending', 'onhold']) \ .filter('member = ', member)\ .order('start_time') @classmethod def get_future_suspended_events_by_member(cls, member): return cls.all() \ .filter('start_time >', local_today()) \ .filter('member = ', member) \ .filter('status IN ', ['suspended'])\ .order('start_time') @classmethod def get_all_future_list(cls): return cls.all() \ .filter('start_time >', local_today()) \ .filter('status IN', ['approved', 'not_approved', 'canceled', 'pending', 'onhold']) \ .order('start_time') @classmethod def get_large_list(cls): future_list = Event.get_approved_list() large_list = [] for e in future_list: if int(e.estimated_size) >= 50: large_list.append(e) return large_list @classmethod def get_approved_list(cls): return cls.all() \ .filter('start_time >', local_today()) \ .filter('status IN', ['approved', 'canceled']) \ .order('start_time') @classmethod def get_by_wifi_password(cls, password): return cls.all() \ .filter('wifi_password ='******'status IN', ['approved']) \ .order('start_time').fetch(10) @classmethod def get_approved_list_with_multiday(cls): events = list(cls.all() \ .filter('end_time >', local_today()) \ .filter('status IN', ['approved', 'canceled'])) # create dupe event objects for each day of multiday events for event in list(events): if event.start_time < local_today(): # remove original if it started before today events.remove(event) for day in range(1, event.num_days): if event.start_time + timedelta(days=day) >= local_today(): clone = copy(event) clone.start_time = datetime.combine(event.start_date(), time()) + timedelta(days=day) clone.is_continued = True events.append(clone) events.sort(key = lambda event: event.start_time) return events @classmethod def get_recent_ongoing_and_future(cls): return cls.all() \ .filter('start_time >', local_today()) \ .filter('status IN', ['approved', 'canceled']) \ .order('start_time').fetch(200) @classmethod def get_recent_past_and_future_approved(cls): return cls.all() \ .filter('start_time >', local_today() - timedelta(days=1)) \ .filter('status IN', ['approved']) \ .order('start_time').fetch(200) @classmethod def get_pending_list(cls): return cls.all() \ .filter('start_time >', local_today()) \ .filter('status IN', ['pending', 'understaffed', 'onhold', 'expired', 'suspended']) \ .order('start_time') @classmethod # show last 60 days and all future not approved events def get_recent_not_approved_list(cls): return cls.all() \ .filter('start_time >', local_today() - timedelta(days=60)) \ .filter('status IN', ['not_approved']) \ .order('start_time') def owner(self): return human_username(self.member) def stafflist(self): return to_sentence_list(map(human_username, self.staff)) def roomlist(self): return to_sentence_list(self.rooms) def roomlist_as_phrase(self): if len(self.rooms) > 0: return "in " + self.roomlist() else: return "" def is_staffed(self): return len(self.staff) >= self.staff_needed() def staff_needed(self): return 0 # if self.estimated_size.isdigit(): # return int(self.estimated_size) / GUESTS_PER_STAFF # else: # # invalid data; just return something reasonable # return 2 def is_approved(self): """Has the events team approved the event? Note: This does not necessarily imply that the event is in state 'approved'.""" return self.status in ('understaffed', 'approved', 'cancelled') def is_canceled(self): return self.status == 'canceled' def is_onhold(self): return self.status == 'onhold' def is_deleted(self): return self.status == 'deleted' def is_past(self): return self.end_time < local_today() def is_not_approved(self): return self.status == 'not_approved' def start_date(self): return self.start_time.date() def end_date(self): return self.end_time.date() @property def num_days(self): num_days = (self.end_date() - self.start_date()).days + 1 if num_days > 1 and self.end_time.timetuple()[3] < 8: # only count that day if the event runs past 8am num_days -= 1 return num_days def multiday(self): self.num_days > 1 def approve(self): user = users.get_current_user() if self.is_staffed(): self.expired = None self.status = 'approved' logging.info('%s approved %s' % (user.nickname(), self.name)) else: self.status = 'understaffed' logging.info('%s approved %s but it is still understaffed' % (user.nickname, self.name)) self.put() def check_wifi_password(self): """ Check and add a wifi password to an event. """ if not self.wifi_password: password = utils.generate_wifi_password() logging.info("Adding wifi password to event %s" % self.name) self.wifi_password = password def rsvp(self): user = users.get_current_user() if user and not self.has_rsvped(): rsvp = Rsvp(event=self) rsvp.put() def has_rsvped(self): user = users.get_current_user() if not user: return False for existing_rsvp in self.rsvps: if existing_rsvp.user == user: return True return False # Works even for logged out users def can_rsvp(self): if self.has_rsvped(): return False time_till_event = self.start_time.replace(tzinfo=pytz.timezone('US/Pacific')) - datetime.now(pytz.timezone('US/Pacific')) hours = time_till_event.seconds/3600+time_till_event.days*24 return (hours > RSVP_DEADLINE) def cancel(self): user = users.get_current_user() self.status = 'canceled' self.put() logging.info('%s canceled %s' % (user.nickname(), self.name)) def on_hold(self): user = users.get_current_user() self.status = 'onhold' self.put() logging.info('%s put %s on hold' % (user.nickname(), self.name)) def not_approved(self): user = users.get_current_user() self.status = 'not_approved' self.put() logging.info('%s not_approved %s' % (user.nickname(), self.name)) def delete(self): user = users.get_current_user() self.status = 'deleted' self.put() logging.info('%s deleted %s' % (user.nickname(), self.name)) def undelete(self): user = users.get_current_user() self.status = 'pending' self.put() logging.info('%s undeleted %s' % (user.nickname(), self.name)) def delete(self): user = users.get_current_user() self.status = 'deleted' self.put() logging.info('%s deleted %s' % (user.nickname(), self.name)) def undelete(self): user = users.get_current_user() self.status = 'pending' self.put() logging.info('%s undeleted %s' % (user.nickname(), self.name)) def expire(self): user = users.get_current_user() self.expired = datetime.now() self.status = 'expired' self.put() logging.info('%s expired %s' % (user.nickname(), self.name)) def add_staff(self, user): self.staff.append(user) if self.is_staffed() and self.status == 'understaffed': self.status = 'approved' self.put() logging.info('%s staffed %s' % (user.nickname(), self.name)) def remove_staff(self, user): self.staff.remove(user) if not self.is_staffed() and self.status == 'approved': self.status = 'understaffed' self.put() logging.info('%s staffed %s' % (user.nickname(), self.name)) def to_dict(self, summarize=False): d = dict() if summarize: props = ['member', 'start_time', 'name', 'type', 'estimated_size', 'end_time', 'rooms', 'status'] else: props = Event.properties().keys() for prop in props: if prop == 'member': d[prop] = getattr(self, prop).email() elif prop == 'staff': d[prop] = map(lambda x: x.email(), getattr(self, prop)) elif prop in ['start_time', 'end_time', 'created', 'expired', 'updated']: if getattr(self, prop): d[prop] = getattr(self, prop).replace(tzinfo=pytz.timezone('US/Pacific')).strftime('%Y-%m-%dT%H:%M:%S') else: d[prop] = getattr(self, prop) d['id'] = self.key().id() return d def human_time(self): start = self.start_time.strftime("%m/%d/%y %I:%M%p") if self.multiday(): end = self.end_time.strftime("%m/%d/%y %I:%M%p") else: end = self.end_time.strftime("%I:%M%p") out = "%s to %s" % (start, end) if self.multiday(): out += " (multiday)" return out def full_url(self): protocol = re.compile("^https?:\/\/") if protocol.search(self.url): return self.url return "https://"+self.url
class Website (db.Model): person = db.ReferenceProperty(required = True, collection_name = 'persons') address = db.LinkProperty(required = True) group = db.ReferenceProperty(required = True, collection_name = 'research_groups') authors = db.ListProperty(db.Key, required = True)