client.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. """
  2. Client module
  3. """
  4. import logging
  5. import re
  6. import time
  7. import requests
  8. from webbot.webbot import Browser
  9. from requests_futures import sessions
  10. logging.basicConfig(
  11. format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
  12. level=logging.INFO
  13. )
  14. LOGGER = logging.getLogger(__name__)
  15. class RRClientException(Exception):
  16. """RR exception"""
  17. def __init__(self, *args, **kwargs):
  18. Exception.__init__(self, *args, **kwargs)
  19. LOGGER.warning('RRClientException')
  20. class Client:
  21. """class for RR client"""
  22. resource_id = {
  23. 'oil': 3,
  24. 'ore': 4,
  25. 'uranium': 11,
  26. 'diamond': 15,
  27. 'liquid oxygen': 21,
  28. 'helium-3': 24,
  29. 'antirad': 13,
  30. 'energy drink': 17,
  31. 'spacerockets': 20,
  32. 'tanks': 2,
  33. 'aircrafts': 1,
  34. 'missiles': 14,
  35. 'bombers': 16,
  36. 'battleships': 18,
  37. 'moon tanks': 22,
  38. 'space stations': 23
  39. }
  40. session_id = None
  41. var_c = None
  42. def __init__(self, credentials, expires=None, show_window=False):
  43. self.login_method = credentials['login_method']
  44. self.username = credentials['username']
  45. self.password = credentials['password']
  46. self.expires = expires
  47. self.show_window = show_window
  48. LOGGER.info('Init client login_method "%s" username "%s"', self.login_method, self.username)
  49. if self.login_method in ["g", "google", "v", "vk", "f", "facebook"]:
  50. self.login()
  51. else:
  52. raise RRClientException("Not a valid login method.")
  53. def login(self):
  54. """Login user"""
  55. LOGGER.info('Login as "%s"', self.username)
  56. auth_text = requests.get("http://rivalregions.com").text
  57. web = Browser(showWindow=self.show_window)
  58. method_dict = {
  59. 'g': self.login_google,
  60. 'google': self.login_google,
  61. 'v': self.login_vk,
  62. 'vk': self.login_vk,
  63. 'f': self.login_facebook,
  64. 'facebook': self.login_facebook,
  65. }
  66. if self.login_method in method_dict:
  67. web = method_dict[self.login_method](web, auth_text)
  68. else:
  69. LOGGER.info('Invallid loggin method "%s"', self.login_method)
  70. time.sleep(5)
  71. LOGGER.info('Get cookie')
  72. sessid = web.get_cookie('PHPSESSID')
  73. expires = sessid.get('expiry', None)
  74. sessid.pop('expiry', None)
  75. sessid.pop('httpOnly', None)
  76. sessid['expires'] = expires
  77. web.close_current_tab()
  78. LOGGER.info('closing login tab')
  79. self.session = requests.Session()
  80. self.expires = expires
  81. self.session_id = sessid
  82. self.session.cookies.set(**sessid)
  83. LOGGER.info('set the var_c')
  84. response = self.session.get('http://rivalregions.com/#overview')
  85. lines = response.text.split("\n")
  86. for line in lines:
  87. if re.match("(.*)var c_html(.*)", line):
  88. self.var_c = line.split("'")[-2]
  89. return
  90. def login_google(self, web, auth_text):
  91. """login using Google"""
  92. LOGGER.info('Login method Google')
  93. auth_text1 = auth_text.split('\t<a href="')
  94. auth_text2 = auth_text1[1].split('" class="sa')
  95. web.go_to(auth_text2[0])
  96. web.type(self.username, into='Email')
  97. web.click('Volgende')
  98. time.sleep(2)
  99. web.type(self.password, into='Password')
  100. web.click('Volgende')
  101. time.sleep(2)
  102. web.click(css_selector=".sa_sn.float_left.imp.gogo")
  103. return web
  104. def login_vk(self, web, auth_text):
  105. """login using VK"""
  106. LOGGER.info('Login method VK')
  107. auth_text1 = auth_text.split("(\'.vkvk\').attr(\'url\', \'")
  108. auth_text2 = auth_text1[1].split('&response')
  109. web.go_to(auth_text2[0])
  110. web.type(self.username, into='email')
  111. web.type(self.password, xpath="/html/body/div/div/div/div[2]/form/div/div/input[7]")
  112. web.click('Log in')
  113. return web
  114. def login_facebook(self, web, auth_text):
  115. """login using Facebook"""
  116. LOGGER.info('Login method Facebook')
  117. auth_text1 = auth_text.split('">\r\n\t\t\t\t<div class="sa_sn imp float_left" ')
  118. auth_text2 = auth_text1[0].split('200px;"><a class="sa_link" href="')
  119. url = auth_text2[1]
  120. web.go_to(url)
  121. web.type(self.username, into='Email')
  122. web.type(self.password, into='Password')
  123. web.click('Log In')
  124. time.sleep(5)
  125. web.click(css_selector='.sa_sn.imp.float_left')
  126. return web
  127. def create_article(
  128. self,
  129. title,
  130. article,
  131. article_lang="en",
  132. paper_id=0,
  133. category='0',
  134. region="4524"
  135. ):
  136. """Create new article"""
  137. response = self.session.get('http://rivalregions.com/#overview')
  138. response = self.session.post("http://rivalregions.com/news/post", data={
  139. 'c': self.var_c,
  140. 'newspaper': paper_id,
  141. 'category': category,
  142. 'paper': article,
  143. 'title': title,
  144. 'region': region
  145. })
  146. def market_info(self, resource, r_id=False):
  147. """
  148. Returns a list of data about current resource market state.
  149. In form price, amount selling, player id, player name string, total offers on market.
  150. """
  151. if not r_id:
  152. res_id = self.resource_id[resource]
  153. else:
  154. res_id = resource
  155. response = self.session.get(f'http://rivalregions.com/storage/market/{res_id}?{self.var_c}')
  156. return self.parse_market_response(response, res_id)
  157. def get_all_market_info(self):
  158. """Request all market info"""
  159. session = sessions.FuturesSession(session=self.session)
  160. results = {}
  161. for type_ in self.resource_id:
  162. if type_ == 'energy drink':
  163. continue
  164. results[type_] = session.get(
  165. f'http://rivalregions.com/storage/market/{self.resource_id[type_]}?{self.var_c}'
  166. )
  167. for res in results:
  168. result = results[res].result()
  169. price, selling_amount, player_id, player_name, total_offers = \
  170. self.parse_market_response(result, self.resource_id[res])
  171. results[res] = {
  172. 'price': price,
  173. 'amount': selling_amount,
  174. 'player_id': player_id,
  175. 'player_name': player_name,
  176. 'total_offers':total_offers
  177. }
  178. return results
  179. @staticmethod
  180. def parse_market_response(response, res_id):
  181. """Parse market response"""
  182. price = re.search('<input price="(.*)" type', response.text).group(1)
  183. selling_amount = re.search('<span max="(.*)" url="', response.text).group(1)
  184. player_id = re.search(
  185. '<span action="slide/profile/(.*)" class="storage_see pointer dot hov2', response.text
  186. ).group(1)
  187. player_name = re.search(
  188. f'<span action="slide/profile/{player_id}" class="storage_see pointer dot hov2">(.*)</span>',
  189. response.text
  190. ).group(1)
  191. total_offers = re.search(
  192. f'Best offer out of <span action="storage/listed/{res_id}" class="storage_see pointer hov2"><span class="dot">(.*)</span></span>:',
  193. response.text
  194. ).group(1)
  195. return price, selling_amount, player_id, player_name, total_offers