| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 | 
"""Client module"""import sysimport loggingimport reimport timefrom datetime import datetimeimport jsonimport requestsimport cfscrapefrom webbot.webbot import Browser# get loggerLOGGER = logging.getLogger(__name__)LOGGER.setLevel(logging.INFO)# create file handlerFILE_HANDLER = logging.FileHandler('output.log')FILE_HANDLER.setLevel(logging.DEBUG)# create console handlerSTREAM_HANDLER = logging.StreamHandler()STREAM_HANDLER.setLevel(logging.INFO)# create formatter and add it to the handlersSTREAM_FORMATTER = logging.Formatter('%(name)s - %(levelname)s - %(message)s')STREAM_HANDLER.setFormatter(STREAM_FORMATTER)FILE_FORMATTER = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')FILE_HANDLER.setFormatter(FILE_FORMATTER)# add the handlers to loggerLOGGER.addHandler(STREAM_HANDLER)LOGGER.addHandler(FILE_HANDLER)class RRClientException(Exception):    """RR exception"""    def __init__(self, *args, **kwargs):        Exception.__init__(self, *args, **kwargs)        LOGGER.warning('RRClientException')class SessionExpireException(Exception):    """Raise when session has expired"""    def __init__(self, *args, **kwargs):        Exception.__init__(self, *args, **kwargs)        LOGGER.warning('Session has expired')class NoLogginException(Exception):    """Raise exception when client isn't logged in"""    def __init__(self, *args, **kwargs):        Exception.__init__(self, *args, **kwargs)        LOGGER.warning('Session has expired')class NoPHPsessidException(Exception):    """Raise exception when cookie isn't found"""    def __init__(self, *args, **kwargs):        Exception.__init__(self, *args, **kwargs)        LOGGER.warning('No phpsessid found')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):            instance.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 wrapperclass Client:    """class for RR client"""    resource_id = {        'oil': 3,        'ore': 4,        'uranium': 11,        'diamond': 15,        'liquid oxygen': 21,        'helium-3': 24,        'antirad': 13,        'energy drink': 17,        'spacerockets': 20,        'tanks': 2,        'aircrafts': 1,        'missiles': 14,        'bombers': 16,        'battleships': 18,        'moon tanks': 22,        'space stations': 23    }    cookie = None    var_c = None    login_method = None    username = None    password = None    session = None    def __init__(self, show_window=False):        self.show_window = show_window        LOGGER.info('Init client, show window %s', self.show_window)    def set_credentials(self, credentials):        """Set the credentials"""        LOGGER.info('Setting "%s" credentials', credentials['username'])        self.login_method = credentials['login_method']        self.username = credentials['username']        self.password = credentials['password']    def login(self):        """Login user if needed"""        cookie = self.get_cookie(self.username)        if cookie is None:            LOGGER.info('Client login "%s" username "%s"', self.login_method, self.username)            if self.login_method not in ["g", "google", "v", "vk", "f", "facebook"]:                raise RRClientException("Not a valid login method.")            auth_text = requests.get("https://rivalregions.com").text            web = Browser(showWindow=self.show_window)            method_dict = {                'g': self.login_google,                'google': self.login_google,                'v': self.login_vk,                'vk': self.login_vk,                'f': self.login_facebook,                'facebook': self.login_facebook,            }            if self.login_method in method_dict:                web = method_dict[self.login_method](web, auth_text)            else:                LOGGER.info('Invallid loggin method "%s"', self.login_method)                sys.exit()            LOGGER.debug('Get cookie')            phpsessid = web.get_cookie('PHPSESSID')            if phpsessid:                cookie = self.create_cookie(                    phpsessid.get('expiry', None),                    phpsessid.get('value', None)                )                self.write_cookie(self.username, cookie)            else:                raise NoPHPsessidException()            LOGGER.debug('closing login tab')            web.close_current_tab()        # new to bypass cloudflare        self.session = cfscrape.CloudflareScraper()        # cloudscraper        # self.session = cloudscraper.CloudScraper(        #     browser={'browser': 'chrome', 'mobile': False},        #     interpreter='nodejs',        #     # debug=False        #     debug=True        # )        # old        # self.session = requests.Session()        # self.session.headers.update({'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)' \        #     'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'})        self.cookie = cookie        self.session.cookies.set(**cookie)        LOGGER.debug('set the var_c')        response = self.session.get('https://rivalregions.com/#overview')        lines = response.text.split("\n")        for line in lines:            if re.match("(.*)var c_html(.*)", line):                var_c = line.split("'")[-2]                LOGGER.debug('var_c: %s', var_c)                self.var_c = line.split("'")[-2]    def login_google(self, web, auth_text):        """login using Google"""        LOGGER.info('Login method Google')        auth_text1 = auth_text.split('\t<a href="')        auth_text2 = auth_text1[1].split('" class="sa')        web.go_to(auth_text2[0])        LOGGER.info('Typing in username')        web.type(self.username, into='Email')        web.click('Volgende')        time.sleep(2)        LOGGER.info('Typing in password')        web.type(self.password, css_selector="input")        web.click('Inloggen')        web.click(css_selector=".sa_sn.float_left.imp.gogo")        time.sleep(1)        return web    def login_vk(self, web, auth_text):        """login using VK"""        LOGGER.info('Login method VK')        auth_text1 = auth_text.split("(\'.vkvk\').attr(\'url\', \'")        auth_text2 = auth_text1[1].split('&response')        web.go_to(auth_text2[0])        web.type(self.username, into='email')        web.type(self.password, xpath="/html/body/div/div/div/div[2]/form/div/div/input[7]")        web.click('Log in')        return web    def login_facebook(self, web, auth_text):        """login using Facebook"""        LOGGER.info('Login method Facebook')        auth_text1 = auth_text.split('">\r\n\t\t\t\t<div class="sa_sn imp float_left" ')        auth_text2 = auth_text1[0].split('200px;"><a class="sa_link" href="')        url = auth_text2[1]        web.go_to(url)        web.type(self.username, into='Email')        web.type(self.password, into='Password')        web.click('Log In')        time.sleep(5)        web.click(css_selector='.sa_sn.imp.float_left')        return web    @classmethod    def write_cookie(cls, username, cookie):        """Write cookie to file"""        LOGGER.info('Saving cookie for "%s"', username)        cookies = None        try:            with open('cookies.json', 'r') as cookies_file:                cookies = json.load(cookies_file)        except FileNotFoundError:            cookies = {}        cookies[username] = {            'expires': cookie['expires'],            'value': cookie['value'],        }        with open('cookies.json', 'w+') as cookies_file:            json.dump(cookies, cookies_file)        LOGGER.info('Saved cookie for "%s"', username)    @classmethod    def get_cookie(cls, username):        """Read cookies for username"""        LOGGER.info('Read cookie for "%s"', username)        try:            with open('cookies.json', 'r') as cookies_file:                cookies = json.load(cookies_file)                for cookie_username, cookie in cookies.items():                    if cookie_username == username:                        LOGGER.info('Found cookie')                        expires = datetime.fromtimestamp(int(cookie['expires']))                        if datetime.now() >= expires:                            LOGGER.info('Cookie is expired')                            return None                        cookie = cls.create_cookie(                            cookie['expires'],                            cookie['value'],                        )                        return cookie        except FileNotFoundError:            pass        return None    @classmethod    def remove_cookie(cls, username):        """Remove cookie from storage"""        LOGGER.info('Removing cookie for "%s"', username)        cookies = None        try:            with open('cookies.json', 'r') as cookies_file:                cookies = json.load(cookies_file)        except FileNotFoundError:            cookies = {}        cookies.pop(username, None)        with open('cookies.json', 'w+') as cookies_file:            json.dump(cookies, cookies_file)        LOGGER.info('Removed cookie for "%s"', username)    @staticmethod    def create_cookie(expires, value):        """Create cookie"""        return {            'domain': 'rivalregions.com',            'name': 'PHPSESSID',            'path': '/',            'secure': False,            'expires': expires,            'value': value,        }    @session_handler    def get(self, path, add_var_c=False):        """Send get request to Rival Regions"""        if path[0] == '/':            path = path[1:]        params = {}        if add_var_c:            params['c'] = self.var_c        LOGGER.debug('GET: %s var_c: %s', path, add_var_c)        if self.session:            response = self.session.get(                url='https://rivalregions.com/{}'.format(path),                params=params            )            if "Session expired, please, reload the page" in response.text:                raise SessionExpireException()        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:]        data['c'] = self.var_c        LOGGER.debug('POST: %s', path)        if self.session:            response = self.session.post(                "https://rivalregions.com/{}".format(path),                data=data            )            if "Session expired, please, reload the page" in response.text:                raise SessionExpireException()        else:            raise NoLogginException()        return response.text    @session_handler    def send_chat(self, language, message):        """send chat message"""        if self.session:            response = self.session.get("https://rivalregions.com/#overview")            if "Session expired, please, reload the page" in response.text:                raise SessionExpireException()            web = Browser(showWindow=self.show_window)            web.go_to('https://rivalregions.com/')            web.add_cookie(self.get_cookie(self.username))            web.go_to('https://rivalregions.com/#slide/chat/lang_{}'.format(language))            web.refresh()            time.sleep(2)            web.type(message, id='message')            web.click(id='chat_send')            web.close_current_tab()        else:            raise NoLogginException()
 |