Bladeren bron

Merge branch 'patch-01'

joostsijm 2 jaren geleden
bovenliggende
commit
1a84eeb830

File diff suppressed because it is too large
+ 526 - 285
Pipfile.lock


+ 25 - 7
README.md

@@ -25,6 +25,24 @@ If you are unsure middleware to use, then it is advised to implement LocalAuthen
 LocalAuthentication is used to login in directly into Rival Regions using supported login methods.
 When running into issues with login then I would appreciate if you could help me resolve the issue. 
 Available login methods: Google (supported), vk (may work, never tested), facebook (may work, never tested)
+
+r# Login methods
+Currently the working login methods are Google and VK.
+If you can help me out and make the other login methods working it would be appreciated. 
+
+login methods:
+
+- google [working]
+- vk [working]
+- facebook
+
+## Middleware
+The API wrapper uses middleware to decide where how to send the request.
+Middlewares can also be used to write direct requests to Rival Regions.
+
+Current middleware
+
+### LocalAuthentication
 Use username, password, and login method to log in local instance of the authenticator.
 
 RemoteAuthentication connects through a remote API using URL and authentication key.
@@ -68,9 +86,9 @@ from rival_regions_wrapper.middleware import LocalAuthentication
 
 authentication = LocalAuthentication()
 authentication.set_credentials(
-  os.environ["USERNAME"],
-  os.environ["PASSWORD"],
-  os.environ["LOGIN_METHOD"]
+  os.environ["RR_USERNAME"],
+  os.environ["RR_PASSWORD"],
+  os.environ["RR_LOGIN_METHOD"]
 )
 ```
 
@@ -107,9 +125,9 @@ Replace `PLACEHOLDER` with your credentials.
 
 Required environ variables:
 ```
-USERNAME=PLACEHOLDER
-PASSWORD=PLACEHOLDER
-LOGIN_METHOD=PLACEHOLDER
+RR_USERNAME=PLACEHOLDER
+RR_PASSWORD=PLACEHOLDER
+RR_LOGIN_METHOD=PLACEHOLDER
 ```
 
 There are several optional environ variables, as you can see here with some example value. 
@@ -126,7 +144,7 @@ PROFILE_ID=2000340574
 MESSAGE=test
 ```
 
-In case you want to use the anti-caption service you can fill in the key in `CAPTCHA_KEY`.
+In case you want to use the anti-captcha service you can fill in the key in `CAPTCHA_KEY`.
 Other variables are required to run test that are skipped by default.
 These test are skipped because the test sends out a request that makes change to Rival Regions, like sending messages, or crafting items.
 You can run those these test by changing the appropiate environ variable and adding the `--no-skip` parameter.

+ 115 - 0
src/rival_regions_wrapper/api_wrapper/work.py

@@ -0,0 +1,115 @@
+"""Work class"""
+
+import re
+
+from bs4 import BeautifulSoup
+
+RESOURCE_DICT = {
+    'oil': 'oil',
+    'ore': 'ore',
+    'yellow': 'gold',
+    'uranium': 'uranium',
+    'diamond': 'diamond'
+}
+
+
+class Work():
+    """Wrapper class for work"""
+    def __init__(self, api_wrapper):
+        self.api_wrapper = api_wrapper
+
+    def switch_factory(self, factory_id):
+        """Switch factory based on factory_id"""
+        response = self.api_wrapper.post('factory/assign',
+                                         data={'factory': factory_id})
+        return response
+
+    def work(self, amount=1, mentor=0):
+        pass
+
+        # TODO GET THE ORDER OF ALL FACTORY TYPES
+        # TODO ASSUME GOLD WILL BE ONLY WEIRD TYPE
+
+        """Work at given factory ID. Amount needs to be energy / 10."""
+        response = self.api_wrapper.post(f'factory/go/{amount}/{mentor}/')
+        soup = BeautifulSoup(response, 'html.parser')
+
+        self.api_wrapper.authentication.client.LOGGER.info(str([i.replace('\t','') for i in soup.stripped_strings]))
+
+        # GOLD MINE OUTPUT
+        #  ['IndX GOLD', '▶', 'Gold mine', '—10 E (+9)', 'Working experience: +1 Pt.',
+        #  '0 $', 'Exp: +20', 'Total: 6900420', 'Taxes: +0 $ (10%)', 'Total: 5.657.542.880.418 $',
+        #  'Work again', 'Auto']
+
+        # OIL MINE OUTPUT 0% WAGE
+        # ['IndX Oil', '▶', 'Oil field', '—10 E (+9)', 'Working experience: +1 Pt.', 'Exp: +20',
+        # 'Total: 120660', '+714.962 bbl', 'Taxes: +0 $ (10%)', 'Total: 5.591.261.983.800 $', '+79.440 bbl (10%)',
+        # 'Total: 8.716.264.048', 'Work again', 'Auto']
+
+        # Current order - Need more research
+        # [factory name, hymn symbol, factory type, energy used (+9? what's this?), working experience gained, xp gain,
+        # total you have, # total factory gains?, taxes, total region has, total region gains resource, total region has
+        # of the resource, work again and auto work buttons]
+
+    def page(self):
+        """Get work page"""
+        path = 'work'
+        response = self.api_wrapper.get(path)
+        soup = BeautifulSoup(response, 'html.parser')
+
+        factory = soup.select_one('.work_item:nth-child(9)')
+        factory_slide = factory.select_one('.factory_slide')
+        factory_dict = {
+            'id': int(factory_slide['action'].replace('factory/index/', '')),
+            'name': factory_slide.text
+        }
+        factory_owner = factory.select_one('.factory_whose')
+        if factory_owner:
+            factory_dict['owner_name'] = factory_owner.text
+            factory_dict['owner_id'] = factory_owner['action'].replace(
+                    'slide/profile/', ''
+                )
+
+        level_str = re.search(
+                r'level\s\d+', factory.select_one('.work_source_1').text
+            )
+        if level_str:
+            factory_dict['level'] = int(re.sub(
+                r'level\s', '', level_str.group(0)
+            ))
+
+        string_list = []
+        factory_button = soup.select_one(
+                    '.work_factory_button'
+                )
+        if factory_button:
+            for string in factory_button.strings:
+                string_list.append(string.strip())
+            try:
+                wage = string_list[2]
+                if '%' in wage:
+                    factory_dict['wage_type'] = 'procentage'
+                    factory_dict['wage'] = float(wage.replace(' %', ''))
+            except IndexError:
+                pass
+
+        work_page = {
+            'factory': factory_dict,
+            'work_exp': {},
+            'resources_left': {},
+        }
+
+        for resource_left in soup.select('span.imp.tip'):
+            classses = resource_left.get('class')
+            for class_name, resource_name in RESOURCE_DICT.items():
+                if class_name in classses:
+                    work_page['resources_left'][resource_name] = \
+                        float(resource_left.text)
+                    break
+
+        for work_exp in soup.select('.work_exp'):
+            work_exp_amount = int(re.sub(
+                    r'exp: | Pt\.', '', work_exp.text.strip()
+                ))
+            work_page['work_exp'][work_exp['url']] = work_exp_amount
+        return work_page

+ 8 - 5
src/rival_regions_wrapper/authentication_handler.py

@@ -30,16 +30,19 @@ LOGIN_METHOD_DICT = {
 class AuthenticationHandler:
     """class for RR client"""
 
-    def __init__(self, show_window=False, captcha_key=None, debug=False):
+    def __init__(self, show_window=False, captcha_key=None, debug=False, new_cookie=False):
         LOGGER.info(
-                'Initialize, show window: "%s", captcha key: "%s", debug: %s',
-                show_window, bool(captcha_key), debug
+                'Initialize, show window: "%s", captcha key: "%s",'
+                'debug: %s, new_cookie: %s',
+                show_window, bool(captcha_key), debug, new_cookie
             )
         self.show_window = show_window
         self.captcha_client = None
         if captcha_key:
             self.captcha_client = AnticaptchaClient(captcha_key)
         self.debug = debug
+        self.new_cookie = new_cookie
+
         self.login_method = None
         self.username = None
         self.password = None
@@ -62,9 +65,9 @@ class AuthenticationHandler:
         """Login user if needed"""
         LOGGER.info('"%s": start authentication', self.username)
         cookies = CookieHandler.get_cookies(self.username)
-        if not cookies:
+        if not cookies or self.new_cookie:
             LOGGER.info(
-                '"%s": No (valid) cookie found, start new login',
+                '"%s": No (valid) cookie found or cookie requested, start new login',
                 self.username,
             )
             cookies = self.login()

+ 0 - 1
src/rival_regions_wrapper/browser.py

@@ -76,7 +76,6 @@ class Browser(webbot.Browser):
             "start_client",
             "start_session",
             "stop_client",
-            "switch_to_alert",
         ]:
             setattr(self, function, getattr(self.driver, function))
 

+ 2 - 2
src/rival_regions_wrapper/middleware.py

@@ -25,10 +25,10 @@ class MiddlewareBase(ABC):
 class LocalAuthentication(MiddlewareBase):
     """Local authentication"""
 
-    def __init__(self, show_window=False, captcha_client=None, debug=False):
+    def __init__(self, show_window=False, captcha_client=None, debug=False, new_cookie=False):
         super().__init__()
         self.authentication_handler = AuthenticationHandler(
-            show_window, captcha_client, debug
+            show_window, captcha_client, debug, new_cookie
         )
 
     def set_credentials(self, username, password, login_method):

+ 4 - 4
tests/conftest.py

@@ -146,9 +146,9 @@ def profile_id():
 @pytest.fixture(scope="module")
 def middleware():
     """Set up wrapper before test"""
-    username = os.environ.get('USERNAME', None)
-    password = os.environ.get('PASSWORD', None)
-    login_method = os.environ.get('LOGIN_METHOD', None)
+    username = os.environ.get('RR_USERNAME', None)
+    password = os.environ.get('RR_PASSWORD', None)
+    login_method = os.environ.get('RR_LOGIN_METHOD', None)
     debug = os.environ.get('DEBUG', None)
     captcha_key = os.environ.get('CAPTCHA_KEY', None)
     if None in (username, password, login_method):
@@ -157,7 +157,7 @@ def middleware():
             'USERNAME, PASSWORD, LOGIN_METHOD'
         )
     _middleware = LocalAuthentication(
-            False, AnticaptchaClient(captcha_key), debug
+            False, AnticaptchaClient(captcha_key), debug, True
         )
     return _middleware.set_credentials(
             username, password, login_method

+ 20 - 0
tests/test_rival_regions_wrapper.py

@@ -359,6 +359,26 @@ def test_work_info(middleware):
     assert isinstance(response['work_exp'], dict), "Work exp should be a dict"
 
 
+@pytest.mark.skip(reason = 'In progress')
+def test_work_do_work(middleware):
+    response = Work(middleware).work()
+    if not response:
+        assert isinstance(response ,bool), "Should be False if can't work"
+    else:
+        assert isinstance(response['factory'], str), "The factory should be a string with name"
+        assert isinstance(response['factory_type'], str), "The factory type should be a string of factory type"
+        assert isinstance(response['income'][0], int), "The income first index should be a integer"
+        assert isinstance(response['income'][1], str), "The income second index should be a string of units"
+
+
+@pytest.mark.skip(reason = 'In progress')
+@pytest.mark.vcr()
+def test_switch_factory(middleware):
+    response = Work(middleware).switch_factory('00000000')
+    # TODO make better tests here
+    assert isinstance(response, str), "The response should be a string 'will be 'ok' if switch successful'"
+
+
 @pytest.fixture
 def article_keys():
     """Standard key fro article"""

Some files were not shown because too many files changed in this diff