コード例 #1
0
def db_get_easting_northing(lon, lat):
    q = "SELECT ST_AsText(%s)" % db_coord_transform(
        lon, lat, cs.WGS84_LATLON_CODE, cs.WEB_MERCATOR_CODE)
    session = session_factory()
    result = session.execute(q).fetchone()[0]
    easting, northing = result.replace('POINT(', '').replace(')', '').split()
    return round(float(easting)), round(float(northing))
コード例 #2
0
def get_reportweek_for_contributor_and_tile(contributor, tile):
    week_class = get_reportweek_class(current_week_number())
    session = session_factory()
    with session.begin(subtransactions=True):
        result = session.query(week_class).filter(and_(week_class.contributor_id == contributor.id,
                                                     week_class.tile_id == tile.id))
        return result.first() if result else None
def add_stumbles_for_contributor(email, display_name, query_json):
    # Hack
    json_object = query_json

    session = session_factory()
    with session.begin(subtransactions=True):
        contributor = session.query(Contributor).filter_by(email=email).first()

        if contributor is None:
            contributor = Contributor(nickname=display_name,
                                      email=email)
            session.add(contributor)
        elif contributor.nickname != display_name:
            # Update the displayname
            contributor.nickname = display_name

            # Need to add to the session to mark as dirty
            session.add(contributor)

        for row in json_object['items']:
            tile_coord = row[key_tile_easting_northing]
            east, north = tile_coord.split(",")
            tile = Tile.get_tile_mercator(int(float(east)), int(float(north)))
            week_per_tile = insert_or_update_reportweek(contributor, tile)
            obs = row[key_observations]
            if not week_per_tile.observation_count:
                week_per_tile.observation_count = 0
            week_per_tile.observation_count += obs

    return True
コード例 #4
0
    def set_country_for_tile(tile, use_intersect=False, use_nearby=False):
        from tile import Tile

        assert isinstance(tile, Tile)
        geo = tile.geo_as_wgs84()

        session = session_factory()
        with session.begin(subtransactions=True):
            result = session.query(CountryBounds).filter(
                CountryBounds.wkb_geometry.ST_Contains(func.ST_Centroid(geo)))
            c = result.first()

            if not c or use_intersect:
                result = session.query(CountryBounds).filter(
                    CountryBounds.wkb_geometry.ST_Intersects(geo))
                c = result.first()

            if not c or use_nearby:
                # https://github.com/geoalchemy/geoalchemy2/issues/94 broken <->
                # also doesn't work SELECT ogc_fid FROM country_bounds ORDER BY wkb_geometry <-> ST_Centroid('%s') LIMIT 1
                nearby = '''
                    WITH index_query AS (
                      SELECT ST_Distance(wkb_geometry, '%s') as d, name, ogc_fid
                        FROM country_bounds
                      ORDER BY wkb_geometry <-> '%s' LIMIT 10)
                      SELECT ogc_fid
                        FROM index_query
                      ORDER BY d limit 1
                    ''' % (geo, geo)
                r = session.execute(nearby)
                c_id = r.fetchone()[0]
                c = session.query(CountryBounds).filter_by(ogc_fid=c_id).first()

            tile.country = c
コード例 #5
0
def add_stumbles_for_contributor(email, display_name, query_json):
    # Hack
    json_object = query_json

    session = session_factory()
    with session.begin(subtransactions=True):
        contributor = session.query(Contributor).filter_by(email=email).first()

        if contributor is None:
            contributor = Contributor(nickname=display_name, email=email)
            session.add(contributor)
        elif contributor.nickname != display_name:
            # Update the displayname
            contributor.nickname = display_name

            # Need to add to the session to mark as dirty
            session.add(contributor)

        for row in json_object['items']:
            tile_coord = row[key_tile_easting_northing]
            east, north = tile_coord.split(",")
            tile = Tile.get_tile_mercator(int(float(east)), int(float(north)))
            week_per_tile = insert_or_update_reportweek(contributor, tile)
            obs = row[key_observations]
            if not week_per_tile.observation_count:
                week_per_tile.observation_count = 0
            week_per_tile.observation_count += obs

    return True
コード例 #6
0
 def geo_as_wgs84(self):
     session = session_factory()
     ewkt = "'" + session.execute(func.ST_AsEWKT(
         self.geometry)).first().values()[0] + "'" + '::geometry'
     # select ST_Transform('SRID=3785;POLYGON((-8839000 5419000,-8839000 5419500,-8838500 5419500,-8838500 5419000,-8839000 5419000))', 4326);
     r = session.execute("select ST_AsEWKT(ST_Transform(%s, %d))" %
                         (ewkt, cs.WGS84_LATLON_CODE))
     return r.fetchone()[0]
コード例 #7
0
def get_reportweek_for_contributor_and_tile(contributor, tile):
    week_class = get_reportweek_class(current_week_number())
    session = session_factory()
    with session.begin(subtransactions=True):
        result = session.query(week_class).filter(
            and_(week_class.contributor_id == contributor.id,
                 week_class.tile_id == tile.id))
        return result.first() if result else None
コード例 #8
0
 def get_globals():
     session = session_factory()
     with session.begin(subtransactions=True):
         try:
             return session.query(LeaderboardGlobals).one()
         except NoResultFound:
             lg = LeaderboardGlobals()
             session.add(lg)
             return lg
コード例 #9
0
    def get_current_week():
        g = LeaderboardGlobals.get_globals()
        if not g.current_week or not 0 < g.current_week < 54:
            session = session_factory()
            with session.begin(subtransactions=True):
                g.current_week = datetime.date.today().year
                session.add(g)

        return g.current_week
コード例 #10
0
def create_one_contributor():
    global contributor_counter
    contributor_counter += 1
    contributor = Contributor()
    contributor.email = '[email protected]%d' % contributor_counter
    contributor.nickname = 'nick%d' % contributor_counter
    session = session_factory()
    with session.begin(subtransactions=True):
        session.add(contributor)
    return contributor
コード例 #11
0
def create_one_contributor():
    global contributor_counter
    contributor_counter += 1
    contributor = Contributor()
    contributor.email = '[email protected]%d' % contributor_counter
    contributor.nickname = 'nick%d' % contributor_counter
    session = session_factory()
    with session.begin(subtransactions=True):
        session.add(contributor)
    return contributor
コード例 #12
0
    def get_tile_mercator(easting, northing):
        session = session_factory()
        with session.begin(subtransactions=True):
            r = session.query(Tile).filter(func.ST_Contains(
                Tile.geometry, func.ST_SetSRID(func.ST_Point(easting, northing), cs.WEB_MERCATOR_CODE))).first()
            if r:
                return r

        ewkt = Tile.create_tile_ewkt_mercator(easting, northing)
        tile = Tile()
        tile.geometry = ewkt
        CountryBounds.set_country_for_tile(tile)
        return tile
コード例 #13
0
    def test_weekly_rollover(self):
        # add data
        self.test_add_contributor_tile_and_report()
        week_class = reportweeks.get_current_reportweek_class()
        session = session_factory()
        rows = None
        try:
            rows = session.query(week_class).one()
        except NoResultFound:
            pass
        assert rows

        g = LeaderboardGlobals.get_globals()
        g.current_week = reportweeks.current_week_number() - 1

        # verify data gets truncated on next access
        week_class = reportweeks.get_current_reportweek_class()
        session = session_factory()
        rows = None
        try:
            rows = session.query(week_class).one()
        except NoResultFound:
            pass
        assert not rows
コード例 #14
0
    def get_tile_mercator(easting, northing):
        session = session_factory()
        with session.begin(subtransactions=True):
            r = session.query(Tile).filter(
                func.ST_Contains(
                    Tile.geometry,
                    func.ST_SetSRID(func.ST_Point(easting, northing),
                                    cs.WEB_MERCATOR_CODE))).first()
            if r:
                return r

        ewkt = Tile.create_tile_ewkt_mercator(easting, northing)
        tile = Tile()
        tile.geometry = ewkt
        CountryBounds.set_country_for_tile(tile)
        return tile
コード例 #15
0
def insert_or_update_reportweek(contributor, tile):
    week_class = get_current_reportweek_class()
    db = get_db()
    session = session_factory()
    with session.begin(subtransactions=True):
        if not db.table_exists(week_class.__tablename__):
            db.get_metadata().create_all(db.engine)

        existing = get_reportweek_for_contributor_and_tile(contributor, tile)
        if existing:
            return existing

        w = week_class()
        w.contributor_id = contributor.id
        w.tile_id = tile.id
        session.add(w)
        return w
コード例 #16
0
def insert_or_update_reportweek(contributor, tile):
    week_class = get_current_reportweek_class()
    db = get_db()
    session = session_factory()
    with session.begin(subtransactions=True):
        if not db.table_exists(week_class.__tablename__):
            db.get_metadata().create_all(db.engine)

        existing = get_reportweek_for_contributor_and_tile(contributor, tile)
        if existing:
            return existing

        w = week_class()
        w.contributor_id = contributor.id
        w.tile_id = tile.id
        session.add(w)
        return w
コード例 #17
0
ファイル: db.py プロジェクト: mozilla/leaderboard_backend
    def drop_all(self):
        from leaderboard.models.country_bounds import CountryBounds  # NOQA
        from leaderboard.models.contributor import Contributor  # NOQA
        from leaderboard.models.tile import Tile  # NOQA
        from leaderboard.models.reportweeks import get_current_reportweek_class
        wk = get_current_reportweek_class()
        if self.table_exists(wk.__tablename__):
            t = wk.__table__
            t.drop(get_db().engine)
        for tbl in reversed(get_db().get_metadata().sorted_tables):
            if self.table_exists(tbl.name):
                get_db().engine.execute(tbl.delete())
                tbl.drop(get_db().engine)

        session = session_factory()
        with session.begin(subtransactions=True):
            session.expunge_all()
            session.expire_all()
コード例 #18
0
ファイル: db.py プロジェクト: crankycoder/leaderboard_backend
    def drop_all(self):
        from leaderboard.models.country_bounds import CountryBounds  # NOQA
        from leaderboard.models.contributor import Contributor  # NOQA
        from leaderboard.models.tile import Tile   # NOQA
        from leaderboard.models.reportweeks import get_current_reportweek_class
        wk = get_current_reportweek_class()
        if self.table_exists(wk.__tablename__):
            t = wk.__table__
            t.drop(get_db().engine)
        for tbl in reversed(get_db().get_metadata().sorted_tables):
            if self.table_exists(tbl.name):
                get_db().engine.execute(tbl.delete())
                tbl.drop(get_db().engine)

        session = session_factory()
        with session.begin(subtransactions=True):
            session.expunge_all()
            session.expire_all()
コード例 #19
0
    def load_countries():
        import ogr
        import os

        pwd = os.path.dirname(os.path.abspath(__file__))
        infile = "%s/../fixtures/world.geo.json" % pwd
        drv = ogr.GetDriverByName('GeoJSON')
        assert drv
        ds = drv.Open(infile)
        layer = ds.GetLayer(0)
        srs = ogr.osr.SpatialReference()
        srs.ImportFromEPSG(WGS84_LATLON_CODE)
        session = session_factory()
        with session.begin(subtransactions=True):
            for feature in layer:
                fid = feature.GetFID()
                name = feature.GetField(0)
                geo = feature.GetGeometryRef()
                wkb = 'SRID=%d;%s' % (CountryBounds.coord_sys(), geo.ExportToWkt())
                country = CountryBounds(ogc_fid=fid, wkb_geometry=wkb, name=name)
                session.add(country)
コード例 #20
0
    def is_week_rolling_over():
        """ Weeks 1-53 are stored in the db, and are reused as the year rolls over.
        As week 1 turns into week2 (for example), week2 must be truncated before using it.
        The current week is stored in the LeaderboardGlobals.
        This function both checks for rollover, and updates the db to the new week.

        :return: True if the actual week is greater than the current week in the db
        """

        from leaderboard.models import reportweeks

        week_in_db = LeaderboardGlobals.get_current_week()
        actual_week = reportweeks.current_week_number()
        is_rollover = actual_week != week_in_db
        if is_rollover:
            session = session_factory()
            with session.begin(subtransactions=True):
                  lbGlobals = LeaderboardGlobals.get_globals()
                  lbGlobals.current_week = actual_week
                  session.add(lbGlobals)
        return is_rollover
コード例 #21
0
def get_reportweek_class(week_num):
    assert (0 < week_num < 54)

    tablename = 'reportweek%d' % week_num

    if LeaderboardGlobals.is_week_rolling_over():
        session = session_factory()
        session.execute('truncate table %s;' % tablename)

    if tablename in _week_classes_cache:
        return _week_classes_cache[tablename]

    class Week(Base):
        __tablename__ = tablename
        id = Column(Integer, primary_key=True)
        contributor_id = Column(Integer, ForeignKey(Contributor.id))
        contributor = relationship(Contributor, backref=backref(tablename))
        tile_id = Column(Integer, ForeignKey(Tile.id))
        tile = relationship(Tile)
        observation_count = Column(BigInteger)
    _week_classes_cache[tablename] = Week

    return Week
コード例 #22
0
def get_leaders_for_country(country_id):
    week_class = reportweeks.get_current_reportweek_class()
    session = session_factory()
    q = session.query(contributor.Contributor,
                      func.sum(week_class.observation_count).label('obs_sum')). \
        filter(tile.Tile.country_id == country_id). \
        filter(week_class.contributor_id == contributor.Contributor.id). \
        filter(week_class.tile_id == tile.Tile.id). \
        group_by(contributor.Contributor.id). \
        order_by(desc('obs_sum'))
    result = q.all()
    if result:
        assert isinstance(result[0][0], contributor.Contributor)
        assert isinstance(result[0][1], Decimal)

    rows = []
    for row in result:
        rows.append({'name': row[0].nickname,
                     'observations': str(row[1])})

    country_name = session.query(country_bounds.CountryBounds.name). \
        filter_by(ogc_fid=country_id).first()

    return {'country_name': country_name, 'leaders': rows}
コード例 #23
0
    def test_submit_server_new_nick(self):
        import time

        session = session_factory()
        contributor = create_one_contributor()
        with session.begin():
            session.add(contributor)
            nick = contributor.nickname
        nickname = time.time()

        # this will update the nick
        add_stumbles_for_contributor(contributor.email, nickname,
                             json.loads(canada_observations_json))

        # check contributor has 1 tile, 1 weekX row, and total obs is 101
        weekly_per_tile = contributor.get_report_for_current_week().values()
        eq_(len(weekly_per_tile), 1)
        single_week = weekly_per_tile[0][0]
        assert isinstance(single_week, get_current_reportweek_class())
        eq_(single_week.observation_count, 101)
        eq_(single_week.tile.country.name.lower(), 'canada')

        # Verify that the contributor nickname was updated
        eq_(contributor.nickname, nickname)
コード例 #24
0
    def test_submit_server_new_nick(self):
        import time

        session = session_factory()
        contributor = create_one_contributor()
        with session.begin():
            session.add(contributor)
            nick = contributor.nickname
        nickname = time.time()

        # this will update the nick
        add_stumbles_for_contributor(contributor.email, nickname,
                                     json.loads(canada_observations_json))

        # check contributor has 1 tile, 1 weekX row, and total obs is 101
        weekly_per_tile = contributor.get_report_for_current_week().values()
        eq_(len(weekly_per_tile), 1)
        single_week = weekly_per_tile[0][0]
        assert isinstance(single_week, get_current_reportweek_class())
        eq_(single_week.observation_count, 101)
        eq_(single_week.tile.country.name.lower(), 'canada')

        # Verify that the contributor nickname was updated
        eq_(contributor.nickname, nickname)
コード例 #25
0
def db_get_easting_northing(lon, lat):
    q = "SELECT ST_AsText(%s)" % db_coord_transform(lon, lat, cs.WGS84_LATLON_CODE, cs.WEB_MERCATOR_CODE)
    session = session_factory()
    result = session.execute(q).fetchone()[0]
    easting, northing = result.replace('POINT(', '').replace(')', '').split()
    return round(float(easting)), round(float(northing))
コード例 #26
0
 def setup(self):
     if not hasattr(self, 'db'):
         self.db = init_sessions()
         self.db.drop_all()
         self.db.create_all()
     self.session = session_factory()
コード例 #27
0
 def geo_as_wgs84(self):
     session = session_factory()
     ewkt = "'" + session.execute(func.ST_AsEWKT(self.geometry)).first().values()[0] + "'" + '::geometry'
     # select ST_Transform('SRID=3785;POLYGON((-8839000 5419000,-8839000 5419500,-8838500 5419500,-8838500 5419000,-8839000 5419000))', 4326);
     r = session.execute("select ST_AsEWKT(ST_Transform(%s, %d))" % (ewkt, cs.WGS84_LATLON_CODE))
     return r.fetchone()[0]