예제 #1
0
 def post(self):
     title_raw = self.request.POST.get('title_url')
     title = Plaque.tokenize_title(title_raw)
     n_matches = Plaque.num_same_title_urls_published(
         title, get_plaqueset_key())
     response_text = title if n_matches > 0 else ""
     self.response.write(response_text)
예제 #2
0
    def get(self):
        find_orphans = self.request.get('find_orphans')
        num_comments = Comment.query().count()
        query = Plaque.query()
        num_plaques = query.count()
        num_pending = query.filter(Plaque.approved == False).count()
        num_images = 0
        images = gcs.listbucket(GCS_BUCKET)
        for image in images:
            num_images += 1

        orphan_pics = set()
        pics_count = defaultdict(int)
        pics = set()

        if find_orphans == 'true':
            # Record which pics are linked to a plaque:
            plaques = Plaque.query().fetch()
            for plaque in plaques:
                pics.add(plaque.pic)
                pics_count[plaque.pic] += 1

            # Find pics that aren't:
            for pic in images:
                if pic not in pics:
                    orphan_pics.add(pic)
        else:
            orphan_pics.add("didn't check for orphans")

        msg = "Count: %s comments, %s plaques (%s pending), %s images, orphans: %s<hr>%s" % (
                num_comments, num_plaques, num_pending, num_images, orphan_pics, pics_count)
        self.response.write(msg)
예제 #3
0
    def get(self, tag, view_all=False):
        """
        View plaques with a given tag on a grid.
        """
        memcache_name = 'plaques_tag_%s' % tag
        page_text = memcache.get(memcache_name)

        if page_text is None:
            query = Plaque.query()
            if not view_all:
                query = query.filter(Plaque.approved == True)

            # TODO: NDB cursor pagination?
            plaques = query.filter(
                Plaque.tags == tag).order(-Plaque.created_on).fetch(
                    limit=DEF_NUM_PER_PAGE)

            template = JINJA_ENVIRONMENT.get_template('all.html')
            template_values = get_template_values(plaques=plaques)
            page_text = template.render(template_values)
            memcache_status = memcache.set(memcache_name, page_text)
            if not memcache_status:
                logging.debug("ViewTag memcache.set for %s failed" %
                              memcache_name)
        else:
            logging.debug("ViewTag memcache.get worked for %s" % memcache_name)

        self.response.write(page_text)
예제 #4
0
def get_featured():
    featured = FeaturedPlaque.query().order(-Plaque.created_on).get()
    if featured is not None:
        plaque = Plaque.query().filter(Plaque.key == featured.plaque).get()
    else:
        plaque = None
    return plaque
예제 #5
0
 def get(self):
     plaques = Plaque.query().fetch()
     for plaque in plaques:
         plaque.set_title_url()
         plaque.put()
     memcache.flush_all()
     self.redirect('/')
예제 #6
0
    def get(self, tag, view_all=False):
        """
        View plaque with a given tag on a grid.
        """
        memcache_name = 'plaque_json_%s' % tag
        page_text = memcache.get(memcache_name)

        if page_text is None:
            query = Plaque.query()
            if not view_all:
                query = query.filter(Plaque.approved == True)

            # TODO: NDB cursor pagination?
            plaques = query.filter(Plaque.tags == tag
                           ).order(-Plaque.created_on
                           ).fetch(limit=DEF_NUM_PER_PAGE)
            map_markers_str = get_map_markers_str(plaques)

            template = JINJA_ENVIRONMENT.get_template('all.html')
            template_values = get_default_template_values(
                                  plaques=plaques,
                                  map_markers_str=map_markers_str,
                              )
            page_text = template.render(template_values)
            memcache_status = memcache.set(memcache_name, page_text)
            if not memcache_status:
                logging.debug("ViewTag memcache.set for %s failed" %
                    memcache_name)
        else:
            logging.debug("ViewTag memcache.get worked for %s" %
                memcache_name)

        self.response.write(page_text)
예제 #7
0
    def _get_page_from_key(self, plaque_key=None):
        """
        Put the single plaque into a list for rendering so that the common map
        functionality can be used unchanged. Attempt to serve a valid plaque,
        but if the inputs are completely messed up, serve the oldest plaque.
        """

        # If it's memecached, use that:
        is_admin = users.is_current_user_admin()
        memcache_name = 'plaque_%s_%s' % (plaque_key, is_admin)
        page_text = memcache.get(memcache_name)
        if page_text is not None:
            return page_text

        # If page is not memcached, get the plaque from the db:
        plaque = self._get_plaque_from_key(plaque_key)

        # If that didn't find anything, serve the default couldn't-find-it
        # plaque (currently hacked in as the earliest plaque):
        if plaque is None:
            earliest_plaque = Plaque.query(Plaque.approved == True).order(
                Plaque.created_on).get()
            self.redirect(earliest_plaque.title_page_url)
            return

        template_values = get_template_values(plaques=[plaque])

        template = JINJA_ENVIRONMENT.get_template('one.html')
        page_text = template.render(template_values)
        memcache_status = memcache.set(memcache_name, page_text)
        if not memcache_status:
            logging.debug("memcache.set for _get_page_from_key failed for %s" %
                          memcache_name)

        return page_text
예제 #8
0
 def get(self):
     plaques = Plaque.query().fetch()
     for plaque in plaques:
         plaque.set_title_url()
         plaque.put()
     memcache.flush_all()
     self.redirect('/')
예제 #9
0
 def get(self, num=DEF_NUM_PENDING):
     try:
         num = int(num)
     except:
         pass
     plaques = Plaque.pending_list(num=num, desc=False)
     self.write_pending(plaques)
예제 #10
0
    def _get_template_values(self, per_page, cursor_urlsafe, is_random, is_featured):
        if is_random:
            plaques = []
            cursor_urlsafe = None
            more = False
            for i in range(per_page):
                plaques.append(get_random_plaque())
        else:
            plaques, next_cursor, more = Plaque.page_plaques(
                per_page, start_cursor_urlsafe=cursor_urlsafe)

            if next_cursor is None:
                cursor_urlsafe = ''
            else:
                cursor_urlsafe = next_cursor.urlsafe()

        #num_plaques = Plaque.query().count()
        #num_pages = int(math.ceil((num_plaques / per_page)))
        template_values = get_default_template_values(
                              plaques=plaques,
                              #num_pages=num_pages,
                              next_cursor_urlsafe=cursor_urlsafe,
                              more=more,
                          )
        if is_random:
            template_values['map_markers_str'] = get_map_markers_str(plaques)
        if is_featured:
            featured = get_featured()
            template_values['featured_plaque'] = featured

        return template_values
예제 #11
0
 def get(self, num_entries=10):
     plaques = Plaque.query().filter(
         Plaque.approved == True).order(-Plaque.created_on).fetch(
             limit=num_entries)
     template = JINJA_ENVIRONMENT.get_template('feed.xml')
     template_values = {'plaques': plaques}
     self.response.write(template.render(template_values))
예제 #12
0
 def get(self):
     plaques = Plaque.query().filter(
         Plaque.updated_on == None).order(-Plaque.created_on).fetch()
     for plaque in plaques:
         plaque.updated_on = plaque.created_on
         plaque.put()
     self.response.write([p.title for p in plaques])
예제 #13
0
def get_featured():
    featured = FeaturedPlaque.query().order(-Plaque.created_on).get()
    if featured is not None:
        plaque = Plaque.query().filter(Plaque.key == featured.plaque).get()
    else:
        plaque = None
    return plaque
예제 #14
0
    def _get_template_values(self, per_page, cursor_urlsafe, is_random,
                             is_featured):
        if is_random:
            plaques = []
            cursor_urlsafe = None
            more = False
            for i in range(per_page):
                plaques.append(get_random_plaque())
        else:
            plaques, next_cursor, more = Plaque.fetch_page(
                per_page, start_cursor=cursor_urlsafe, urlsafe=True)

            if next_cursor is None:
                cursor_urlsafe = ''
            else:
                cursor_urlsafe = next_cursor.urlsafe()

        template_values = get_template_values(
            plaques=plaques, next_cursor_urlsafe=cursor_urlsafe, more=more)
        if is_featured:
            featured = get_featured()
            template_values['featured_plaque'] = featured
            fake = FakePlaqueForRootUrlPreviews()
            template_values['fake_plaque_for_root_url_previews'] = fake

        return template_values
예제 #15
0
def get_default_template_values(**kwargs):
    memcache_name = 'default_template_values_%s' % users.is_current_user_admin()
    template_values = memcache.get(memcache_name)
    if template_values is None:
        num_pending = Plaque.num_pending(num=DEF_NUM_PENDING)
        footer_items = get_footer_items()
        loginout_output = loginout()

        template_values = {
            'num_pending': num_pending,
            'footer_items': footer_items,
            'loginout': loginout_output,
            'icon_size': DEF_MAP_ICON_SIZE_PIX,
        }
        memcache_status = memcache.set(memcache_name, template_values)
        if not memcache_status:
            logging.debug(
                "memcaching.set to %s for default_template_values failed" %
                memcache_name)
    else:
        logging.debug(
            "memcache.get from %s worked for default_template_values" %
            memcache_name)

    for k, v in kwargs.items():
        template_values[k] = v
    return template_values
예제 #16
0
 def get(self, num_entries=10):
     plaques = Plaque.query(
                   ).filter(Plaque.approved == True
                   ).order(-Plaque.created_on
                   ).fetch(limit=num_entries)
     template = JINJA_ENVIRONMENT.get_template('feed.xml')
     template_values = {'plaques': plaques}
     self.response.write(template.render(template_values))
예제 #17
0
 def get(self):
     #raise NotImplementedError("Turned off")
     plaques = Plaque.pending_list(num=500)
     for plaque in plaques:
         plaque.approved = True
         plaque.put()
     memcache.flush_all()
     self.redirect('/')
예제 #18
0
 def get(self):
     plaques = Plaque.query(
                   ).filter(Plaque.updated_on == None
                   ).order(-Plaque.created_on
                   ).fetch()
     for plaque in plaques:
         plaque.updated_on = plaque.created_on
         plaque.put()
     self.response.write([p.title for p in plaques])
예제 #19
0
def get_random_time():
    """
    Get a random time during the operation of the site.
    """
    memcache_names = ['first', 'last']
    memcache_out = memcache.get_multi(memcache_names)
    memcache_worked = len(memcache_out.keys()) == len(memcache_names)
    if memcache_worked:
        first = memcache_out[memcache_names[0]]
        last = memcache_out[memcache_names[1]]
    else:
        first_plaque = Plaque.query().filter(Plaque.approved == True).order(
            Plaque.created_on).get()
        if first_plaque:
            first = first_plaque.created_on
        else:
            first = None

        last_plaque = Plaque.query().filter(
            Plaque.approved == True).order(-Plaque.created_on).get()
        if last_plaque:
            last = last_plaque.created_on
        else:
            last = None

        memcache_status = memcache.set_multi({
            memcache_names[0]: first,
            memcache_names[1]: last
        })
        if memcache_status:
            logging.debug("""memcache.set in Handlers.get_random_time() failed:
                %s were not set""" % memcache_status)

    if first is None or last is None:
        random_time = None
    else:
        diff = last - first
        diff_seconds = int(diff.total_seconds())
        rand_seconds = random.randint(0, diff_seconds)
        random_delta = datetime.timedelta(seconds=rand_seconds)
        random_time = first + random_delta

    return random_time
예제 #20
0
 def _json_for_update(self, updated_on, summary=True):
     logging.info("Updated_on is %s in _json_for_update" % updated_on)
     plaques = Plaque.query().filter(Plaque.approved == True).filter(
         Plaque.created_on > updated_on).order(-Plaque.created_on).fetch()
     logging.info("_json_for_update got %s plaques" % len(plaques))
     for i, plaque in enumerate(plaques):
         logging.info("_json_for_update plaque %s date: %s" %
                      (i, plaque.updated_on))
     json_output = self._plaques_to_json(plaques, summary)
     return json_output
예제 #21
0
 def get(self):
     plaques = Plaque.pending_list(1)
     if plaques:
         plaque = plaques[0]
         logging.info("redirecting to {}".format(plaque.title_page_url))
         self.redirect(plaque.title_page_url)
         return
     else:
         page_text = self._get_page_from_key(plaque_key=None)
         self.response.write(page_text)
예제 #22
0
    def get(self, num=DEF_NUM_PENDING):
        try:
            num = int(num)
        except:
            pass

        num_to_select_from = 500
        plaques = Plaque.pending_list(num_to_select_from)
        return_plaques = random.sample(plaques, num)

        self.write_pending(return_plaques)
예제 #23
0
 def _json_for_update(self, updated_on, summary=True):
     logging.info("Updated_on is %s in _json_for_update" % updated_on)
     plaques = Plaque.query(
                    ).filter(Plaque.approved == True
                    ).filter(Plaque.created_on > updated_on
                    ).order(-Plaque.created_on
                    ).fetch()
     logging.info("_json_for_update got %s plaques" % len(plaques))
     for i, plaque in enumerate(plaques):
         logging.info("_json_for_update plaque %s date: %s" % (i, plaque.updated_on))
     json_output = self._plaques_to_json(plaques, summary)
     return json_output
예제 #24
0
def get_random_time():
    """
    Get a random time during the operation of the site.
    """
    memcache_names = ['first', 'last']
    memcache_out = memcache.get_multi(memcache_names)
    memcache_worked = len(memcache_out.keys()) == len(memcache_names)
    if memcache_worked:
            first = memcache_out[memcache_names[0]]
            last = memcache_out[memcache_names[1]]
    else:
        first_plaque = Plaque.query().filter(Plaque.approved == True).order(Plaque.created_on).get()
        if first_plaque:
            first = first_plaque.created_on
        else:
            first = None

        last_plaque = Plaque.query().filter(Plaque.approved == True).order(-Plaque.created_on).get()
        if last_plaque:
            last = last_plaque.created_on
        else:
            last = None

        memcache_status = memcache.set_multi({
            memcache_names[0]: first,
            memcache_names[1]: last
        })
        if memcache_status:
            logging.debug("""memcache.set in Handlers.get_random_time() failed:
                %s were not set""" % memcache_status)

    if first is None or last is None:
        random_time = None
    else:
        diff = last - first
        diff_seconds = int(diff.total_seconds())
        rand_seconds = random.randint(0, diff_seconds)
        random_offset = datetime.timedelta(seconds=rand_seconds)
        random_time = first + random_offset
        return random_time
예제 #25
0
    def get(self):
        verbose = self.request.get('verbose')
        query = Plaque.query()
        num_plaques = query.count()
        num_pending = query.filter(Plaque.approved == False).count()

        if verbose:
            tmpl = "<ul> <li>{} published</li> <li>{} pending</li> </ul>"
        else:
            tmpl = "{} published, {} pending\n"

        msg = tmpl.format(num_plaques - num_pending, num_pending)
        self.response.write(msg)
예제 #26
0
    def _json_for_all(self, summary=True):
        plaques_all = []
        num = 1000
        more = True
        cursor = None
        while more:
            plaques, cursor, more = Plaque.fetch_page(num=num,
                                                      start_cursor=cursor,
                                                      urlsafe=False)
            plaques_all.extend(plaques)
            logging.info("tot: %s, current: %s, cursor: %s, more?: %s" %
                         (len(plaques_all), len(plaques_all), cursor, more))

        json_output = self._plaques_to_json(plaques_all, summary)
        return json_output
예제 #27
0
 def get(self):
     plaques = Plaque.query().fetch()
     plaque_search_index = search.Index(PLAQUE_SEARCH_INDEX_NAME)
     igood = 0
     ibad = 0
     for plaque in plaques:
         try:
             plaque_search_index.put(plaque.to_search_document())
             igood += 1
         except search.Error as err:
             ibad += 1
             logging.error(err)
         logging.debug('in process: wrote %s good docs, %s failed' % (
                       igood, ibad))
     self.response.write('wrote %s good docs, %s failed' % (igood, ibad))
예제 #28
0
 def get(self):
     plaques = Plaque.query().fetch()
     plaque_search_index = search.Index(PLAQUE_SEARCH_INDEX_NAME)
     igood = 0
     ibad = 0
     for plaque in plaques:
         try:
             plaque_search_index.put(plaque.to_search_document())
             igood += 1
         except search.Error as err:
             ibad += 1
             logging.error(err)
         logging.debug('in process: wrote %s good docs, %s failed' %
                       (igood, ibad))
     self.response.write('wrote %s good docs, %s failed' % (igood, ibad))
예제 #29
0
    def get(self, lat=None, lng=None, zoom=None):

        template_values = get_template_values(bigmap=True)
        query = Plaque.query()
        num_plaques = query.filter(Plaque.approved == True).count()
        template_values['counts'] = num_plaques
        logging.debug(template_values)
        if lat is not None and lng is not None:
            template_values['bigmap_center'] = True
            template_values['bigmap_lat'] = lat
            template_values['bigmap_lng'] = lng

            if zoom is not None:
                template_values['bigmap_zoom'] = zoom

        template = JINJA_ENVIRONMENT.get_template(self.template_file)
        template_text = template.render(template_values)
        self.response.write(template_text)
예제 #30
0
    def _json_for_all(self, summary=True):
        # TODO: this should not hardcode a 20k plaque limit.
        # TODO: NDB cursor pagination for this
        block_size = 1000
        num_blocks = 20
        max_num_plaques = num_blocks * block_size
        plaques_all = []

        for ik in range(0, max_num_plaques, block_size):
            plaques = Plaque.query(
                           ).filter(Plaque.approved == True
                           ).order(-Plaque.created_on
                           ).fetch(offset=ik, limit=block_size)
            # Now add it to the total list:
            plaques_all.extend(plaques)

        json_output = self._plaques_to_json(plaques_all, summary)
        return json_output
예제 #31
0
    def get(self, num=DEF_NUM_PENDING):
        try:
            num = int(num)
        except:
            pass
        plaques = Plaque.pending_list(num)
        user = users.get_current_user()
        name = "anon" if user is None else user.nickname()
        logging.info("User %s is viewing pending plaques" % name)

        template = JINJA_ENVIRONMENT.get_template('all.html')
        map_markers_str = get_map_markers_str(plaques)
        template_values = get_default_template_values(
                              map_markers_str=map_markers_str,
                              plaques=plaques,
                          )
        template_text = template.render(template_values)
        self.response.write(template_text)
예제 #32
0
    def _get_plaque_from_key(self, plaque_key=None):
        # Get plaque from db from db:
        plaque = None
        logging.info("plaque_key=%s" % plaque_key)
        if plaque_key is not None:
            # Get by title, allowing only admins to see unapproved ones:
            logging.debug("Using plaque.title_url: '%s'" % plaque_key)
            query = Plaque.query().filter(Plaque.title_url == plaque_key)
            if not users.is_current_user_admin():
                query = query.filter(Plaque.approved == True)
            logging.debug("query is %s " % query)
            plaque = query.get()

            if plaque is None:
                try:
                    plaque = ndb.Key(urlsafe=plaque_key).get()
                except:
                    pass
        return plaque
예제 #33
0
    def get(self):

        #raise NotImplementedError("Turned off")

        if not users.is_current_user_admin():
            return "admin only, please log in"
        plaques = Plaque.pending_list(num=67)

        user = users.get_current_user()
        name = "anon" if user is None else user.nickname()
        msg = "%s ran ApproveAllPending on %s plaques" % (name, len(plaques))
        email_admin(msg, msg)

        logging.info("Approving %s plaques in ApproveAllPending" %
                     len(plaques))
        for plaque in plaques:
            plaque.approved = True
            plaque.put()
        memcache.flush_all()
        self.redirect('/')
예제 #34
0
    def get(self):
        plaque_search_index = search.Index(PLAQUE_SEARCH_INDEX_NAME)
        ideleted = 0
        # Delete all the search documents
        while True:
            # Get a list of documents populating only the doc_id field and
            # extract the ids.
            document_ids = [
                document.doc_id
                for document in plaque_search_index.get_range(ids_only=True)
            ]
            ideleted += len(document_ids)
            if not document_ids:
                break
            # Delete the documents for the given ids from the Index.
            plaque_search_index.delete(document_ids)
        logging.debug('deleted %s search index docs' % ideleted)

        # Write all new search docs and put them in the index
        plaques = Plaque.query().fetch()
        docs = []
        igood = 0
        ibad = 0
        for plaque in plaques:
            try:
                docs.append(plaque.to_search_document())
                igood += 1
            except search.Error as err:
                ibad += 1
                logging.error(err)
            #if ip % 100 == 0:
            #logging.debug('in process: wrote %s good docs, %s failed' % (
            #igood, ibad))
        iput = 0
        for i in range(0, len(docs), 100):
            iput += 100
            plaque_search_index.put(docs[i:i + 100])

        self.response.write(
            'deleted %s docs, created %s, failed to create %s, put %s' %
            (ideleted, igood, ibad, iput))
예제 #35
0
def get_random_plaque_key():
    """
    Get a random plaque key.  Limit to total number of runs to 100 to prevent
    infinite loop if there are no plaques.
    """
    plaque_key = None
    bailout = 0
    while plaque_key is None and bailout < 100:
        bailout += 1
        random_time = get_random_time()
        if random_time is None:
            plaque_key = None
        else:
            plaque_key = Plaque.query(
                              ).filter(Plaque.approved == True
                              ).filter(Plaque.created_on > random_time
                              ).get(keys_only=True)
    if plaque_key is None:
        return None
    else:
        return plaque_key.urlsafe()
예제 #36
0
    def get(self):
        plaque_search_index = search.Index(PLAQUE_SEARCH_INDEX_NAME)
        ideleted = 0
        # Delete all the search documents
        while True:
            # Get a list of documents populating only the doc_id field and
            # extract the ids.
            document_ids = [
                document.doc_id for document
                    in plaque_search_index.get_range(ids_only=True)]
            ideleted += len(document_ids)
            if not document_ids:
                break
            # Delete the documents for the given ids from the Index.
            plaque_search_index.delete(document_ids)
        logging.debug('deleted %s search index docs' % ideleted)

        # Write all new search docs and put them in the index
        plaques = Plaque.query().fetch()
        docs = []
        igood = 0
        ibad = 0
        for plaque in plaques:
            try:
                docs.append(plaque.to_search_document())
                igood += 1
            except search.Error as err:
                ibad += 1
                logging.error(err)
            #if ip % 100 == 0:
                #logging.debug('in process: wrote %s good docs, %s failed' % (
                              #igood, ibad))
        iput = 0
        for i in range(0, len(docs), 100):
            iput += 100
            plaque_search_index.put(docs[i:i+100])

        self.response.write(
            'deleted %s docs, created %s, failed to create %s, put %s' % (
            ideleted, igood, ibad, iput))
예제 #37
0
    def _create_or_update_plaque(self, is_edit, plaqueset_key):
        """
        Create a new plaque entity if it does not exist, or update one if it
        does.
        """
        if not is_edit:
            plaque = Plaque(parent=plaqueset_key)
        else:
            plaque_key = self.request.get('plaque_key')
            plaque = ndb.Key(urlsafe=plaque_key).get()

        location, created_by, title, description, img_name, img_fh, tags = \
            self._get_form_args()

        plaque.location = location
        plaque.title = title
        plaque.set_title_url(plaqueset_key, is_edit)
        plaque.description = description
        plaque.tags = tags
        plaque.approved = users.is_current_user_admin()
        plaque.updated_on = datetime.datetime.now()

        # Upload the image for a new plaque, or update the image for an
        # editted plaque, if specified.
        is_upload_pic = (is_edit and img_name is not None) or (not is_edit)
        if is_upload_pic:
            self._upload_image(img_name, img_fh, plaque)

        # Write to the updated_* fields if this is an edit:
        #
        if is_edit:
            plaque.updated_by = users.get_current_user()
            plaque.updated_on = datetime.datetime.now()
            img_rot = self.request.get('img_rot')
            if img_rot is not None and img_rot != 0:
                plaque.img_rot = int(img_rot)
        else:
            plaque.created_by = created_by
            plaque.updated_by = None

        old_site_id = self.request.get('old_site_id', None)
        if old_site_id is not None:
            try:
                plaque.old_site_id = int(old_site_id)
            except ValueError as err:
                logging.info('Eating bad ValueError for '
                             'old_site_id in AddPlaque')
        plaque.put()
        return plaque
예제 #38
0
def get_random_plaque_key(method='time'):
    """
    Get a random plaque key.  Limit to total number of runs to 100 to prevent
    infinite loop if there are no plaques.

    There are at least three strategies to get a random plaque:

        1. Perform a Plaque.query().count(), get a random int in the [0,count)
           range, and get the plaque at that offset using
           Plaque.query.get(offset=foo).

           This technique favors large submissions of plaques that were
           imported automatically (e.g. North Carolina, Geographs,
           Toronto/Ontario), and that large offsets are expensive in the NDB
           system.

        2. 'time': Pick a random time since the start of the site, and find a
           plaque that has a created_by value close to that time.

           This technique favors plaques which were submitted by users who have
           submitted many plaques over a long period of time, and will be
           unlikely to pick a plaque which would be picked by technique #1.

        3. 'geo': Pick a random geographical spot on the globe, and get the
           plaque closest to that.

           This will favor plaques that are further away from other plaques.

    """
    plaque_key = None
    bailout = 0
    plaque_search_index = search.Index(PLAQUE_SEARCH_INDEX_NAME)
    while plaque_key is None and bailout < 100:
        bailout += 1
        if method == 'geo':
            # Math from http://mathworld.wolfram.com/SpherePointPicking.html
            rand_u = random.random()
            rand_v = random.random()
            lng = ((2.0 * rand_u) - 1.0) * 180.0  # Range: [-180.0, 180.0)
            lat = math.acos(2.0 * rand_v - 1) * 180.0 / math.pi - 90.0
            search_radius_meters = 100000  # 100 km

            query_string = 'distance(location, geopoint(%s, %s)) < %s' % (
                lat, lng, search_radius_meters)
            query = search.Query(query_string)
            results = plaque_search_index.search(query)
            logging.info("bailout %s: produced results (%s)" %
                         (bailout, results))
            if results.number_found > 0:
                doc_id = results[0].doc_id
                plaque_key = ndb.Key(doc_id).get()
        else:  #method == 'time'
            random_time = get_random_time()
            if random_time is not None:
                plaque_key = Plaque.query().filter(
                    Plaque.approved == True).filter(
                        Plaque.created_on > random_time).get(keys_only=True)
    if plaque_key is None:
        return None

    return plaque_key.urlsafe()
예제 #39
0
 def get(self):
     plaque = Plaque.pending_list(1)[0]
     page_text = self._get_from_key(plaque_key=plaque.key.urlsafe())
     self.response.write(page_text)
예제 #40
0
    def _get_from_key(self, comment_key=None, plaque_key=None):
        """
        Put the single plaque into a list for rendering so that the common
        map functionality can be used unchanged. Attempt to serve a valid
        plaque, but if the inputs are completely messed up, serve a random
        plaque.
        """
        is_admin = users.is_current_user_admin()
        memcache_name = 'view_one_%s_%s' % (plaque_key, is_admin)
        logging.info(
            "memcache name in ViewOnePlaqueParent._get_from_key is %s" %
            memcache_name)
        page_text = memcache.get(memcache_name)
        if page_text is None:
            plaque = None
            logging.info("plaque_key=%s" % plaque_key)
            if comment_key is not None:
                logging.debug("Using comment key")
                comment = ndb.Key(urlsafe=comment_key).get()
                plaque = Plaque.query().filter(Plaque.approved == True
                                      ).filter(Plaque.comments == comment.key
                                      ).get()
            elif plaque_key is not None:
                try:
                    logging.debug("Trying old_site_id")
                    old_site_id = int(plaque_key)
                    plaque = Plaque.query(
                        ).filter(Plaque.approved == True
                        ).filter(Plaque.old_site_id == old_site_id
                        ).get()
                except ValueError as err:
                    # Get by title, allowing only admins to see unapproved ones:
                    logging.debug("Using plaque.title_url: '%s'" % plaque_key)
                    query = Plaque.query().filter(Plaque.title_url == plaque_key)
                    if not users.is_current_user_admin():
                        query = query.filter(Plaque.approved == True)
                    logging.debug("query is %s " % query)
                    plaque = query.get()
                    if plaque is None:
                        try:
                            logging.debug("Using plaque_key: '%s'" % plaque_key)
                            plaque = ndb.Key(urlsafe=plaque_key).get()
                            logging.debug("Using plaque_key, "
                                          "plaque retrieved was: '%s'" % plaque)
                        except:
                            pass

            if plaque is None:
                logging.debug("Neither comment_key nor plaque_key is specified. "
                              "Serve the first plaque, so that memcache will "
                              "always serve the same thing.")
                plaque = earliest_approved(Plaque)
                self.redirect(plaque.title_page_url)
                return

            template = JINJA_ENVIRONMENT.get_template('one.html')
            template_values = get_default_template_values(
                                  plaques=[plaque],
                                  map_markers_str=get_map_markers_str([plaque]),
                                  icon_size=32,
                              )

            page_text = template.render(template_values)
            memcache_status = memcache.set(memcache_name, page_text)
            if not memcache_status:
                logging.debug("memcaching for _get_from_key failed for %s" %
                              memcache_name)
        else:
            logging.debug("memcache.get worked for _get_from_key for %s" %
                          memcache_name)

        return page_text
예제 #41
0
    def _create_or_update_plaque(self, is_edit, plaqueset_key):
        """
        Create a new plaque entity if it does not exist, or update one if it
        does.
        """
        if not is_edit:
            plaque = Plaque(parent=plaqueset_key)
        else:
            plaque_key = self.request.get('plaque_key')
            plaque = ndb.Key(urlsafe=plaque_key).get()

        location, created_by, title, description, img_name, img_fh, tags = \
            self._get_form_args()

        plaque.location = location
        if title != plaque.title:
            plaque.title = title
            plaque.set_title_url(plaqueset_key)
        else:
            plaque.title = title

        plaque.description = description
        plaque.tags = tags
        if not is_edit:
            plaque.approved = False
        plaque.updated_on = datetime.datetime.now()

        # Upload the image for a new plaque, or update the image for an
        # editted plaque, if specified.
        is_upload_pic = (is_edit and img_name is not None) or (not is_edit)
        if is_upload_pic:
            #TODO openbenches: disable upload here?
            self._upload_image(img_name, img_fh, plaque)

        # Write to the updated_* fields if this is an edit:
        #
        if is_edit:
            plaque.updated_by = users.get_current_user()
            plaque.updated_on = datetime.datetime.now()
            img_rot = self.request.get('img_rot')
            if img_rot is not None and img_rot != 0:
                plaque.img_rot = int(img_rot)
        else:
            plaque.created_by = created_by
            plaque.updated_by = None

        old_site_id = self.request.get('old_site_id', None)
        if old_site_id is not None:
            try:
                plaque.old_site_id = int(old_site_id)
            except ValueError as err:
                logging.info('Eating bad ValueError for '
                             'old_site_id in AddPlaque')
        plaque.put()
        return plaque
예제 #42
0
def get_pages_list(per_page=DEF_NUM_PER_PAGE):
    num_pages = int(math.ceil(float(Plaque.num_approved()) /
                              float(per_page)))
    pages_list = [1+p for p in range(num_pages)]
    return pages_list