Esempio n. 1
0
class UserData(db.Model):
    user = db.UserProperty(required=True, auto_current_user_add=True)
    url = db.LinkProperty(required=True)
    ref = db.ReferenceProperty()
    date = db.DateTimeProperty(auto_now_add=True)
Esempio n. 2
0
class BusStop(db.Model):
    stopId = db.StringProperty()
    stopPosition = db.ListProperty(str)
    stopDesc = db.StringProperty()
    reqDate = db.DateTimeProperty(auto_now_add=True)
    reqUser = db.UserProperty()
Esempio n. 3
0
File: Poar.py Progetto: rezpe/Poar
class Store(DictModel):
	name = db.StringProperty()
        content = db.TextProperty()
        typeo = db.StringProperty()
	date = db.DateTimeProperty()
	owner = db.UserProperty()
Esempio n. 4
0
class RegisteredUser(db.Model):
    user = db.UserProperty()
    registered = db.DateTimeProperty(auto_now_add=True)
Esempio n. 5
0
class Rate(db.Model):
    author = db.UserProperty()
    riff = db.ReferenceProperty()
Esempio n. 6
0
class GAESubscription(db.Model):
    user = db.UserProperty()
    feed = db.ReferenceProperty(GAEFeed)
    up = db.IntegerProperty()
    down = db.IntegerProperty()
Esempio n. 7
0
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()
Esempio n. 8
0
class User(db.Model):
  user = db.UserProperty(required=False)
  dispname = db.StringProperty()
  email = db.StringProperty()
  isadmin = db.BooleanProperty(default=False)
Esempio n. 9
0
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)
Esempio n. 10
0
class Feedback(db.Model):
    user = db.UserProperty(auto_current_user_add=True)
    event = db.ReferenceProperty(Event)
    rating = db.IntegerProperty()
    comment = db.StringProperty(multiline=True)
    created = db.DateTimeProperty(auto_now_add=True)
Esempio n. 11
0
class Rsvp(db.Model):
    user = db.UserProperty(auto_current_user_add=True)
    event = db.ReferenceProperty(Event, collection_name='rsvps')
    created = db.DateTimeProperty(auto_now_add=True)
Esempio n. 12
0
class Event(db.Model):
    status = db.StringProperty(required=True,
                               default='pending',
                               choices=set([
                                   'pending', 'understaffed', 'approved',
                                   'not_approved', 'canceled', 'onhold',
                                   'expired', 'deleted'
                               ]))
    # If the member who created the event is now suspended, what the previous
    # event status was.
    original_status = db.StringProperty(default=None,
                                        choices=set([
                                            'pending', 'understaffed',
                                            'approved', 'not_approved',
                                            'canceled', 'onhold', 'expired',
                                            'deleted'
                                        ]))
    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()

    @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_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_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_past_and_future(cls):
        return cls.all() \
            .filter('start_time >', local_today()  - timedelta(days=1)) \
            .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']) \
            .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 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 "http://" + self.url
Esempio n. 13
0
class UserUpload(db.Model):
    user = db.UserProperty()
    description = db.StringProperty()
    blob = blobstore.BlobReferenceProperty()
Esempio n. 14
0
class Communication(db.Model):
    author = db.UserProperty()
    receiver = db.UserProperty()
    content = db.StringProperty(multiline = True)
    date = db.DateTimeProperty(auto_now_add = True)
Esempio n. 15
0
class Group(db.Model):
    MapId = db.IntegerProperty(required=False)
    Title = db.StringProperty(required=True)
    Description = db.StringProperty(required=False)
    Owner = db.UserProperty(required=True)
Esempio n. 16
0
class Reservation(db.Model):
    reservationKey = db.StringProperty()
    reservedFor = db.UserProperty()
    expirationDateTime = db.DateTimeProperty()
Esempio n. 17
0
class GAEUser(db.Model):
    user = db.UserProperty()
    lastupdate = db.DateTimeProperty()
    worddb = db.BlobProperty()
Esempio n. 18
0
class Player(db.Model):
    color = db.StringProperty()
    user = db.UserProperty()
    score = db.IntegerProperty(default=0)
    order = db.IntegerProperty()

    # send a dict of resources, integer mappings to add to players resources
    # negative integers subtract resources
    # if a resource isn't listed under a player it is assumed they have zero
    def resetResources(self):
        resource_dict = dict()
        for r in self.parent().resources:
            resource_dict[r] = 0

        #TODO: add exception handling
        db.run_in_transaction(self.__setResourcesTran, resource_dict)

    def __setResourcesTran(self, resource_dict):
        rd = resource_dict.copy()
        #HACK: shouldn't be more than 25 resource types, but still...
        playerResources = db.Query(PlayerResources).ancestor(self).fetch(25)
        #TODO: add transactions around this logic

        # first add to the resources we know about
        for pr in playerResources:
            if not rd.get(pr.resource, None) is None:
                pr.amount = rd[pr.resource]
                pr.put()
                del rd[pr.resource]

        # then loop through remaining resources and add them as player resources
        for r, a in rd.items():
            pr = PlayerResources(parent=self, resource=r, amount=a)
            pr.put()

        return True

    def adjustResources(self, resource_dict, validate_only=False):
        ret = db.run_in_transaction(self.__adjustResourcesTrans, resource_dict,
                                    validate_only)

        if ret is None:
            return False
        else:
            return ret

    def __adjustResourcesTrans(self, resource_dict, validate_only):
        rd = resource_dict.copy()
        #HACK: shouldn't be more than 25 resource types, but still...
        playerResources = db.Query(PlayerResources).ancestor(self).fetch(25)
        #TODO: add transactions around this logic

        # first add to the resources we know about
        for pr in playerResources:
            if not rd.get(pr.resource, None) is None:
                if pr.amount + rd[pr.resource] < 0:
                    raise db.Rollback()
                elif not validate_only:
                    pr.amount += rd[pr.resource]
                    pr.put()
                    del rd[pr.resource]

        # then loop through remaining resources and add them as player resources
        for r, a in rd.items():
            if a < 0:
                raise db.Rollback()
            elif not validate_only:
                logging.info("adjusting %s = %d:" % (r, a))
                pr = PlayerResources(parent=self, resource=r, amount=a)
                pr.put()

        return True
Esempio n. 19
0
class GAESeenPost(db.Model):
    user = db.UserProperty()
    feed = db.ReferenceProperty(GAEFeed)  # non-normalized
    post = db.ReferenceProperty(GAEPost)
class UserStat(db.Model):
    pic = db.ReferenceProperty(TexRender)
    user = db.UserProperty()


# TODO: add user commenting capabilities
Esempio n. 21
0
class Greeting(db.Model):
    """Models an individual Guestbook entry with an author, content, and date."""
    author = db.UserProperty()
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)
Esempio n. 22
0
class UserData(db.Model):
    user = db.UserProperty()
    aws_username = db.StringProperty()
Esempio n. 23
0
class RegisteredUserSettings(db.Model):
    user = db.UserProperty()
    last_changed = db.DateTimeProperty(auto_now=True)

    paging_pager_count = db.IntegerProperty(required=True)
Esempio n. 24
0
class Post(db.Model):
    title = db.StringProperty()
    slug = db.StringProperty()
    pub_date = db.DateTimeProperty(auto_now_add=True)
    author = db.UserProperty(auto_current_user_add=True)

    excerpt = db.TextProperty(default=None)
    body = db.TextProperty()

    excerpt_html = db.TextProperty(default=None)
    body_html = db.TextProperty()

    tags = db.StringListProperty()

    def get_absolute_url(self):
        return "/blog/%04d/%02d/%02d/%s" % (self.pub_date.year,
                                            self.pub_date.month,
                                            self.pub_date.day, self.slug)

    def get_edit_url(self):
        return "/admin/post/edit/%04d/%02d/%02d/%s" % (
            self.pub_date.year, self.pub_date.month, self.pub_date.day,
            self.slug)

    def get_delete_url(self):
        return "/admin/post/delete/%04d/%02d/%02d/%s" % (
            self.pub_date.year, self.pub_date.month, self.pub_date.day,
            self.slug)

    def delete(self):
        if db.delete(self):
            return 1
        else:
            return 0

    def put(self):
        """
        Make sure that the slug is unique for the given date before
        the data is actually saved.
        """

        # Delete the cached archive list if we are saving a new post
        if not self.is_saved():
            memcache.delete('archive_list')

        # Delete the cached tag list whenever a post is created/updated
        memcache.delete('tag_list')

        self.test_for_slug_collision()
        self.populate_html_fields()

        key = super(Post, self).put()
        return key

    def test_for_slug_collision(self):
        # Build the time span to check for slug uniqueness
        start_date = datetime.datetime(self.pub_date.year, self.pub_date.month,
                                       self.pub_date.day)
        time_delta = datetime.timedelta(days=1)
        end_date = start_date + time_delta

        # Create a query to check for slug uniqueness in the specified time span
        query = Post.all(keys_only=True)
        query.filter('pub_date >= ', start_date)
        query.filter('pub_date < ', end_date)
        query.filter('slug = ', self.slug)

        # Get the Post Key that match the given query (if it exists)
        post = query.get()

        # If any slug matches were found then an exception should be raised
        if post and (not self.is_saved() or self.key() != post):
            raise SlugConstraintViolation(start_date, self.slug)

    def populate_html_fields(self):
        # Setup Markdown with the code highlighter
        md = markdown.Markdown(extensions=['codehilite'])

        # Convert the excerpt and body Markdown into html
        if self.excerpt != None:
            self.excerpt_html = md.convert(self.excerpt)
        if self.body != None:
            self.body_html = md.convert(self.body)
Esempio n. 25
0
class FileMetadata(db.Model):
    """A helper class that will hold metadata for the user's blobs.

    Specifially, we want to keep track of who uploaded it, where they uploaded it
    from (right now they can only upload from their computer, but in the future
    urlfetch would be nice to add), and links to the results of their MR jobs. To
    enable our querying to scan over our input data, we store keys in the form
    'user/date/blob_key', where 'user' is the given user's e-mail address, 'date'
    is the date and time that they uploaded the item on, and 'blob_key'
    indicates the location in the Blobstore that the item can be found at. '/'
    is not the actual separator between these values - we use '..' since it is
    an illegal set of characters for an e-mail address to contain.
    """

    __SEP = ".."
    __NEXT = "./"

    owner = db.UserProperty()
    filename = db.StringProperty()
    uploadedOn = db.DateTimeProperty()
    source = db.StringProperty()
    blobkey = db.StringProperty()
    song_sales_link = db.StringListProperty()
    song_profit_link = db.StringListProperty()
    artist_songs_link = db.StringListProperty()
    artist_profit_link = db.StringListProperty()
    genre_song_sales_link = db.StringListProperty()
    genre_song_profit_link = db.StringListProperty()
    genre_artist_songs_link = db.StringListProperty()
    genre_artist_profit_link = db.StringListProperty()
    find_most_common_link = db.StringListProperty()



    @staticmethod
    def getFirstKeyForUser(username):
        """Helper function that returns the first possible key a user could own.

        This is useful for table scanning, in conjunction with getLastKeyForUser.

        Args:
            username: The given user's e-mail address.
        Returns:
            The internal key representing the earliest possible key that a user could
            own (although the value of this key is not able to be used for actual
            user data).
        """

        return db.Key.from_path("FileMetadata", username + FileMetadata.__SEP)

    @staticmethod
    def getLastKeyForUser(username):
        """Helper function that returns the last possible key a user could own.

        This is useful for table scanning, in conjunction with getFirstKeyForUser.

        Args:
            username: The given user's e-mail address.
        Returns:
            The internal key representing the last possible key that a user could
            own (although the value of this key is not able to be used for actual
            user data).
        """

        return db.Key.from_path("FileMetadata", username + FileMetadata.__NEXT)

    @staticmethod
    def getKeyName(username, date, blob_key):
        """Returns the internal key for a particular item in the database.

        Our items are stored with keys of the form 'user/date/blob_key' ('/' is
        not the real separator, but __SEP is).

        Args:
            username: The given user's e-mail address.
            date: A datetime object representing the date and time that an input
                file was uploaded to this app.
            blob_key: The blob key corresponding to the location of the input file
                in the Blobstore.
        Returns:
            The internal key for the item specified by (username, date, blob_key).
        """

        sep = FileMetadata.__SEP
        return str(username + sep + str(date) + sep + blob_key)
Esempio n. 26
0
class Account(db.Model):
    user = db.UserProperty()
Esempio n. 27
0
class User(BaseModel):
    """A model with the same attributes and methods as a Django user model.

  The model has two additions. The first addition is a 'user' attribute which
  references a App Engine user. The second is the 'get_djangouser_for_user'
  classmethod that should be used to retrieve a DjangoUser instance from a App
  Engine user object.
  """
    user = db.UserProperty(required=True)
    username = db.StringProperty(required=True)
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    email = db.EmailProperty()
    password = db.StringProperty()
    is_staff = db.BooleanProperty(default=False, required=True)
    is_active = db.BooleanProperty(default=True, required=True)
    is_superuser = db.BooleanProperty(default=False, required=True)
    last_login = db.DateTimeProperty(auto_now_add=True, required=True)
    date_joined = db.DateTimeProperty(auto_now_add=True, required=True)
    groups = EmptyManager()
    user_permissions = EmptyManager()

    def __unicode__(self):
        return self.username

    def __str__(self):
        return unicode(self).encode('utf-8')

    @classmethod
    def get_djangouser_for_user(cls, user):
        query = cls.all().filter("user ="******"""Gets and deletes messages for this user"""
        msgs = []
        for msg in self.message_set:
            msgs.append(msg)
            msg.delete()
        return msgs

    def is_anonymous(self):
        """Always return False"""
        return False

    def is_authenticated(self):
        """Always return True"""
        return True

    def get_absolute_url(self):
        return "/users/%s/" % urllib.quote(smart_str(self.username))

    def get_full_name(self):
        full_name = u'%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def email_user(self, subject, message, from_email):
        """Sends an email to this user.

    According to the App Engine email API the from_email must be the
    email address of a registered administrator for the application.
    """
        mail.send_mail(subject, message, from_email, [self.email])

    @property
    def pk(self):
        try:
            return str(self.key())
        except db.NotSavedError:
            pass

    def get_profile(self):
        """
    Returns site-specific profile for this user. Raises
    SiteProfileNotAvailable if this site does not allow profiles.

    When using the App Engine authentication framework, users are created
    automatically.
    """
        from django.contrib.auth.models import SiteProfileNotAvailable
        if not hasattr(self, '_profile_cache'):
            from django.conf import settings
            if not hasattr(settings, "AUTH_PROFILE_MODULE"):
                raise SiteProfileNotAvailable
            try:
                app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
                model = models.get_model(app_label, model_name)
                self._profile_cache = model.all().filter("user ="******"id"):
            created = True
        super(User, self).save()
        if created:
            user_created.send(sender=self.__class__, instance=self)
Esempio n. 28
0
class GeoLink(db.Model):
    url = db.StringProperty()
    user = db.UserProperty()
    shortlink = db.StringProperty()
    linkmap = db.TextProperty()
    linkmap_key = db.StringProperty()
    created_on = db.DateTimeProperty(auto_now_add=True)

    @property
    def geolink(self):
        if self.shortlink is None:
            return GEOLINK_BASE_URL + 'l/' + str(self.key())
        else:
            return self.shortlink

    @property
    def infolink(self):
        return GEOLINK_BASE_URL + 'i/' + str(self.key())

    def linkmap_find(self, code_value):
        value = None
        lines = self.linkmap.split('\n')
        for line in lines:
            parts = line.split('|')
            if parts[0].rstrip().lower() == code_value.lower():
                value = parts[1].rstrip()
            if parts[1].rstrip().lower() == code_value.lower():
                value = parts[0].rstrip()
        return value

    def validate(self):
        isValidInput = False
        if self.url:
            #validate input url
            link_code_count = 0
            for code in GEOLINK_CODES:
                link_code_start = self.url.find(code)
                if link_code_start != -1:
                    link_code_count += 1
            if link_code_count == 0:
                raise main.ValidationError("link must use at least 1 code")
            else:
                if GeoLink.validateURL(self.url):
                    isValidInput = True
        elif self.linkmap:
            #validate input linkmap and linkmap_key
            if self.linkmap and self.linkmap_key:
                valid_codes = None
                if self.linkmap_key == "state_code":
                    valid_codes = LIST_STATE_CODES
                elif self.linkmap_key == "state":
                    valid_codes = LIST_STATES
                else:
                    raise main.ValidationError("Invalid code for map")
                lines = self.linkmap.split('\n')
                for line in lines:
                    parts = line.split('|')
                    if len(parts) != 2:
                        raise main.ValidationError(
                            "Each line must have a code and a URL seperated by |"
                        )
                    if parts[0].rstrip().upper() in valid_codes:
                        GeoLink.validateURL(parts[1])
                    elif parts[1].rstrip().upper() in valid_codes:
                        GeoLink.validateURL(parts[0])
                    else:
                        raise main.ValidationError(
                            "Missing or invalid code value")
                isValidInput = True
        else:
            raise main.ValidationError("Must enter link or linkmap")
        return isValidInput

    @classmethod
    def validateURL(cls, url):
        #TODO: throw exception instead of catching
        parts = None
        try:
            parts = urlparse.urlparse(url)
        except Exception, e:
            logging.error(e)
            raise main.ValidationError("URL is not valid")
        if not all([parts.scheme, parts.netloc]):
            raise main.ValidationError("URL not complete")
        if parts.scheme not in ['http', 'https']:
            raise main.ValidationError("URL missing scheme (http or https)")
        return True
Esempio n. 29
0
class Greeting(db.Model):
    author = db.UserProperty()
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)
Esempio n. 30
0
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