def _reload_version(self, key):
        """Reload a single package version from its tarball."""

        version = PackageVersion.get(key)
        with closing(cloud_storage.read(version.storage_path)) as f:
            new_version = PackageVersion.from_archive(
                f, uploader=version.uploader)

        with models.transaction():
            # Reload the old version in case anything (e.g. sort order) changed.
            version = PackageVersion.get(key)
            package = version.package

            # We don't load new_version.package.latest_version here for two
            # reasons. One is to avoid a needless data store lookup; the other
            # is because it's possible that that version is being reloaded in
            # another transaction and thus in a weird transitional state.
            latest_version_key = Package.latest_version.get_value_for_datastore(
                package)
            if latest_version_key == key:
                package.latest_version = new_version

            new_version.created = version.created
            new_version.downloads = version.downloads
            new_version.sort_order = version.sort_order
            version.delete()
            new_version.put()
            package.put()

        memcache.incr('versions_reloaded')
    def create(self, id, **kwargs):
        """Create a new package version.

        This creates a single package version. It will also create all the
        package metadata if that doesn't already exist. The package archive is
        uploaded to cloud storage separately.

        If the user doesn't own the package or isn't logged in with admin
        privileges, this will return a 403. If the package already has a version
        with this number, or if the version is invalid, this will return a 400.

        Arguments:
          id: The id of the package in cloud storage.
        """

        try:
            route = handlers.request().route
            if 'id' in route: del route['id']

            try:
                with closing(cloud_storage.read('tmp/' + id)) as f:
                    version = PackageVersion.from_archive(
                        f, uploaderEmail=handlers.get_oauth_user().email())
            except (KeyError, files.ExistenceError):
                handlers.http_error(
                    403, "Package upload " + id + " does not exist.")

            # If the package for this version already exists, make sure we're an
            # uploader for it. If it doesn't, we're fine to create it anew.
            if version.package.is_saved():
                if not version.package.has_uploader_email(
                    handlers.get_oauth_user().email()):
                    handlers.http_error(
                        403, "You aren't an uploader for package '%s'." %
                                 version.package.name)
                elif version.package.has_version(version.version):
                    message = 'Package "%s" already has version "%s".' % \
                        (version.package.name, version.version)
                    handlers.http_error(400, message)

                if self._should_update_latest_version(version):
                    version.package.latest_version = version
            else:
                version.package.latest_version = version

            cloud_storage.modify_object(version.storage_path,
                                        acl='public-read',
                                        copy_source='tmp/' + id)

            with models.transaction():
                version.package.put()
                version.put()
                version.package.invalidate_cache()

            deferred.defer(self._compute_version_order, version.package.name)

            return handlers.json_success('%s %s uploaded successfully.' %
                (version.package.name, version.version))
        finally:
            cloud_storage.delete_object('tmp/' + id)
Example #3
0
def _create_or_sign_in(username, name, email):
    with models.transaction() as tx:
        user = tx.query(User).filter_by(username=username).first()
        if not user:
            user = User(username=username, name=name, email=email)
            tx.add(user)
    login_user(user)
Example #4
0
    def create(self, id, **kwargs):
        """Create a new package version.

        This creates a single package version. It will also create all the
        package metadata if that doesn't already exist. The package archive is
        uploaded to cloud storage separately.

        If the user doesn't own the package or isn't logged in with admin
        privileges, this will return a 403. If the package already has a version
        with this number, or if the version is invalid, this will return a 400.

        Arguments:
          id: The id of the package in cloud storage.
        """

        try:
            route = handlers.request().route
            if 'id' in route: del route['id']

            try:
                with closing(cloud_storage.read('tmp/' + id)) as f:
                    version = PackageVersion.from_archive(
                        f, uploader=handlers.get_oauth_user())
            except (KeyError, files.ExistenceError):
                handlers.http_error(
                    403, "Package upload " + id + " does not exist.")

            # If the package for this version already exists, make sure we're an
            # uploader for it. If it doesn't, we're fine to create it anew.
            if version.package.is_saved():
                if not version.package.has_uploader(handlers.get_oauth_user()):
                    handlers.http_error(
                        403, "You aren't an uploader for package '%s'." %
                        version.package.name)
                elif version.package.has_version(version.version):
                    message = 'Package "%s" already has version "%s".' % \
                        (version.package.name, version.version)
                    handlers.http_error(400, message)

                if self._should_update_latest_version(version):
                    version.package.latest_version = version
            else:
                version.package.latest_version = version

            cloud_storage.modify_object(version.storage_path,
                                        acl='public-read',
                                        copy_source='tmp/' + id)

            with models.transaction():
                version.package.put()
                version.put()

            deferred.defer(self._compute_version_order, version.package.name)

            return handlers.json_success(
                '%s %s uploaded successfully.' %
                (version.package.name, version.version))
        finally:
            cloud_storage.delete_object('tmp/' + id)
 def _count_download(self, key):
     """Increment the download count for a package version."""
     with models.transaction():
         version = PackageVersion.get(key)
         version.downloads += 1
         version.package.downloads += 1
         version.put()
         version.package.put()
 def _compute_version_order(self, name):
     """Compute the sort order for all versions of a given package."""
     versions = list(Package.get_by_key_name(name).version_set.run())
     versions.sort(key=lambda version: version.version)
     for i, version in enumerate(versions):
         version.sort_order = i
     with models.transaction():
         for version in versions: version.put()
Example #7
0
 def _count_download(self, key):
     """Increment the download count for a package version."""
     with models.transaction():
         version = PackageVersion.get(key)
         version.downloads += 1
         version.package.downloads += 1
         version.put()
         version.package.put()
Example #8
0
 def _compute_version_order(self, name):
     """Compute the sort order for all versions of a given package."""
     versions = list(Package.get_by_key_name(name).version_set.run())
     versions.sort(key=lambda version: version.version)
     for i, version in enumerate(versions):
         version.sort_order = i
     with models.transaction():
         for version in versions:
             version.put()
Example #9
0
def create():
    form = CreateBetForm()
    if form.validate_on_submit():
        with transaction() as tx:
            bet = Bet(title=form.name.data,
                      description=form.description.data,
                      owner=current_user)
            tx.add(bet)
            for t in form.outcomes.entries:
                tx.add(Outcome(title=t.data, bet=bet))
        return redirect(url_for('bets.bet', bet_id=bet.bet_id))
    return render_template("bets/create.html", create_form=form)
Example #10
0
def resolve_bet(bet_id):
    with transaction() as tx:
        bet = tx.query(Bet).filter_by(bet_id=bet_id).first_or_404()
        if bet.owner != current_user:
            raise Forbidden
        resolve_form = ResolveForm()
        resolve_form.set_choices_for_bet(bet)
        if bet.closed and not bet.resolved and resolve_form.validate_on_submit(
        ):
            time = resolve_form.resolve_time.data
            bet.resolved_at = time
            choice = resolve_form.resolve_choice.data
            bet.won_outcome_id = choice if choice else None
            payments.resolve_payment(tx, bet)
    return redirect(url_for("bets.bet", bet_id=bet_id))
Example #11
0
    def set_person(self, person_id):
        self.trans = models.transaction()
        if person_id:
            model = self.trans.Person.get(person_id)
        else:
            model = self.trans.Person()

        categories = [c.name for c in self.trans.Category.select()]
        categories.insert(0, "")
        self.category.prefill(categories)
        if model.category:
            self.category.select(model.category.name)
        else:
            self.category.select("")
        self.phones.add_list(model.phones)
        self.set_model(model)
Example #12
0
    def set_person(self, person_id):
        self.trans = models.transaction()
        if person_id:
            model = self.trans.Person.get(person_id)
        else:
            model = self.trans.Person()

        categories = [c.name for c in self.trans.Category.select()]
        categories.insert(0, "")
        self.category.prefill(categories)
        if model.category:
            self.category.select(model.category.name)
        else:
            self.category.select("")
        self.phones.add_list(model.phones)
        self.set_model(model)
Example #13
0
def bid(outcome, dir):
    form = CreateBidForm()
    if dir != "yes" and dir != "no":
        raise BadRequest
    with models.transaction() as txn:
        outcome = txn.query(Outcome).filter_by(
            outcome_id=outcome).first_or_404()
        if outcome.bet.closed:
            raise BadRequest
        if form.validate_on_submit():
            engine.resolve_bet(txn, current_user, outcome, form.price.data,
                               form.amount.data, form.dir.data == "yes")
            return redirect(url_for('bets.bet', bet_id=outcome.bet_id))
    return render_template("bets/bid.html",
                           bet=outcome.bet,
                           outcome=outcome,
                           bid_form=form,
                           dir=dir)
Example #14
0
    def _reload_version(self, key):
        """Reload a single package version from its tarball."""

        version = PackageVersion.get(key)
        logging.info('Reloading %s %s' %
                     (version.package.name, version.version))

        with closing(cloud_storage.read(version.storage_path)) as f:
            new_version = PackageVersion.from_archive(
                f, uploaderEmail=version.uploaderEmail)

        with models.transaction():
            # Reload the old version in case anything (e.g. sort order) changed.
            version = PackageVersion.get(key)
            package = version.package

            # We don't load new_version.package.latest_version here for two
            # reasons. One is to avoid a needless data store lookup; the other
            # is because it's possible that that version is being reloaded in
            # another transaction and thus in a weird transitional state.
            latest_version_key = Package.latest_version.get_value_for_datastore(
                package)
            if latest_version_key == key:
                package.latest_version = new_version

            new_version.created = version.created
            new_version.downloads = version.downloads
            new_version.sort_order = version.sort_order
            version.delete()
            new_version.put()

            # Only save the package if its latest version has been updated.
            # Otherwise, its latest version may be being updated in parallel,
            # causing icky bugs.
            if latest_version_key == key:
                package.put()
                package.invalidate_cache()

        count = memcache.incr('versions_reloaded')
        logging.info('%s/%s versions reloaded' %
                     (count, memcache.get('versions_to_reload')))
Example #15
0
    def _reload_version(self, key):
        """Reload a single package version from its tarball."""

        version = PackageVersion.get(key)
        logging.info('Reloading %s %s' % (version.package.name, version.version))

        with closing(cloud_storage.read(version.storage_path)) as f:
            new_version = PackageVersion.from_archive(
                f, uploader=version.uploader)

        with models.transaction():
            # Reload the old version in case anything (e.g. sort order) changed.
            version = PackageVersion.get(key)
            package = version.package

            # We don't load new_version.package.latest_version here for two
            # reasons. One is to avoid a needless data store lookup; the other
            # is because it's possible that that version is being reloaded in
            # another transaction and thus in a weird transitional state.
            latest_version_key = Package.latest_version.get_value_for_datastore(
                package)
            if latest_version_key == key:
                package.latest_version = new_version

            new_version.created = version.created
            new_version.downloads = version.downloads
            new_version.sort_order = version.sort_order
            version.delete()
            new_version.put()

            # Only save the package if its latest version has been updated.
            # Otherwise, its latest version may be being updated in parallel,
            # causing icky bugs.
            if latest_version_key == key:
                package.put()
                package.invalidate_cache()


        count = memcache.incr('versions_reloaded')
        logging.info('%s/%s versions reloaded' %
                     (count, memcache.get('versions_to_reload')))
    def create(self, package_id, id, format='html', **kwargs):
        """Create a new package version.

        This creates a single package version. It will also create all the
        package metadata if that doesn't already exist. The package archive is
        uploaded to cloud storage separately.

        If the user doesn't own the package or isn't logged in with admin
        privileges, this will return a 403. If the package already has a version
        with this number, or if the version is invalid, this will redirect to
        the new version form.

        Arguments:
          id: The id of the package in cloud storage.
        """

        try:
            is_json = format == 'json'

            route = handlers.request().route
            if 'id' in route: del route['id']

            package = handlers.request().maybe_package
            if package and handlers.get_current_user() not in package.uploaders:
                handlers.request().error(
                    403, "You aren't an uploader for package '%s'." %
                             package.name)
            elif not handlers.is_current_user_admin():
                handlers.request().error(
                    403, "Only admins may create packages.")

            try:
                with closing(cloud_storage.read('tmp/' + id)) as f:
                    version = PackageVersion.from_archive(
                        f, uploader=handlers.get_current_user())
            except (KeyError, files.ExistenceError):
                handlers.request().error(
                    403, "Package upload " + id + " does not exist.")

            if version.package.is_saved():
                if handlers.get_current_user() not in version.package.uploaders:
                    handlers.request().error(
                        403, "You aren't an uploader for package '%s'." %
                                 version.package.name)
                elif version.package.has_version(version.version):
                    message = 'Package "%s" already has version "%s".' % \
                        (version.package.name, version.version)
                    if is_json: handlers.json_error(400, message)

                    handlers.flash(message)
                    url = handlers.request().url(
                        action='new', package_id=version.package.name)
                    raise cherrypy.HTTPRedirect(url)

                if self._should_update_latest_version(version):
                    version.package.latest_version = version
            else:
                version.package.latest_version = version

            cloud_storage.modify_object(version.storage_path,
                                        acl='public-read',
                                        copy_source='tmp/' + id)

            with models.transaction():
                version.package.put()
                version.put()

            deferred.defer(self._compute_version_order, version.package.name)

            message = '%s %s uploaded successfully.' % \
                (version.package.name, version.version)
            if is_json:
                cherrypy.response.headers['Content-Type'] = 'application/json'
                return json.dumps({"success": {"message": message}})

            handlers.flash(message)
            raise cherrypy.HTTPRedirect('/packages/%s' % version.package.name)
        finally:
            cloud_storage.delete_object('tmp/' + id)