Bläddra i källkod

First working iteration

JoostSijm 5 år sedan
förälder
incheckning
c3bf0de192
7 ändrade filer med 180 tillägg och 133 borttagningar
  1. 8 0
      app/__init__.py
  2. 3 15
      app/__main__.py
  3. 33 26
      app/api.py
  4. 59 88
      app/app.py
  5. 41 2
      app/database.py
  6. 10 2
      app/jobs.py
  7. 26 0
      app/models.py

+ 8 - 0
app/__init__.py

@@ -74,6 +74,14 @@ RESOURCE_NAMES = {
     'diamonds': 15,
 }
 
+DEEP_EXPLORATION_MAX = {
+    0: 637,
+    3: 371,
+    4: 356,
+    11: 25,
+    15: 27,
+}
+
 RESOURCE_MAX = {
     0: 2500,
     3: 600,

+ 3 - 15
app/__main__.py

@@ -7,12 +7,11 @@ from app import SCHEDULER, LOGGER, RESOURCE_NAMES, jobs
 
 
 if __name__ == '__main__':
-    jobs.check_deep_exploration(4002)
+    # jobs.start_orders()
+    # jobs.sync_deep_exploration(4002)
+    jobs.start_deep_exploration(1)
     sys.exit()
 
-    add_telegram_update_job(2788, '@vn_resources', 'gold')
-    add_telegram_update_job(2788, '@vn_uranium_resources', 'uranium')
-
     try:
         while True:
             time.sleep(100)
@@ -20,14 +19,3 @@ if __name__ == '__main__':
         LOGGER.info('Exiting application')
         SCHEDULER.shutdown()
         sys.exit()
-
-def add_telegram_update_job(state_id, telegram_id, resource_type):
-    """Add telegram update job"""
-    SCHEDULER.add_job(
-        jobs.send_telegram_update,
-        'cron',
-        args=[state_id, telegram_id, resource_type],
-        id='{}_send_telegram_update_{}'.format(state_id, resource_type),
-        replace_existing=True,
-        minute='5'
-    )

+ 33 - 26
app/api.py

@@ -38,35 +38,42 @@ def parse_deep_explorations(html):
         }
     return deep_explorations
 
-def deep_explorate(state_id, capital_id, deep_exploration_id, amount, alt):
+def deep_explorate(state_id, capital_id, resource_type, amount, alt):
     """Main function"""
-    # Check location
-    # response = requests.get(
-    #     '{}main/content'.format(BASE_URL),
-    #     headers=HEADERS
-    # )
-    # soup = BeautifulSoup(response.text, 'html.parser')
-    # state_div = soup.find_all('div', {'class': 'index_case_50'})[1]
-    # action = state_div.findChild()['action']
-    # current_state_id = int(re.sub('.*/', '', action))
-    # LOGGER.info('Current state %s', current_state_id)
-
+    response = requests.get(
+        '{}main/content'.format(BASE_URL),
+        headers=HEADERS
+    )
+    soup = BeautifulSoup(response.text, 'html.parser')
+    state_div = soup.find_all('div', {'class': 'index_case_50'})[1]
+    action = state_div.findChild()['action']
+    current_state_id = int(re.sub('.*/', '', action))
+    LOGGER.info('Current state %s', current_state_id)
     params = {}
-    # if current_state_id != state_id:
-    #     params['alt'] = True
-    if alt:
-        params['alt'] = True
+    if current_state_id != state_id:
+        LOGGER.info(
+            'Not in the correct state, %s instead of %s', 
+            current_state_id, state_id
+        )
+    else:
+        params = {}
+        # if current_state_id != state_id:
+        #     params['alt'] = True
+        if alt:
+            params['alt'] = True
 
-    json_data = {
-        'tmp_gov': '{}_{}'.format(deep_exploration_id, amount)
-    }
+        json_data = {
+            'tmp_gov': '{}_{}'.format(resource_type, amount)
+        }
 
-    requests.post(
-        '{}parliament/donew/34/{}_{}/{}'.format(BASE_URL, deep_exploration_id, amount, capital_id),
-        headers=HEADERS,
-        params=params,
-        json=json_data
-    )
+        requests.post(
+            '{}parliament/donew/34/{}_{}/{}'.format(
+                BASE_URL, resource_type, amount, capital_id
+            ),
+            headers=HEADERS,
+            params=params,
+            json=json_data
+        )
 
     response = requests.get(
         '{}parliament/index/{}'.format(BASE_URL, capital_id),
@@ -74,7 +81,7 @@ def deep_explorate(state_id, capital_id, deep_exploration_id, amount, alt):
     )
     soup = BeautifulSoup(response.text, 'html.parser')
     active_laws = soup.find('div', {'id': 'parliament_active_laws'})
-    deep_exploration_name = RESOURCE_IDS[deep_exploration_id]
+    deep_exploration_name = RESOURCE_IDS[resource_type]
     exploration_laws = active_laws.findAll(text='Deep exploration,')
     LOGGER.info('Resources exploration: state, %s deep_explorations', deep_exploration_name)
     for exploration_law in exploration_laws:

+ 59 - 88
app/app.py

@@ -3,103 +3,74 @@
 import random
 from datetime import datetime, timedelta
 
-from telegram import ParseMode
+from app import LOGGER, SCHEDULER, RESOURCE_IDS, DEEP_EXPLORATION_MAX , jobs, api, database
 
-from app import LOGGER, SCHEDULER, TELEGRAM_BOT, RESOURCE_NAMES, jobs, api, database
 
-
-def check_deep_exploration(region_id):
+def sync_deep_exploration(region_id):
     """Check resources and refill if necessary"""
     deep_explorations = api.download_deep_explorations(region_id)
     database.save_deep_explorations(region_id, deep_explorations)
-    deep_exploration = database.get_active_deep_exploration(region_id)
-    print(deep_exploration)
-    return
-    if do_refill and need_refill(regions, refill_percentage):
-        max_seconds = max_refill_seconds(regions, refill_percentage, 900)
+
+def start_orders():
+    """start deep exploration orders"""
+    orders = database.get_orders()
+    for order in orders:
+        deep_exploration = database.get_active_deep_exploration(order.region_id)
+        if deep_exploration is None:
+            sync_deep_exploration(order.region_id)
+        deep_exploration = database.get_active_deep_exploration(order.region_id)
+        start_date = deep_exploration.until_date_time if deep_exploration else datetime.now()
+        max_seconds = 300
         random_seconds = random.randint(0, max_seconds)
-        random_time_delta = timedelta(seconds=random_seconds)
-        scheduled_date = datetime.now() + random_time_delta
-        job_id = 'refill_{}_{}'.format(capital_id, resource_id)
+        scheduled_date = start_date + timedelta(seconds=random_seconds)
         LOGGER.info(
-            'Refil resource %s at %s (%s minutes)',
-            resource_id,
-            scheduled_date,
-            round(random_time_delta.seconds / 60)
+            'Deep exploration at %s for %s in %s',
+            scheduled_date.strftime("%Y-%m-%d %H:%M"),
+            RESOURCE_IDS[order.resource_type],
+            order.region_id
+        )
+        SCHEDULER.add_job(
+            jobs.start_deep_exploration,
+            'date',
+            args=[order.id],
+            id='deep_exploration_{}_{}'.format(order.region_id, order.resource_type),
+            replace_existing=True,
+            run_date=scheduled_date
         )
-        job = SCHEDULER.get_job(job_id)
-        if not job:
-            SCHEDULER.add_job(
-                jobs.refill_resource,
-                'date',
-                args=[state_id, capital_id, resource_id, alt],
-                id=job_id,
-                run_date=scheduled_date
-            )
 
-def print_resources(regions):
-    """print resources"""
-    if regions:
-        print('region                        expl max   D left    c %    t %')
-        for region in regions.values():
-            region['explored_percentage'] = 100 / region['maximum'] * region['explored']
-            region['total_left'] = region['explored'] + region['limit_left']
-            region['total_percentage'] = 100 / 2500 * region['total_left']
-            print('{:25}: {:7.2f}{:4}{:4}{:5}{:7.2f}{:7.2f}'.format(
-                region['region_name'],
-                region['explored'],
-                region['maximum'],
-                region['deep_exploration'],
-                region['limit_left'],
-                region['explored_percentage'],
-                region['total_percentage'],
-            ))
-    else:
-        LOGGER.error('no region to print data')
+def start_deep_exploration(order_id):
+    """Start deep exploration"""
+    LOGGER.info('Start order %s', order_id)
+    order = database.get_order(order_id)
+    order_types = {
+        0: get_max_points, # max
+        1: get_fixed_points, # fixed
+        2: get_percentage_points, # percentage
+        3: get_auto_points, # auto
+    }
+    if order.order_type in order_types:
+        points = order_types[order.order_type](order)
+        print(points)
+        state = database.get_state(order.region_id)
+        api.deep_explorate(
+            state.id, order.region_id, order.resource_type, points, False
+        )
 
-def need_refill(regions, limit):
-    """Check if refill is needed"""
-    for region in regions.values():
-        percentage = 100 / region['maximum'] * region['explored']
-        if percentage < limit and region['limit_left']:
-            return True
-    return False
 
-def max_refill_seconds(regions, limit, max_time):
-    """Give random seconds for next refill"""
-    lowest_percentage = limit
-    for region in regions.values():
-        percentage = 100 / region['maximum'] * region['explored']
-        if percentage < lowest_percentage:
-            lowest_percentage = percentage
-    return int(max_time / limit * lowest_percentage)
+def get_max_points(order):
+    """Get  deep exploration points for order"""
+    region = database.get_region(order.region_id)
+    resource_limit = region.get_limit(order.resource_type)
+    return DEEP_EXPLORATION_MAX[order.resource_type] - resource_limit
 
-def send_telegram_update(state_id, group_id, resource_name):
-    """Send resource update to telegram"""
-    resource_id = RESOURCE_NAMES[resource_name]
-    # date = datetime.now()
-    date = datetime.today().replace(hour=18, minute=5) - timedelta(1)
-    print(date)
-    message = database.get_work_percentage(state_id, resource_id, date, 1, 1)
-    date = datetime.today().replace(hour=19, minute=5) - timedelta(1)
-    print(date)
-    message = database.get_work_percentage(state_id, resource_id, date, 1, 1)
-    date = datetime.today().replace(hour=20, minute=5) - timedelta(1)
-    print(date)
-    message = database.get_work_percentage(state_id, resource_id, date, 1, 1)
-    date = datetime.today().replace(hour=21, minute=5) - timedelta(1)
-    print(date)
-    message = database.get_work_percentage(state_id, resource_id, date, 1, 1)
-    date = datetime.today().replace(hour=22, minute=5) - timedelta(1)
-    print(date)
-    message = database.get_work_percentage(state_id, resource_id, date, 1, 1)
-    return
-    if message:
-        print(message)
-        TELEGRAM_BOT.sendMessage(
-            chat_id=group_id,
-            text='```\n{}```'.format(message),
-            parse_mode=ParseMode.MARKDOWN
-        )
-    else:
-        LOGGER.error('no data for Telegram message')
+def get_fixed_points(order):
+    """Get  deep exploration points for order"""
+    return order.amount
+    
+def get_percentage_points(order):
+    """Get  deep exploration points for order"""
+    return 1
+    
+def get_auto_points(order):
+    """Get  deep exploration points for order"""
+    return 1

+ 41 - 2
app/database.py

@@ -2,10 +2,10 @@
 
 from datetime import datetime, timedelta, timezone
 
-from sqlalchemy.orm import joinedload
+from sqlalchemy import or_
 
 from app import SESSION, RESOURCE_MAX
-from app.models import Region, DeepExploration
+from app.models import State, Region, DeepExploration, DeepExplorationOrder, StateRegion
 
 
 def save_deep_explorations(region_id, deep_explorations):
@@ -45,3 +45,42 @@ def save_region(session, region_id):
     region.name = 'UNKNOWN'
     session.add(region)
     return region
+
+def get_orders():
+    """Get deep exploration orders"""
+    session = SESSION()
+    date_time_now = datetime.now()
+    orders = session.query(DeepExplorationOrder) \
+        .filter(DeepExplorationOrder.from_date_time <= date_time_now) \
+        .filter(or_(
+            DeepExplorationOrder.until_date_time >= date_time_now,
+            DeepExplorationOrder.until_date_time == None
+        )) \
+        .all()
+    session.close()
+    return orders
+
+def get_order(order_id):
+    """Get order by id"""
+    session = SESSION()
+    order = session.query(DeepExplorationOrder).get(order_id)
+    session.close()
+    return order
+
+def get_region(region_id):
+    """Get region by id"""
+    session = SESSION()
+    region = session.query(Region).get(region_id)
+    session.close()
+    return region
+
+def get_state(region_id):
+    """Get state from region"""
+    session = SESSION()
+    state = session.query(State) \
+        .join(State.state_regions) \
+        .filter(StateRegion.region_id == region_id) \
+        .filter(StateRegion.until_date_time == None) \
+        .first()
+    session.close()
+    return state

+ 10 - 2
app/jobs.py

@@ -3,6 +3,14 @@
 from app import app, api
 
 
-def check_deep_exploration(region_id):
+def sync_deep_exploration(region_id):
     """Check resources and refill if necessary"""
-    app.check_deep_exploration(region_id)
+    app.sync_deep_exploration(region_id)
+
+def start_orders():
+    """Start deep exploration orders"""
+    app.start_orders()
+
+def start_deep_exploration(order_id):
+    """Start deep exploration"""
+    app.start_deep_exploration(order_id)

+ 26 - 0
app/models.py

@@ -26,6 +26,17 @@ class Region(Base):
     uranium_limit = Column(SmallInteger)
     diamond_limit = Column(SmallInteger)
 
+    def get_limit(self, resource_type):
+        """get limit for resoruce type"""
+        limit = {
+            0: self.gold_limit,
+            3: self.oil_limit,
+            4: self.ore_limit,
+            11: self.uranium_limit,
+            15: self.diamond_limit,
+        }
+        return limit[resource_type] if resource_type in limit else None
+
 
 class StateRegion(Base):
     """Model for state region"""
@@ -35,6 +46,15 @@ class StateRegion(Base):
     from_date_time = Column(DateTime, primary_key=True)
     until_date_time = Column(DateTime)
 
+    region = relationship(
+        'Region',
+        backref=backref('state_regions', lazy='dynamic')
+    )
+    state = relationship(
+        'State',
+        backref=backref('state_regions', lazy='dynamic')
+    )
+
 
 class DeepExploration(Base):
     """Model for deep exploration"""
@@ -60,6 +80,12 @@ class DeepExplorationOrder(Base):
     from_date_time = Column(DateTime)
     until_date_time = Column(DateTime)
 
+    region_id = Column(Integer, ForeignKey('region.id'))
+    region = relationship(
+        'Region',
+        backref=backref('resource_stats', lazy='dynamic')
+    )
+
     order_types = {
         0: 'max',
         1: 'fixed',