22# coding=utf-8
33from datetime import date , datetime
44import os
5+ import random
56import sys
67import asyncio
8+ import tempfile
79import time
810import signal
911import traceback
12+ from urllib import request
13+ from urllib .request import FancyURLopener
1014
1115import hangups
1216from hangups .ui .utils import get_conv_name
1317from Core .Commands .Dispatcher import DispatcherSingleton
1418
15- from Core .Util import ConfigDict
19+ from Core .Util import ConfigDict , UtilDB
1620from Core import Handlers
1721
1822
23+ class HangoutsBotOpener (FancyURLopener ):
24+ version = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'
25+
26+
27+ request .urlretrieve = HangoutsBotOpener ().retrieve
28+
1929__version__ = '1.1'
2030LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
21- base_config = '''{
22- "admins": ["YOUR-USER-ID-HERE"],
23- "autoreplies_enabled": true,
24- "autoreplies": [
25- [["bot", "robot", "Yo"], "/think {}"]
26- ],
27- "development_mode": false,
28- "commands_admin": ["hangouts", "reload", "quit", "config", "block"],
29- "commands_conversation_admin": ["leave", "echo", "block"]
30- "commands_enabled": true,
31- "forwarding_enabled": false,
32- "rename_watching_enabled": true,
33- "conversations": {
34- "CONV-ID-HERE": {
35- "autoreplies": [
36- [["whistle", "bot", "whistlebot"], "/think {}"],
37- [["trash"], "You're trash"]
38- ],
39- "forward_to": [
40- "CONV1_ID"
41- ]
42- }
43- }
44- }'''
4531
4632
4733class ConversationEvent (object ):
@@ -82,6 +68,9 @@ def __init__(self, cookies_path, config_path, command_char='/', max_retries=5):
8268 self .config = ConfigDict .ConfigDict (config_path )
8369 self .devmode = self .get_config_suboption ('' , 'development_mode' )
8470
71+ self .database = "database.db"
72+ UtilDB .setDatabase (self .database )
73+
8574 # Handle signals on Unix
8675 # (add_signal_handler is not implemented on Windows)
8776 try :
@@ -137,7 +126,7 @@ def run(self):
137126 """Connect to Hangouts and run bot"""
138127 cookies = self .login (self ._cookies_path )
139128 if cookies :
140- for retry in range ( self . _max_retries ) :
129+ while True :
141130 try :
142131 # Create Hangups client
143132 self ._client = hangups .Client (cookies )
@@ -155,9 +144,7 @@ def run(self):
155144 log .writelines (str (datetime .now ()) + ":\n " + traceback .format_exc () + "\n \n " )
156145 log .close ()
157146 print (traceback .format_exc ())
158- print ('Waiting {} seconds...' .format (5 + retry * 5 ))
159- time .sleep (5 + retry * 5 )
160- print ('Trying to connect again (try {} of {})...' .format (retry + 1 , self ._max_retries ))
147+ time .sleep (10 )
161148 print ('Maximum number of retries reached! Exiting...' )
162149 sys .exit (1 )
163150
@@ -240,17 +227,32 @@ def send_message(self, conversation, text):
240227 """"Send simple chat message"""
241228 self .send_message_segments (conversation , [hangups .ChatMessageSegment (text )])
242229
243- def send_message_segments (self , conversation , segments ):
230+
231+ def send_message_segments (self , conversation , segments , image_id = None ):
244232 """Send chat message segments"""
245233 # Ignore if the user hasn't typed a message.
246234 if len (segments ) == 0 :
247235 return
248236 # XXX: Exception handling here is still a bit broken. Uncaught
249237 # exceptions in _on_message_sent will only be logged.
250238 asyncio .async (
251- conversation .send_message (segments )
239+ conversation .send_message (segments , image_id = image_id )
252240 ).add_done_callback (self ._on_message_sent )
253241
242+
243+ @asyncio .coroutine
244+ def upload_image (self , url , filename = None , delete = False ):
245+ if not filename :
246+ tempdir = tempfile .gettempdir ()
247+ filename = tempdir + os .sep + '{}.png' .format (random .randint (0 , 9999999999 ))
248+ request .urlretrieve (url , filename )
249+ file = open (filename , "rb" )
250+ image_id = yield from self ._client .upload_image (file )
251+ if delete :
252+ file .close ()
253+ os .remove (filename )
254+ return image_id
255+
254256 def list_conversations (self ):
255257 """List all active conversations"""
256258 convs = sorted (self ._conv_list .get_all (),
@@ -298,7 +300,7 @@ def _on_connect(self, initial_data):
298300
299301 print ('Conversations:' )
300302 for c in self .list_conversations ():
301- print (' {} ({})' .format (get_conv_name (c , truncate = True ), c .id_ ))
303+ print (( ' {} ({})' .format (get_conv_name (c , truncate = True ), c .id_ )). encode ( 'UTF-8' ))
302304 print ()
303305
304306 def _on_event (self , conv_event ):
0 commit comments