Esempio n. 1
0
class Post(db.Model):
    title = db.StringProperty(required = True)
    body = db.TextProperty(required = True)
    author = db.ReferenceProperty(required = True)
    created = db.DateTimeProperty(User, auto_now_add = True)
Esempio n. 2
0
class Art(db.Model):
    title = db.StringProperty(required=True)
    art = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    coords = db.GeoPtProperty(
    )  #not required because would affect old art submissions
Esempio n. 3
0
class Page(search.Searchable, db.Model):
    author_name = db.StringProperty()
    title = db.StringProperty()
    content = db.TextProperty()
    INDEX_TITLE_FROM_PROP = 'title'
Esempio n. 4
0
class Snippet(db.Model):
    user = db.ReferenceProperty(User)
    text = db.TextProperty()
    date = db.DateProperty()
Esempio n. 5
0
class Blog(db.Model):
    title = db.StringProperty(required=True)
    body = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
Esempio n. 6
0
class DurableJobEntity(entities.BaseEntity):
    """A class that represents a persistent database entity of durable job."""

    updated_on = db.DateTimeProperty(indexed=True)
    execution_time_sec = db.IntegerProperty(indexed=False)
    status_code = db.IntegerProperty(indexed=False)
    output = db.TextProperty(indexed=False)
    sequence_num = db.IntegerProperty(indexed=False)

    @classmethod
    def _get_by_name(cls, name):
        return DurableJobEntity.get_by_key_name(name)

    @classmethod
    def _update(cls, name, sequence_num, status_code, output):
        """Updates job state in a datastore."""
        assert db.is_in_transaction()

        job = DurableJobEntity._get_by_name(name)
        if not job:
            logging.error('Job was not started or was deleted: %s', name)
            return
        if job.sequence_num != sequence_num:
            logging.warning('Request to update status code to %d ' %
                            status_code +
                            'for sequence number %d ' % sequence_num +
                            'but job is already on run %d' % job.sequence_num)
            return
        now = datetime.datetime.utcnow()
        if status_code in (STATUS_CODE_STARTED, STATUS_CODE_QUEUED):
            job.execution_time_sec = 0
        else:
            job.execution_time_sec += long(
                (now - job.updated_on).total_seconds())
        job.updated_on = now
        job.status_code = status_code
        if output:
            job.output = output
        job.put()

    @classmethod
    def _create_job(cls, name):
        """Creates new or reset a state of existing job in a datastore."""
        assert db.is_in_transaction()

        job = DurableJobEntity._get_by_name(name)
        if not job:
            job = DurableJobEntity(key_name=name)
        job.updated_on = datetime.datetime.utcnow()
        job.execution_time_sec = 0
        job.status_code = STATUS_CODE_QUEUED
        job.output = None
        if not job.sequence_num:
            job.sequence_num = 1
        else:
            job.sequence_num += 1
        job.put()
        return job.sequence_num

    @classmethod
    def _start_job(cls, name, sequence_num, output=None):
        return cls._update(name, sequence_num, STATUS_CODE_STARTED, output)

    @classmethod
    def _complete_job(cls, name, sequence_num, output):
        return cls._update(name, sequence_num, STATUS_CODE_COMPLETED, output)

    @classmethod
    def _fail_job(cls, name, sequence_num, output):
        return cls._update(name, sequence_num, STATUS_CODE_FAILED, output)

    @property
    def has_finished(self):
        return self.status_code in [STATUS_CODE_COMPLETED, STATUS_CODE_FAILED]
Esempio n. 7
0
class _PipelineRecord(db.Model):
    """Represents a Pipeline.

  Properties:
    class_path: Path of the Python class to use for this pipeline.
    root_pipeline: The root of the whole workflow; set to itself this pipeline
      is its own root.
    fanned_out: List of child _PipelineRecords that were started when this
      generator pipeline moved from WAITING to RUN.
    start_time: For pipelines with no start _BarrierRecord, when this pipeline
      was enqueued to run immediately.
    finalized_time: When this pipeline moved from WAITING or RUN to DONE.
    params: Serialized parameter dictionary.
    status: The current status of the pipeline.
    current_attempt: The current attempt (starting at 0) to run.
    max_attempts: Maximum number of attempts (starting at 0) to run.
    next_retry_time: ETA of the next retry attempt.
    retry_message: Why the last attempt failed; None or empty if no message.

  Root pipeline properties:
    is_root_pipeline: This is a root pipeline.
    abort_message: Why the whole pipeline was aborted; only saved on
      root pipelines.
    abort_requested: If an abort signal has been requested for this root
      pipeline; only saved on root pipelines
  """

    WAITING = 'waiting'
    RUN = 'run'
    DONE = 'done'
    ABORTED = 'aborted'

    class_path = db.StringProperty()
    root_pipeline = db.SelfReferenceProperty(
        collection_name='child_pipelines_set')
    fanned_out = db.ListProperty(db.Key, indexed=False)
    start_time = db.DateTimeProperty(indexed=True)
    finalized_time = db.DateTimeProperty(indexed=False)

    # One of these two will be set, depending on the size of the params.
    params_text = db.TextProperty(name='params')
    params_blob = blobstore.BlobReferenceProperty(name='params_blob',
                                                  indexed=False)

    status = db.StringProperty(choices=(WAITING, RUN, DONE, ABORTED),
                               default=WAITING)

    # Retry behavior
    current_attempt = db.IntegerProperty(default=0, indexed=False)
    max_attempts = db.IntegerProperty(default=1, indexed=False)
    next_retry_time = db.DateTimeProperty(indexed=False)
    retry_message = db.TextProperty()

    # Root pipeline properties
    is_root_pipeline = db.BooleanProperty()
    abort_message = db.TextProperty()
    abort_requested = db.BooleanProperty(indexed=False)

    @classmethod
    def kind(cls):
        return '_AE_Pipeline_Record'

    @property
    def params(self):
        """Returns the dictionary of parameters for this Pipeline."""
        if hasattr(self, '_params_decoded'):
            return self._params_decoded

        if self.params_blob is not None:
            value_encoded = self.params_blob.open().read()
        else:
            value_encoded = self.params_text

        value = simplejson.loads(value_encoded, cls=util.JsonDecoder)
        if isinstance(value, dict):
            kwargs = value.get('kwargs')
            if kwargs:
                adjusted_kwargs = {}
                for arg_key, arg_value in kwargs.iteritems():
                    # Python only allows non-unicode strings as keyword arguments.
                    adjusted_kwargs[str(arg_key)] = arg_value
                value['kwargs'] = adjusted_kwargs

        self._params_decoded = value
        return self._params_decoded

    def truncated_copy(self):
        """Create a lightweight copy of the pipeline with the args truncated."""
        return _LowMemoryPipelineRecord(self)
Esempio n. 8
0
class SocialGroup(db.Model):
    user = db.ReferenceProperty(SocialUser)
    social_account = db.ReferenceProperty(SocialAccount)
    social_account_item_id = db.TextProperty()

    name = db.StringProperty()
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()
  finished = db.BooleanProperty()
  combined = db.TextProperty()
  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(self.request_id)
    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)
    log.set_finished(self.finished)
    log.set_combined(self.combined)

    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)
Esempio n. 10
0
class Quotes(db.Model):
    quote=db.TextProperty(required=True)
    author=db.StringProperty(required=True)
Esempio n. 11
0
class MyUser(db.Model):
    email = db.EmailProperty()
    display_name = db.TextProperty()
    past_view_count = db.IntegerProperty(
        default=0)  # just for demo purposes ...
Esempio n. 12
0
class Posts(db.Model):
    subject = db.StringProperty(required=True)
    content = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
Esempio n. 13
0
class settingsbd(db.Model):
  keyS = db.StringProperty()
  valueS = db.TextProperty()
Esempio n. 14
0
class Art(db.Model):
    title = db.StringProperty(required=True)
    art = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    coords = db.GeoPtProperty()
Esempio n. 15
0
class ShardState(db.Model):
  """Single shard execution state.

  The shard state is stored in the datastore and is later aggregated by
  controller task. ShardState key_name is equal to shard_id.

  Shard state contains critical state to ensure the correctness of
  shard execution. It is the single source of truth about a shard's
  progress. For example:
  1. A slice is allowed to run only if its payload matches shard state's
     expectation.
  2. A slice is considered running only if it has acquired the shard's lock.
  3. A slice is considered done only if it has successfully committed shard
     state to db.

  Properties about the shard:
    active: if we have this shard still running as boolean.
    counters_map: shard's counters map as CountersMap. All counters yielded
      within mapreduce are stored here.
    mapreduce_id: unique id of the mapreduce.
    shard_id: unique id of this shard as string.
    shard_number: ordered number for this shard.
    retries: the number of times this shard has been retried.
    result_status: If not None, the final status of this shard.
    update_time: The last time this shard state was updated.
    shard_description: A string description of the work this shard will do.
    last_work_item: A string description of the last work item processed.
    writer_state: writer state for this shard. The shard's output writer
      instance can save in-memory output references to this field in its
      "finalize" method.

   Properties about slice management:
    slice_id: slice id of current executing slice. A slice's task
      will not run unless its slice_id matches this. Initial
      value is 0. By the end of slice execution, this number is
      incremented by 1.
    slice_start_time: a slice updates this to now at the beginning of
      execution. If the transaction succeeds, the current task holds
      a lease of slice duration + some grace period. During this time, no
      other task with the same slice_id will execute. Upon slice failure,
      the task should try to unset this value to allow retries to carry on
      ASAP.
    slice_request_id: the request id that holds/held the lease. When lease has
      expired, new request needs to verify that said request has indeed
      ended according to logs API. Do this only when lease has expired
      because logs API is expensive. This field should always be set/unset
      with slice_start_time. It is possible Logs API doesn't log a request
      at all or doesn't log the end of a request. So a new request can
      proceed after a long conservative timeout.
    slice_retries: the number of times a slice has been retried due to
      processing data when lock is held. Taskqueue/datastore errors
      related to slice/shard management are not counted. This count is
      only a lower bound and is used to determined when to fail a slice
      completely.
    acquired_once: whether the lock for this slice has been acquired at
      least once. When this is True, duplicates in outputs are possible.
  """

  RESULT_SUCCESS = "success"
  RESULT_FAILED = "failed"
  # Shard can be in aborted state when user issued abort, or controller
  # issued abort because some other shard failed.
  RESULT_ABORTED = "aborted"

  _RESULTS = frozenset([RESULT_SUCCESS, RESULT_FAILED, RESULT_ABORTED])

  # Maximum number of shard states to hold in memory at any time.
  _MAX_STATES_IN_MEMORY = 10

  # Functional properties.
  mapreduce_id = db.StringProperty(required=True)
  active = db.BooleanProperty(default=True, indexed=False)
  counters_map = json_util.JsonProperty(
      CountersMap, default=CountersMap(), indexed=False)
  result_status = db.StringProperty(choices=_RESULTS, indexed=False)
  retries = db.IntegerProperty(default=0, indexed=False)
  writer_state = json_util.JsonProperty(dict, indexed=False)
  slice_id = db.IntegerProperty(default=0, indexed=False)
  slice_start_time = db.DateTimeProperty(indexed=False)
  slice_request_id = db.ByteStringProperty(indexed=False)
  slice_retries = db.IntegerProperty(default=0, indexed=False)
  acquired_once = db.BooleanProperty(default=False, indexed=False)

  # For UI purposes only.
  update_time = db.DateTimeProperty(auto_now=True, indexed=False)
  shard_description = db.TextProperty(default="")
  last_work_item = db.TextProperty(default="")

  def __str__(self):
    kv = {"active": self.active,
          "slice_id": self.slice_id,
          "last_work_item": self.last_work_item,
          "update_time": self.update_time}
    if self.result_status:
      kv["result_status"] = self.result_status
    if self.retries:
      kv["retries"] = self.retries
    if self.slice_start_time:
      kv["slice_start_time"] = self.slice_start_time
    if self.slice_retries:
      kv["slice_retries"] = self.slice_retries
    if self.slice_request_id:
      kv["slice_request_id"] = self.slice_request_id
    if self.acquired_once:
      kv["acquired_once"] = self.acquired_once
    keys = kv.keys()
    keys.sort()

    result = "ShardState is {"
    for k in keys:
      result += k + ":" + str(kv[k]) + ","
    result += "}"
    return result

  def reset_for_retry(self):
    """Reset self for shard retry."""
    self.retries += 1
    self.last_work_item = ""
    self.active = True
    self.result_status = None
    self.counters_map = CountersMap()
    self.slice_id = 0
    self.slice_start_time = None
    self.slice_request_id = None
    self.slice_retries = 0
    self.acquired_once = False

  def advance_for_next_slice(self, recovery_slice=False):
    """Advance self for next slice.

    Args:
      recovery_slice: True if this slice is running recovery logic.
        See handlers.MapperWorkerCallbackHandler._attempt_slice_recovery
        for more info.
    """
    self.slice_start_time = None
    self.slice_request_id = None
    self.slice_retries = 0
    self.acquired_once = False
    if recovery_slice:
      self.slice_id += 2
    else:
      self.slice_id += 1

  def set_for_failure(self):
    self.active = False
    self.result_status = self.RESULT_FAILED

  def set_for_abort(self):
    self.active = False
    self.result_status = self.RESULT_ABORTED

  def set_for_success(self):
    self.active = False
    self.result_status = self.RESULT_SUCCESS
    self.slice_start_time = None
    self.slice_request_id = None
    self.slice_retries = 0
    self.acquired_once = False

  def copy_from(self, other_state):
    """Copy data from another shard state entity to self."""
    for prop in self.properties().values():
      setattr(self, prop.name, getattr(other_state, prop.name))

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      return False
    return self.properties() == other.properties()

  def get_shard_number(self):
    """Gets the shard number from the key name."""
    return int(self.key().name().split("-")[-1])

  shard_number = property(get_shard_number)

  def get_shard_id(self):
    """Returns the shard ID."""
    return self.key().name()

  shard_id = property(get_shard_id)

  @classmethod
  def kind(cls):
    """Returns entity kind."""
    return "_AE_MR_ShardState"

  @classmethod
  def shard_id_from_number(cls, mapreduce_id, shard_number):
    """Get shard id by mapreduce id and shard number.

    Args:
      mapreduce_id: mapreduce id as string.
      shard_number: shard number to compute id for as int.

    Returns:
      shard id as string.
    """
    return "%s-%d" % (mapreduce_id, shard_number)

  @classmethod
  def get_key_by_shard_id(cls, shard_id):
    """Retrieves the Key for this ShardState.

    Args:
      shard_id: The shard ID to fetch.

    Returns:
      The Datatore key to use to retrieve this ShardState.
    """
    return db.Key.from_path(cls.kind(), shard_id)

  @classmethod
  def get_by_shard_id(cls, shard_id):
    """Get shard state from datastore by shard_id.

    Args:
      shard_id: shard id as string.

    Returns:
      ShardState for given shard id or None if it's not found.
    """
    return cls.get_by_key_name(shard_id)

  @classmethod
  def find_by_mapreduce_state(cls, mapreduce_state):
    """Find all shard states for given mapreduce.

    Deprecated. Use find_all_by_mapreduce_state.
    This will be removed after 1.8.9 release.

    Args:
      mapreduce_state: MapreduceState instance

    Returns:
      A list of ShardStates.
    """
    return list(cls.find_all_by_mapreduce_state(mapreduce_state))

  @classmethod
  def find_all_by_mapreduce_state(cls, mapreduce_state):
    """Find all shard states for given mapreduce.

    Args:
      mapreduce_state: MapreduceState instance

    Yields:
      shard states sorted by shard id.
    """
    keys = cls.calculate_keys_by_mapreduce_state(mapreduce_state)
    i = 0
    while i < len(keys):
      @db.non_transactional
      def no_tx_get(i):
        return db.get(keys[i:i+cls._MAX_STATES_IN_MEMORY])
      # We need a separate function to so that we can mix non-transactional and
      # use be a generator
      states = no_tx_get(i)
      for s in states:
        i += 1
        if s is not None:
          yield s

  @classmethod
  def calculate_keys_by_mapreduce_state(cls, mapreduce_state):
    """Calculate all shard states keys for given mapreduce.

    Args:
      mapreduce_state: MapreduceState instance

    Returns:
      A list of keys for shard states, sorted by shard id.
      The corresponding shard states may not exist.
    """
    if mapreduce_state is None:
      return []

    keys = []
    for i in range(mapreduce_state.mapreduce_spec.mapper.shard_count):
      shard_id = cls.shard_id_from_number(mapreduce_state.key().name(), i)
      keys.append(cls.get_key_by_shard_id(shard_id))
    return keys

  @classmethod
  def create_new(cls, mapreduce_id, shard_number):
    """Create new shard state.

    Args:
      mapreduce_id: unique mapreduce id as string.
      shard_number: shard number for which to create shard state.

    Returns:
      new instance of ShardState ready to put into datastore.
    """
    shard_id = cls.shard_id_from_number(mapreduce_id, shard_number)
    state = cls(key_name=shard_id,
                mapreduce_id=mapreduce_id)
    return state
class _LogLine(db.Model):
  """Representation of an application-level log line."""
  time = db.IntegerProperty()
  level = db.IntegerProperty()
  message = db.TextProperty()
Esempio n. 17
0
class FeedbackSettings(db.Model):
    From = db.StringProperty()
    ValidRecipients = db.StringListProperty()
    StyleSheet = db.TextProperty()
    ReCaptchaPublic = db.StringProperty()
    ReCaptchaPrivate = db.StringProperty()
Esempio n. 18
0
class Election(db.Model):
    """
    An election that users may vote for.
    """
    name = db.StringProperty(required=True)
    start = db.DateTimeProperty(required=True)  # Time when voting begins
    end = db.DateTimeProperty(required=True)  # Time when voting ends
    organization = db.ReferenceProperty(Organization,
                                        collection_name='elections')
    result_computed = db.BooleanProperty(required=True, default=False)
    result_delay = db.IntegerProperty(
        required=True, default=0)  # Results delay to public in seconds
    universal = db.BooleanProperty(required=True, default=False)
    hidden = db.BooleanProperty(required=True, default=False)
    task_count = db.IntegerProperty(
        required=True,  # Counter used to identify tasks
        default=0)
    voter_count = db.IntegerProperty(required=True, default=0)
    voted_count = db.IntegerProperty(required=True, default=0)
    description = db.TextProperty(required=False, default="")

    def to_json(self, parseable_date=False):
        # calculate the publication date by adding result delay to end
        pub = self.end + timedelta(seconds=self.result_delay)
        # parseable_date means it can be parsed in JS with Date.parse()
        times = {
            'start': self.start.strftime('%a, %B %d, %Y, %I:%M %p') + ' UTC',
            'end': self.end.strftime('%a, %B %d, %Y, %I:%M %p') + ' UTC',
            'pub': pub.strftime('%a, %B %d, %Y, %I:%M %p') + ' UTC'
        } if parseable_date else {
            'start': str(self.start),
            'end': str(self.end),
            'pub': str(pub)
        }

        now = datetime.now()
        status = 'Not started'
        if now > self.start:
            status = 'Voting in progress'
        if now > self.end:
            status = 'Voting has ended'
        if self.result_computed:
            status = 'Result computed'

        return {
            'id': str(self.key()),
            'name': self.name,
            'organization': self.organization.name,
            'times': times,
            'result_computed': self.result_computed,
            'result_delay': self.result_delay,
            'universal': self.universal,
            'hidden': self.hidden,
            'voter_count': self.voter_count,
            'voted_count': self.voted_count,
            'description': self.description,
            'status': status,
        }

    @property
    def election_positions(self):
        return [
            ep for ep in ElectionPosition.gql(
                "WHERE election=:1 ORDER BY datetime_created", self)
        ]
Esempio n. 19
0
class Post(db.Model):
    title = db.StringProperty()
    author = db.UserProperty()
    content = db.TextProperty()
    format = db.StringProperty()
    date = db.DateTimeProperty()
Esempio n. 20
0
class Membership(db.Model):
  hash = db.StringProperty()
  first_name = db.StringProperty(required=True)
  last_name = db.StringProperty(required=True)
  email = db.StringProperty(required=True)
  # The hash of the user's password.
  # TODO(danielp): Make this required after we finish migrating away from domain
  # accounts.
  password_hash = db.StringProperty()
  twitter = db.StringProperty(required=False)
  plan  = db.StringProperty(required=False)
  status  = db.StringProperty() # None, active, suspended
  referuserid = db.StringProperty()
  referrer  = db.StringProperty()
  rfid_tag = db.StringProperty()
  extra_599main = db.StringProperty()
  extra_dnd = db.BooleanProperty(default=False)
  auto_signin = db.StringProperty()
  unsubscribe_reason = db.TextProperty()
  hardship_comment = db.TextProperty()

  spreedly_token = db.StringProperty()
  parking_pass = db.StringProperty()

  created = db.DateTimeProperty(auto_now_add=True)
  updated = db.DateTimeProperty()

  # How many times the user has signed in this month.
  signins = db.IntegerProperty(default=0)
  # When the last time they signed in was.
  last_signin = db.DateTimeProperty()

  # The following are legacy parameters.
  # TODO(danielp): Remove these after we complete the migration away from
  # domain accounts.

  # Whether we've created a google apps user yet.
  domain_user = db.BooleanProperty(default=False)
  # The user's domain username.
  username = db.StringProperty()
  # Temporarily stores the user's domain password.
  password = db.StringProperty(default=None)

  """ Override of the default put method which allows us to skip changing the
  updated property for testing purposes.
  skip_time_update: Whether or not to set updated to the current date and time.
  """
  def put(self, *args, **kwargs):
    if not kwargs.pop("skip_time_update", False):
      self.updated = datetime.datetime.now()

    super(Membership, self).put(*args, **kwargs)

  def icon(self):
    return str("http://www.gravatar.com/avatar/" + hashlib.md5(self.email.lower()).hexdigest())

  def full_name(self):
    return '%s %s' % (self.first_name, self.last_name)

  def spreedly_url(self):
    config = Config()
    return str("https://subs.pinpayments.com/%s/subscriber_accounts/%s" % \
        (config.SPREEDLY_ACCOUNT, self.spreedly_token))

  def spreedly_admin_url(self):
    config = Config()
    return str("https://subs.pinpayments.com/%s/subscribers/%s" % \
        (config.SPREEDLY_ACCOUNT, self.key().id()))

  def subscribe_url(self, plan=None):
    config = Config()
    if not plan:
      plan = self.plan
    url = "https://subs.pinpayments.com/%s/subscribers/%i/%s/subscribe/%s" % \
        (config.SPREEDLY_ACCOUNT, self.key().id(),
         self.spreedly_token, plans.Plan.get_by_name(plan).plan_id)
    return str(url)

  """ URL we use to subscribe a person for the first time.
  host: The first part of the return URL, e.g. signup.hackerdojo.com.
  plan: Optionally specifies a different plan to use. """
  def new_subscribe_url(self, host, plan=None):
    config = Config()
    if not plan:
      plan = self.plan

    query_str = urllib.urlencode({"first_name": self.first_name,
                                  "last_name": self.last_name,
                                  "email": self.email,
                                  "return_url": "http://%s/success/%s" % \
                                      (host, self.hash)})
    url = "https://subs.pinpayments.com/%s/subscribers/%i/subscribe/%s/%s?%s" % \
        (config.SPREEDLY_ACCOUNT, self.key().id(),
         plans.Plan.get_by_name(plan).plan_id, self.username, query_str)
    return str(url)

  def force_full_subscribe_url(self):
    config = Config()
    url = "https://subs.pinpayments.com/%s/subscribers/%i/%s/subscribe/%s" % \
        (config.SPREEDLY_ACCOUNT, self.key().id(),
        self.spreedly_token, plans.newfull.plan_id)
    return str(url)

  def unsubscribe_url(self):
    return "http://signup.hackerdojo.com/unsubscribe/%i" % (self.key().id())

  """ Returns this user's unique ID, which can be an integer or string. """
  def get_id(self):
    return self.key().id()

  """ Sets the user's password.
  password: The password which will be hashed and stored. """
  def set_password(self, password):
    logging.debug("Setting password for user %s." % (self.email))

    self.password_hash = security.generate_password_hash(password, length=12)

  """ Creates a new authorization token for a given user ID.
  user_id: User unique ID.
  Returns: A string with the authorization token. """
  @classmethod
  def create_auth_token(cls, user_id):
    token = UserToken(user_id, "auth")
    token.save()

    return token.token

  """ Deletes a given authorization token.
  user_id: User unique ID.
  token: A string with the authorization token. """
  @classmethod
  def delete_auth_token(cls, user_id, token):
    token = UserToken.verify(user_id, "auth", token)
    if not token:
      logging.warning("Delete: Ignoring bad token for %d." % (user_id))
      return

    token.delete()

  """ Returns a Membership object based on a user ID and token.
  user_id: The unique ID of the requesting user.
  token: The token string to be verified.
  Returns: A tuple (Membership, timestamp), with a Membership object and
  the token timestamp, or (None, None) if both were not found. """
  @classmethod
  def get_by_auth_token(cls, user_id, token):
    # First, check that the token is valid.
    token = UserToken.verify(user_id, "auth", token)
    if not token:
      logging.warning("Bad token, not getting user %d." % (user_id))
      return (None, None)

    user = cls.get_by_id(user_id)
    timestamp = token.timestamp
    return (user, timestamp)

  """ Gets the user with the specified login credentials.
  email: The email of the user.
  password: The password of the user.
  Returns: Membership object if found. """
  @classmethod
  def get_by_auth_password(cls, email, password):
    user = cls.get_by_email(email)
    if not user:
      raise auth.InvalidAuthIdError("No user with email '%s'." % (email))

    if not security.check_password_hash(password, user.password_hash):
      raise auth.InvalidPasswordError("Bad password for user '%s'." % (email))

    return user

  """ Gets the user with the specified email.
  email: Either the normal email, or the hackerdojo.com email of the user.
  Returns: The membership object corresponding to the user, or None if no user
  was found. """
  @classmethod
  def get_by_email(cls, email):
    # TODO(danielp): Remove code for dealing with hackerdojo.com emails after
    # we've finished migrating away from domain accounts.
    if "@hackerdojo.com" in email:
      username = email.split("@")[0]
      return cls.get_by_username(username)

    return cls.all().filter('email =', email).get()

  @classmethod
  def get_by_hash(cls, hash):
    return cls.all().filter('hash =', hash).get()

  # This is a legacy method:
  # TODO(danielp): Remove this after we migrate away from domain accounts.
  @classmethod
  def get_by_username(cls, username):
    return cls.all().filter('username ='******'s email. This will be used as a unique ID.
  password: The user's raw password. Will be hashed before saving, obviously.
  other_properties: Keyword arguments specifying properties that will be
  forwarded to the Membership constructor. All the other required properties
  should be in here.
  Returns: The created Membership entity. """
  @classmethod
  def create_user(cls, email, password, **other_properties):
    logging.info("Creating user with email '%s', other properties: %s." % \
                 (email, other_properties))

    password_hash = security.generate_password_hash(password, length=12)
    member = cls(email=email, password_hash=password_hash, **other_properties)
    member.put()

    return member
Esempio n. 21
0
class BlogInput(db.Model):
    subject = db.StringProperty(required=True)
    content = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    date = db.DateProperty(auto_now_add=True)
Esempio n. 22
0
class Issue(db.Model):
    """Represents a single issue which is being voted on"""
    status = db.StringProperty(required=True,
                               default='active',
                               choices=set(['active', 'done', 'canceled']))
    is_public = db.BooleanProperty(
        default=False)  #is issue listed on site or just by sharing url?
    creator = db.UserProperty(auto_current_user=True)
    title = db.StringProperty(required=True)
    description = db.TextProperty()
    duration = db.IntegerProperty()
    creation_date = db.DateTimeProperty(auto_now_add=True)
    start_time = db.DateTimeProperty()  #time when first vote is cast
    end_time = db.DateTimeProperty()  #time when vote will end

    #Implicit Properties:
    #choices = Implicitly created list of choice objects
    #votes - implicitly created list of vote objects

    def add_choice(self, choice_name):
        new_choice = Choice(name=choice_name, issue=self)
        new_choice.put()

    def remove_choice(self, choice):
        choice.delete()

    def vote_count(self):
        return self.votes.count(999999)

    def vote_for_member(self, member=None):
        if not member:
            member = users.get_current_user()
        logging.info('member:%s voted:%s' %
                     (member.nickname(), self.votes.filter('member =',
                                                           member).fetch(20)))
        return self.votes.filter('member =', member).get()

    def register_vote(self, choice, member=None):
        if not member:
            member = users.get_current_user()
        member_vote = self.vote_for_member(member)
        was_changed = False
        if (member_vote):
            member_vote.choice = choice
            was_changed = True
        else:
            member_vote = Vote(member=member, choice=choice, issue=self)
        member_vote.put()
        if (not self.start_time):
            self.start_time = datetime.now()
            self.end_time = self.start_time + timedelta(hours=self.duration)
            self.put()
        return was_changed

    def extend_duration(self, hours):
        self.duration += hours
        if self.start_time:
            self.end_time = self.start_time + timedelta(hours=self.duration)
        self.put()

    def days_left(self):
        delta = self.end_time - datetime.now()
        return delta.days

    def hours_left(self):
        delta = self.end_time - datetime.now()
        #days = delta.days
        #hours = days*24 + delta.seconds/3600
        hours = delta.seconds / 3600
        return hours

    def is_active(self):
        return self.status in ('active')

    def has_results(self):
        return self.status in ('done')

    def member_is_creator(self, member=None):
        if not member:
            member = users.get_current_user()
        return member == self.creator

    def winning_choices(
            self):  #returns list of keys of winning choices (may be a tie)
        result = []
        high_vote = 0
        for choice in self.choices:
            cnt = choice.vote_count()
            if cnt == high_vote:
                result.append(choice.key())
            elif cnt > high_vote:
                result = [choice.key()]
                high_vote = cnt
        return result

    def update_status(self):
        if self.is_active:
            if self.end_time:
                if self.end_time <= datetime.now():
                    logging.info('status changed for issue: %s' % (self.title))
                    self.status = 'done'
                    self.put()

    @classmethod
    def issues_created_by(cls, member=None, limit=20):
        if not member:
            member = users.get_current_user()
        return cls.all().filter('creator =',
                                member).order('-creation_date').fetch(limit)

    @classmethod
    def issues_voted_on(cls, member=None, limit=20):
        if not member:
            member = users.get_current_user()
        if not member:  #if logged out
            return []
        member_votes = Vote.all().filter(
            'member =', member).order('-update_time').fetch(limit)
        ##logging.info('member_votes:%s' % (member_votes))
        ##logging.info('output:%s' % ([vote.issue for vote in member_votes]))
        return [vote.issue for vote in member_votes]

    @classmethod
    def recent_results(
        cls,
        member=None,
        limit=20
    ):  #*** Need to fix, limit will be incorrect here because of filtering
        if not member:
            member = users.get_current_user()
        if not member:  #if logged out
            return []
        recent = cls.all().filter('status =',
                                  'done').order('-end_time').fetch(limit)
        return [issue for issue in recent
                if issue.vote_for_member()]  #***this is probably slow
Esempio n. 23
0
class BlogEntries(db.Model):
    title = db.StringProperty(required = True)
    content = db.TextProperty(required = True)
    created = db.DateTimeProperty(auto_now_add = True)
Esempio n. 24
0
class Video(Searchable, db.Model):

    youtube_id = db.StringProperty()
    url = db.StringProperty()
    title = db.StringProperty()
    description = db.TextProperty()
    playlists = db.StringListProperty()
    keywords = db.StringProperty()
    duration = db.IntegerProperty(default=0)

    # Human readable, unique id that can be used in URLS.
    readable_id = db.StringProperty()

    # YouTube view count from last sync.
    views = db.IntegerProperty(default=0)

    # Date first added via KA library sync with YouTube.
    # This property hasn't always existsed, so for many old videos
    # this date may be much later than the actual YouTube upload date.
    date_added = db.DateTimeProperty(auto_now_add=True)

    INDEX_ONLY = ['title', 'keywords', 'description']
    INDEX_TITLE_FROM_PROP = 'title'
    INDEX_USES_MULTI_ENTITIES = False

    @staticmethod
    def get_for_readable_id(readable_id):
        video = None
        query = Video.all()
        query.filter('readable_id =', readable_id)
        # The following should just be:
        # video = query.get()
        # but the database currently contains multiple Video objects for a particular
        # video.  Some are old.  Some are due to a YouTube sync where the youtube urls
        # changed and our code was producing youtube_ids that ended with '_player'.
        # This hack gets the most recent valid Video object.
        key_id = 0
        for v in query:
            if v.key().id() > key_id and not v.youtube_id.endswith('_player'):
                video = v
                key_id = v.key().id()
        # End of hack
        return video

    def first_playlist(self):
        query = VideoPlaylist.all()
        query.filter('video =', self)
        query.filter('live_association =', True)
        video_playlist = query.get()
        if video_playlist:
            return video_playlist.playlist
        return None

    def current_user_points(self):
        user_video = UserVideo.get_for_video_and_user(self,
                                                      util.get_current_user())
        if user_video:
            return points.VideoPointCalculator(user_video)
        else:
            return 0

    @staticmethod
    def get_dict(query, fxn_key):
        video_dict = {}
        for video in query.fetch(10000):
            video_dict[fxn_key(video)] = video
        return video_dict
Esempio n. 25
0
class Page(db.Model):
    uri = db.StringProperty()
    #html metadata
    title = db.StringProperty()
    description = db.StringProperty()
    keywords = db.StringProperty()
    #html content
    date = db.DateTimeProperty()
    date_last_edited = db.DateTimeProperty()
    headline = db.StringProperty()
    img = db.StringProperty()
    img_square_css = db.StringProperty()
    list_display = db.StringProperty()

    # see https://cdnjs.com/libraries/highlight.js/ for list
    syntaxes = db.StringProperty()

    def get_syntax_list(self):
        return get_syntax_list([self])

    snippet = db.TextProperty()
    snippet_is_markdown = db.BooleanProperty(default=True)
    content = db.TextProperty()
    content_is_markdown = db.BooleanProperty(default=True)

    def display_date(self):
        if self.date:
            if self.date_last_edited:
                return '{} (updated {})'.format(self.date,
                                                self.date_last_edited)
            else:
                return self.date
        elif self.date_last_edited:
            return 'updated {}'.format(self.date_last_edited)
        else:
            return None

    def display_date_short(self):
        if self.date_last_edited:
            return 'updated ' + self.date_last_edited.split('-')[0]
        elif self.date:
            return self.date.split('-')[0]
        else:
            return None

    def get_snippet(self):
        if self.snippet:
            return self.snippet
        elif not self.content:
            return None
        else:
            break_text = '<br id="break"/>'
            index_of_break = self.content.find(break_text)
            if index_of_break < 0:
                return None
            else:
                return self.content[0:index_of_break]

    #organization
    list_id = db.StringProperty()
    precedence = db.FloatProperty(default=1.0)
    is_public = db.BooleanProperty(default=False)

    def load(self, **entries):
        self.__dict__.update(entries)
Esempio n. 26
0
class Exercise(db.Model):

    name = db.StringProperty()
    short_display_name = db.StringProperty(default="")
    prerequisites = db.StringListProperty()
    covers = db.StringListProperty()
    v_position = db.IntegerProperty()
    h_position = db.IntegerProperty()
    seconds_per_fast_problem = db.FloatProperty(
        default=consts.MIN_SECONDS_PER_FAST_PROBLEM
    )  # Seconds expected to finish a problem 'quickly' for badge calculation

    # True if this exercise is live and visible to all users.
    # Non-live exercises are only visible to admins.
    live = db.BooleanProperty(default=False)

    # True if this exercise is a quasi-exercise generated by
    # combining the content of other exercises
    summative = db.BooleanProperty(default=False)

    # Teachers contribute raw html with embedded CSS and JS
    # and we sanitize it with Caja before displaying it to
    # students.
    author = db.UserProperty()
    raw_html = db.TextProperty()
    last_modified = db.DateTimeProperty()
    safe_html = db.TextProperty()
    safe_js = db.TextProperty()
    last_sanitized = db.DateTimeProperty(default=datetime.datetime.min)
    sanitizer_used = db.StringProperty()

    @staticmethod
    def get_by_name(name):
        dict_exercises = Exercise.__get_dict_use_cache_unsafe__()
        if dict_exercises.has_key(name):
            if dict_exercises[name].is_visible_to_current_user():
                return dict_exercises[name]
        return None

    @staticmethod
    def to_display_name(name):
        if name:
            return name.replace('_', ' ').capitalize()
        return ""

    def display_name(self):
        return Exercise.to_display_name(self.name)

    @staticmethod
    def to_short_name(name):
        exercise = Exercise.get_by_name(name)
        if exercise:
            return exercise.short_name()
        return ""

    def short_name(self):
        if self.short_display_name:
            return self.short_display_name[:11]
        return self.display_name()[:11]

    def is_visible_to_current_user(self):
        return self.live or users.is_current_user_admin()

    def required_streak(self):
        if self.summative:
            return consts.REQUIRED_STREAK * len(self.prerequisites)
        else:
            return consts.REQUIRED_STREAK

    def struggling_threshold(self):
        return 3 * self.required_streak()

    def summative_children(self):
        if not self.summative:
            return []
        query = db.Query(Exercise)
        query.filter("name IN ", self.prerequisites)
        return query

    def non_summative_exercise(self, problem_number):
        if not self.summative:
            return self

        if len(self.prerequisites) <= 0:
            raise Exception(
                "Summative exercise '%s' does not include any other exercises"
                % self.name)

        # For now we just cycle through all of the included exercises in a summative exercise
        index = int(problem_number) % len(self.prerequisites)
        exid = self.prerequisites[index]

        query = Exercise.all()
        query.filter('name =', exid)
        exercise = query.get()

        if not exercise:
            raise Exception("Unable to find included exercise")

        if exercise.summative:
            return exercise.non_summative_exercise(problem_number)
        else:
            return exercise

    def related_videos(self):
        exercise_videos = None
        query = ExerciseVideo.all()
        query.filter('exercise =', self.key())
        return query

    @layer_cache.cache_with_key_fxn(
        lambda self: "related_videos_%s" % self.key(),
        layer=layer_cache.SINGLE_LAYER_MEMCACHE_ONLY)
    def related_videos_fetch(self):
        exercise_videos = self.related_videos().fetch(10)
        for exercise_video in exercise_videos:
            exercise_video.video  # Pre-cache video entity
        return exercise_videos

    _CURRENT_SANITIZER = "http://caja.appspot.com/"

    def ensure_sanitized(self):
        if self.last_sanitized >= self.last_modified and self.sanitizer_used == Exercise._CURRENT_SANITIZER:
            return
        cajoled = cajole.cajole(self.raw_html)
        if 'error' in cajoled:
            raise Exception(cajoled['html'])
        self.safe_html = db.Text(cajoled['html'])
        self.safe_js = db.Text(cajoled['js'])
        self.last_sanitized = datetime.datetime.now()
        self.sanitizer = Exercise._CURRENT_SANITIZER
        self.put()

    @classmethod
    def all(cls, live_only=False):
        query = super(Exercise, cls).all()
        if live_only or not users.is_current_user_admin():
            query.filter("live =", True)
        return query

    @classmethod
    def all_unsafe(cls):
        return super(Exercise, cls).all()

    @staticmethod
    def get_all_use_cache():
        if users.is_current_user_admin():
            return Exercise.__get_all_use_cache_unsafe__()
        else:
            return Exercise.__get_all_use_cache_safe__()

    @staticmethod
    @layer_cache.cache_with_key_fxn(
        lambda *args, **kwargs: "all_exercises_unsafe_%s" % Setting.
        cached_exercises_date())
    def __get_all_use_cache_unsafe__():
        query = Exercise.all_unsafe().order('h_position')
        return query.fetch(200)

    @staticmethod
    @layer_cache.cache_with_key_fxn(
        lambda *args, **kwargs: "all_exercises_safe_%s" % Setting.
        cached_exercises_date())
    def __get_all_use_cache_safe__():
        query = Exercise.all(live_only=True).order('h_position')
        return query.fetch(200)

    @staticmethod
    @layer_cache.cache_with_key_fxn(
        lambda *args, **kwargs: "all_exercises_dict_unsafe_%s" % Setting.
        cached_exercises_date())
    def __get_dict_use_cache_unsafe__():
        exercises = Exercise.__get_all_use_cache_unsafe__()
        dict_exercises = {}
        for exercise in exercises:
            dict_exercises[exercise.name] = exercise
        return dict_exercises

    _EXERCISES_COUNT_KEY = "Exercise.count()"

    @staticmethod
    def get_count():
        count = memcache.get(Exercise._EXERCISES_COUNT_KEY,
                             namespace=App.version)
        if count is None:
            count = Exercise.all().count()
            memcache.set(Exercise._EXERCISES_COUNT_KEY,
                         count,
                         namespace=App.version)
        return count

    def put(self):
        Setting.cached_exercises_date(str(datetime.datetime.now()))
        memcache.delete(Exercise._EXERCISES_COUNT_KEY, namespace=App.version)
        db.Model.put(self)
class BQueryModel(db.Model):
    author = db.UserProperty()
    querystr = db.TextProperty()
    qdesc = db.TextProperty()
    date = db.DateTimeProperty(auto_now_add=True)
Esempio n. 28
0
class MapreduceState(db.Model):
  """Holds accumulated state of mapreduce execution.

  MapreduceState is stored in datastore with a key name equal to the
  mapreduce ID. Only controller tasks can write to MapreduceState.

  Properties:
    mapreduce_spec: cached deserialized MapreduceSpec instance. read-only
    active: if this MR is still running.
    last_poll_time: last time controller job has polled this mapreduce.
    counters_map: shard's counters map as CountersMap. Mirrors
      counters_map_json.
    chart_url: last computed mapreduce status chart url. This chart displays the
      progress of all the shards the best way it can.
    sparkline_url: last computed mapreduce status chart url in small format.
    result_status: If not None, the final status of the job.
    active_shards: How many shards are still processing. This starts as 0,
      then set by KickOffJob handler to be the actual number of input
      readers after input splitting, and is updated by Controller task
      as shards finish.
    start_time: When the job started.
    writer_state: Json property to be used by writer to store its state.
      This is filled when single output per job. Will be deprecated.
      Use OutputWriter.get_filenames instead.
  """

  RESULT_SUCCESS = "success"
  RESULT_FAILED = "failed"
  RESULT_ABORTED = "aborted"

  _RESULTS = frozenset([RESULT_SUCCESS, RESULT_FAILED, RESULT_ABORTED])

  # Functional properties.
  # TODO(user): Replace mapreduce_spec with job_config.
  mapreduce_spec = json_util.JsonProperty(MapreduceSpec, indexed=False)
  active = db.BooleanProperty(default=True, indexed=False)
  last_poll_time = db.DateTimeProperty(required=True)
  counters_map = json_util.JsonProperty(
      CountersMap, default=CountersMap(), indexed=False)
  app_id = db.StringProperty(required=False, indexed=True)
  writer_state = json_util.JsonProperty(dict, indexed=False)
  active_shards = db.IntegerProperty(default=0, indexed=False)
  failed_shards = db.IntegerProperty(default=0, indexed=False)
  aborted_shards = db.IntegerProperty(default=0, indexed=False)
  result_status = db.StringProperty(required=False, choices=_RESULTS)

  # For UI purposes only.
  chart_url = db.TextProperty(default="")
  chart_width = db.IntegerProperty(default=300, indexed=False)
  sparkline_url = db.TextProperty(default="")
  start_time = db.DateTimeProperty(auto_now_add=True)

  @classmethod
  def kind(cls):
    """Returns entity kind."""
    return "_AE_MR_MapreduceState"

  @classmethod
  def get_key_by_job_id(cls, mapreduce_id):
    """Retrieves the Key for a Job.

    Args:
      mapreduce_id: The job to retrieve.

    Returns:
      Datastore Key that can be used to fetch the MapreduceState.
    """
    return db.Key.from_path(cls.kind(), str(mapreduce_id))

  @classmethod
  def get_by_job_id(cls, mapreduce_id):
    """Retrieves the instance of state for a Job.

    Args:
      mapreduce_id: The mapreduce job to retrieve.

    Returns:
      instance of MapreduceState for passed id.
    """
    return db.get(cls.get_key_by_job_id(mapreduce_id))

  def set_processed_counts(self, shards_processed):
    """Updates a chart url to display processed count for each shard.

    Args:
      shards_processed: list of integers with number of processed entities in
        each shard
    """
    chart = google_chart_api.BarChart(shards_processed)
    shard_count = len(shards_processed)

    if shards_processed:
      # Only 16 labels on the whole chart.
      stride_length = max(1, shard_count / 16)
      chart.bottom.labels = []
      for x in xrange(shard_count):
        if (x % stride_length == 0 or
            x == shard_count - 1):
          chart.bottom.labels.append(x)
        else:
          chart.bottom.labels.append("")
      chart.left.labels = ["0", str(max(shards_processed))]
      chart.left.min = 0

    self.chart_width = min(700, max(300, shard_count * 20))
    self.chart_url = chart.display.Url(self.chart_width, 200)

  def get_processed(self):
    """Number of processed entities.

    Returns:
      The total number of processed entities as int.
    """
    return self.counters_map.get(context.COUNTER_MAPPER_CALLS)

  processed = property(get_processed)

  @staticmethod
  def create_new(mapreduce_id=None,
                 gettime=datetime.datetime.now):
    """Create a new MapreduceState.

    Args:
      mapreduce_id: Mapreduce id as string.
      gettime: Used for testing.
    """
    if not mapreduce_id:
      mapreduce_id = MapreduceState.new_mapreduce_id()
    state = MapreduceState(key_name=mapreduce_id,
                           last_poll_time=gettime())
    state.set_processed_counts([])
    return state

  @staticmethod
  def new_mapreduce_id():
    """Generate new mapreduce id."""
    return util._get_descending_key()

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      return False
    return self.properties() == other.properties()
Esempio n. 29
0
class NoninflectedPage(search.Searchable, db.Model):
    """Used to test search without stemming, e.g. for precise, non-inflected words"""
    author_name = db.StringProperty()
    content = db.TextProperty()
    INDEX_STEMMING = False
    INDEX_ONLY = ['content']
Esempio n. 30
0
class PostDump(db.Model):
    handle = db.StringProperty(required=True)
    json = db.TextProperty()
    group = db.StringProperty()
    touch_time = db.DateTimeProperty(auto_now_add=True, auto_now=True)