diff options
-rwxr-xr-x | async_bot.py | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/async_bot.py b/async_bot.py new file mode 100755 index 0000000..5f33f7e --- /dev/null +++ b/async_bot.py | |||
@@ -0,0 +1,255 @@ | |||
1 | # -*- coding: utf-8 -*- | ||
2 | |||
3 | import os | ||
4 | import re | ||
5 | import time | ||
6 | import json | ||
7 | import logging | ||
8 | import urllib | ||
9 | import sys | ||
10 | from selenium import webdriver | ||
11 | |||
12 | import telegram | ||
13 | from pymongo import MongoClient | ||
14 | |||
15 | import ingrex | ||
16 | |||
17 | import aiohttp | ||
18 | import asyncio | ||
19 | import async_timeout | ||
20 | |||
21 | bot = None | ||
22 | BOT_TOKEN = '' | ||
23 | CHANNEL_NAME = '' | ||
24 | Email = '' | ||
25 | Passwd = '' | ||
26 | PhantomJSPath = '' | ||
27 | DBName = '' | ||
28 | DBUser = '' | ||
29 | DBPass = '' | ||
30 | DBHost = '' | ||
31 | BlockList = '' | ||
32 | LOG_FILENAME = 'voh.log' | ||
33 | TIME_ZONE='Asia/Shanghai' | ||
34 | |||
35 | |||
36 | class CookieException(Exception): | ||
37 | pass | ||
38 | |||
39 | |||
40 | def get_time(): | ||
41 | return time.strftime('%x %X %Z') | ||
42 | |||
43 | |||
44 | def read_config(): | ||
45 | global Email | ||
46 | global Passwd | ||
47 | global BOT_TOKEN | ||
48 | global CHANNEL_NAME | ||
49 | global PhantomJSPath | ||
50 | global DBName | ||
51 | global DBUser | ||
52 | global DBPass | ||
53 | global DBHost | ||
54 | global BlockList | ||
55 | global LOG_FILENAME | ||
56 | |||
57 | configfile = open("./config.json") | ||
58 | config = json.load(configfile) | ||
59 | Email = config["Email"] | ||
60 | Passwd = config["Passwd"] | ||
61 | BOT_TOKEN = config["BOT_TOKEN"] | ||
62 | CHANNEL_NAME = config["CHANNEL_NAME"] | ||
63 | PhantomJSPath = config["PhantomJSPath"] | ||
64 | DBName = config["DBName"] | ||
65 | DBUser = config["DBUser"] | ||
66 | DBPass = config["DBPass"] | ||
67 | DBHost = config["DBHost"] | ||
68 | BlockList = config["BlockList"] | ||
69 | |||
70 | os.environ['TZ'] = TIME_ZONE | ||
71 | time.tzset() | ||
72 | |||
73 | logging.basicConfig(level=logging.DEBUG, | ||
74 | filename=LOG_FILENAME, | ||
75 | filemode='w') | ||
76 | console = logging.StreamHandler() | ||
77 | console.setLevel(logging.INFO) | ||
78 | formatter = logging.Formatter('%(name)-8s: %(levelname)-4s %(message)s') | ||
79 | console.setFormatter(formatter) | ||
80 | logging.getLogger('').addHandler(console) | ||
81 | |||
82 | |||
83 | def fetch_cookie(): | ||
84 | logger = logging.getLogger('fetch_cookie') | ||
85 | logger.info(get_time() + ': Fetching Cookie...') | ||
86 | |||
87 | driver = webdriver.PhantomJS(PhantomJSPath) | ||
88 | driver.get('https://www.ingress.com/intel') | ||
89 | |||
90 | # get login page | ||
91 | link = driver.find_elements_by_tag_name('a')[0].get_attribute('href') | ||
92 | driver.get(link) | ||
93 | driver.get_screenshot_as_file('1.png') | ||
94 | |||
95 | # simulate manual login | ||
96 | driver.set_page_load_timeout(10) | ||
97 | driver.set_script_timeout(20) | ||
98 | driver.find_element_by_id('Email').send_keys(Email) | ||
99 | driver.get_screenshot_as_file('2.png') | ||
100 | driver.find_element_by_css_selector('#next').click() | ||
101 | time.sleep(3) | ||
102 | driver.find_element_by_id('Passwd').send_keys(Passwd) | ||
103 | driver.get_screenshot_as_file('3.png') | ||
104 | driver.find_element_by_css_selector('#signIn').click() | ||
105 | time.sleep(3) | ||
106 | driver.get_screenshot_as_file('4.png') | ||
107 | |||
108 | # get cookies | ||
109 | cookies = driver.get_cookies() | ||
110 | |||
111 | csrftoken = '' | ||
112 | SACSID = '' | ||
113 | for key in cookies: | ||
114 | if key['name'] == 'csrftoken': | ||
115 | csrftoken = key['value'] | ||
116 | if key['name'] == 'SACSID': | ||
117 | SACSID = key['value'] | ||
118 | |||
119 | if csrftoken == '' or SACSID == '': | ||
120 | raise CookieException | ||
121 | |||
122 | with open('cookie', 'w') as file: | ||
123 | cookie = 'SACSID='+SACSID+'; csrftoken='+csrftoken+'; ingress.intelmap.shflt=viz; ingress.intelmap.lat=29.098418372855484; ingress.intelmap.lng=119.81689453125; ingress.intelmap.zoom=17' | ||
124 | file.write(cookie) | ||
125 | |||
126 | logger.info(get_time() + ': Fetching Cookie Succeed') | ||
127 | driver.quit() | ||
128 | return True | ||
129 | |||
130 | |||
131 | def send_message(bot, message, monitor=False): | ||
132 | logger = logging.getLogger('send_message') | ||
133 | while True: | ||
134 | try: | ||
135 | if monitor is True: | ||
136 | bot.sendMessage(chat_id="@voamonitor", text=message) | ||
137 | else: | ||
138 | bot.sendMessage(chat_id=CHANNEL_NAME, text=message) | ||
139 | logger.info(get_time() + ": sendMsg " + message) | ||
140 | break | ||
141 | except telegram.TelegramError: | ||
142 | logger.error(get_time() + ": Send Message to Channel Failed") | ||
143 | time.sleep(1) | ||
144 | except Exception: | ||
145 | logger.error(get_time() + ": Unexpected error: " + str(sys.exc_info()[0])) | ||
146 | time.sleep(1) | ||
147 | |||
148 | |||
149 | def find_message_record(id): | ||
150 | uri = 'mongodb://' + DBHost | ||
151 | conn = MongoClient(uri) | ||
152 | conn.api.authenticate(DBUser, DBPass, DBName) | ||
153 | database = conn[DBName] | ||
154 | collection = database.entries | ||
155 | count = collection.find({"id": id}).count() | ||
156 | conn.close() | ||
157 | if count == 0: | ||
158 | return False | ||
159 | else: | ||
160 | return True | ||
161 | |||
162 | |||
163 | def insert_message_to_database(time, id, msg): | ||
164 | uri = 'mongodb://' + DBHost | ||
165 | conn = MongoClient(uri) | ||
166 | conn.api.authenticate(DBUser, DBPass, DBName) | ||
167 | database = conn[DBName] | ||
168 | collection = database.entries | ||
169 | post = {"id": id, "time": time, "msg": msg} | ||
170 | collection.insert(post) | ||
171 | conn.close() | ||
172 | |||
173 | |||
174 | def main(): | ||
175 | logger = logging.getLogger('main') | ||
176 | |||
177 | # Lat Lng of Hangzhou | ||
178 | field = { | ||
179 | 'minLngE6': 119618783, | ||
180 | 'minLatE6': 29912919, | ||
181 | 'maxLngE6': 121018722, | ||
182 | 'maxLatE6': 30573739, | ||
183 | } | ||
184 | |||
185 | mints = -1 | ||
186 | maxts = -1 | ||
187 | reverse = False | ||
188 | tab = 'all' | ||
189 | |||
190 | # fetch cookie | ||
191 | while True: | ||
192 | try: | ||
193 | if fetch_cookie(): | ||
194 | break | ||
195 | except CookieException: | ||
196 | logger.error(get_time() + ': Fetch Cookie Failed') | ||
197 | time.sleep(3) | ||
198 | except Exception: | ||
199 | logger.error(get_time() + ": Unexpected error: " + str(sys.exc_info()[0])) | ||
200 | time.sleep(3) | ||
201 | |||
202 | # fetch message | ||
203 | count = 0 | ||
204 | while True: | ||
205 | count += 1 | ||
206 | |||
207 | with open('cookie') as cookies: | ||
208 | cookies = cookies.read().strip() | ||
209 | logger.info(get_time() + ": {} Fetching from Intel...".format(str(count))) | ||
210 | |||
211 | # fetch message per time | ||
212 | while True: | ||
213 | try: | ||
214 | intel = ingrex.Intel(cookies, field) | ||
215 | result = intel.fetch_msg(mints, maxts, reverse, tab) | ||
216 | if result: | ||
217 | mints = result[0][1] + 1 | ||
218 | break | ||
219 | except CookieException: | ||
220 | while True: | ||
221 | try: | ||
222 | if fetch_cookie(): | ||
223 | break | ||
224 | except CookieException: | ||
225 | time.sleep(3) | ||
226 | except Exception: | ||
227 | logger.error(get_time() + ": Unexpected error: " + str(sys.exc_info()[0])) | ||
228 | time.sleep(3) | ||
229 | |||
230 | for item in result[::-1]: | ||
231 | # Check spam message | ||
232 | pattern = re.compile(BlockList) | ||
233 | match = pattern.search(str(item)) | ||
234 | if match: | ||
235 | continue | ||
236 | |||
237 | message = ingrex.Message(item) | ||
238 | if message.ptype == 'PLAYER_GENERATED': | ||
239 | logger.info(get_time() + " " + message.msg) | ||
240 | if find_message_record(message.guid) is False: | ||
241 | insert_message_to_database(message.time, message.guid, message.msg) | ||
242 | send_message(bot, message.msg, False) | ||
243 | |||
244 | time.sleep(10) | ||
245 | |||
246 | if __name__ == '__main__': | ||
247 | read_config() | ||
248 | bot = telegram.Bot(BOT_TOKEN) | ||
249 | |||
250 | while True: | ||
251 | try: | ||
252 | main() | ||
253 | except Exception: | ||
254 | send_message(bot, 'Main Unexpected error' + str(sys.exc_info()[0]), True) | ||
255 | time.sleep(3) \ No newline at end of file | ||