database.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. """Main application"""
  2. from datetime import datetime, timedelta, timezone
  3. from sqlalchemy.orm import joinedload
  4. from app import SESSION, RESOURCE_MAX
  5. from app.models import ResourceTrack, ResourceStat, Region
  6. def save_resources(state_id, regions, resource_id):
  7. """Save resources to database"""
  8. session = SESSION()
  9. resource_track = ResourceTrack()
  10. resource_track.state_id = state_id
  11. resource_track.resource_type = resource_id
  12. resource_track.date_time = datetime.now()
  13. session.add(resource_track)
  14. session.commit()
  15. for region_id, region_dict in regions.items():
  16. region = session.query(Region).get(region_id)
  17. if not region:
  18. region = save_region(session, region_id, region_dict)
  19. resource_stat = ResourceStat()
  20. resource_stat.resource_track_id = resource_track.id
  21. resource_stat.region_id = region.id
  22. resource_stat.explored = region_dict['explored']
  23. resource_stat.deep_exploration = region_dict['deep_exploration']
  24. resource_stat.limit_left = region_dict['limit_left']
  25. session.add(resource_stat)
  26. session.commit()
  27. session.close()
  28. def save_region(session, region_id, region_dict):
  29. """Save player to database"""
  30. region = Region()
  31. region.id = region_id
  32. region.name = region_dict['region_name']
  33. session.add(region)
  34. return region
  35. def get_resources(region_id, date, resource_type):
  36. """Get resources on a date"""
  37. end_date_time = date.replace(hour=19, minute=0, second=0, microsecond=0)
  38. start_date_time = end_date_time - timedelta(1)
  39. session = SESSION()
  40. resource = {}
  41. resource_stats = session.query(ResourceStat) \
  42. .options(joinedload(ResourceStat.resource_track)) \
  43. .join(ResourceStat.resource_track) \
  44. .filter(ResourceStat.region_id == region_id) \
  45. .filter(ResourceTrack.resource_type == resource_type) \
  46. .filter(ResourceTrack.date_time >= start_date_time) \
  47. .filter(ResourceTrack.date_time <= end_date_time) \
  48. .order_by(ResourceTrack.date_time.desc()) \
  49. .all()
  50. start_limit = resource_stats[0].explored
  51. for resource_stat in resource_stats:
  52. time = resource_stat.resource_track.date_time
  53. resource[time] = resource_stat.explored + resource_stat.limit_left
  54. session.close()
  55. new_resource = {}
  56. for time, amount in resource.items():
  57. new_time = time.replace(tzinfo=timezone.utc).astimezone(tz=None) + timedelta(hours=1)
  58. new_resource[new_time] = amount - start_limit
  59. return new_resource
  60. def _get_state_stat(session, state_id, resource_type, date_time, deep_exploration):
  61. """Get state stats from date"""
  62. ten_minutes = timedelta(minutes=10)
  63. query = session.query(ResourceStat) \
  64. .options(joinedload(ResourceStat.resource_track), joinedload(ResourceStat.region)) \
  65. .join(ResourceStat.resource_track) \
  66. .filter(ResourceTrack.state_id == state_id) \
  67. .filter(ResourceTrack.resource_type == resource_type) \
  68. .filter(ResourceTrack.date_time >= date_time - ten_minutes) \
  69. .filter(ResourceTrack.date_time <= date_time + ten_minutes) \
  70. .filter(ResourceTrack.date_time <= date_time + ten_minutes)
  71. if deep_exploration:
  72. query = query.filter(ResourceStat.deep_exploration > 0)
  73. stats = query.all()
  74. stats_dict = {}
  75. for stat in stats:
  76. stats_dict[stat.region_id] = stat
  77. return stats_dict
  78. def get_work_percentage(state_id, resource_type, end_date_time, hours, times):
  79. """Get work percentage for state in last x hours"""
  80. end_date_time = end_date_time.replace(minute=0, second=0, microsecond=0)
  81. deep = bool(resource_type)
  82. session = SESSION()
  83. data = {
  84. 0: {
  85. 'date': end_date_time,
  86. 'stats': _get_state_stat(session, state_id, resource_type, end_date_time, deep)
  87. }
  88. }
  89. for i in range(times, 0, -1):
  90. current_date_time = end_date_time - timedelta(hours=hours*i)
  91. data[i] = {
  92. 'date': current_date_time,
  93. 'stats': _get_state_stat(session, state_id, resource_type, current_date_time, deep)
  94. }
  95. session.close()
  96. regions = {}
  97. for region_id, stat in data[0]['stats'].items():
  98. regions[region_id] = stat.region.name
  99. for i in range(0, times):
  100. data[i]['progress'] = {}
  101. reset_date_time = data[i+1]['date']
  102. if reset_date_time.hour >= 19:
  103. reset_date_time = reset_date_time + timedelta(1)
  104. reset_date_time = reset_date_time.replace(hour=19)
  105. time_left = reset_date_time - data[i]['date']
  106. if time_left.seconds != 0:
  107. seconds_left = time_left.seconds
  108. else:
  109. seconds_left = 86400
  110. for region_id, stat in data[i]['stats'].items():
  111. if i+1 not in data or stat.region_id not in data[i+1]['stats']:
  112. continue
  113. next_stat = data[i+1]['stats'][stat.region_id]
  114. if seconds_left == 82800:
  115. mined = RESOURCE_MAX[resource_type] + next_stat.explored - stat.total()
  116. required = next_stat.total() / (seconds_left / (hours * 3600))
  117. else:
  118. mined = next_stat.total() - stat.total()
  119. required = next_stat.total() / (seconds_left / (hours * 3600))
  120. if required != 0:
  121. coefficient = 100 / RESOURCE_MAX[resource_type]
  122. percentage = (mined / required - 1) * next_stat.total() * coefficient + 100
  123. else:
  124. percentage = 100
  125. data[i]['progress'][stat.region_id] = percentage
  126. # print('{:4} left: {:3} mined: {:3} required: {:6.2f} percentage: {:6.2f}'.format(
  127. # stat.region_id, next_stat.total(), mined, required, percentage
  128. # ))
  129. message_text = ''
  130. message_text += '{:17}: {:>8}\n'.format('region', 'workers')
  131. for date in data.values():
  132. if 'progress' in date:
  133. for region_id, progress in sorted(date['progress'].items(), key=lambda x: x[1]):
  134. message_text += '{:17}: {:6.2f} %\n'.format(
  135. regions[region_id].replace('Netherlands', 'NL'),
  136. progress
  137. )
  138. return message_text