Browse Source

Rewrite parts of the application, missing docs

JoostSijm 3 years ago
parent
commit
3355efa681

+ 1 - 1
README.md

@@ -76,7 +76,7 @@ region = authentication.get('listed/upgrades/{}'.format(region_id))
 
 Example of API wrapper to get oil current available resources from a state
 ```python
-from rival_regions_wrapper.api_wrapper import ResourceState
+from rival_regions_wrapper.wrapper import ResourceState
 
 state = 3382
 resource = 'oil'

+ 2 - 2
src/rival_regions_wrapper/__init__.py

@@ -28,10 +28,10 @@ STREAM_HANDLER = logging.StreamHandler()
 STREAM_HANDLER.setLevel(logging.INFO)
 
 # create formatter and add it to the handlers
-STREAM_FORMATTER = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
+STREAM_FORMATTER = logging.Formatter('%(name)s - %(module)s - %(levelname)s - %(message)s')
 STREAM_HANDLER.setFormatter(STREAM_FORMATTER)
 FILE_FORMATTER = logging \
-        .Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+        .Formatter('%(asctime)s - %(name)s - %(module)s - %(levelname)s - %(message)s')
 FILE_HANDLER.setFormatter(FILE_FORMATTER)
 
 # add the handlers to logger

+ 224 - 0
src/rival_regions_wrapper/api.py

@@ -0,0 +1,224 @@
+"""
+Rival Regions API methods
+"""
+
+import time
+
+from rival_regions_wrapper import LOGGER
+from rival_regions_wrapper.cookie_handler import CookieHandler
+from rival_regions_wrapper.exceptions import SessionExpireException, \
+        NoLogginException
+
+
+def session_handler(func):
+    """Handle expired sessions"""
+    def wrapper(*args, **kwargs):
+        instance = args[0]
+        return try_run(instance, func, *args, **kwargs)
+
+    def try_run(instance, func, *args, **kwargs):
+        try:
+            return func(*args, **kwargs)
+        except (SessionExpireException, ConnectionError, ConnectionResetError):
+            CookieHandler.remove_cookie(instance.username)
+            instance.login()
+            return try_run(instance, func, *args, **kwargs)
+        except NoLogginException:
+            instance.login()
+            return try_run(instance, func, *args, **kwargs)
+    return wrapper
+
+def check_response(response):
+    """Check resonse for authentication"""
+    if not isinstance(response, str):
+        response = response.text
+    if "Session expired, please, reload the page" in response or \
+            'window.location="https://rivalregions.com";' in response:
+        raise SessionExpireException()
+
+@session_handler
+def get(middleware, path, add_var_c=False):
+    """Send get request to Rival Regions"""
+    if path[0] == '/':
+        path = path[1:]
+
+    params = {}
+    if add_var_c:
+        params['c'] = middleware.authentication_handler.var_c
+
+    LOGGER.info(
+            '"%s": GET: "%s" var_c: %s', middleware.username, path, add_var_c
+        )
+    if middleware.authentication_handler.session:
+        response = middleware.authentication_handler.session.get(
+            url='https://rivalregions.com/{}'.format(path),
+            params=params
+        )
+        check_response(response)
+    else:
+        raise NoLogginException()
+    return response.text
+
+@session_handler
+def post(middleware, path, data=None):
+    """Send post request to Rival Regions"""
+    if path[0] == '/':
+        path = path[1:]
+    if not data:
+        data = {}
+    data['c'] = middleware.authentication_handler.var_c
+
+    LOGGER.info('"%s": POST: "%s"', middleware.username, path)
+    if middleware.authentication_handler.session:
+        response = middleware.authentication_handler.session.post(
+            "https://rivalregions.com/{}".format(path),
+            data=data
+        )
+        check_response(response)
+    else:
+        raise NoLogginException()
+    return response.text
+
+@session_handler
+def conference_message(middleware, conference_id, message):
+    """Send conference message"""
+    browser = middleware.authentication_handler.get_browser()
+    try:
+        browser.go_to('https://rivalregions.com/#slide/conference/{}'
+                .format(conference_id)
+            )
+        browser.refresh()
+        time.sleep(2)
+
+        character_count = 0
+        tmp_messages = []
+        for sentence in message.split('\n'):
+            sentence_character_count = 0
+            tmp_sentence = []
+            for word in sentence.split(' '):
+                sentence_character_count += len(word) + 1
+                if sentence_character_count >= 899:
+                    message = '{}\n{}'.format('\n'.join(
+                            tmp_messages),
+                            ' '.join(tmp_sentence)
+                        )
+                    LOGGER.info('"%s": CONF "%s": next message length: %s',
+                            middleware.username, conference_id, len(message)
+                        )
+                    browser.type(message, id='message')
+                    browser.click(id='chat_send')
+                    sentence_character_count = 0
+                    tmp_sentence = []
+                    character_count = 0
+                    tmp_messages = []
+                tmp_sentence.append(word)
+
+            sentence = ' '.join(tmp_sentence)
+            character_count += len(sentence) + 1
+            if character_count >= 900:
+                message = '\n'.join(tmp_messages)
+                LOGGER.info('"%s": CONF "%s": next message length: %s',
+                        middleware.username, conference_id, len(message)
+                    )
+                browser.type(message, id='message')
+                browser.click(id='chat_send')
+                character_count = 0
+                tmp_messages = []
+            tmp_messages.append(sentence)
+
+        if tmp_messages:
+            message = '\n'.join(tmp_messages)
+            LOGGER.info('"%s": CONF "%s": next message length: %s',
+                    middleware.username, conference_id, len(message)
+                )
+            browser.type(message, id='message')
+            browser.click(id='chat_send')
+
+        LOGGER.info('"%s": CONF "%s": finished sending message',
+                middleware.username, conference_id
+            )
+    finally:
+        browser.close_current_tab()
+
+@session_handler
+def conference_notification(middleware, conference_id, message, sound):
+    """Send conference notification"""
+    data = {
+            'sound': 1 if sound else 0,
+            'text': message,
+            'c': middleware.authentication_handler.var_c,
+        }
+
+    response = middleware.post(
+            "https://rivalregions.com/rival/konffcm/{}/".format(
+                conference_id
+            ),
+            data=data
+        )
+    check_response(response)
+    LOGGER.info('"%s": CONF: id %s send notification ',
+            middleware.username,
+            conference_id
+        )
+    return response
+
+@session_handler
+def conference_change_title(middleware, conference_id, title):
+    """Change conference title"""
+    data = {
+            't': title,
+            'c': middleware.authentication_handler.var_c,
+        }
+    response = middleware.post(
+            "https://rivalregions.com/rival/changename/{}/".format(
+                conference_id
+            ),
+            data=data
+        )
+    check_response(response)
+    LOGGER.info('"%s": CONF: id %s changed title',
+            middleware.username,
+            conference_id
+        )
+    return response
+
+@session_handler
+def profile_message(middleware, profile_id, message):
+    """send personal message"""
+    LOGGER.info('"%s": PM: user id %s', middleware.username, profile_id)
+    browser = middleware.authentication_handler.get_browser()
+    try:
+        browser.go_to(
+                'https://rivalregions.com/#messages/{}'.format(profile_id)
+            )
+        browser.refresh()
+        time.sleep(2)
+        browser.type(message, id='message')
+        browser.click(id='chat_send')
+        LOGGER.info('"%s:" PM: user id %s, finished sending message',
+                middleware.username,
+                profile_id
+            )
+    finally:
+        browser.close_current_tab()
+
+@session_handler
+def language_message(middleware, language, message):
+    """Send message in language chat"""
+    browser = middleware.authentication_handler.get_browser()
+    try:
+        browser.go_to(
+                'https://rivalregions.com/#slide/chat/lang_{}'.format(
+                        language
+                    )
+            )
+        browser.refresh()
+        time.sleep(2)
+        browser.type(message, id='message')
+        browser.click(id='chat_send')
+
+        LOGGER.info('"%s": CHAT: language %s, finished sending message',
+                middleware.username, language
+            )
+    finally:
+        browser.close_current_tab()

+ 0 - 15
src/rival_regions_wrapper/api_wrapper/__init__.py

@@ -1,15 +0,0 @@
-"""API wrapper for Rival Regions"""
-
-from rival_regions_wrapper.middleware import LocalAuthentication
-
-from rival_regions_wrapper.api_wrapper.profile import Profile
-from rival_regions_wrapper.api_wrapper.storage import Storage
-from rival_regions_wrapper.api_wrapper.market import Market
-from rival_regions_wrapper.api_wrapper.resource_state import ResourceState
-from rival_regions_wrapper.api_wrapper.perks import Perks
-from rival_regions_wrapper.api_wrapper.craft import Craft
-from rival_regions_wrapper.api_wrapper.overview import Overview
-from rival_regions_wrapper.api_wrapper.war import War
-from rival_regions_wrapper.api_wrapper.work import Work
-from rival_regions_wrapper.api_wrapper.article import Article
-from rival_regions_wrapper.api_wrapper.conference import Conference

+ 0 - 143
src/rival_regions_wrapper/api_wrapper/conference.py

@@ -1,143 +0,0 @@
-"""Conference class"""
-
-import time
-
-from rival_regions_wrapper import authentication_handler, LOGGER
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
-
-
-class Conference(AbstractWrapper):
-    """Wrapper class for confernce"""
-    def __init__(self, api_wrapper, conference_id):
-        AbstractWrapper.__init__(self, api_wrapper)
-        self.conference_id = conference_id
-
-    @authentication_handler.session_handler
-    def message(self, message):
-        """Send message to conference"""
-        LOGGER.info(
-                '"%s": CONF "%s": start send message',
-                self.api_wrapper.client.username, self.conference_id
-            )
-        browser = self.api_wrapper.client.get_browser()
-        try:
-            browser.go_to(
-                    'https://rivalregions.com/#slide/conference/{}'
-                    .format(self.conference_id)
-                )
-            browser.refresh()
-            time.sleep(2)
-
-            character_count = 0
-            tmp_messages = []
-            for sentence in message.split('\n'):
-                sentence_character_count = 0
-                tmp_sentence = []
-                for word in sentence.split(' '):
-                    sentence_character_count += len(word) + 1
-                    if sentence_character_count >= 899:
-                        message = '{}\n{}'.format('\n'.join(
-                                tmp_messages),
-                                ' '.join(tmp_sentence)
-                            )
-                        LOGGER.info(
-                                '"%s": CONF "%s": next message length: %s',
-                                self.api_wrapper.client.username,
-                                self.conference_id, len(message)
-                            )
-                        browser.type(message, id='message')
-                        browser.click(id='chat_send')
-                        sentence_character_count = 0
-                        tmp_sentence = []
-                        character_count = 0
-                        tmp_messages = []
-                    tmp_sentence.append(word)
-
-                sentence = ' '.join(tmp_sentence)
-                character_count += len(sentence) + 1
-                if character_count >= 900:
-                    message = '\n'.join(tmp_messages)
-                    LOGGER.info(
-                            '"%s": CONF "%s": next message length: %s',
-                            self.api_wrapper.client.username,
-                            self.conference_id, len(message)
-                        )
-                    browser.type(message, id='message')
-                    browser.click(id='chat_send')
-                    character_count = 0
-                    tmp_messages = []
-                tmp_messages.append(sentence)
-
-            if tmp_messages:
-                message = '\n'.join(tmp_messages)
-                LOGGER.info(
-                        '"%s": CONF "%s": next message length: %s',
-                        self.api_wrapper.client.username,
-                        self.conference_id, len(message)
-                    )
-                browser.type(message, id='message')
-                browser.click(id='chat_send')
-
-            LOGGER.info(
-                    '"%s": CONF "%s": finished sending message',
-                    self.api_wrapper.client.username, self.conference_id
-                )
-        finally:
-            browser.close_current_tab()
-
-    @authentication_handler.session_handler
-    def notification(self, message, sound):
-        """Send notification to conference"""
-        LOGGER.info(
-                '"%s": CONF: %s notification',
-                self.api_wrapper.client.username, self.conference_id
-            )
-        data = {
-            'sound': 1 if sound else 0,
-            'text': message,
-            'c': self.api_wrapper.client.var_c,
-        }
-
-        if self.api_wrapper.client.session:
-            response = self.api_wrapper.client.session.post(
-                "https://rivalregions.com/rival/konffcm/{}/".format(
-                    self.conference_id
-                ),
-                data=data
-            )
-            self.api_wrapper.client.check_response(response)
-        else:
-            raise authentication_handler.NoLogginException()
-        LOGGER.info(
-                '"%s": CONF: id %s send notification ',
-                self.api_wrapper.client.username, self.conference_id
-            )
-        return response.text
-
-    @authentication_handler.session_handler
-    def change_title(self, title):
-        """Change title of conference"""
-        LOGGER.info(
-                '"%s": CONF: %s change title: %s',
-                self.api_wrapper.client.username, self.conference_id, title
-            )
-        data = {
-            't': title,
-            'c': self.api_wrapper.client.var_c,
-        }
-
-        if self.api_wrapper.client.session:
-            response = self.api_wrapper.client.session.post(
-                "https://rivalregions.com/rival/changename/{}/".format(
-                    self.conference_id
-                ),
-                data=data
-            )
-            self.api_wrapper.client.check_response(response)
-        else:
-            raise authentication_handler.NoLogginException()
-        LOGGER.info(
-                '"%s": CONF: id %s changed title',
-                self.api_wrapper.client.username, self.conference_id
-            )
-        return response.text

+ 0 - 33
src/rival_regions_wrapper/api_wrapper/language_chat.py

@@ -1,33 +0,0 @@
-"""Language chat class"""
-
-from rival_regions_wrapper import authentication_handler, LOGGER
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
-
-
-class LanguageChat(AbstractWrapper):
-    """Wrapper class for language chat"""
-    def __init__(self, api_wrapper, language):
-        AbstractWrapper.__init__(self, api_wrapper)
-        self.language = language
-
-    @authentication_handler.session_handler
-    def message(self, message):
-        """send message to language chat"""
-        LOGGER.info(
-                '"%s": CHAT: language %s',
-                self.api_wrapper.client.username, self.language
-            )
-        browser = self.api_wrapper.client.get_browser()
-        try:
-            browser.go_to(
-                    'https://rivalregions.com/#slide/chat/lang_{}'.format(
-                            self.language
-                        )
-                )
-            self.api_wrapper.client.send_chat(browser, message)
-            LOGGER.info(
-                    '"%s": CHAT: language %s, finished sending message',
-                    self.api_wrapper.client.username, self.language
-                )
-        finally:
-            browser.close_current_tab()

+ 66 - 184
src/rival_regions_wrapper/authentication_handler.py

@@ -2,154 +2,67 @@
 Authentication handler module
 """
 
-import time
-import sys
 import re
 
-from python_anticaptcha import AnticaptchaClient, ImageToTextTask
-
 import requests
 import cfscrape
 
 from rival_regions_wrapper import LOGGER, login_methods
 from rival_regions_wrapper.cookie_handler import CookieHandler
 from rival_regions_wrapper.browser import Browser
-from rival_regions_wrapper.exceptions import SessionExpireException, \
-        NoLogginException, NoCookieException
-
-
-def session_handler(func):
-    """Handle expired sessions"""
-    def wrapper(*args, **kwargs):
-        instance = args[0]
-        return try_run(instance, func, *args, **kwargs)
+from rival_regions_wrapper.exceptions import InvalidLoginMethodException, \
+        SessionExpireException, NoLogginException, NoCookieException
 
-    def try_run(instance, func, *args, **kwargs):
-        try:
-            return func(*args, **kwargs)
-        except (SessionExpireException, ConnectionError, ConnectionResetError):
-            CookieHandler.remove_cookie(instance.username)
-            instance.login()
-            return try_run(instance, func, *args, **kwargs)
-        except NoLogginException:
-            instance.login()
-            return try_run(instance, func, *args, **kwargs)
 
-    return wrapper
+LOGIN_METHOD_DICT = {
+    'g': login_methods.login_google,
+    'google': login_methods.login_google,
+    'v': login_methods.login_vk,
+    'vk': login_methods.login_vk,
+    'f': login_methods.login_facebook,
+    'facebook': login_methods.login_facebook,
+}
 
 
 class AuthenticationHandler:
     """class for RR client"""
-    cookie = None
-    var_c = None
-    login_method = None
-    username = None
-    password = None
-    session = None
-    captcha_client = None
-
     def __init__(self, show_window=False, captcha_client=None):
+        LOGGER.info('Initialize, show window: "%s", captcha client: "%s"',
+                show_window, bool(captcha_client)
+            )
         self.show_window = show_window
         self.captcha_client = captcha_client
-        LOGGER.info('Initialize authentication handler, show window: "%s"',
-                    self.show_window)
+        self.login_method = None
+        self.username = None
+        self.password = None
+        self.session = None
+        self.var_c = None
 
-    def set_credentials(self, credentials):
+    def set_credentials(self, login_method, username, password):
         """Set the credentials"""
-        LOGGER.info('"%s": setting credentials', credentials['username'])
-        self.login_method = credentials['login_method']
-        self.username = credentials['username']
-        self.password = credentials['password']
-        self.login()
-
-    def login(self):
-        """Login user if needed"""
-        LOGGER.info(
-                '"%s": start login, method: "%s"',
-                self.username, self.login_method
+        LOGGER.info('"%s": setting credentials, method: "%s"',
+                username, login_method
             )
+        if login_method not in LOGIN_METHOD_DICT:
+            raise InvalidLoginMethodException()
+        self.login_method = login_method
+        self.username = username
+        self.password = password
+        self.authenticate()
+
+    def authenticate(self):
+        """Login user if needed"""
+        LOGGER.info('"%s": start authentication', self.username)
         cookies = CookieHandler.get_cookies(self.username)
         if not cookies:
-            cookies = []
-            LOGGER.info(
-                    '"%s": no cookie, new login, method "%s"',
-                    self.username, self.login_method
+            LOGGER.info('"%s": No (valid) cookie found, start new login',
+                    self.username
+                )
+            cookies = self.login()
+            LOGGER.info('"%s": storing cookie',
+                    self.username
                 )
-
-            login_method_dict = {
-                'g': login_methods.login_google,
-                'google': login_methods.login_google,
-                'v': login_methods.login_vk,
-                'vk': login_methods.login_vk,
-                'f': login_methods.login_facebook,
-                'facebook': login_methods.login_facebook,
-            }
-
-            auth_text = requests.get("https://rivalregions.com").text
-            browser = Browser(showWindow=self.show_window)
-
-            if self.login_method in login_method_dict:
-                browser = login_method_dict[self.login_method](
-                        browser,
-                        auth_text,
-                        self.username,
-                        self.password,
-                        self.captcha_client
-                    )
-            else:
-                LOGGER.info(
-                        '"%s": Invalid login method "%s"',
-                        self.username, self.login_method
-                    )
-                sys.exit()
-
-            LOGGER.info('"%s": Get PHPSESSID', self.username)
-            browser_cookie = browser.get_cookie('PHPSESSID')
-            if browser_cookie:
-                expiry = browser_cookie.get('expiry', None)
-                value = browser_cookie.get('value', None)
-                LOGGER.info(
-                        '"%s": "value": %s, "expiry": %s',
-                        self.username, value, expiry
-                    )
-                cookie = CookieHandler.create_cookie(
-                        'PHPSESSID',
-                        expiry,
-                        value
-                    )
-                cookies.append(cookie)
-            else:
-                raise NoCookieException()
-
-            cookie_names = ['rr_f']
-            for cookie_name in cookie_names:
-                browser_cookie = browser.get_cookie(cookie_name)
-                if browser_cookie:
-                    LOGGER.info(
-                        '"%s": Get %s',
-                        self.username, cookie_name
-                    )
-                    expiry = browser_cookie.get('expiry', None)
-                    value = browser_cookie.get('value', None)
-                    cookies.append(
-                        CookieHandler.create_cookie(
-                            cookie_name,
-                            expiry,
-                            value
-                        )
-                    )
-                    LOGGER.info(
-                            '"%s": "value": %s, "expiry": %s',
-                            self.username, value, expiry
-                        )
-                else:
-                    raise NoCookieException()
-
             CookieHandler.write_cookies(self.username, cookies)
-            LOGGER.debug('"%s": closing login tab', self.username)
-            browser.close_current_tab()
-        else:
-            LOGGER.info('"%s": Cookies found', self.username)
 
         self.session = cfscrape.CloudflareScraper()
         for cookie in cookies:
@@ -164,58 +77,43 @@ class AuthenticationHandler:
                 LOGGER.debug('"%s": got var_c: %s', self.username, var_c)
                 self.var_c = line.split("'")[-2]
 
-    @session_handler
-    def get(self, path, add_var_c=False):
-        """Send get request to Rival Regions"""
-        if path[0] == '/':
-            path = path[1:]
+    def login(self):
+        """Login"""
+        auth_text = requests.get("https://rivalregions.com").text
+        browser = Browser(showWindow=self.show_window)
+        browser = LOGIN_METHOD_DICT[self.login_method](
+                browser,
+                auth_text,
+                self.username,
+                self.password,
+                self.captcha_client
+            )
+
+        cookies = []
+        for cookie_name in ['PHPSESSID', 'rr_f']:
+            browser_cookie = browser.get_cookie(cookie_name)
+            if browser_cookie:
+                LOGGER.info('"%s": Get "%s" cookie',
+                        self.username, cookie_name
+                    )
+                cookies.append(CookieHandler.create_cookie(
+                        cookie_name,
+                        browser_cookie.get('expiry', None),
+                        browser_cookie.get('value', None)
+                    ))
+            else:
+                raise NoCookieException()
 
-        params = {}
-        if add_var_c:
-            params['c'] = self.var_c
+        LOGGER.debug('"%s": closing login tab', self.username)
+        browser.close_current_tab()
+        return cookies
 
-        LOGGER.info(
-                '"%s": GET: "%s" var_c: %s', self.username, path, add_var_c
-            )
-        if self.session:
-            response = self.session.get(
-                url='https://rivalregions.com/{}'.format(path),
-                params=params
-            )
-            self.check_response(response)
-        else:
-            raise NoLogginException()
-        return response.text
-
-    @session_handler
-    def post(self, path, data=None):
-        """Send post request to Rival Regions"""
-        if path[0] == '/':
-            path = path[1:]
-        if not data:
-            data = {}
-        data['c'] = self.var_c
-
-        LOGGER.info('"%s": POST: "%s"', self.username, path)
-        if self.session:
-            response = self.session.post(
-                "https://rivalregions.com/{}".format(path),
-                data=data
-            )
-            self.check_response(response)
-        else:
-            raise NoLogginException()
-        return response.text
 
     def get_browser(self):
         """Get browser"""
         if not self.session:
             raise NoLogginException()
 
-        response = self.session.get(
-                "https://rivalregions.com/#overview"
-            )
-        self.check_response(response)
         browser = Browser(showWindow=self.show_window)
         browser.go_to('https://rivalregions.com/')
         for cookie_name, value in \
@@ -224,19 +122,3 @@ class AuthenticationHandler:
                     CookieHandler.create_cookie(cookie_name, None, value)
                 )
         return browser
-
-    @classmethod
-    def send_chat(cls, browser, message):
-        """Send message"""
-        browser.refresh()
-        time.sleep(2)
-        browser.type(message, id='message')
-        browser.click(id='chat_send')
-
-    @classmethod
-    def check_response(cls, response):
-        """Check resonse for authentication"""
-        # print(response.text)
-        if "Session expired, please, reload the page" in response.text or \
-                'window.location="https://rivalregions.com";' in response.text:
-            raise SessionExpireException()

+ 3 - 3
src/rival_regions_wrapper/cookie_handler.py

@@ -37,14 +37,14 @@ class CookieHandler():
     @classmethod
     def get_cookies(cls, username):
         """Read cookies for username"""
-        LOGGER.info('"%s": Reading cookie', username)
+        LOGGER.info('"%s": Searching for cookie', username)
         cookies = []
         try:
             with open('{}/cookies.json'.format(DATA_DIR), 'r') as cookies_file:
                 cookies_data = json.load(cookies_file)
                 for cookie_username, user_cookies in cookies_data.items():
                     if cookie_username == username:
-                        LOGGER.info('"%s": Found cookies', username)
+                        LOGGER.info('"%s": Found cookie', username)
                         for cookie_name, cookie in user_cookies.items():
                             expires = datetime.fromtimestamp(
                                     int(cookie['expiry'])
@@ -53,7 +53,7 @@ class CookieHandler():
                                 LOGGER.info(
                                         '"%s": Cookie is expired', username
                                     )
-                                return None
+                                return cookies
                             cookies.append(cls.create_cookie(
                                 cookie_name,
                                 cookie['expiry'],

+ 7 - 0
src/rival_regions_wrapper/exceptions.py

@@ -5,6 +5,13 @@ Exceptions used in Rival Regions Wrapper
 from rival_regions_wrapper import LOGGER
 
 
+class InvalidLoginMethodException(Exception):
+    """Raise exception when login method is invalid"""
+    def __init__(self, *args, **kwargs):
+        Exception.__init__(self, *args, **kwargs)
+        LOGGER.warning('Login method invalid')
+
+
 class RRClientException(Exception):
     """RR exception"""
     def __init__(self, *args, **kwargs):

+ 9 - 9
src/rival_regions_wrapper/login_methods.py

@@ -13,7 +13,7 @@ from rival_regions_wrapper.exceptions import NoCaptchaClientException, \
 # This should be working
 def login_google(browser, auth_text, username, password, captcha_client=None):
     """login using Google"""
-    LOGGER.info('"%s": Google: Login start', username)
+    LOGGER.info('Google: "%s": Login start', username)
     auth_text1 = auth_text.split('\t<a href="')
     auth_text2 = auth_text1[1].split('" class="sa')
     time.sleep(1)
@@ -21,34 +21,34 @@ def login_google(browser, auth_text, username, password, captcha_client=None):
 
     # browser.get_screenshot_as_file('test_1.png')
 
-    LOGGER.info('"%s": Google: Typing in username', username)
+    LOGGER.info('Google: "%s": Typing in username', username)
     browser.type(username, into='Email')
 
     # browser.get_screenshot_as_file('test_2.png')
 
-    LOGGER.info('"%s": Google: pressing next button', username)
+    LOGGER.info('Google: "%s": pressing next button', username)
     browser.click(css_selector='#next')
     time.sleep(1)
 
     # browser.get_screenshot_as_file('test_3.png')
 
     if browser.driver.find_elements_by_css_selector('#captcha-box'):
-        LOGGER.info('"%s": Google: Captcha present', username)
+        LOGGER.info('Google: "%s": Captcha present', username)
         if not captcha_client:
             raise NoCaptchaClientException()
         captcha_url = browser \
                 .find_elements(css_selector='#captcha-img img')[0] \
                 .get_attribute('src')
-        LOGGER.debug('"%s": Google: Captcha url: "%s"', username, captcha_url)
+        LOGGER.debug('Google: "%s": Captcha url: "%s"', username, captcha_url)
         image = requests.get(captcha_url, stream=True).raw
         image.decode_content = True
 
         task = ImageToTextTask(image)
         job = captcha_client.createTask(task)
-        LOGGER.info('"%s": Google: Start solve captcha', username)
+        LOGGER.info('Google: "%s": Start solve captcha', username)
         job.join()
 
-        LOGGER.info('"%s": Google: captcha: "%s"', username, job.get_captcha_text())
+        LOGGER.info('Google: %s": captcha: "%s"', username, job.get_captcha_text())
         browser.type(
                 job.get_captcha_text(),
                 css_selector='#identifier-captcha-input'
@@ -63,12 +63,12 @@ def login_google(browser, auth_text, username, password, captcha_client=None):
     # with open('source.html', 'w') as source:
     #     source.write(browser.get_page_source())
 
-    LOGGER.info('"%s": Google: Typing in password', username)
+    LOGGER.info('Google: "%s": Typing in password', username)
     browser.type(password, css_selector='input')
 
     # browser.get_screenshot_as_file('test_5.png')
 
-    LOGGER.info('"%s": Google: pressing sign in button', username)
+    LOGGER.info('Google: "%s": pressing sign in button', username)
     browser.click(css_selector='#submit')
     time.sleep(3)
 

+ 20 - 16
src/rival_regions_wrapper/middleware.py

@@ -4,14 +4,16 @@ from abc import ABC, abstractmethod
 
 import requests
 
+from rival_regions_wrapper import api
 from rival_regions_wrapper.authentication_handler import AuthenticationHandler
 
 
 class MiddlewareBase(ABC):
     """Middleware abstract base class"""
+    username = None
 
     @abstractmethod
-    def get(self, path, add_c_var=False):
+    def get(self, path, add_var_c=False):
         """Send get request"""
 
     @abstractmethod
@@ -21,37 +23,39 @@ class MiddlewareBase(ABC):
 
 class LocalAuthentication(MiddlewareBase):
     """Local authentication"""
-
-    def __init__(self, username, password, login_method,
-            show_window=False, captcha_client=None):
-        self.client = AuthenticationHandler(show_window, captcha_client)
-        self.client.set_credentials({
-            'username': username,
-            'password': password,
-            'login_method': login_method
-        })
+    def __init__(self, show_window=False, captcha_client=None):
         super().__init__()
+        self.authentication_handler = AuthenticationHandler(
+                show_window, captcha_client
+            )
+
+    def set_credentials(self, username, password, login_method):
+        """Set login credentials"""
+        self.username = username
+        self.authentication_handler.set_credentials(
+                login_method, username, password
+            )
+        return self
 
-    def get(self, path, add_c_var=False):
+    def get(self, path, add_var_c=False):
         """Send get requests"""
-        return self.client.get(path)
+        return api.get(self, path, add_var_c)
 
     def post(self, path, data=None):
         """Send post request"""
-        return self.client.post(path, data=data)
+        return api.post(self, path, data=data)
 
 
 class RemoteAuthentication(MiddlewareBase):
     """Remote authentication"""
-
     def __init__(self, api_url, authentication_key):
+        super().__init__()
         self.api_url = api_url
         self.headers = {
             'Authorization': authentication_key
         }
-        super().__init__()
 
-    def get(self, path, add_c_var=False):
+    def get(self, path, add_var_c=False):
         """Send get requests"""
         try:
             response = requests.get(

+ 16 - 0
src/rival_regions_wrapper/wrapper/__init__.py

@@ -0,0 +1,16 @@
+"""Wrapper for Rival Regions functions"""
+
+from rival_regions_wrapper.middleware import LocalAuthentication
+
+from rival_regions_wrapper.wrapper.profile import Profile
+from rival_regions_wrapper.wrapper.storage import Storage
+from rival_regions_wrapper.wrapper.market import Market
+from rival_regions_wrapper.wrapper.resource_state import ResourceState
+from rival_regions_wrapper.wrapper.perks import Perks
+from rival_regions_wrapper.wrapper.craft import Craft
+from rival_regions_wrapper.wrapper.overview import Overview
+from rival_regions_wrapper.wrapper.war import War
+from rival_regions_wrapper.wrapper.work import Work
+from rival_regions_wrapper.wrapper.article import Article
+from rival_regions_wrapper.wrapper.conference import Conference
+from rival_regions_wrapper.wrapper.language_chat import LanguageChat

+ 2 - 2
src/rival_regions_wrapper/api_wrapper/abstract_wrapper.py → src/rival_regions_wrapper/wrapper/abstract_wrapper.py

@@ -7,5 +7,5 @@ from abc import ABC
 
 class AbstractWrapper(ABC):
     """abstract base class for wrappers"""
-    def __init__(self, api_wrapper):
-        self.api_wrapper = api_wrapper
+    def __init__(self, middleware):
+        self.middleware = middleware

+ 2 - 2
src/rival_regions_wrapper/api_wrapper/article.py → src/rival_regions_wrapper/wrapper/article.py

@@ -6,7 +6,7 @@ import re
 from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Article(AbstractWrapper):
@@ -14,7 +14,7 @@ class Article(AbstractWrapper):
     def info(self, article_id):
         """Get artcile"""
         path = 'news/show/{}'.format(article_id)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
 
         links = soup.select('.newspaper_links')

+ 48 - 0
src/rival_regions_wrapper/wrapper/conference.py

@@ -0,0 +1,48 @@
+"""Conference class"""
+
+from rival_regions_wrapper import LOGGER, api
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
+
+
+class Conference(AbstractWrapper):
+    """Wrapper class for confernce"""
+    def __init__(self, middleware, conference_id):
+        AbstractWrapper.__init__(self, middleware)
+        self.conference_id = conference_id
+
+    def message(self, message):
+        """Send message to conference"""
+        LOGGER.info('"%s": CONF "%s": start send message',
+                self.middleware.username,
+                self.conference_id
+            )
+        api.conference_message(
+                self.middleware,
+                self.conference_id,
+                message
+            )
+
+    def notification(self, message, sound):
+        """Send notification to conference"""
+        LOGGER.info('"%s": CONF: %s notification',
+                self.middleware.username,
+                self.conference_id
+            )
+        return api.conference_notification(
+                self.middleware,
+                self.conference_id,
+                message,
+                sound
+            )
+
+    def change_title(self, title):
+        """Change title of conference"""
+        LOGGER.info('"%s": CONF: %s change title: %s',
+                self.middleware.username,
+                self.conference_id, title
+            )
+        return api.conference_change_title(
+                self.middleware,
+                self.conference_id,
+                title
+            )

+ 5 - 3
src/rival_regions_wrapper/api_wrapper/craft.py → src/rival_regions_wrapper/wrapper/craft.py

@@ -5,7 +5,7 @@ import re
 from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Craft(AbstractWrapper):
@@ -15,7 +15,7 @@ class Craft(AbstractWrapper):
         if isinstance(item, str) and item in util.ITEM_KEYS:
             item = util.ITEM_KEYS[item]
         path = 'storage/produce/{}'.format(item)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         resources = soup.select_one('.storage_produce_exp')
         resource_dict = {
@@ -47,5 +47,7 @@ class Craft(AbstractWrapper):
         """Craft item"""
         if isinstance(item, str) and item in util.ITEM_KEYS:
             item = util.ITEM_KEYS[item]
-        self.api_wrapper.post('storage/newproduce/{}/{}'.format(item, amount))
+        self.middleware.post(
+                'storage/newproduce/{}/{}'.format(item, amount)
+            )
         return True

+ 23 - 0
src/rival_regions_wrapper/wrapper/language_chat.py

@@ -0,0 +1,23 @@
+"""Language chat class"""
+
+from rival_regions_wrapper import LOGGER, api
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
+
+
+class LanguageChat(AbstractWrapper):
+    """Wrapper class for language chat"""
+    def __init__(self, middleware, language):
+        AbstractWrapper.__init__(self, middleware)
+        self.language = language
+
+    def message(self, message):
+        """send message to language chat"""
+        LOGGER.info('"%s": CHAT: language %s',
+                self.middleware.username,
+                self.language
+            )
+        api.language_message(
+                self.middleware,
+                self.language,
+                message
+            )

+ 2 - 2
src/rival_regions_wrapper/api_wrapper/market.py → src/rival_regions_wrapper/wrapper/market.py

@@ -5,7 +5,7 @@ import re
 from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Market(AbstractWrapper):
@@ -15,7 +15,7 @@ class Market(AbstractWrapper):
         if isinstance(resource, str) and resource in util.ITEM_KEYS:
             resource = util.ITEM_KEYS[resource]
         path = 'storage/listed/{}'.format(resource)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
 
         offers_tree = soup.find_all(class_='list_link')

+ 4 - 4
src/rival_regions_wrapper/api_wrapper/overview.py → src/rival_regions_wrapper/wrapper/overview.py

@@ -2,8 +2,8 @@
 
 from bs4 import BeautifulSoup
 
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
-from rival_regions_wrapper.api_wrapper.perks import Perks
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.perks import Perks
 
 
 class Overview(AbstractWrapper):
@@ -11,7 +11,7 @@ class Overview(AbstractWrapper):
     def info(self):
         """Get overview """
         path = 'main/content'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         perks = Perks.info_parse(soup)
         auto_war = soup.select_one('.war_index_war span.pointer:nth-child(4)')
@@ -30,7 +30,7 @@ class Overview(AbstractWrapper):
     def status(self):
         """Get current status"""
         path = 'main'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         profile_url = soup.select_one('#header_my_avatar')['action']
         party_url = soup.select_one('#party_menu_members')['action']

+ 5 - 3
src/rival_regions_wrapper/api_wrapper/perks.py → src/rival_regions_wrapper/wrapper/perks.py

@@ -5,7 +5,7 @@ import re
 from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Perks(AbstractWrapper):
@@ -13,7 +13,7 @@ class Perks(AbstractWrapper):
     def info(self):
         """Get perks"""
         path = 'main/content'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         return self.info_parse(soup)
 
@@ -65,5 +65,7 @@ class Perks(AbstractWrapper):
         if isinstance(upgrade_type, str) and upgrade_type in upgrade_type_keys:
             upgrade_type = upgrade_type_keys[upgrade_type]
 
-        self.api_wrapper.post('perks/up/{}/{}'.format(perk, upgrade_type))
+        self.middleware.post(
+                'perks/up/{}/{}'.format(perk, upgrade_type)
+            )
         return True

+ 9 - 23
src/rival_regions_wrapper/api_wrapper/profile.py → src/rival_regions_wrapper/wrapper/profile.py

@@ -4,20 +4,20 @@ import re
 
 from bs4 import BeautifulSoup
 
-from rival_regions_wrapper import authentication_handler, LOGGER
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper import LOGGER, api
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Profile(AbstractWrapper):
     """Wrapper class for profile"""
-    def __init__(self, api_wrapper, profile_id):
-        AbstractWrapper.__init__(self, api_wrapper)
+    def __init__(self, middleware, profile_id):
+        AbstractWrapper.__init__(self, middleware)
         self.profile_id = profile_id
 
     def info(self):
         """Get profile"""
         path = 'slide/profile/{}'.format(self.profile_id)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         level = soup.select_one('div.oil:nth-child(2) > div:nth-child(2)').text
         perks = soup.select('table tr:nth-child(2) span')
@@ -34,24 +34,10 @@ class Profile(AbstractWrapper):
         }
         return profile
 
-    @authentication_handler.session_handler
     def message(self, message):
         """send personal message"""
-        LOGGER.info(
-                '"%s": PM: user id %s',
-                self.api_wrapper.client.username, self.profile_id
+        LOGGER.info('"%s": PM: user id %s',
+                self.middleware.username,
+                self.profile_id
             )
-        browser = self.api_wrapper.client.get_browser()
-        try:
-            browser.go_to(
-                    'https://rivalregions.com/#messages/{}'.format(
-                            self.profile_id
-                        )
-                )
-            self.api_wrapper.client.send_chat(browser, message)
-            LOGGER.info(
-                    '"%s:" PM: user id %s, finished sending message',
-                    self.api_wrapper.client.username, self.profile_id
-                )
-        finally:
-            browser.close_current_tab()
+        api.profile_message(self.middleware, self.profile_id, message)

+ 4 - 4
src/rival_regions_wrapper/api_wrapper/resource_state.py → src/rival_regions_wrapper/wrapper/resource_state.py

@@ -4,13 +4,13 @@ import re
 
 from bs4 import BeautifulSoup
 
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class ResourceState(AbstractWrapper):
     """Wrapper class for resource state"""
-    def __init__(self, api_wrapper, state_id):
-        AbstractWrapper.__init__(self, api_wrapper)
+    def __init__(self, middleware, state_id):
+        AbstractWrapper.__init__(self, middleware)
         self.state_id = state_id
 
     def info(self, resource):
@@ -24,7 +24,7 @@ class ResourceState(AbstractWrapper):
         if isinstance(resource, int) and resource in keys:
             resource = keys[resource]
         path = 'listed/stateresources/{}/{}'.format(self.state_id, resource)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         regions_tree = soup.find_all(class_='list_link')
         regions = []

+ 2 - 2
src/rival_regions_wrapper/api_wrapper/storage.py → src/rival_regions_wrapper/wrapper/storage.py

@@ -4,7 +4,7 @@ from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
 
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Storage(AbstractWrapper):
@@ -12,7 +12,7 @@ class Storage(AbstractWrapper):
     def info(self):
         """storage info"""
         path = 'storage'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         storage = {}
         for key, item_id in util.ITEM_KEYS.items():

+ 3 - 3
src/rival_regions_wrapper/api_wrapper/war.py → src/rival_regions_wrapper/wrapper/war.py

@@ -7,7 +7,7 @@ import unicodedata
 from bs4 import BeautifulSoup
 
 from rival_regions_wrapper import util
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 class War(AbstractWrapper):
@@ -15,7 +15,7 @@ class War(AbstractWrapper):
     def page(self):
         """Get training war"""
         path = 'war'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         pattern = re.compile(r'war\/details\/\d+')
         script = soup.find('script', text=pattern)
@@ -32,7 +32,7 @@ class War(AbstractWrapper):
     def info(self, war_id):
         """Get war info"""
         path = 'war/details/{}'.format(war_id)
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
         war_info = {
             'war_id': war_id,

+ 2 - 2
src/rival_regions_wrapper/api_wrapper/work.py → src/rival_regions_wrapper/wrapper/work.py

@@ -4,7 +4,7 @@ import re
 
 from bs4 import BeautifulSoup
 
-from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper.wrapper.abstract_wrapper import AbstractWrapper
 
 
 RESOURCE_DICT = {
@@ -21,7 +21,7 @@ class Work(AbstractWrapper):
     def page(self):
         """Get work page"""
         path = 'work'
-        response = self.api_wrapper.get(path)
+        response = self.middleware.get(path)
         soup = BeautifulSoup(response, 'html.parser')
 
         factory = soup.select_one('.work_item:nth-child(9)')

+ 6 - 7
tests/conftest.py

@@ -45,7 +45,7 @@ def vcr(vcr):
 
 
 @pytest.fixture(scope="module")
-def api_wrapper():
+def middleware():
     """Set up wrapper before test"""
     username = os.environ.get('USERNAME', None)
     password = os.environ.get('PASSWORD', None)
@@ -56,10 +56,9 @@ def api_wrapper():
             'Load the following variables in your user environment: '
             'username, password, login_method'
         )
-    return LocalAuthentication(
-            username,
-            password,
-            login_method,
-            False,
-            AnticaptchaClient(captcha_key),
+    _middleware = LocalAuthentication(
+            False, AnticaptchaClient(captcha_key)
+        )
+    return _middleware.set_credentials(
+            username, password, login_method
         )

+ 60 - 59
tests/test_rival_regions_wrapper.py

@@ -6,8 +6,9 @@ from datetime import datetime, timedelta
 
 import pytest
 
-from rival_regions_wrapper.api_wrapper import Profile, Storage, Market, \
-        ResourceState, Perks, Craft, Overview, War, Work, Article, Conference
+from rival_regions_wrapper.wrapper import Profile, Storage, Market, \
+        ResourceState, Perks, Craft, Overview, War, Work, Article, \
+        Conference, LanguageChat
 
 
 @pytest.fixture
@@ -20,9 +21,9 @@ def profile_keys():
 
 
 @pytest.mark.vcr()
-def test_profile_info(api_wrapper, profile_keys):
+def test_profile_info(middleware, profile_keys):
     """Test an API call to get client info"""
-    profile_instance = Profile(api_wrapper, 192852686)
+    profile_instance = Profile(middleware, 192852686)
     response = profile_instance.info()
 
     assert isinstance(response, dict), "The response should be a dict"
@@ -40,9 +41,9 @@ def test_profile_info(api_wrapper, profile_keys):
 
 
 @pytest.mark.skip(reason="message request")
-def test_profile_message(api_wrapper):
+def test_profile_message(middleware):
     """Test an API to send message to profile"""
-    Profile(api_wrapper, 2000340574).message('hi')
+    Profile(middleware, 2000340574).message('hi')
 
 
 @pytest.fixture
@@ -63,9 +64,9 @@ def storage_keys():
 
 
 @pytest.mark.vcr()
-def test_storage_info(api_wrapper, storage_keys):
+def test_storage_info(middleware, storage_keys):
     """Test an API call to get storage info"""
-    response = Storage(api_wrapper).info()
+    response = Storage(middleware).info()
 
     assert isinstance(response, dict), "The response should be a dict"
     assert set(storage_keys).issubset(response.keys()), \
@@ -79,10 +80,10 @@ def market_keys():
 
 
 @pytest.mark.vcr()
-def test_market_info(api_wrapper, market_keys):
+def test_market_info(middleware, market_keys):
     """Test an API call to get market info"""
     resource = 'oil'
-    response = Market(api_wrapper).info(resource)
+    response = Market(middleware).info(resource)
 
     assert isinstance(response, list), "The response should be a list"
     if response:
@@ -110,11 +111,11 @@ def resource_keys():
 
 
 @pytest.mark.vcr()
-def test_resource_state_info(api_wrapper, resource_keys):
+def test_resource_state_info(middleware, resource_keys):
     """Test an API call to get market info"""
     state = 3382
     resource = 'oil'
-    response = ResourceState(api_wrapper, state).info(resource)
+    response = ResourceState(middleware, state).info(resource)
 
     assert isinstance(response, list), "The response should be a list"
     if response:
@@ -146,9 +147,9 @@ def perks_keys():
 
 
 @pytest.mark.vcr()
-def test_perks_info(api_wrapper, perks_keys):
+def test_perks_info(middleware, perks_keys):
     """Test an API call to get perks info"""
-    response = Perks(api_wrapper).info()
+    response = Perks(middleware).info()
 
     assert isinstance(response, dict), \
         "The response should be a dict"
@@ -171,11 +172,11 @@ def test_perks_info(api_wrapper, perks_keys):
 
 
 @pytest.mark.skip(reason="Update request")
-def test_perks_upgrade(api_wrapper):
+def test_perks_upgrade(middleware):
     """Test an API call to upgrade perk"""
-    perk = 'endurance'
-    upgrade_type = 'money'
-    Perks(api_wrapper).upgrade(perk, upgrade_type)
+    perk = 'strenght'
+    upgrade_type = 'gold'
+    Perks(middleware).upgrade(perk, upgrade_type)
 
 
 @pytest.fixture
@@ -185,10 +186,10 @@ def craft_keys():
 
 
 @pytest.mark.skip(reason="Update request")
-def test_craft_produce(api_wrapper):
+def test_craft_produce(middleware):
     """Test an API call to produce new item"""
     item = 'energy_drink'
-    Craft(api_wrapper).produce(item, 10)
+    Craft(middleware).produce(item, 10)
 
     assert True
 
@@ -200,9 +201,9 @@ def overview_info_keys():
 
 
 @pytest.mark.vcr()
-def test_overview_info(api_wrapper, overview_info_keys):
+def test_overview_info(middleware, overview_info_keys):
     """Test an API call for overview"""
-    response = Overview(api_wrapper).info()
+    response = Overview(middleware).info()
 
     assert isinstance(response, dict), "The response hould be a dict"
     assert set(overview_info_keys).issubset(response.keys()), \
@@ -219,9 +220,9 @@ def overview_status_keys():
 
 
 @pytest.mark.vcr()
-def test_overview_status(api_wrapper, overview_status_keys):
+def test_overview_status(middleware, overview_status_keys):
     """Test an API cal for status"""
-    response = Overview(api_wrapper).status()
+    response = Overview(middleware).status()
 
     assert isinstance(response, dict), "The response hould be a dict"
     assert set(overview_status_keys).issubset(response.keys()), \
@@ -229,9 +230,9 @@ def test_overview_status(api_wrapper, overview_status_keys):
 
 
 @pytest.mark.vcr()
-def test_war_page(api_wrapper):
+def test_war_page(middleware):
     """Test getting training war"""
-    response = War(api_wrapper).page()
+    response = War(middleware).page()
 
     assert isinstance(response, dict), "The response should be a dict"
     if response['training_war']:
@@ -240,9 +241,9 @@ def test_war_page(api_wrapper):
 
 
 @pytest.mark.vcr()
-def test_war_info(api_wrapper):
+def test_war_info(middleware):
     """Test war info"""
-    war = War(api_wrapper)
+    war = War(middleware)
     war_page = war.page()
     war_id = war_page['training_war']
     response = war.info(war_id)
@@ -270,10 +271,10 @@ def test_war_info(api_wrapper):
 
 
 @pytest.mark.vcr()
-def test_war_info_ground_war(api_wrapper):
+def test_war_info_ground_war(middleware):
     """Test war info"""
     war_id = 329541
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'war', "Type should be a ground war"
@@ -301,59 +302,59 @@ def test_war_info_ground_war(api_wrapper):
 
 
 @pytest.mark.vcr()
-def test_war_info_coup(api_wrapper):
+def test_war_info_coup(middleware):
     """Test war info"""
     war_id = 329518
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'coup', "Type should be a coup"
 
 
 @pytest.mark.vcr()
-def test_war_info_revolution(api_wrapper):
+def test_war_info_revolution(middleware):
     """Test war info"""
     war_id = 329461
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'revolution', "Type should be a revolution"
 
 
 @pytest.mark.vcr()
-def test_war_info_trooper_war(api_wrapper):
+def test_war_info_trooper_war(middleware):
     """Test war info"""
     war_id = 329458
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'troopers war', "Type should be a trooper war"
 
 
 @pytest.mark.vcr()
-def test_war_info_sea_war(api_wrapper):
+def test_war_info_sea_war(middleware):
     """Test war info"""
     war_id = 329618
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'sea war', "Type should be a sea war"
 
 
 @pytest.mark.vcr()
-def test_war_info_space_war(api_wrapper):
+def test_war_info_space_war(middleware):
     """Test war info"""
     war_id = 329531
-    response = War(api_wrapper).info(war_id)
+    response = War(middleware).info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'space war', "Type should be a space war"
 
 
 @pytest.mark.vcr()
-def test_work_info(api_wrapper):
+def test_work_info(middleware):
     """Test work info"""
-    response = Work(api_wrapper).page()
+    response = Work(middleware).page()
 
     assert isinstance(response, dict), "The response should be a dict"
     assert isinstance(response['factory'], dict), "Factory should be a dict"
@@ -374,10 +375,10 @@ def article_keys():
 
 
 @pytest.mark.vcr()
-def test_article_info_one(api_wrapper, article_keys):
+def test_article_info_one(middleware, article_keys):
     """Test article info"""
     article_id = 2708696
-    response = Article(api_wrapper).info(article_id)
+    response = Article(middleware).info(article_id)
 
     assert isinstance(response, dict), "The resonse should be a dict"
     assert set(article_keys).issubset(response.keys()), \
@@ -413,10 +414,10 @@ def test_article_info_one(api_wrapper, article_keys):
 
 
 @pytest.mark.vcr()
-def test_article_info_two(api_wrapper, article_keys):
+def test_article_info_two(middleware, article_keys):
     """Test article info"""
     article_id = 2862982
-    response = Article(api_wrapper).info(article_id)
+    response = Article(middleware).info(article_id)
 
     assert isinstance(response, dict), "The resonse should be a dict"
     assert set(article_keys).issubset(response.keys()), \
@@ -447,28 +448,28 @@ def test_article_info_two(api_wrapper, article_keys):
         "Post date should be a datetime"
 
 
-@pytest.mark.skip(reason="message request")
-def test_conference_message(api_wrapper):
+@pytest.mark.skip(reason="conference message request")
+def test_conference_message(middleware):
     """Test conference message"""
     conference_id = 439289
-    Conference(api_wrapper, conference_id).message('hi')
+    Conference(middleware, conference_id).message('hi')
 
 
-@pytest.mark.skip(reason="notification request")
-def test_conference_notification(api_wrapper):
+@pytest.mark.skip(reason="conference notification request")
+def test_conference_notification(middleware):
     """Test conference notification"""
     conference_id = 439289
-    Conference(api_wrapper, conference_id).notification('hi', True)
+    Conference(middleware, conference_id).notification('hi', True)
 
 
-@pytest.mark.skip(reason="notification request")
-def test_conference_change_title(api_wrapper):
+@pytest.mark.skip(reason="conference title change request")
+def test_conference_change_title(middleware):
     """Test conference change title"""
     conference_id = 439289
-    Conference(api_wrapper, conference_id).change_title('new title')
+    Conference(middleware, conference_id).change_title('new title')
 
 
-@pytest.mark.skip(reason="message request")
-def test_language_chat_(api_wrapper):
-    """Test an API to send message to profile"""
-    Profile(api_wrapper, 2000340574).message('hi')
+@pytest.mark.skip(reason="language chat message request")
+def test_language_chat_message(middleware):
+    """Test sending message to language chat"""
+    LanguageChat(middleware, 'da').message('hi')