def __init__(self, engine, gtfs_url):
        super(GTFSMixin, self).__init__(engine)

        if isinstance(self.engine.config['gtfs_db_path'], apsw.Connection):
            self.conn = self.engine.config['gtfs_db_path']
        else:
            self.conn = apsw.Connection(self.engine.config['gtfs_db_path'])
        self.conn.setrowtrace(gtfs_row_tracer)
        cur = self.conn.cursor()

        version = next(cur.execute('pragma user_version'))['user_version']
        if version == 0:
            script = resource_string(
                __name__, 'gtfs_{0}.sql'.format(SCHEMA_USER_VERSION))
            if isinstance(script, six.binary_type):
                script = script.decode('utf-8')
            cur.execute(script)
        elif version < SCHEMA_USER_VERSION:
            raise NotImplementedError()
        elif version > SCHEMA_USER_VERSION:
            raise RuntimeError('Database version is {0}, but only version {1} '
                               'is known'.format(version, SCHEMA_USER_VERSION))

        tables = [r['name'] for r in cur.execute('select name from '
                                                 'sqlite_master where '
                                                 'type="table"')
                  if not r['name'].startswith('_')]

        if isinstance(gtfs_url, six.binary_type):
            gtfs_url = gtfs_url.decode('utf-8')
        resp = self._cached_requests.get(gtfs_url)
        zip = six.BytesIO(resp.content).getvalue()
        hash = hashlib.sha256(zip).hexdigest()

        resp = [x['id'] for x in cur.execute(
            'select id from _feeds where url=? AND sha256sum=?',
            (gtfs_url, hash))]
        if len(resp) == 1:
            self.feed_id = resp[0]
        else:
            cur.execute('begin transaction')
            old_ids = [(x['id'],) for x in cur.execute(
                '''select id from _feeds where url=?''', (gtfs_url,))]
            cur.executemany('delete from _feeds where id=?', old_ids)
            for table in tables:
                cur.executemany('delete from {0} where _feed=?'.format(table),
                                old_ids)

            cur.execute('insert into _feeds (url, sha256sum) '
                        'values (?, ?)', (gtfs_url, hash))
            self.feed_id = self.conn.last_insert_rowid()
            with zipfile.ZipFile(six.BytesIO(zip)) as z:
                for table in tables:
                    filename = table + '.txt'
                    if filename not in z.namelist():
                        continue
                    with z.open(filename) as f:
                        data = CSVReader(f)
                        columns = []
                        coldata = []
                        for x in cur.execute(
                                'pragma table_info({0})'.format(table)):
                            if x['name'] in data.header:
                                columns.append(x['name'])
                                coldata.append((
                                    x['type'], data.header.index(x['name'])))
                        # _feed must be at end
                        columns.append('_feed')

                        stmt = ('insert into {0} ({1}) values ({2})'
                                .format(table, ', '.join(columns),
                                        ', '.join(('?',) * len(columns))))

                        def row_gen(row):
                            for t, idx in coldata:
                                if idx < len(row) and row[idx] is not None:
                                    yield FIX_TYPE_MAP[t](row[idx])
                                else:
                                    yield None
                            yield self.feed_id
                        cur.executemany(stmt, (row_gen(row) for row in data))
            cur.execute('commit transaction')

            cur.execute('begin transaction')
            for row in cur.execute(
                    '''select trip_id from trips where _feed=?''',
                    (self.feed_id,)):
                innercur = self.conn.cursor()
                trip_id = row['trip_id']

                # interpolate missing stop times
                known_times = {r['seq']: dict(r) for r in innercur.execute(
                    '''select arrival_time as a, departure_time as d,
                    stop_sequence as seq from stop_times where trip_id=:trip_id
                    and _feed=:_feed and arrival_time is not null
                    order by stop_sequence asc''',
                    {'trip_id': trip_id, '_feed': self.feed_id})}
                if not known_times:
                    # this trip is headway only
                    continue
                unknown_times = [r['stop_sequence'] for r in innercur.execute(
                    '''select stop_sequence from stop_times where
                    trip_id=:trip_id and _feed=:_feed and
                    arrival_time is null order by stop_sequence asc''',
                    {'trip_id': trip_id, '_feed': self.feed_id})]
                for i, seq in enumerate(unknown_times):
                    left = max(filter(lambda k: k < seq, known_times))
                    right = min(filter(lambda k: k > seq, known_times))
                    start = known_times[left].get('d', known_times[left]['a'])
                    gap = known_times[right]['a'] - start
                    count = len(list(filter(lambda k: left < k < right,
                                            unknown_times))) + 1
                    time = ((gap.total_seconds() * (i + 1) / count) +
                            start.total_seconds())
                    innercur.execute(
                        '''update stop_times set _arrival_interpolate=:a where
                        trip_id=:trip_id and _feed=:_feed and
                        stop_sequence=:seq''',
                        {'trip_id': trip_id, '_feed': self.feed_id,
                         'a': time, 'seq': seq})

                # fill in _min_arrival_time
                min_time = innercur.execute(
                    '''select min(coalesce(arrival_time, _arrival_interpolate))
                    as min_time from stop_times where trip_id=? and _feed=?''',
                    (trip_id, self.feed_id)).fetchone()['min_time']
                innercur.execute('''update trips set _min_arrival_time=?
                                 where trip_id=? and _feed=?''',
                                 (min_time, trip_id, self.feed_id))

            cur.execute(
                '''insert into _stops_routes (stop_id, route_id, _feed)
                select distinct st.stop_id, t.route_id, t._feed from
                (select trip_id, stop_id from stop_times where _feed=:_feed)
                as st join
                (select trip_id, route_id, _feed from trips where _feed=:_feed)
                as t on st.trip_id=t.trip_id''', {'_feed': self.feed_id})
            cur.execute('commit transaction')
dataset/ETHPy150Open spaceboats/busbus/busbus/provider/gtfs.py/GTFSMixin.__init__/original