|  | @@ -0,0 +1,229 @@
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +"""
 | 
	
		
			
				|  |  | +Client module
 | 
	
		
			
				|  |  | +"""
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import logging
 | 
	
		
			
				|  |  | +import re
 | 
	
		
			
				|  |  | +import time
 | 
	
		
			
				|  |  | +import requests
 | 
	
		
			
				|  |  | +from webbot.webbot import Browser
 | 
	
		
			
				|  |  | +from requests_futures import sessions
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +logging.basicConfig(
 | 
	
		
			
				|  |  | +    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 | 
	
		
			
				|  |  | +    level=logging.INFO
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +LOGGER = logging.getLogger(__name__)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class RRClientException(Exception):
 | 
	
		
			
				|  |  | +    """RR exception"""
 | 
	
		
			
				|  |  | +    def __init__(self, *args, **kwargs):
 | 
	
		
			
				|  |  | +        Exception.__init__(self, *args, **kwargs)
 | 
	
		
			
				|  |  | +    LOGGER.warning('RRClientException')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class 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
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    session_id = None
 | 
	
		
			
				|  |  | +    var_c = None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def __init__(self, credentials, expires=None, show_window=False):
 | 
	
		
			
				|  |  | +        self.login_method = credentials['login_method']
 | 
	
		
			
				|  |  | +        self.username = credentials['username']
 | 
	
		
			
				|  |  | +        self.password = credentials['password']
 | 
	
		
			
				|  |  | +        self.expires = expires
 | 
	
		
			
				|  |  | +        self.show_window = show_window
 | 
	
		
			
				|  |  | +        LOGGER.info('Init client login_method "%s" username "%s"', self.login_method, self.username)
 | 
	
		
			
				|  |  | +        if self.login_method in ["g", "google", "v", "vk", "f", "facebook"]:
 | 
	
		
			
				|  |  | +            self.login()
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            raise RRClientException("Not a valid login method.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def login(self):
 | 
	
		
			
				|  |  | +        """Login user"""
 | 
	
		
			
				|  |  | +        LOGGER.info('Login in "%s"', self.username)
 | 
	
		
			
				|  |  | +        login_method = self.login_method
 | 
	
		
			
				|  |  | +        self.session = requests.Session()
 | 
	
		
			
				|  |  | +        auth_text = requests.get("http://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 login_method in method_dict:
 | 
	
		
			
				|  |  | +            web = method_dict[login_method](web, auth_text)
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            LOGGER.info('Invallid loggin method "%s"', login_method)
 | 
	
		
			
				|  |  | +        time.sleep(5)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        LOGGER.info('Get cookie')
 | 
	
		
			
				|  |  | +        sessid = web.get_cookie('PHPSESSID')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        expires = sessid.get('expiry', None)
 | 
	
		
			
				|  |  | +        sessid.pop('expiry', None)
 | 
	
		
			
				|  |  | +        sessid.pop('httpOnly', None)
 | 
	
		
			
				|  |  | +        sessid['expires'] = expires
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        web.close_current_tab()
 | 
	
		
			
				|  |  | +        LOGGER.info('closing login tab')
 | 
	
		
			
				|  |  | +        self.expires = expires
 | 
	
		
			
				|  |  | +        self.session_id = sessid
 | 
	
		
			
				|  |  | +        self.session.cookies.set(**sessid)
 | 
	
		
			
				|  |  | +        self.set_var_c()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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])
 | 
	
		
			
				|  |  | +        web.type(self.username, into='Email')
 | 
	
		
			
				|  |  | +        web.click('Volgende')
 | 
	
		
			
				|  |  | +        time.sleep(5)
 | 
	
		
			
				|  |  | +        web.type(self.password, into='Password')
 | 
	
		
			
				|  |  | +        web.click('Volgende')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        web.click(css_selector=".sa_sn.float_left.imp.gogo")
 | 
	
		
			
				|  |  | +        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
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def set_var_c(self):
 | 
	
		
			
				|  |  | +        """Set var_c"""
 | 
	
		
			
				|  |  | +        LOGGER.info('set the var_c')
 | 
	
		
			
				|  |  | +        response = self.session.get('http://rivalregions.com/#overview')
 | 
	
		
			
				|  |  | +        print(response.status_code)
 | 
	
		
			
				|  |  | +        lines = response.text.split("\n")
 | 
	
		
			
				|  |  | +        print(lines)
 | 
	
		
			
				|  |  | +        for line in lines:
 | 
	
		
			
				|  |  | +            if re.match("(.*)var c_html(.*)", line):
 | 
	
		
			
				|  |  | +                print(line)
 | 
	
		
			
				|  |  | +                self.var_c = line.split("'")[-2]
 | 
	
		
			
				|  |  | +                return
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def create_article(
 | 
	
		
			
				|  |  | +            self,
 | 
	
		
			
				|  |  | +            title,
 | 
	
		
			
				|  |  | +            article,
 | 
	
		
			
				|  |  | +            article_lang="en",
 | 
	
		
			
				|  |  | +            paper_id=0,
 | 
	
		
			
				|  |  | +            category='0',
 | 
	
		
			
				|  |  | +            region="4524"
 | 
	
		
			
				|  |  | +    ):
 | 
	
		
			
				|  |  | +        """Create new article"""
 | 
	
		
			
				|  |  | +        response = self.session.get('http://rivalregions.com/#overview')
 | 
	
		
			
				|  |  | +        response = self.session.post("http://rivalregions.com/news/post", data={
 | 
	
		
			
				|  |  | +            'c': self.var_c,
 | 
	
		
			
				|  |  | +            'newspaper': paper_id,
 | 
	
		
			
				|  |  | +            'category': category,
 | 
	
		
			
				|  |  | +            'paper': article,
 | 
	
		
			
				|  |  | +            'title': title,
 | 
	
		
			
				|  |  | +            'region': region
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def market_info(self, resource, r_id=False):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        Returns a list of data about current resource market state.
 | 
	
		
			
				|  |  | +        In form price, amount selling, player id, player name string, total offers on market.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if not r_id:
 | 
	
		
			
				|  |  | +            res_id = self.resource_id[resource]
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            res_id = resource
 | 
	
		
			
				|  |  | +        response = self.session.get(f'http://rivalregions.com/storage/market/{res_id}?{self.var_c}')
 | 
	
		
			
				|  |  | +        return self.parse_market_response(response, res_id)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get_all_market_info(self):
 | 
	
		
			
				|  |  | +        """Request all market info"""
 | 
	
		
			
				|  |  | +        session = sessions.FuturesSession(session=self.session)
 | 
	
		
			
				|  |  | +        results = {}
 | 
	
		
			
				|  |  | +        for type_ in self.resource_id:
 | 
	
		
			
				|  |  | +            if type_ == 'energy drink':
 | 
	
		
			
				|  |  | +                continue
 | 
	
		
			
				|  |  | +            results[type_] = session.get(
 | 
	
		
			
				|  |  | +                f'http://rivalregions.com/storage/market/{self.resource_id[type_]}?{self.var_c}'
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +        for res in results:
 | 
	
		
			
				|  |  | +            result = results[res].result()
 | 
	
		
			
				|  |  | +            price, selling_amount, player_id, player_name, total_offers = \
 | 
	
		
			
				|  |  | +                self.parse_market_response(result, self.resource_id[res])
 | 
	
		
			
				|  |  | +            results[res] = {
 | 
	
		
			
				|  |  | +                'price': price,
 | 
	
		
			
				|  |  | +                'amount': selling_amount,
 | 
	
		
			
				|  |  | +                'player_id': player_id,
 | 
	
		
			
				|  |  | +                'player_name': player_name,
 | 
	
		
			
				|  |  | +                'total_offers':total_offers
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        return results
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @staticmethod
 | 
	
		
			
				|  |  | +    def parse_market_response(response, res_id):
 | 
	
		
			
				|  |  | +        """Parse market response"""
 | 
	
		
			
				|  |  | +        price = re.search('<input price="(.*)" type', response.text).group(1)
 | 
	
		
			
				|  |  | +        selling_amount = re.search('<span max="(.*)" url="', response.text).group(1)
 | 
	
		
			
				|  |  | +        player_id = re.search(
 | 
	
		
			
				|  |  | +            '<span action="slide/profile/(.*)" class="storage_see pointer dot hov2', response.text
 | 
	
		
			
				|  |  | +        ).group(1)
 | 
	
		
			
				|  |  | +        player_name = re.search(
 | 
	
		
			
				|  |  | +            f'<span action="slide/profile/{player_id}" class="storage_see pointer dot hov2">(.*)</span>',
 | 
	
		
			
				|  |  | +            response.text
 | 
	
		
			
				|  |  | +        ).group(1)
 | 
	
		
			
				|  |  | +        total_offers = re.search(
 | 
	
		
			
				|  |  | +            f'Best offer out of <span action="storage/listed/{res_id}" class="storage_see pointer hov2"><span class="dot">(.*)</span></span>:',
 | 
	
		
			
				|  |  | +            response.text
 | 
	
		
			
				|  |  | +        ).group(1)
 | 
	
		
			
				|  |  | +        return price, selling_amount, player_id, player_name, total_offers
 |