def begin_new_trial(self):

        # save username and trial time to db
        sql = ("""
         INSERT INTO landmark_experiment
            (username, trial_time)
         VALUES
            (%s, now())
         """) % (self.req.db.quoted(self.req.client.username), )
        self.req.db.transaction_begin_rw()
        self.req.db.sql(sql)
        self.req.db.transaction_commit()

        # choose 5 random routes from list
        routes = random.sample(conf.landmarks_exp_rt_system_ids,
                               Landmark.experiment_count)

        # save routes to db
        for sys_id in routes:
            sql = ("""
            INSERT INTO landmark_exp_route
               (username, route_system_id, last_modified)
            VALUES
               (%s, %d, now())
            """) % (
                self.req.db.quoted(self.req.client.username),
                sys_id,
            )
            self.req.db.transaction_begin_rw()
            self.req.db.sql(sql)
            self.req.db.transaction_commit()
            # send route to client
            route_xml = etree.Element('route')
            misc.xa_set(route_xml, 'route_system_id', sys_id)
            self.xml.append(route_xml)
    def get_existing_trial(self):

        # Check that the user hasn't completed the experiment previously.
        sql = ("""
         SELECT COUNT(feedback)
         FROM landmark_exp_feedback AS r
         WHERE r.username = %s
         """ % (self.req.db.quoted(self.req.client.username), ))
        rows = self.req.db.sql(sql)
        g.assurt(len(rows) == 1)
        if rows[0]['count'] == 0:

            # find out which routes this user has not finished
            sql = ("""
            SELECT route_system_id
            FROM landmark_exp_route AS r
            WHERE r.username = %s
              AND NOT r.done
            """ % (self.req.db.quoted(self.req.client.username), ))
            rows = self.req.db.sql(sql)

            # send list of routes to client
            for row in rows:
                route_xml = etree.Element('route')
                misc.xa_set(route_xml, 'route_system_id',
                            row['route_system_id'])
                self.xml.append(route_xml)
Exemple #3
0
 def prepare_response(self):
    results_xml = etree.Element('results')
    misc.xa_set(results_xml, 'ftxt', self.req.filters.filter_by_text_smart)
    # NOTE: revision_get does this instead of as_xml:
    #       self.results = qb.db.table_to_dom('revision', grevs_sql_all)
    for res in self.results:
       results_xml.append(res.as_xml())
    self.doc.append(results_xml)
Exemple #4
0
 def prepare_resp_doc(self, the_doc, item_type):
    sub_doc = etree.Element('items')
    misc.xa_set(sub_doc, 'ityp', item_type)
    if self.grand_total is not None:
       # Tell the user the complete number of items that match their query.
       misc.xa_set(sub_doc, 'grand_total', self.grand_total)
    the_doc.append(sub_doc)
    return sub_doc
Exemple #5
0
 def prepare_resp_doc(self, the_doc, item_type):
     sub_doc = etree.Element('items')
     misc.xa_set(sub_doc, 'ityp', item_type)
     if self.grand_total is not None:
         # Tell the user the complete number of items that match their query.
         misc.xa_set(sub_doc, 'grand_total', self.grand_total)
     the_doc.append(sub_doc)
     return sub_doc
 def as_xml(self, elem_name='gwis_error'):
    doc = etree.Element(elem_name)
    misc.xa_set(doc, 'msg', str(self))
    if self.tag is not None:
       misc.xa_set(doc, 'tag', self.tag)
    for gerr in self.gerrs:
       gerr.append_gml(doc, False)
    xml = etree.tostring(doc)
    return xml
Exemple #7
0
   def attrs_to_xml(self, elem, need_digest, extra_attrs=None, 
                          include_input_only_attrs=False):
      '''Add my attributes named in attrs as XML attributes of element elem.'''

      # The route finder uses extra_attrs, e.g.,
      #   [b'bonus_tagged', b'penalty_tagged', b'rating']

      if need_digest:
         md5sum = hashlib.md5()

      # Only send attributes whose definition says it should be sent to client.
      if not include_input_only_attrs:
         attrs = self.gwis_defns[0]
      else:
         attrs = self.gwis_defns[1]
      if extra_attrs:
         for extra_attr in extra_attrs:
            attrs += (extra_attr, extra_attr,)

      #log.debug('attrs_to_xml: attrs: %s' % (str(attrs),))

      # EXPLAIN: Not sure why we sort here....
      #for attr in sorted(attrs):
      for attr in attrs:
         #log.debug(' >> attr: %s / %s' % (attr, getattr(self, attr),))
         attr_val = getattr(self, attr[0], None)
         if attr_val is not None:
            misc.xa_set(elem, attr[1], attr_val)

# FIXME: This code is probably obsolete, since Diff now does the checking when
# the byways are checked out.
            # If we need a digest, we build an md5 hash based on the
            # non-geometric properties of the item. The digest is used when
            # diffing in the client to quickly tell if anything has changed.
            # - Certain property changes are meaningless, so we exclude them
   # FIXME I think this is broken... needs to be tested...
   #       (okay i no longer think it's broken)
   # FIXME Move some of these to geofeature.py and make a class array
            # MAGIC_NUMBER: 0 is col_tuple[One.scol_pyname]
            if (need_digest and attr[0] not in (
#'system_id',
#'branch_id',
               'stack_id',
               'version',
               'geometry_len',
               'beg_node_id',
               'fin_node_id',
   # I missing a bunch of generated cols that probably should be excluded...
               'node_lhs_elevation_m',
               'node_rhs_elevation_m',
               'split_from_stack_id',)):
               md5sum.update(attr[0] + str(getattr(self, attr[0])))
      if (need_digest):
         # NOTE The GML elem 'dng' is called digest_nongeo in flashclient
         # FIXME Rename to rev_digest?
         misc.xa_set(elem, 'dng', md5sum.hexdigest())
Exemple #8
0
 def prepare_response(self):
    e = etree.Element('access_control')
    misc.xa_set(e, 'control_type', self.control_type)
    self.doc.append(e)
    # FIXME Does need_digest apply to control access records? Maybe just to
    #       group_membership, which is revisioned. (This is what checkout
    #       does)
    need_digest = isinstance(self.req.revision.rev, revision.Diff)
    # Add the results from the SQL query to our XML document.
    self.control_handler.append_gml(e, need_digest)
   def fetch_n_save(self):
      command.Op_Handler.fetch_n_save(self)

      self.xml = etree.Element('lmrk_exp')

      misc.xa_set(self.xml, 'active', conf.landmarks_experiment_active)

      if ((conf.landmarks_experiment_active)
          and (self.req.client.username)
          and (self.req.client.username != conf.anonymous_username)):
         self.get_existing_trial_route_count_remaining()
Exemple #10
0
 def fetch_n_save(self):
     command.Op_Handler.fetch_n_save(self)
     self.xml = etree.Element('lmrk_trial')
     if (not conf.landmarks_experiment_active):
         misc.xa_set(self.xml, 'cond', 'exp-off')
     else:
         if ((not self.req.client.username)
                 or (self.req.client.username == conf.anonymous_username)):
             misc.xa_set(self.xml, 'cond', 'no-usr')
         elif (self.trial_num is not None):
             self.get_previous_trial()
         else:
             self.set_new_trial()
Exemple #11
0
 def as_xml(self):
    bans = etree.Element('bans')
    misc.xa_set(bans, 'public_user', self.public_ban_user)
    misc.xa_set(bans, 'full_user', self.full_ban_user)
    misc.xa_set(bans, 'public_ip', self.public_ban_ip)
    misc.xa_set(bans, 'full_ip', self.full_ban_ip)
    return bans
Exemple #12
0
    def postpare_response(self, doc, elem, extras):

        # gwis.command_.checkout sets up the XML document. We add a few
        # attributes to the <items> doc and make new ones for the link_posts.

        g.assurt(self.owning_thread is not None)

        # Add a few thread details to the XML doc.
        misc.xa_set(elem, 'thread_stack_id', self.owning_thread.stack_id)
        misc.xa_set(elem, 'thread_title', self.owning_thread.name)
        misc.xa_set(elem, 'ttype', self.owning_thread.ttype)
        misc.xa_set(elem, 'thread_type_id', self.owning_thread.thread_type_id)

        # Add the link_values and their geometries.
        #doc.append(self.result)
        # NOTE: Users can link some geofeature types to posts, but not all types.
        #       We currently don't support branches, routes, or terrain.
        for link_posts in (
                self.linked_byways,
                self.linked_regions,
                self.linked_waypoints,
                self.linked_revisions,
                self.linked_routes,
        ):
            if link_posts:
                # MAGIC_NUMBER: 'link_post'
                sub_doc = self.prepare_resp_doc(doc, 'link_post')
                link_posts.append_gml(sub_doc, need_digest=False)

        if self.reac_data:
            doc.append(self.reac_data)
Exemple #13
0
   def postpare_response(self, doc, elem, extras):

      # gwis.command_.checkout sets up the XML document. We add a few
      # attributes to the <items> doc and make new ones for the link_posts.

      g.assurt(self.owning_thread is not None)

      # Add a few thread details to the XML doc.
      misc.xa_set(elem, 'thread_stack_id', self.owning_thread.stack_id)
      misc.xa_set(elem, 'thread_title', self.owning_thread.name)
      misc.xa_set(elem, 'ttype', self.owning_thread.ttype)
      misc.xa_set(elem, 'thread_type_id', self.owning_thread.thread_type_id)

      # Add the link_values and their geometries.
      #doc.append(self.result)
      # NOTE: Users can link some geofeature types to posts, but not all types.
      #       We currently don't support branches, routes, or terrain.
      for link_posts in (self.linked_byways,
                         self.linked_regions,
                         self.linked_waypoints,
                         self.linked_revisions,
                         self.linked_routes,):
         if link_posts:
            # MAGIC_NUMBER: 'link_post'
            sub_doc = self.prepare_resp_doc(doc, 'link_post')
            link_posts.append_gml(sub_doc, need_digest=False)

      if self.reac_data:
         doc.append(self.reac_data);
Exemple #14
0
    def get_previous_trial(self):
        # We need the track id and the landmark prompt locations
        sql = ("""
         SELECT track_id, condition
         FROM landmark_trial AS t
         WHERE
            t.username = %s
            AND t.trial_num = %s
         """ % (
            self.req.db.quoted(self.req.client.username),
            self.trial_num,
        ))
        rows = self.req.db.sql(sql)
        misc.xa_set(self.xml, 'tid', rows[0]['track_id'])
        misc.xa_set(self.xml, 'cond', rows[0]['condition'])

        sql = ("""
         SELECT n.node_stack_id, ST_AsText(n.endpoint_xy) as geo
         FROM landmark_prompt AS p
         JOIN node_endpt_xy as n ON (p.node_id = n.node_stack_id)
         WHERE
            p.username = %s
            AND p.trial_num = %s
         """ % (
            self.req.db.quoted(self.req.client.username),
            self.trial_num,
        ))
        rows = self.req.db.sql(sql)

        for row in rows:
            prompts_xml = etree.Element('prompt')
            misc.xa_set(prompts_xml, 'nid', row['node_stack_id'])
            misc.xa_set(prompts_xml, 'geometry', row['geo'][6:-1])
            self.xml.append(prompts_xml)
Exemple #15
0
    def append_gpx(self, db, elem, step_number):

        # NOTE: we must re-query the geometry so that we can transform it into
        # WGS84 for the gpx spec
        # FIXME: EXPLAIN: Do we care about permissions here?
        # FIXME: If we know we're exporting to GPX, can't we do this on fetch?
        if self.travel_mode == Travel_Mode.bicycle:
            rows = db.sql("""
            SELECT
               ST_AsText(ST_Transform(geometry, %d)) as geometry
            FROM 
               geofeature
            WHERE
               system_id = %d
            """ % (
                conf.srid_latlon,
                self.byway_id,
            ))
        else:
            g.assurt(self.step_number)
            rows = db.sql("""
            SELECT
               ST_AsText(ST_Transform(transit_geometry, %d)) as geometry
            FROM 
               route_step
            WHERE
               route_id = %d 
               AND step_number = %d
            """ % (
                conf.srid_latlon,
                self.route_id,
                self.step_number,
            ))

        wgs_xy = geometry.wkt_line_to_xy(rows[0]['geometry'])
        if not self.forward:
            wgs_xy.reverse()

        for lonlat in wgs_xy:
            # Parsed pair is [longitude, latitude]
            # FIXME: Search this element name. Why 'trk'? Because GPX?
            new = etree.Element('trkpt')
            misc.xa_set(new, 'lat', lonlat[1])
            misc.xa_set(new, 'lon', lonlat[0])

            name = etree.SubElement(new, 'name')
            name.text = self.step_name

            elem.append(new)
Exemple #16
0
   def prepare_response(self):

      if self.rid_count is not None:
         # Tell the user the complete number of revision that match their query
         misc.xa_set(self.results, 'total', self.rid_count)

      if self.req.filters.include_geosummary:
         # Remove each geosummary attribute and install in its place a
         # geosummary child element with a properly formatted coordinate list.
         for row in self.results:
            if row.get('geosummary'):
               g.assurt(row.get('geosummary')[:2] == 'M ')
               geosummary_child = etree.Element('geosummary')
               gml.append_MultiPolygon(geosummary_child, row.get('geosummary'))
               del row.attrib['geosummary']
               row.append(geosummary_child)

      self.doc.append(self.results)
Exemple #17
0
    def prepare_response(self):

        g.assurt(self.req.client.username != conf.anonymous_username)

        # Skipping: BUG 2688: No need to use transaction_retryable,
        #                     since user_token_gen does it own retrying.
        e = etree.Element('token')
        e.text = self.req.client.user_token_generate(self.req.client.username)
        self.doc.append(e)

        # FIXME: Bug nnnn: Generate the session ID / sessid here, too...

        e = etree.Element('preferences')
        p = self.preferences_get()
        for (col, value) in p.items():
            misc.xa_set(e, col, value)

        self.doc.append(e)
Exemple #18
0
    def prepare_response(self):

        if self.rid_count is not None:
            # Tell the user the complete number of revision that match their query
            misc.xa_set(self.results, 'total', self.rid_count)

        if self.req.filters.include_geosummary:
            # Remove each geosummary attribute and install in its place a
            # geosummary child element with a properly formatted coordinate list.
            for row in self.results:
                if row.get('geosummary'):
                    g.assurt(row.get('geosummary')[:2] == 'M ')
                    geosummary_child = etree.Element('geosummary')
                    gml.append_MultiPolygon(geosummary_child,
                                            row.get('geosummary'))
                    del row.attrib['geosummary']
                    row.append(geosummary_child)

        self.doc.append(self.results)
    def prepare_metaresp(self):
        command_base.Op_Handler.prepare_metaresp(self)

        # MAYBE: Like cp_maint_beg and cp_maint_fin, we could have the client
        #        ask for 'semiprotect', since flashclient should only need it if
        #        the user is editing (it restricts new and anonymous users from
        #        editing but not from getting routes). See: kval_get.py.
        misc.xa_set(self.doc, 'semiprotect', self.semiprotect_wait())

        if self.user_client_ban.is_banned():
            self.doc.append(self.user_client_ban.as_xml())

        # Check if the user's email address is invalid
        # NOTE: Flashclient will show a popup to tell the user if
        #       their email address is marked bouncing.
        if self.req.client.username != conf.anonymous_username:
            if (user_email.flag_get(self.req.db, self.req.client.username,
                                    'bouncing')):
                misc.xa_set(
                    self.doc, 'bouncing',
                    user_email.addr_get(self.req.db, self.req.client.username,
                                        False))
Exemple #20
0
    def fetch_n_save(self):
        command.Op_Handler.fetch_n_save(self)
        self.xml = etree.Element('lmrk_need')
        if (conf.landmarks_experiment_active):

            sql = ("""
            SELECT distinct n.stack_id, ST_AsText(nxy.endpoint_xy) as geo,
                   (SELECT count(*)
                     FROM geofeature
                        JOIN group_item_access as gia
                           ON (geofeature.stack_id = gia.stack_id
                               AND geofeature.version = gia.version)
                        WHERE geofeature_layer_id=103
                        AND ST_Distance(nxy.endpoint_xy, geofeature.geometry)
                            < 50
                        AND NOT deleted
                        AND valid_until_rid = %d
                        AND gia.branch_id = %d) as points_nearby
            FROM node_endpoint as n
            JOIN node_endpt_xy as nxy ON (n.stack_id = nxy.node_stack_id)
            WHERE ST_Distance(nxy.endpoint_xy,
                              ST_SetSRID(ST_Point(%s, %s), %d)) < 500
               AND reference_n > 2
            """ % (
                conf.rid_inf,
                branch.Many.baseline_id(self.req.db),
                self.x,
                self.y,
                conf.default_srid,
            ))

            # TODO: get only stuff in current branch
            rows = self.req.db.sql(sql)
            for row in rows:
                if (row['points_nearby'] == 0):
                    need_xml = etree.Element('need')
                    misc.xa_set(need_xml, 'nid', row['stack_id'])
                    misc.xa_set(need_xml, 'geometry', row['geo'][6:-1])
                    self.xml.append(need_xml)
Exemple #21
0
   def prepare_metaresp(self):
      command_base.Op_Handler.prepare_metaresp(self)

      # MAYBE: Like cp_maint_beg and cp_maint_fin, we could have the client
      #        ask for 'semiprotect', since flashclient should only need it if
      #        the user is editing (it restricts new and anonymous users from
      #        editing but not from getting routes). See: kval_get.py.
      misc.xa_set(self.doc, 'semiprotect', self.semiprotect_wait())

      if self.user_client_ban.is_banned():
         self.doc.append(self.user_client_ban.as_xml())

      # Check if the user's email address is invalid
      # NOTE: Flashclient will show a popup to tell the user if
      #       their email address is marked bouncing.
      if self.req.client.username != conf.anonymous_username:
         if (user_email.flag_get(
               self.req.db, self.req.client.username, 'bouncing')):
            misc.xa_set(
               self.doc,
               'bouncing',
               user_email.addr_get(
                  self.req.db, self.req.client.username, False))
 def get_trial(self):
 
    # get routes from pt 1
    routes_p1 = list()
    sql = (
       """
       SELECT route_system_id
       FROM landmark_exp_route AS r
       WHERE r.username = %s
         AND part = 1
       """ % (self.req.db.quoted(self.req.client.username),))
    rows = self.req.db.sql(sql)
    for row in rows:
       routes_p1.append(row['route_system_id'])
 
    # get pt 2 routes
    sql = (
       """
       SELECT u.route_system_id, u.route_user_id, u.done
       FROM landmark_exp_route AS r
          LEFT JOIN landmark_exp_route_p2_users as u
          ON (u.username = r.username
              AND u.route_system_id = r.route_system_id)
       WHERE
          r.username = %s
          AND part = 2
       """ % (self.req.db.quoted(self.req.client.username),))
    rows = self.req.db.sql(sql)
    
    routes_p2 = list()
    # if list is empty, generate new routes
    if len(rows) == 0:
       routes_p2 = self.generate_new_routes(routes_p1)
    else:
       # keep only new routes
       for r in rows:
          if (not r['done']):
             routes_p2.append((r['route_system_id'], r['route_user_id'],))
       
    
    # send list of routes to client
    for r_id in routes_p1:
       route_xml = etree.Element('route_p1')
       misc.xa_set(route_xml, 'route_system_id', r_id)
       self.xml.append(route_xml)
    for rt in routes_p2:
       route_xml = etree.Element('route_p2')
       misc.xa_set(route_xml, 'route_system_id', rt[0])
       misc.xa_set(route_xml, 'route_user_id', rt[1])
       self.xml.append(route_xml)
Exemple #23
0
 def prepare_metaresp(self):
    'Another fetch cycle for things best done after saving.'
    # SYNC_ME: Search fetch doc metadata.
    #log.debug('prepare_metaresp: VERSION.major: %s' % (VERSION.major,))
    misc.xa_set(self.doc, 'major', VERSION.major)
    misc.xa_set(self.doc, 'gwis_version', conf.gwis_version)
    # BUG nnnn: How best to handle updating the user's working revision.
    #           For now, we always send the rid_max, because of how
    #           flashclient is programmed (which is to reset rev_viewport
    #           and make it again when the first GWIS response is received).
    # MAYBE/BUG nnnn: Flashclient and Android should ping periodically for
    #                 the revision ID, e.g., maybe via key_value_get.py.
    rid_max = str(revision.Revision.revision_max(self.req.db))
    misc.xa_set(self.doc, 'rid_max', rid_max)
    def get_trial(self):

        # get routes from pt 1
        routes_p1 = list()
        sql = ("""
         SELECT route_system_id
         FROM landmark_exp_route AS r
         WHERE r.username = %s
           AND part = 1
         """ % (self.req.db.quoted(self.req.client.username), ))
        rows = self.req.db.sql(sql)
        for row in rows:
            routes_p1.append(row['route_system_id'])

        # get pt 2 routes
        sql = ("""
         SELECT u.route_system_id, u.route_user_id, u.done
         FROM landmark_exp_route AS r
            LEFT JOIN landmark_exp_route_p2_users as u
            ON (u.username = r.username
                AND u.route_system_id = r.route_system_id)
         WHERE
            r.username = %s
            AND part = 2
         """ % (self.req.db.quoted(self.req.client.username), ))
        rows = self.req.db.sql(sql)

        routes_p2 = list()
        # if list is empty, generate new routes
        if len(rows) == 0:
            routes_p2 = self.generate_new_routes(routes_p1)
        else:
            # keep only new routes
            for r in rows:
                if (not r['done']):
                    routes_p2.append((
                        r['route_system_id'],
                        r['route_user_id'],
                    ))

        # send list of routes to client
        for r_id in routes_p1:
            route_xml = etree.Element('route_p1')
            misc.xa_set(route_xml, 'route_system_id', r_id)
            self.xml.append(route_xml)
        for rt in routes_p2:
            route_xml = etree.Element('route_p2')
            misc.xa_set(route_xml, 'route_system_id', rt[0])
            misc.xa_set(route_xml, 'route_user_id', rt[1])
            self.xml.append(route_xml)
Exemple #25
0
 def append_gml(self,
                elem,
                need_digest,
                new=None,
                extra_attrs=None,
                include_input_only_attrs=False):
     # We're called by item_base.Many for each record it found. It created
     # a master XML document, and it wants us to create a child document to
     # contain the geofeature.
     g.assurt(not new)
     if new is None:
         # NOTE This code CxPx from item_versioned.append_gml
         g.assurt(self.item_type_id != '')
         new = etree.Element(Item_Type.id_to_str(self.item_type_id))
     if need_digest:
         # NOTE The GML elem 'dg' is the _d_igest for _g_eometry
         # EXPLAIN: How is the digest used?
         # FIXME: Can I use any of the geometries?? Probably not...
         g.assurt(self.geometry_svg)
         # MAYBE: Depending on the geometry representation, it's a diff digest.
         geometry = self.geometry_svg or self.geometry_wkt
         # or self.geometry_raw
         misc.xa_set(new, 'dg', hashlib.md5(geometry).hexdigest())
     if self.attrs:
         attrs = etree.Element('attrs')
         for attr_name, attr_val in self.attrs.iteritems():
             attr = etree.Element('a')
             misc.xa_set(attr, 'k', attr_name)
             # FIXME: Does this value need to be encoded?
             #        Test with </t> in a tag name. or <t>
             misc.xa_set(attr, 'v', attr_val)
             attrs.append(attr)
         new.append(attrs)
     if self.tagged:
         # We can't just use a comma-separated list because some tags include
         # commas. It's easiest just to make another subdocument.
         #   NO: misc.xa_set(new, 'tags', ', '.join(self.tagged))
         tags = etree.Element('tags')
         for tag_name in self.tagged:
             tag = etree.Element('t')
             tag.text = tag_name
             tags.append(tag)
         new.append(tags)
     self.append_gml_geometry(new)
     return item_user_watching.One.append_gml(self, elem, need_digest, new,
                                              extra_attrs,
                                              include_input_only_attrs)
   def get_existing_trial_route_count_remaining(self):

      # Send count of remaining routes and completed routes to client.

      route_xml = etree.Element('route')

      sql = (
         """
         SELECT COUNT(route_system_id) AS count
         FROM landmark_exp_route AS r
         WHERE
            r.username = %s
            AND NOT r.done
            AND part = %d
         """ % (self.req.db.quoted(self.req.client.username),
                self.experiment_part,))
      rows = self.req.db.sql(sql)
      g.assurt(len(rows) == 1)
      misc.xa_set(route_xml, 'routes_togo', rows[0]['count'])
      self.xml.append(route_xml)

      sql = (
         """
         SELECT COUNT(route_system_id) AS count
         FROM landmark_exp_route AS r
         WHERE
            r.username = %s
            AND r.done
            AND part = %d
         """ % (self.req.db.quoted(self.req.client.username),
                self.experiment_part,))
      rows = self.req.db.sql(sql)
      g.assurt(len(rows) == 1)
      misc.xa_set(route_xml, 'routes_done', rows[0]['count'])
      self.xml.append(route_xml)

      sql = (
         """
         SELECT COUNT(feedback)
         FROM landmark_exp_feedback AS r
         WHERE r.username = %s
         """ % (self.req.db.quoted(self.req.client.username),))
      rows = self.req.db.sql(sql)
      g.assurt(len(rows) == 1)
      misc.xa_set(route_xml, 'user_done', rows[0]['count'])
      self.xml.append(route_xml)
Exemple #27
0
    def search_calculate_reactions(self, qb):

        # BUG_FALL_2013: Delete this fcn.

        # See polarity_sql = Many.sql_polarity in thread.py: [lb] thinks this
        # fcn. can be deleted. We calculate the likes and dislikes of a thread,
        # but it doesn't make sense to count it for just one post... especially
        # since a post with polarity has no comment, so it doesn't make sense
        # that we'd hydrate such a post. And posts with comments have no polarity
        # so the likes and dislikes will be zero...
        g.assurt(False)  # FIXME: Delete this fcn. and the commented-out code
        #        above that calls it.

        g.assurt(self.owning_thread is not None)

        if (self.owning_thread.thread_type_id == Thread_Type.reaction):

            # SELECT polarity, body FROM post WHERE body IS NULL;
            # ==> polarity is 1 or -1, body is never set.
            # SELECT polarity, body FROM post WHERE body IS NOT NULL;
            # ==> polarityis 0 and body is set.

            # MAYBE: Does this sql take a while?
            time_0 = time.time()

            rsql = thread.Many.sql_polarity(qb, self.owning_thread.stack_id)

            rres = qb.db.sql(rsql)

            self.reac_data = etree.Element('reac_data')
            misc.xa_set(self.reac_data, 'likes', rres[0]['likes'])
            misc.xa_set(self.reac_data, 'dislikes', rres[0]['dislikes'])
            misc.xa_set(self.reac_data, 'comments', rres[0]['comments'])

            log.debug(
                'srch_calc_reacts: likes: %d / disls: %d / cmmnts: %d / %s' % (
                    rres[0]['likes'],
                    rres[0]['dislikes'],
                    rres[0]['comments'],
                    misc.time_format_elapsed(time_0),
                ))
Exemple #28
0
   def search_calculate_reactions(self, qb):

# BUG_FALL_2013: Delete this fcn.

      # See polarity_sql = Many.sql_polarity in thread.py: [lb] thinks this
      # fcn. can be deleted. We calculate the likes and dislikes of a thread,
      # but it doesn't make sense to count it for just one post... especially
      # since a post with polarity has no comment, so it doesn't make sense
      # that we'd hydrate such a post. And posts with comments have no polarity
      # so the likes and dislikes will be zero...
      g.assurt(False) # FIXME: Delete this fcn. and the commented-out code
                      #        above that calls it.

      g.assurt(self.owning_thread is not None)

      if (self.owning_thread.thread_type_id == Thread_Type.reaction):

         # SELECT polarity, body FROM post WHERE body IS NULL;
         # ==> polarity is 1 or -1, body is never set.
         # SELECT polarity, body FROM post WHERE body IS NOT NULL;
         # ==> polarityis 0 and body is set.

         # MAYBE: Does this sql take a while?
         time_0 = time.time()

         rsql = thread.Many.sql_polarity(qb, self.owning_thread.stack_id)

         rres = qb.db.sql(rsql)

         self.reac_data = etree.Element('reac_data')
         misc.xa_set(self.reac_data, 'likes', rres[0]['likes'])
         misc.xa_set(self.reac_data, 'dislikes', rres[0]['dislikes'])
         misc.xa_set(self.reac_data, 'comments', rres[0]['comments'])

         log.debug(
            'srch_calc_reacts: likes: %d / disls: %d / cmmnts: %d / %s'
            % (rres[0]['likes'], rres[0]['dislikes'], rres[0]['comments'],
               misc.time_format_elapsed(time_0),))
Exemple #29
0
 def append_gml(self, elem):
    new = et.Element(Item_Type.id_to_str(self.item_type_id))
    misc.xa_set(new, 'name', self.name)
    misc.xa_set(new, 'item_id', self.item_id)
    misc.xa_set(new, 'type_id', self.type_id)
    misc.xa_set(new, 'step', self.step_number)
    misc.xa_set(new, 'dist', self.dist)
    misc.xa_set(new, 'disp', self.display)
    if self.geometry:
       if self.type_id == Item_Type.WAYPOINT:
          gml.append_Point(new, self.geometry)
       else:
          gml.append_Polygon(new, self.geometry)
    elem.append(new)
Exemple #30
0
 def append_gml(self, elem):
     new = et.Element(Item_Type.id_to_str(self.item_type_id))
     misc.xa_set(new, 'name', self.name)
     misc.xa_set(new, 'item_id', self.item_id)
     misc.xa_set(new, 'type_id', self.type_id)
     misc.xa_set(new, 'step', self.step_number)
     misc.xa_set(new, 'dist', self.dist)
     misc.xa_set(new, 'disp', self.display)
     if self.geometry:
         if self.type_id == Item_Type.WAYPOINT:
             gml.append_Point(new, self.geometry)
         else:
             gml.append_Polygon(new, self.geometry)
     elem.append(new)
Exemple #31
0
   def fetch_n_save(self):

      command.Op_Handler.fetch_n_save(self)

      qb = self.req.as_iqb()

      for addr in self.addrs:

         addr_qb = None
         try:
            # Start with fresh qb for each addr, so that qb_filters is
            # fresh and so none of the temp tables pre-exist.
            addr_qb = qb.clone(skip_clauses=True, skip_filtport=True,
                               db_get_new=True)
            (result_gps, hit_count_text,) = self.addr_geocode(addr_qb, addr)
         finally:
            if (addr_qb is not None) and (addr_qb.db is not None):
               addr_qb.db.close()
               addr_qb.db = None

         # FIXME Better, I [reid] think, to _not_ throw an exception and let 
         #       flashclient deal with it (perhaps in Address_Choose.mxml)?
         #       But this is fine for now.
         self.raise_error_if_no_results(addr, result_gps)
         #
         # FIXME: This used to use Address().as_xml(), but the results from
         # addr_geocode are search results now. So maybe implement
         # gp_res.as_xml_addr()
         addr_xml = etree.Element('addr')

         # BUG nnnn: Android does not encode properly, e.g., raw '&'s in XML.
         # [lb] tried to work around the android bug by converting raw '&'s,
         #      but android expects the addr in our response to match the addr
         #      in the query... so we'd have to replace our corrected addr
         #      query with the original, incorrectly (un)encoded request here.
         #      If not (as the code is here, now) if we change the addr by
         #      fixing it, android will ignore the response and will send
         #      another request. And the cycle repeats itself....
         misc.xa_set(addr_xml, 'text', addr)

         # HACK: hit_count_text is used by the route finder to complain to the
         # user if too many userpoints of the same name were found.
         misc.xa_set(addr_xml, 'hit_count_text', hit_count_text)
         for gp_res in result_gps:
            # See the class: Search_Result_Geofeature.
            gf_res = gp_res.result_gfs[0]
            # SYNC_ME: gwis.command_.geocode.fetch_n_save 
            #          and item.util.address.as_xml
            res_xml = etree.Element('addr')
            # From Search_Result_Group:
            misc.xa_set(res_xml, 'text', gp_res.gf_name)
            misc.xa_set(res_xml, 'gc_id', gp_res.gc_fulfiller)
            misc.xa_set(res_xml, 'gc_ego', gp_res.gc_confidence)
            # From Search_Result_Geofeature:
            misc.xa_set(res_xml, 'x', gf_res.x)
            misc.xa_set(res_xml, 'y', gf_res.y)
            misc.xa_set(res_xml, 'width', gf_res.width)
            misc.xa_set(res_xml, 'height', gf_res.height)
            #
            addr_xml.append(res_xml)
         self.doc.append(addr_xml)
Exemple #32
0
 def as_xml(self):
    elem = etree.Element('result')
    misc.xa_set(elem, 'gf_name', self.gf_name)
    misc.xa_set(elem, 'gf_type_id', self.gf_type_id)
    # Skipping (since some are addys... or maybe that doesn't matter):
    #   misc.xa_set(elem, 'gf_stack_id', self.gf_stack_id)
    for result in self.result_gfs:
       obj = etree.Element('gf_item')
       misc.xa_set(obj, 'stack_id', result.stack_id)
       if result.geometry:
          misc.xa_set(obj, 'geometry', result.geometry)
       # Skipping center, which we only use interally.
       misc.xa_set(obj, 'x', result.x)
       misc.xa_set(obj, 'y', result.y)
       # MAYBE: width and height... or no one cares?
       elem.append(obj)
    # 
    obj_in = etree.Element('ts_in')
    obj_ex = etree.Element('ts_ex')
    for vect_name in search_full_text.Full_Text_Query_Part.ts_vects:
       misc.xa_set(obj_in, vect_name, self.ts_include[vect_name])
       misc.xa_set(obj_ex, vect_name, self.ts_exclude[vect_name])
    elem.append(obj_in)
    elem.append(obj_ex)
    #
    return elem
    def fetch_n_save(self):
        command.Op_Handler.fetch_n_save(self)

        # Assemble the qb from the request.
        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))

        item_stack_ids = qb.filters.decode_ids_compact('./fbil_sids',
                                                       self.req.doc_in)
        if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
            raise GWIS_Error('Expecting one stack ID in fbil_sids doc.')

        items = item_user_access.Many()
        g.assurt(qb.sql_clauses is None)
        qb.sql_clauses = item_user_access.Many.sql_clauses_cols_all.clone()
        qb.filters.dont_load_feat_attcs = True
        qb.filters.only_stack_ids = item_stack_ids
        sql_many = items.search_get_sql(qb)

        sql_itmf = ("""
         SELECT
            itmf.item_stack_id
            , itmf.username
            -- , itmf.user_id
            , itmf.library_squelch
            , itmf.show_in_history
            -- , itmf.last_viewed
            -- , itmf.branch_id
         FROM (%s) AS gia
         JOIN item_findability AS itmf
            ON (gia.stack_id = itmf.item_stack_id)
         WHERE
            (       (itmf.username = %s)
                AND (gia.access_level_id <= %d))
            OR (    (itmf.username = %s)
                AND (gia.access_level_id <= %d))
         """ % (
            sql_many,
            qb.db.quoted(conf.anonymous_username),
            Access_Level.arbiter,
            qb.db.quoted(qb.username),
            Access_Level.viewer,
        ))

        rows = qb.db.sql(sql_itmf)

        if len(rows) == 0:
            raise GWIS_Warning('No item_findability for user-item.')

        # We'll find one or two records: one for the user, and one for the
        # public.
        # EXPLAIN: What records exist for anon route request?
        #          [lb] thinks it's a GIA record with a stealth secret,
        #               but probably not an item_findability record.
        #
        #          FIXME: TEST: anon get route, log in, save route
        #
        fbilities = etree.Element('fbilities')
        for row in rows:
            fbility = etree.Element('fbility')
            misc.xa_set(fbility, 'sid', row['item_stack_id'])
            if row['username'] == conf.anonymous_username:
                # MAGIC_NUMBER: Usernames prefixed with a floorbar are special.
                username_hacked = '_anonymous'
            else:
                username_hacked = row['username']
            misc.xa_set(fbility, 'unom', username_hacked)
            #misc.xa_set(fbility, 'uid', row['user_id'])
            misc.xa_set(fbility, 'sqel', row['library_squelch'])
            misc.xa_set(fbility, 'hist', row['show_in_history'])
            #misc.xa_set(fbility, 'lstv', row['last_viewed'])
            #misc.xa_set(fbility, 'brid', row['branch_id'])
            fbilities.append(fbility)
        self.itmf_xml = fbilities
Exemple #34
0
    def set_new_trial(self):
        conditions = {
            'now-low': 0,
            'now-high': 0,
            'later-low': 0,
            'later-high': 0,
        }
        # get trial history (what condition and how many prompts)
        sql = ("""
         SELECT condition, count(*) AS ct
         FROM landmark_trial AS t
         JOIN landmark_prompt AS p ON (t.username = p.username
                                       AND t.trial_num = p.trial_num)
         WHERE
            t.username = %s
            AND track_id IS NOT NULL
            AND NOT track_id = -1
         GROUP BY condition
         """ % (self.req.db.quoted(self.req.client.username), ))
        rows = self.req.db.sql(sql)

        # get highest trial number
        sql = ("""
         SELECT MAX(trial_num) AS num
         FROM landmark_trial AS t
         WHERE t.username = %s
         """ % (self.req.db.quoted(self.req.client.username), ))
        max_trial_num = -1
        num_trial_rows = self.req.db.sql(sql)
        if (len(num_trial_rows) > 0):
            max_trial_num = num_trial_rows[0]['num']
        if max_trial_num is None:
            max_trial_num = -1
        new_trial_num = max_trial_num + 1

        if (new_trial_num > 0):
            # Check whether the last trial was incomplete
            sql = ("""
            SELECT condition
            FROM landmark_trial AS t
            WHERE
               t.username = %s
               AND track_id = -1
               AND trial_num = %d
            GROUP BY condition
            """ % (
                self.req.db.quoted(self.req.client.username),
                max_trial_num,
            ))
            p_rows = self.req.db.sql(sql)
            if (len(p_rows) > 0 and p_rows[0]['condition'] is not None):
                # This will give priority to retrying previous incomplete condition
                conditions[(p_rows[0]['condition'] + '-low')] -= 100
                conditions[(p_rows[0]['condition'] + '-high')] -= 100

        if (len(rows) == 0):
            # if no history, get first trial conditions for all users
            sql = ("""
            SELECT t.username, condition, count(*) AS ct
            FROM landmark_trial AS t
            JOIN landmark_prompt AS p ON (t.username = p.username
                                          AND t.trial_num = p.trial_num)
            WHERE
               t.trial_num = 0
            GROUP BY t.username, condition
            """)
            rows = self.req.db.sql(sql)
        # get counts for conditions and choose lowest (random if more than
        # one with the lowest count)
        for row in rows:
            if row['ct'] < 4:
                conditions[(row['condition'] + '-low')] += 1
            else:
                conditions[(row['condition'] + '-high')] += 1
        # decide on new conditions and save
        condition_keys = ['now-low', 'now-high', 'later-low', 'later-high']
        min_conds = [condition_keys[0]]
        min_ct = conditions[min_conds[0]]
        for i in xrange(1, len(condition_keys)):
            if (conditions[condition_keys[i]] < min_ct):
                min_conds = [condition_keys[i]]
                min_ct = conditions[min_conds[0]]
            elif (conditions[condition_keys[i]] == min_ct):
                min_conds.append(condition_keys[i])
        final_condition = 'none'
        if (len(min_conds) == 1):
            # we have our condition
            final_condition = min_conds[0]
        else:
            # We need to assing one randomly
            random.seed(time.time())
            final_condition = min_conds[random.randint(0, len(min_conds) - 1)]
        misc.xa_set(self.xml, 'cond', final_condition)
        misc.xa_set(self.xml, 'trial_num', new_trial_num)

        # Save trial information
        sql = ("""
         INSERT INTO landmark_trial
            (username, trial_num, trial_time,
             condition, track_id, email_sent)
         VALUES
            (%s, %d, now(), '%s', %d, '%s')
         """) % (
            self.req.db.quoted(self.req.client.username),
            new_trial_num,
            str.split(final_condition, '-')[0],
            -1,
            False,
        )
        self.req.db.transaction_begin_rw()
        self.req.db.sql(sql)
        self.req.db.transaction_commit()
    def fetch_n_save(self):

        command.Op_Handler.fetch_n_save(self)

        # Assemble the qb from the request.
        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))

        item_stack_ids = qb.filters.decode_ids_compact('./ssec_sids',
                                                       self.req.doc_in)
        if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
            raise GWIS_Error('Expecting one stack ID in ssec_sids doc.')

        item_stack_id = int(item_stack_ids)
        if item_stack_id <= 0:
            raise GWIS_Error('Expecting positive valued stack ID.')

        items_fetched = item_user_access.Many()
        # So we get access_infer, etc.
        qb.filters.include_item_stack = True
        # Don't forget to maybe use the session ID.
        qb.filters.gia_use_sessid = self.req.filters.gia_use_sessid
        items_fetched.search_by_stack_id(item_stack_id, qb)

        if not items_fetched:
            raise GWIS_Error(
                'Item stack ID not found or you cannot access: %d' %
                (item_stack_id, ))

        g.assurt(len(items_fetched) == 1)
        item = items_fetched[0]
        log.verbose1('verify_access: fetched: %s' % (str(item), ))
        g.assurt(not item.fresh)
        g.assurt(not item.valid)

        # What's the policy for who can make stealth secret values?
        # They're not really that special, but if every item in the database
        # had one, that's a lotta mozzarrella.
        #
        # Users should at least be able to edit: for example, if an owner of a
        # route linked to a route in a discussion, the public has view access
        # to the route based on the discussion, but we wouldn't want someone
        # with view access to create a stealth secret, since the owner should
        # actively manage the stealth secret access via the gia sharing widget.

        #  item.groups_access_load_from_db(qb)
        #  g.assurt(item.groups_access) # else, stealth to permissions_free?
        #  access_infer_id = item.get_access_infer(qb)
        if item.access_style_id == Access_Style.pub_editor:
            # Re prev. comments, ability to edit includes ability to make ssecs.
            if not item.can_edit():
                raise GWIS_Error(
                    'You must be editor of public item to create link: %d' %
                    (item_stack_id, ))
        elif item.access_style_id == Access_Style.usr_editor:
            g.assurt(item.can_edit())
        elif item.access_style_id == Access_Style.restricted:
            # Restricted item types, like routes and track, can only have stealth
            # access created by their arbiters and owners.
            if not item.can_arbit():
                raise GWIS_Error(
                    'You must be arbiter of restricted item to create link: %d'
                    % (item_stack_id, ))
            # This is the path when an anonymous user gets a route and makes a
            # link for it. We'll call add_stealth_gia to make sure user has access
            # to the stealth secret.
        else:
            raise GWIS_Error('What you are trying to do is not supported.')

        if item.stealth_secret:
            new_stealth_secret = False
            stealth_secret = item.stealth_secret
            log.warning('fetch_n_save: Item already has link: %d' %
                        (item_stack_id, ))
        else:
            new_stealth_secret = True
            stealth_secret = self.make_stealth_secret(item)
            # See also route_get: Maybe we should just INSERT INTO
            # group_item_access ourselves, but instead we sneakily
            # use the commit command to process a style_change.
            if ((qb.filters.gia_use_sessid)
                    and (qb.username == conf.anonymous_username)):
                item_arr = [
                    item,
                ]
                self.req.db.transaction_retryable(self.add_stealth_gia,
                                                  self.req, item_arr)
                item = item_arr[0]

        # The outermost document.
        ssecrets = etree.Element('ssecrets')
        # The response document.
        ssecret = etree.Element('ssecret')
        misc.xa_set(ssecret, 'stack_id', item.stack_id)
        misc.xa_set(ssecret, 'ssecret', stealth_secret)
        # Include the possibly changed access_infer_id.
        if new_stealth_secret:
            misc.xa_set(ssecret, 'acif', item.access_infer_id)
            # Include the possibly new and changed grac records.
            if item.groups_access is None:
                item.groups_access_load_from_db(qb)
            log.debug('fetch_n_save: no. groups_access: %d' %
                      (len(item.groups_access), ))
            grac_doc = etree.Element('access_control')
            misc.xa_set(grac_doc, 'control_type', 'group_item_access')
            for grpa in item.groups_access.itervalues():
                grpa.append_gml(grac_doc, need_digest=False)
            ssecret.append(grac_doc)
        # Bundle it up.
        ssecrets.append(ssecret)
        # And we're done.
        self.ssec_xml = ssecrets
Exemple #36
0
    def attrs_to_xml(self,
                     elem,
                     need_digest,
                     extra_attrs=None,
                     include_input_only_attrs=False):
        '''Add my attributes named in attrs as XML attributes of element elem.'''

        # The route finder uses extra_attrs, e.g.,
        #   [b'bonus_tagged', b'penalty_tagged', b'rating']

        if need_digest:
            md5sum = hashlib.md5()

        # Only send attributes whose definition says it should be sent to client.
        if not include_input_only_attrs:
            attrs = self.gwis_defns[0]
        else:
            attrs = self.gwis_defns[1]
        if extra_attrs:
            for extra_attr in extra_attrs:
                attrs += (
                    extra_attr,
                    extra_attr,
                )

        #log.debug('attrs_to_xml: attrs: %s' % (str(attrs),))

        # EXPLAIN: Not sure why we sort here....
        #for attr in sorted(attrs):
        for attr in attrs:
            #log.debug(' >> attr: %s / %s' % (attr, getattr(self, attr),))
            attr_val = getattr(self, attr[0], None)
            if attr_val is not None:
                misc.xa_set(elem, attr[1], attr_val)

                # FIXME: This code is probably obsolete, since Diff now does the checking when
                # the byways are checked out.
                # If we need a digest, we build an md5 hash based on the
                # non-geometric properties of the item. The digest is used when
                # diffing in the client to quickly tell if anything has changed.
                # - Certain property changes are meaningless, so we exclude them
                # FIXME I think this is broken... needs to be tested...
                #       (okay i no longer think it's broken)
                # FIXME Move some of these to geofeature.py and make a class array
                # MAGIC_NUMBER: 0 is col_tuple[One.scol_pyname]
                if (need_digest and attr[0] not in (
                        #'system_id',
                        #'branch_id',
                        'stack_id',
                        'version',
                        'geometry_len',
                        'beg_node_id',
                        'fin_node_id',
                        # I missing a bunch of generated cols that probably should be excluded...
                        'node_lhs_elevation_m',
                        'node_rhs_elevation_m',
                        'split_from_stack_id',
                )):
                    md5sum.update(attr[0] + str(getattr(self, attr[0])))
        if (need_digest):
            # NOTE The GML elem 'dng' is called digest_nongeo in flashclient
            # FIXME Rename to rev_digest?
            misc.xa_set(elem, 'dng', md5sum.hexdigest())
Exemple #37
0
   def fetch_n_save(self):

      command.Op_Handler.fetch_n_save(self)

      # Assemble the qb from the request.
      qb = self.req.as_iqb(addons=False)
      g.assurt(qb.filters == Query_Filters(None))

      item_stack_ids = qb.filters.decode_ids_compact('./ssec_sids',
                                                     self.req.doc_in)
      if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
         raise GWIS_Error('Expecting one stack ID in ssec_sids doc.')

      item_stack_id = int(item_stack_ids)
      if item_stack_id <= 0:
         raise GWIS_Error('Expecting positive valued stack ID.')

      items_fetched = item_user_access.Many()
      # So we get access_infer, etc.
      qb.filters.include_item_stack = True
      # Don't forget to maybe use the session ID.
      qb.filters.gia_use_sessid = self.req.filters.gia_use_sessid
      items_fetched.search_by_stack_id(item_stack_id, qb)

      if not items_fetched:
         raise GWIS_Error('Item stack ID not found or you cannot access: %d'
                          % (item_stack_id,))

      g.assurt(len(items_fetched) == 1)
      item = items_fetched[0]
      log.verbose1('verify_access: fetched: %s' % (str(item),))
      g.assurt(not item.fresh)
      g.assurt(not item.valid)

      # What's the policy for who can make stealth secret values?
      # They're not really that special, but if every item in the database
      # had one, that's a lotta mozzarrella.
      #
      # Users should at least be able to edit: for example, if an owner of a
      # route linked to a route in a discussion, the public has view access
      # to the route based on the discussion, but we wouldn't want someone
      # with view access to create a stealth secret, since the owner should
      # actively manage the stealth secret access via the gia sharing widget.

      #  item.groups_access_load_from_db(qb)
      #  g.assurt(item.groups_access) # else, stealth to permissions_free?
      #  access_infer_id = item.get_access_infer(qb)
      if item.access_style_id == Access_Style.pub_editor:
         # Re prev. comments, ability to edit includes ability to make ssecs.
         if not item.can_edit():
            raise GWIS_Error(
               'You must be editor of public item to create link: %d'
               % (item_stack_id,))
      elif item.access_style_id == Access_Style.usr_editor:
         g.assurt(item.can_edit())
      elif item.access_style_id == Access_Style.restricted:
         # Restricted item types, like routes and track, can only have stealth
         # access created by their arbiters and owners.
         if not item.can_arbit():
            raise GWIS_Error(
               'You must be arbiter of restricted item to create link: %d'
               % (item_stack_id,))
         # This is the path when an anonymous user gets a route and makes a
         # link for it. We'll call add_stealth_gia to make sure user has access
         # to the stealth secret.
      else:
         raise GWIS_Error('What you are trying to do is not supported.')

      if item.stealth_secret:
         new_stealth_secret = False
         stealth_secret = item.stealth_secret
         log.warning('fetch_n_save: Item already has link: %d'
                     % (item_stack_id,))
      else:
         new_stealth_secret = True
         stealth_secret = self.make_stealth_secret(item)
         # See also route_get: Maybe we should just INSERT INTO
         # group_item_access ourselves, but instead we sneakily
         # use the commit command to process a style_change.
         if ((qb.filters.gia_use_sessid)
             and (qb.username == conf.anonymous_username)):
            item_arr = [item,]
            self.req.db.transaction_retryable(self.add_stealth_gia,
                                              self.req, item_arr)
            item = item_arr[0]

      # The outermost document.
      ssecrets = etree.Element('ssecrets')
      # The response document.
      ssecret = etree.Element('ssecret')
      misc.xa_set(ssecret, 'stack_id', item.stack_id)
      misc.xa_set(ssecret, 'ssecret', stealth_secret)
      # Include the possibly changed access_infer_id.
      if new_stealth_secret:
         misc.xa_set(ssecret, 'acif', item.access_infer_id)
         # Include the possibly new and changed grac records.
         if item.groups_access is None:
            item.groups_access_load_from_db(qb)
         log.debug('fetch_n_save: no. groups_access: %d'
                   % (len(item.groups_access),))
         grac_doc = etree.Element('access_control')
         misc.xa_set(grac_doc, 'control_type', 'group_item_access')
         for grpa in item.groups_access.itervalues():
            grpa.append_gml(grac_doc, need_digest=False)
         ssecret.append(grac_doc)
      # Bundle it up.
      ssecrets.append(ssecret)
      # And we're done.
      self.ssec_xml = ssecrets
Exemple #38
0
   def as_xml(self):

      # SYNC_ME: gwis.command_.geocode.fetch_n_save 
      #          and item.util.address.as_xml

      elem = etree.Element('addr')

      misc.xa_set(elem, 'text', self.text)
      misc.xa_set(elem, 'x', self.x)
      misc.xa_set(elem, 'y', self.y)
      misc.xa_set(elem, 'width', self.width)
      misc.xa_set(elem, 'height', self.height)

      #misc.xa_set(elem, 'street', self.street)
      #misc.xa_set(elem, 'city', self.city)
      #misc.xa_set(elem, 'county', self.county)
      #misc.xa_set(elem, 'state', self.state)
      #misc.xa_set(elem, 'zip', self.zip)
      #misc.xa_set(elem, 'country', self.country)

      # BUG nnnn: Should flashclient use the entity type?
      misc.xa_set(elem, 'gc_fulfiller', self.gc_fulfiller)
      misc.xa_set(elem, 'gc_confidence', self.gc_confidence)

      return elem
   def fetch_n_save(self):
      command.Op_Handler.fetch_n_save(self)

      # Assemble the qb from the request.
      qb = self.req.as_iqb(addons=False)
      g.assurt(qb.filters == Query_Filters(None))

      item_stack_ids = qb.filters.decode_ids_compact('./fbil_sids',
                                                     self.req.doc_in)
      if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
         raise GWIS_Error('Expecting one stack ID in fbil_sids doc.')

      items = item_user_access.Many()
      g.assurt(qb.sql_clauses is None)
      qb.sql_clauses = item_user_access.Many.sql_clauses_cols_all.clone()
      qb.filters.dont_load_feat_attcs = True
      qb.filters.only_stack_ids = item_stack_ids
      sql_many = items.search_get_sql(qb)

      sql_itmf = (
         """
         SELECT
            itmf.item_stack_id
            , itmf.username
            -- , itmf.user_id
            , itmf.library_squelch
            , itmf.show_in_history
            -- , itmf.last_viewed
            -- , itmf.branch_id
         FROM (%s) AS gia
         JOIN item_findability AS itmf
            ON (gia.stack_id = itmf.item_stack_id)
         WHERE
            (       (itmf.username = %s)
                AND (gia.access_level_id <= %d))
            OR (    (itmf.username = %s)
                AND (gia.access_level_id <= %d))
         """ % (sql_many,
                qb.db.quoted(conf.anonymous_username),
                Access_Level.arbiter,
                qb.db.quoted(qb.username),
                Access_Level.viewer,))

      rows = qb.db.sql(sql_itmf)

      if len(rows) == 0:
         raise GWIS_Warning('No item_findability for user-item.')

      # We'll find one or two records: one for the user, and one for the
      # public.
      # EXPLAIN: What records exist for anon route request?
      #          [lb] thinks it's a GIA record with a stealth secret,
      #               but probably not an item_findability record.
      #
      #          FIXME: TEST: anon get route, log in, save route
      #
      fbilities = etree.Element('fbilities')
      for row in rows:
         fbility = etree.Element('fbility')
         misc.xa_set(fbility, 'sid', row['item_stack_id'])
         if row['username'] == conf.anonymous_username:
            # MAGIC_NUMBER: Usernames prefixed with a floorbar are special.
            username_hacked = '_anonymous'
         else:
            username_hacked = row['username']
         misc.xa_set(fbility, 'unom', username_hacked)
         #misc.xa_set(fbility, 'uid', row['user_id'])
         misc.xa_set(fbility, 'sqel', row['library_squelch'])
         misc.xa_set(fbility, 'hist', row['show_in_history'])
         #misc.xa_set(fbility, 'lstv', row['last_viewed'])
         #misc.xa_set(fbility, 'brid', row['branch_id'])
         fbilities.append(fbility)
      self.itmf_xml = fbilities