Advertisement
Guest User

Untitled

a guest
Aug 22nd, 2016
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.16 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import logging
  4. import calendar
  5. import sys
  6. import time
  7. import math
  8. from peewee import SqliteDatabase, InsertQuery, \
  9. IntegerField, CharField, DoubleField, BooleanField, \
  10. DateTimeField, CompositeKey, fn
  11. from playhouse.flask_utils import FlaskDB
  12. from playhouse.pool import PooledMySQLDatabase
  13. from playhouse.shortcuts import RetryOperationalError
  14. from playhouse.migrate import migrate, MySQLMigrator, SqliteMigrator
  15. from datetime import datetime, timedelta
  16. from base64 import b64encode
  17.  
  18. from . import config
  19. from .utils import get_pokemon_name, get_pokemon_rarity, get_pokemon_types, get_args
  20. from .transform import transform_from_wgs_to_gcj
  21. from .customLog import printPokemon
  22. import luna
  23.  
  24. log = logging.getLogger(__name__)
  25.  
  26. args = get_args()
  27. flaskDb = FlaskDB()
  28.  
  29. db_schema_version = 5
  30.  
  31.  
  32. class MyRetryDB(RetryOperationalError, PooledMySQLDatabase):
  33. pass
  34.  
  35.  
  36. def init_database(app):
  37. if args.db_type == 'mysql':
  38. log.info('Connecting to MySQL database on %s:%i', args.db_host, args.db_port)
  39. connections = args.db_max_connections
  40. if hasattr(args, 'accounts'):
  41. connections *= len(args.accounts)
  42. db = MyRetryDB(
  43. args.db_name,
  44. user=args.db_user,
  45. password=args.db_pass,
  46. host=args.db_host,
  47. port=args.db_port,
  48. max_connections=connections,
  49. stale_timeout=300)
  50. else:
  51. log.info('Connecting to local SQLite database')
  52. db = SqliteDatabase(args.db)
  53.  
  54. app.config['DATABASE'] = db
  55. flaskDb.init_app(app)
  56.  
  57. return db
  58.  
  59.  
  60. class BaseModel(flaskDb.Model):
  61.  
  62. @classmethod
  63. def get_all(cls):
  64. results = [m for m in cls.select().dicts()]
  65. if args.china:
  66. for result in results:
  67. result['latitude'], result['longitude'] = \
  68. transform_from_wgs_to_gcj(
  69. result['latitude'], result['longitude'])
  70. return results
  71.  
  72.  
  73. class Pokemon(BaseModel):
  74. # We are base64 encoding the ids delivered by the api
  75. # because they are too big for sqlite to handle
  76. encounter_id = CharField(primary_key=True, max_length=50)
  77. spawnpoint_id = CharField(index=True)
  78. pokemon_id = IntegerField(index=True)
  79. latitude = DoubleField()
  80. longitude = DoubleField()
  81. disappear_time = DateTimeField(index=True)
  82.  
  83. class Meta:
  84. indexes = ((('latitude', 'longitude'), False),)
  85.  
  86. @staticmethod
  87. def get_active(swLat, swLng, neLat, neLng):
  88. if swLat is None or swLng is None or neLat is None or neLng is None:
  89. query = (Pokemon
  90. .select()
  91. .where(Pokemon.disappear_time > datetime.utcnow())
  92. .dicts())
  93. else:
  94. query = (Pokemon
  95. .select()
  96. .where((Pokemon.disappear_time > datetime.utcnow()) &
  97. (Pokemon.latitude >= swLat) &
  98. (Pokemon.longitude >= swLng) &
  99. (Pokemon.latitude <= neLat) &
  100. (Pokemon.longitude <= neLng))
  101. .dicts())
  102.  
  103. pokemons = []
  104. for p in query:
  105. p['pokemon_name'] = get_pokemon_name(p['pokemon_id'])
  106. p['pokemon_rarity'] = get_pokemon_rarity(p['pokemon_id'])
  107. p['pokemon_types'] = get_pokemon_types(p['pokemon_id'])
  108. if args.china:
  109. p['latitude'], p['longitude'] = \
  110. transform_from_wgs_to_gcj(p['latitude'], p['longitude'])
  111. pokemons.append(p)
  112.  
  113. return pokemons
  114.  
  115. @staticmethod
  116. def get_active_by_id(ids, swLat, swLng, neLat, neLng):
  117. if swLat is None or swLng is None or neLat is None or neLng is None:
  118. query = (Pokemon
  119. .select()
  120. .where((Pokemon.pokemon_id << ids) &
  121. (Pokemon.disappear_time > datetime.utcnow()))
  122. .dicts())
  123. else:
  124. query = (Pokemon
  125. .select()
  126. .where((Pokemon.pokemon_id << ids) &
  127. (Pokemon.disappear_time > datetime.utcnow()) &
  128. (Pokemon.latitude >= swLat) &
  129. (Pokemon.longitude >= swLng) &
  130. (Pokemon.latitude <= neLat) &
  131. (Pokemon.longitude <= neLng))
  132. .dicts())
  133.  
  134. pokemons = []
  135. for p in query:
  136. p['pokemon_name'] = get_pokemon_name(p['pokemon_id'])
  137. p['pokemon_rarity'] = get_pokemon_rarity(p['pokemon_id'])
  138. p['pokemon_types'] = get_pokemon_types(p['pokemon_id'])
  139. if args.china:
  140. p['latitude'], p['longitude'] = \
  141. transform_from_wgs_to_gcj(p['latitude'], p['longitude'])
  142. pokemons.append(p)
  143.  
  144. return pokemons
  145.  
  146. @classmethod
  147. def get_seen(cls, timediff):
  148. if timediff:
  149. timediff = datetime.utcnow() - timediff
  150. pokemon_count_query = (Pokemon
  151. .select(Pokemon.pokemon_id,
  152. fn.COUNT(Pokemon.pokemon_id).alias('count'),
  153. fn.MAX(Pokemon.disappear_time).alias('lastappeared')
  154. )
  155. .where(Pokemon.disappear_time > timediff)
  156. .group_by(Pokemon.pokemon_id)
  157. .alias('counttable')
  158. )
  159. query = (Pokemon
  160. .select(Pokemon.pokemon_id,
  161. Pokemon.disappear_time,
  162. Pokemon.latitude,
  163. Pokemon.longitude,
  164. pokemon_count_query.c.count)
  165. .join(pokemon_count_query, on=(Pokemon.pokemon_id == pokemon_count_query.c.pokemon_id))
  166. .where(Pokemon.disappear_time == pokemon_count_query.c.lastappeared)
  167. .dicts()
  168. )
  169. pokemons = []
  170. total = 0
  171. for p in query:
  172. p['pokemon_name'] = get_pokemon_name(p['pokemon_id'])
  173. pokemons.append(p)
  174. total += p['count']
  175.  
  176. return {'pokemon': pokemons, 'total': total}
  177.  
  178. @classmethod
  179. def get_appearances(cls, pokemon_id, last_appearance):
  180. query = (Pokemon
  181. .select()
  182. .where((Pokemon.pokemon_id == pokemon_id) &
  183. (Pokemon.disappear_time > datetime.utcfromtimestamp(last_appearance / 1000.0))
  184. )
  185. .order_by(Pokemon.disappear_time.asc())
  186. .dicts()
  187. )
  188. appearances = []
  189. for a in query:
  190. appearances.append(a)
  191. return appearances
  192.  
  193. @classmethod
  194. def get_spawnpoints(cls, swLat, swLng, neLat, neLng):
  195. query = Pokemon.select(Pokemon.latitude, Pokemon.longitude, Pokemon.spawnpoint_id)
  196.  
  197. if None not in (swLat, swLng, neLat, neLng):
  198. query = (query
  199. .where((Pokemon.latitude >= swLat) &
  200. (Pokemon.longitude >= swLng) &
  201. (Pokemon.latitude <= neLat) &
  202. (Pokemon.longitude <= neLng)
  203. )
  204. )
  205.  
  206. # Sqlite doesn't support distinct on columns
  207. if args.db_type == 'mysql':
  208. query = query.distinct(Pokemon.spawnpoint_id)
  209. else:
  210. query = query.group_by(Pokemon.spawnpoint_id)
  211.  
  212. return list(query.dicts())
  213.  
  214. @classmethod
  215. def get_spawnpoints_in_hex(cls, center, steps):
  216. log.info('got {}steps'.format(steps))
  217. # work out hex bounding box
  218. hdist = ((steps * 120.0) - 50.0) / 1000.0
  219. vdist = ((steps * 105.0) - 35.0) / 1000.0
  220. R = 6378.1 # km radius of the earth
  221. vang = math.degrees(vdist / R)
  222. hang = math.degrees(hdist / (R * math.cos(math.radians(center[0]))))
  223. north = center[0] + vang
  224. south = center[0] - vang
  225. east = center[1] + hang
  226. west = center[1] - hang
  227. # get all spawns in that box
  228. query = (Pokemon
  229. .select(Pokemon.latitude.alias('lat'),
  230. Pokemon.longitude.alias('lng'),
  231. ((Pokemon.disappear_time.minute * 60) + Pokemon.disappear_time.second).alias('time'),
  232. Pokemon.spawnpoint_id
  233. ))
  234. query = (query.where((Pokemon.latitude <= north) &
  235. (Pokemon.latitude >= south) &
  236. (Pokemon.longitude >= west) &
  237. (Pokemon.longitude <= east)
  238. ))
  239. # Sqlite doesn't support distinct on columns
  240. if args.db_type == 'mysql':
  241. query = query.distinct(Pokemon.spawnpoint_id)
  242. else:
  243. query = query.group_by(Pokemon.spawnpoint_id)
  244.  
  245. s = list(query.dicts())
  246. # for each spawn work out if it is in the hex (clipping the diagonals)
  247. trueSpawns = []
  248. for spawn in s:
  249. spawn['time'] = (spawn['time'] + 2700) % 3600
  250. # get the offset from the center of each spawn in km
  251. offset = [math.radians(spawn['lat'] - center[0]) * R, math.radians(spawn['lng'] - center[1]) * (R * math.cos(math.radians(center[0])))]
  252. # check agains the 4 lines that make up the diagonals
  253. if (offset[1] + (offset[0] * 0.5)) > hdist: # too far ne
  254. continue
  255. if (offset[1] - (offset[0] * 0.5)) > hdist: # too far se
  256. continue
  257. if ((offset[0] * 0.5) - offset[1]) > hdist: # too far nw
  258. continue
  259. if ((0 - offset[1]) - (offset[0] * 0.5)) > hdist: # too far sw
  260. continue
  261. # if it gets to here its a good spawn
  262. trueSpawns.append(spawn)
  263. return trueSpawns
  264.  
  265.  
  266. class Pokestop(BaseModel):
  267. pokestop_id = CharField(primary_key=True, max_length=50)
  268. enabled = BooleanField()
  269. latitude = DoubleField()
  270. longitude = DoubleField()
  271. last_modified = DateTimeField(index=True)
  272. lure_expiration = DateTimeField(null=True, index=True)
  273. active_fort_modifier = CharField(max_length=50, null=True)
  274.  
  275. class Meta:
  276. indexes = ((('latitude', 'longitude'), False),)
  277.  
  278. @staticmethod
  279. def get_stops(swLat, swLng, neLat, neLng):
  280. if swLat is None or swLng is None or neLat is None or neLng is None:
  281. query = (Pokestop
  282. .select()
  283. .dicts())
  284. else:
  285. query = (Pokestop
  286. .select()
  287. .where((Pokestop.latitude >= swLat) &
  288. (Pokestop.longitude >= swLng) &
  289. (Pokestop.latitude <= neLat) &
  290. (Pokestop.longitude <= neLng))
  291. .dicts())
  292.  
  293. pokestops = []
  294. for p in query:
  295. if args.china:
  296. p['latitude'], p['longitude'] = \
  297. transform_from_wgs_to_gcj(p['latitude'], p['longitude'])
  298. pokestops.append(p)
  299.  
  300. return pokestops
  301.  
  302.  
  303. class Gym(BaseModel):
  304. UNCONTESTED = 0
  305. TEAM_MYSTIC = 1
  306. TEAM_VALOR = 2
  307. TEAM_INSTINCT = 3
  308.  
  309. gym_id = CharField(primary_key=True, max_length=50)
  310. team_id = IntegerField()
  311. guard_pokemon_id = IntegerField()
  312. gym_points = IntegerField()
  313. enabled = BooleanField()
  314. latitude = DoubleField()
  315. longitude = DoubleField()
  316. last_modified = DateTimeField(index=True)
  317.  
  318. class Meta:
  319. indexes = ((('latitude', 'longitude'), False),)
  320.  
  321. @staticmethod
  322. def get_gyms(swLat, swLng, neLat, neLng):
  323. if swLat is None or swLng is None or neLat is None or neLng is None:
  324. query = (Gym
  325. .select()
  326. .dicts())
  327. else:
  328. query = (Gym
  329. .select()
  330. .where((Gym.latitude >= swLat) &
  331. (Gym.longitude >= swLng) &
  332. (Gym.latitude <= neLat) &
  333. (Gym.longitude <= neLng))
  334. .dicts())
  335.  
  336. gyms = []
  337. for g in query:
  338. gyms.append(g)
  339.  
  340. return gyms
  341.  
  342.  
  343. class ScannedLocation(BaseModel):
  344. latitude = DoubleField()
  345. longitude = DoubleField()
  346. last_modified = DateTimeField(index=True)
  347.  
  348. class Meta:
  349. primary_key = CompositeKey('latitude', 'longitude')
  350.  
  351. @staticmethod
  352. def get_recent(swLat, swLng, neLat, neLng):
  353. query = (ScannedLocation
  354. .select()
  355. .where((ScannedLocation.last_modified >=
  356. (datetime.utcnow() - timedelta(minutes=15))) &
  357. (ScannedLocation.latitude >= swLat) &
  358. (ScannedLocation.longitude >= swLng) &
  359. (ScannedLocation.latitude <= neLat) &
  360. (ScannedLocation.longitude <= neLng))
  361. .dicts())
  362.  
  363. scans = []
  364. for s in query:
  365. scans.append(s)
  366.  
  367. return scans
  368.  
  369.  
  370. class Versions(flaskDb.Model):
  371. key = CharField()
  372. val = IntegerField()
  373.  
  374. class Meta:
  375. primary_key = False
  376.  
  377.  
  378. # todo: this probably shouldn't _really_ be in "models" anymore, but w/e
  379. def parse_map(args, map_dict, step_location, db_update_queue, wh_update_queue):
  380. pokemons = {}
  381. pokestops = {}
  382. gyms = {}
  383.  
  384. cells = map_dict['responses']['GET_MAP_OBJECTS']['map_cells']
  385. for cell in cells:
  386. if config['parse_pokemon']:
  387. for p in cell.get('wild_pokemons', []):
  388. # time_till_hidden_ms was overflowing causing a negative integer.
  389. # It was also returning a value above 3.6M ms.
  390. if 0 < p['time_till_hidden_ms'] < 3600000:
  391. d_t = datetime.utcfromtimestamp(
  392. (p['last_modified_timestamp_ms'] +
  393. p['time_till_hidden_ms']) / 1000.0)
  394. else:
  395. # Set a value of 15 minutes because currently its unknown but larger than 15.
  396. d_t = datetime.utcfromtimestamp((p['last_modified_timestamp_ms'] + 900000) / 1000.0)
  397.  
  398. printPokemon(p['pokemon_data']['pokemon_id'], p['latitude'],
  399. p['longitude'], d_t)
  400. pokemons[p['encounter_id']] = {
  401. 'encounter_id': b64encode(str(p['encounter_id'])),
  402. 'spawnpoint_id': p['spawn_point_id'],
  403. 'pokemon_id': p['pokemon_data']['pokemon_id'],
  404. 'latitude': p['latitude'],
  405. 'longitude': p['longitude'],
  406. 'disappear_time': d_t
  407. }
  408.  
  409. if args.webhooks:
  410. wh_update_queue.put(('pokemon', {
  411. 'encounter_id': b64encode(str(p['encounter_id'])),
  412. 'spawnpoint_id': p['spawn_point_id'],
  413. 'pokemon_id': p['pokemon_data']['pokemon_id'],
  414. 'latitude': p['latitude'],
  415. 'longitude': p['longitude'],
  416. 'disappear_time': calendar.timegm(d_t.timetuple()),
  417. 'last_modified_time': p['last_modified_timestamp_ms'],
  418. 'time_until_hidden_ms': p['time_till_hidden_ms']
  419. }))
  420.  
  421. for f in cell.get('forts', []):
  422. if config['parse_pokestops'] and f.get('type') == 1: # Pokestops
  423. if 'active_fort_modifier' in f:
  424. lure_expiration = datetime.utcfromtimestamp(
  425. f['last_modified_timestamp_ms'] / 1000.0) + timedelta(minutes=30)
  426. active_fort_modifier = f['active_fort_modifier']
  427. if args.webhooks and args.webhook_updates_only:
  428. wh_update_queue.put(('pokestop', {
  429. 'pokestop_id': b64encode(str(f['id'])),
  430. 'enabled': f['enabled'],
  431. 'latitude': f['latitude'],
  432. 'longitude': f['longitude'],
  433. 'last_modified_time': f['last_modified_timestamp_ms'],
  434. 'lure_expiration': calendar.timegm(lure_expiration.timetuple()),
  435. 'active_fort_modifier': active_fort_modifier
  436. }))
  437. else:
  438. lure_expiration, active_fort_modifier = None, None
  439.  
  440. pokestops[f['id']] = {
  441. 'pokestop_id': f['id'],
  442. 'enabled': f['enabled'],
  443. 'latitude': f['latitude'],
  444. 'longitude': f['longitude'],
  445. 'last_modified': datetime.utcfromtimestamp(
  446. f['last_modified_timestamp_ms'] / 1000.0),
  447. 'lure_expiration': lure_expiration,
  448. 'active_fort_modifier': active_fort_modifier
  449. }
  450.  
  451. # Send all pokéstops to webhooks
  452. if args.webhooks and not args.webhook_updates_only:
  453. # Explicitly set 'webhook_data', in case we want to change the information pushed to webhooks,
  454. # similar to above and previous commits.
  455. l_e = None
  456.  
  457. if lure_expiration is not None:
  458. l_e = calendar.timegm(lure_expiration.timetuple())
  459.  
  460. wh_update_queue.put(('pokestop', {
  461. 'pokestop_id': b64encode(str(f['id'])),
  462. 'enabled': f['enabled'],
  463. 'latitude': f['latitude'],
  464. 'longitude': f['longitude'],
  465. 'last_modified': calendar.timegm(pokestops[f['id']]['last_modified'].timetuple()),
  466. 'lure_expiration': l_e,
  467. 'active_fort_modifier': active_fort_modifier
  468. }))
  469.  
  470. elif config['parse_gyms'] and f.get('type') is None: # Currently, there are only stops and gyms
  471. gyms[f['id']] = {
  472. 'gym_id': f['id'],
  473. 'team_id': f.get('owned_by_team', 0),
  474. 'guard_pokemon_id': f.get('guard_pokemon_id', 0),
  475. 'gym_points': f.get('gym_points', 0),
  476. 'enabled': f['enabled'],
  477. 'latitude': f['latitude'],
  478. 'longitude': f['longitude'],
  479. 'last_modified': datetime.utcfromtimestamp(
  480. f['last_modified_timestamp_ms'] / 1000.0),
  481. }
  482.  
  483. # Send gyms to webhooks
  484. if args.webhooks and not args.webhook_updates_only:
  485. # Explicitly set 'webhook_data', in case we want to change the information pushed to webhooks,
  486. # similar to above and previous commits.
  487. wh_update_queue.put(('gym', {
  488. 'gym_id': b64encode(str(f['id'])),
  489. 'team_id': f.get('owned_by_team', 0),
  490. 'guard_pokemon_id': f.get('guard_pokemon_id', 0),
  491. 'gym_points': f.get('gym_points', 0),
  492. 'enabled': f['enabled'],
  493. 'latitude': f['latitude'],
  494. 'longitude': f['longitude'],
  495. 'last_modified': calendar.timegm(gyms[f['id']]['last_modified'].timetuple())
  496. }))
  497.  
  498. if len(pokemons):
  499. db_update_queue.put((Pokemon, pokemons))
  500. if len(pokestops):
  501. db_update_queue.put((Pokestop, pokestops))
  502. if len(gyms):
  503. db_update_queue.put((Gym, gyms))
  504.  
  505. log.info('Parsing found %d pokemons, %d pokestops, and %d gyms',
  506. len(pokemons),
  507. len(pokestops),
  508. len(gyms))
  509.  
  510. db_update_queue.put((ScannedLocation, {0: {
  511. 'latitude': step_location[0],
  512. 'longitude': step_location[1],
  513. 'last_modified': datetime.utcnow()
  514. }}))
  515.  
  516. return len(pokemons) + len(pokestops) + len(gyms)
  517.  
  518.  
  519. def db_updater(args, q):
  520. # The forever loop
  521. while True:
  522. try:
  523.  
  524. while True:
  525. try:
  526. flaskDb.connect_db()
  527. break
  528. except Exception as e:
  529. log.warning('%s... Retrying', e)
  530.  
  531. # Loop the queue
  532. while True:
  533. model, data = q.get()
  534. bulk_upsert(model, data)
  535. q.task_done()
  536. log.debug('Upserted to %s, %d records (upsert queue remaining: %d)',
  537. model.__name__,
  538. len(data),
  539. q.qsize())
  540. if q.qsize() > 50:
  541. log.warning("DB queue is > 50 (@%d); try increasing --db-threads", q.qsize())
  542.  
  543. except Exception as e:
  544. log.exception('Exception in db_updater: %s', e)
  545.  
  546.  
  547. def clean_db_loop(args):
  548. while True:
  549. try:
  550.  
  551. # Clean out old scanned locations
  552. query = (ScannedLocation
  553. .delete()
  554. .where((ScannedLocation.last_modified <
  555. (datetime.utcnow() - timedelta(minutes=30)))))
  556. query.execute()
  557.  
  558. # If desired, clear old pokemon spawns
  559. if args.purge_data > 0:
  560. query = (Pokemon
  561. .delete()
  562. .where((Pokemon.disappear_time <
  563. (datetime.utcnow() - timedelta(hours=args.purge_data)))))
  564.  
  565. log.info('Regular database cleaning complete')
  566. time.sleep(60)
  567. except Exception as e:
  568. log.exception('Exception in clean_db_loop: %s', e)
  569.  
  570.  
  571. def bulk_upsert(cls, data):
  572. num_rows = len(data.values())
  573. i = 0
  574. step = 120
  575.  
  576. while i < num_rows:
  577. log.debug('Inserting items %d to %d', i, min(i + step, num_rows))
  578. try:
  579. InsertQuery(cls, rows=data.values()[i:min(i + step, num_rows)]).upsert().execute()
  580. except Exception as e:
  581. log.warning('%s... Retrying', e)
  582. continue
  583.  
  584. i += step
  585.  
  586.  
  587. def create_tables(db):
  588. db.connect()
  589. verify_database_schema(db)
  590. db.create_tables([Pokemon, Pokestop, Gym, ScannedLocation], safe=True)
  591. db.close()
  592.  
  593.  
  594. def drop_tables(db):
  595. db.connect()
  596. db.drop_tables([Pokemon, Pokestop, Gym, ScannedLocation, Versions], safe=True)
  597. db.close()
  598.  
  599.  
  600. def verify_database_schema(db):
  601. if not Versions.table_exists():
  602. db.create_tables([Versions])
  603.  
  604. if ScannedLocation.table_exists():
  605. # Versions table didn't exist, but there were tables. This must mean the user
  606. # is coming from a database that existed before we started tracking the schema
  607. # version. Perform a full upgrade.
  608. InsertQuery(Versions, {Versions.key: 'schema_version', Versions.val: 0}).execute()
  609. database_migrate(db, 0)
  610. else:
  611. InsertQuery(Versions, {Versions.key: 'schema_version', Versions.val: db_schema_version}).execute()
  612.  
  613. else:
  614. db_ver = Versions.get(Versions.key == 'schema_version').val
  615.  
  616. if db_ver < db_schema_version:
  617. database_migrate(db, db_ver)
  618.  
  619. elif db_ver > db_schema_version:
  620. log.error("Your database version (%i) appears to be newer than the code supports (%i).",
  621. db_ver, db_schema_version)
  622. log.error("Please upgrade your code base or drop all tables in your database.")
  623. sys.exit(1)
  624.  
  625.  
  626. def database_migrate(db, old_ver):
  627. # Update database schema version
  628. Versions.update(val=db_schema_version).where(Versions.key == 'schema_version').execute()
  629.  
  630. log.info("Detected database version %i, updating to %i", old_ver, db_schema_version)
  631.  
  632. # Perform migrations here
  633. migrator = None
  634. if args.db_type == 'mysql':
  635. migrator = MySQLMigrator(db)
  636. else:
  637. migrator = SqliteMigrator(db)
  638.  
  639. # No longer necessary, we're doing this at schema 4 as well
  640. # if old_ver < 1:
  641. # db.drop_tables([ScannedLocation])
  642.  
  643. if old_ver < 2:
  644. migrate(migrator.add_column('pokestop', 'encounter_id', CharField(max_length=50, null=True)))
  645.  
  646. if old_ver < 3:
  647. migrate(
  648. migrator.add_column('pokestop', 'active_fort_modifier', CharField(max_length=50, null=True)),
  649. migrator.drop_column('pokestop', 'encounter_id'),
  650. migrator.drop_column('pokestop', 'active_pokemon_id')
  651. )
  652.  
  653. if old_ver < 4:
  654. db.drop_tables([ScannedLocation])
  655.  
  656. if old_ver < 5:
  657. # Some pokemon were added before the 595 bug was "fixed"
  658. # Clean those up for a better UX
  659. query = (Pokemon
  660. .delete()
  661. .where(Pokemon.disappear_time >
  662. (datetime.utcnow() - timedelta(hours=24))))
  663. query.execute()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement