def roomlanguage(bot, event, *args): """sets the current room language supply parameter as either ISO639-1 2-letter language code or fulltext/fragment of language to set (e.g. "chinese", "hebr", "swahili", etc). """ language_map = gs.get_languages() language = " ".join(args) if not language: try: bot.send_message_parsed( event.conv, _('<i>syncroom "{}" language is {}</i>').format( get_conv_name(event.conv), language_map[_get_room_language(bot, event.conv_id)])) except KeyError: pass return for iso_language in language_map: text_language = language_map[iso_language] if language.lower() in text_language.lower( ) or language == iso_language.upper(): bot.conversation_memory_set(event.conv_id, 'syncroom_language', iso_language) bot.send_message_parsed( event.conv, _('<i>syncroom "{}" language set to {}</i>').format( get_conv_name(event.conv), text_language)) break
def conversation_to_channel(conv): """Return channel name for hangups.Conversation.""" # Must be 50 characters max and not contain space or comma. conv_hash = hashlib.sha1(conv.id_.encode()).hexdigest() # comma to underscore # space to nospace name = get_conv_name(conv).replace(',', '_').replace(' ', '') # only keep alpha nums name = re.sub(r'[^0-9a-zA-Z_]+', '', name) if name == "": name = emoji.emoji_to_shortcode(get_conv_name(conv)) name = re.sub(r'[^0-9a-zA-Z_]+', '', name) name = "{}".format(name[:21]) if name in hashes and hashes[name] != conv_hash: while name in hashes: if len(name) > 50: name = "{}_".format(name[:-1]) else: name = "{}_".format(name) hashes[name.lower()] = conv_hash return name
def roomlanguage(bot, event, *args): """sets the current room language supply parameter as either ISO639-1 2-letter language code or fulltext/fragment of language to set (e.g. "chinese", "hebr", "swahili", etc). """ language_map = gs.get_languages() language = " ".join(args) if not language: try: bot.send_message_parsed( event.conv, _('<i>syncroom "{}" language is {}</i>').format( get_conv_name(event.conv), language_map[_get_room_language(bot, event.conv_id)])) except KeyError: pass return for iso_language in language_map: text_language = language_map[iso_language] if language.lower() in text_language.lower() or language == iso_language.upper(): bot.conversation_memory_set(event.conv_id, 'syncroom_language', iso_language) bot.send_message_parsed( event.conv, _('<i>syncroom "{}" language set to {}</i>').format( get_conv_name(event.conv), text_language)) break
def __on_connect(self, initial_data): """ Handle connection """ self.__log.debug("Bot connected") self.__id = initial_data.self_entity.id_.gaia_id self.__user_list = hangups.UserList(self.__client, initial_data.self_entity, initial_data.entities, initial_data.conversation_participants) self.__conversation_list = hangups.ConversationList(self.__client, initial_data.conversation_states, self.__user_list, initial_data.sync_timestamp) self.__conversation_list.on_event.add_observer(self.__on_conversation_event) # create known conversation self.__log.debug('Loading initial conversations:') for conversation in self.__conversation_list.get_all(): self.__brain.register_conversation(get_conv_name(conversation, truncate=True), conversation.id_) self.__log.debug(' {} ({})' .format(get_conv_name(conversation, truncate=True), conversation.id_)) # create known users self.__log.debug('Loading initial users:') for user in self.__user_list.get_all(): self.__brain.register_user(full_name=user.full_name, gaia_id=user.id_.gaia_id) self.__log.debug('* {}' .format(user.full_name))
def update_conversations(self): """Update list of conversations""" self.conversationsListWidget.clear() for conv in sorted(self.conv_list.get_all(), reverse=True, key=lambda c: c.last_modified): item = QtGui.QListWidgetItem(get_conv_name(conv, truncate=True)) item.setToolTip(get_conv_name(conv)) item.setData(QtCore.Qt.UserRole, conv.id_) self.conversationsListWidget.addItem(item)
def kick(bot, event, *args): user_ids_to_remove = list(set(args)) user_ids = list() for u in sorted(event.conv.users, key=lambda x: x.full_name.split()[-1]): if not u.id_.chat_id in user_ids_to_remove: user_ids.append(u.id_.chat_id) response = yield from bot._client.createconversation(user_ids) new_conversation_id = response['conversation']['id']['id'] bot.send_html_to_conversation( new_conversation_id, _("<i>New conversation created</i><br /><b>Please leave the old one</b>" )) bot.send_html_to_conversation(event.conv_id, _("<b>PLEASE LEAVE THIS HANGOUT</b>")) conv = bot._conv_list.get(event.conv_id) conv_title = get_conv_name(conv) # Double confirm that the bot is not going to change the topic back bot.initialise_memory(event.conv_id, "conv_data") bot.memory.set_by_path(["conv_data", event.conv_id, "topic"], "") yield from bot._client.setchatname(event.conv_id, _("[DEAD]")) yield from bot._client.setchatname(new_conversation_id, conv_title)
def __init__(self, conversation, close_callback, keybindings): rename_dialog = RenameConversationDialog( conversation, lambda: frame.contents.__setitem__('body', (list_box, None)), close_callback ) items = [ urwid.Text( 'Conversation name: {}'.format(get_conv_name(conversation)) ), urwid.Button( 'Change Conversation Name', on_press=lambda _: frame.contents.__setitem__( 'body', (rename_dialog, None) ) ), urwid.Divider('-'), urwid.Button('Back', on_press=lambda _: close_callback()), ] list_walker = urwid.SimpleFocusListWalker(items) list_box = urwid.ListBox(list_walker) frame = urwid.Frame(list_box) padding = urwid.Padding(frame, left=1, right=1) line_box = urwid.LineBox(padding, title='Conversation Menu') super().__init__(line_box) self._keys = keybindings
def _send_notification(bot, event, phrase, user): """Alert a user that a keyword that they subscribed to has been used""" conversation_name = get_conv_name(event.conv, truncate=True) logging.info( _("subscribe: keyword '{}' in '{}' ({})").format( phrase, conversation_name, event.conv.id_)) """send alert with 1on1 conversation""" conv_1on1 = bot.get_1on1_conversation(user.id_.chat_id) if conv_1on1: try: user_has_dnd = bot.call_shared("dnd.user_check", user.id_.chat_id) except KeyError: user_has_dnd = False if not user_has_dnd: # shared dnd check bot.send_message_parsed( conv_1on1, _("<b>{}</b> mentioned '{}' in <i>{}</i>:<br />{}").format( event.user.full_name, phrase, conversation_name, event.text)) logging.info( _("subscribe: {} ({}) alerted via 1on1 ({})").format( user.full_name, user.id_.chat_id, conv_1on1.id_)) else: logging.info( _("subscribe: {} ({}) has dnd").format(user.full_name, user.id_.chat_id)) else: logging.warning( _("subscribe: user {} ({}) could not be alerted via 1on1").format( user.full_name, user.id_.chat_id))
def set_title(self, future=None): title = get_conv_name(self.conv, show_unread=False, truncate=True) pyotherside.send('set-conversation-title', self.conv.id_, title, get_unread_messages_count(self.conv), self.status_message) if future: future.result()
def _on_event(self, conv_event): """Create notification for new messages.""" conv = self._conv_list.get(conv_event.conversation_id) user = conv.get_user(conv_event.user_id) # Ignore non-messages or messages sent by yourself. if (not user.is_self and isinstance(conv_event, hangups.ChatMessageEvent)): # We have to escape angle brackets because freedesktop.org # notifications support markup. cmd = [ arg.format( sender_name=NOTIFY_ESCAPER(user.full_name), msg_text=NOTIFY_ESCAPER(conv_event.text), replaces_id=self._replaces_id, convo_name=NOTIFY_ESCAPER(get_conv_name(conv)), ) for arg in NOTIFY_CMD ] # Run the notification and parse out the replaces_id. Since the # command is a list of arguments, and we're not using a shell, this # should be safe. logger.info('Creating notification with command: {}'.format(cmd)) try: output = subprocess.check_output( cmd, stderr=subprocess.STDOUT).decode() except (subprocess.CalledProcessError, FileNotFoundError) as e: logger.warning('Notification command failed: {}'.format(e)) return try: self._replaces_id = RESULT_RE.match(output).groups()[0] except (AttributeError, IndexError) as e: logger.warning('Failed to parse notification command ' 'result: {}'.format(e))
def _on_event(self, conv_event): """Create notification for new messages.""" conv = self._conv_list.get(conv_event.conversation_id) user = conv.get_user(conv_event.user_id) # Ignore non-messages or messages sent by yourself. if (not user.is_self and isinstance(conv_event, hangups.ChatMessageEvent)): # We have to escape angle brackets because freedesktop.org # notifications support markup. cmd = [arg.format( sender_name=NOTIFY_ESCAPER(user.full_name), msg_text=NOTIFY_ESCAPER(conv_event.text), replaces_id=self._replaces_id, convo_name=NOTIFY_ESCAPER(get_conv_name(conv)), ) for arg in NOTIFY_CMD] # Run the notification and parse out the replaces_id. Since the # command is a list of arguments, and we're not using a shell, this # should be safe. logger.info('Creating notification with command: {}'.format(cmd)) try: output = subprocess.check_output( cmd, stderr=subprocess.STDOUT ).decode() except (subprocess.CalledProcessError, FileNotFoundError) as e: logger.warning('Notification command failed: {}'.format(e)) return try: self._replaces_id = RESULT_RE.match(output).groups()[0] except (AttributeError, IndexError) as e: logger.warning('Failed to parse notification command ' 'result: {}'.format(e))
def print_conversations(self): print(_('Conversations:')) for c in self.list_conversations(): print(' {} ({}) u:{}'.format(get_conv_name(c, truncate=True), c.id_, len(c.users))) for u in c.users: print(' {} ({}) {}'.format(u.first_name, u.full_name, u.id_.chat_id)) print()
def user_list(bot, event, conv_name='', user_name='', *args): """List all participants in current (or specified) conversation You can also use . for current conversation. Includes G+ accounts and emails. Usage: /bot users_list [conversation_name] [user_name]""" conv_name = strip_quotes(conv_name) user_name = strip_quotes(user_name) convs = [event.conv] if not conv_name or conv_name == '.' else bot.find_conversations(conv_name) segments = [] for c in convs: segments.append(hangups.ChatMessageSegment(_('List of participants in "{}" ({} total):').format( get_conv_name(c, truncate=True), len(c.users)), is_bold=True)) segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)) for u in bot.find_users(user_name, conv=c): link = 'https://plus.google.com/u/0/{}/about'.format(u.id_.chat_id) segments.append(hangups.ChatMessageSegment(u.full_name, hangups.SegmentType.LINK, link_target=link)) if u.emails: segments.append(hangups.ChatMessageSegment(' (')) segments.append(hangups.ChatMessageSegment(u.emails[0], hangups.SegmentType.LINK, link_target='mailto:{}'.format(u.emails[0]))) segments.append(hangups.ChatMessageSegment(')')) segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)) segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)) bot.send_message_segments(event.conv, segments)
def rsvp(bot, event, *args): """show/claim invite codes""" if len(args) == 1: yield from _claim_invite(bot, args[0], event.user.id_.chat_id) else: invites = [] if bot.memory.exists(["invites"]): for invite_id, invite in bot.memory["invites"].items(): if invite["user_id"] in ("*", event.user.id_.chat_id): if invite["expiry"] > time.time(): invites.append(invite) if len(invites) > 0: lines = [] lines.append(_("<b>Invites for {}:</b>").format(event.user.full_name)) for invite in invites: conversation_name = get_conv_name(bot._conv_list.get(invite["group_id"])) expiry_in_days = round((invite["expiry"] - time.time()) / 86400, 1) lines.append("<b>{}</b> ... {} ({} days left)".format(conversation_name, invite["id"], expiry_in_days)) lines.append("") lines.append(_("<em>To claim an invite, use the rsvp command followed by the invite code</em>")) bot.send_html_to_conversation(event.conv_id, "<br />".join(lines)) else: bot.send_html_to_conversation(event.conv_id, _("<em>no invites to display</em>"))
def _send_notification(bot, event, phrase, user): """Alert a user that a keyword that they subscribed to has been used""" conversation_name = get_conv_name(event.conv, truncate=True); logging.info(_("subscribe: keyword '{}' in '{}' ({})").format(phrase, conversation_name, event.conv.id_)) """send alert with 1on1 conversation""" conv_1on1 = bot.get_1on1_conversation(user.id_.chat_id) if conv_1on1: try: user_has_dnd = bot.call_shared("dnd.user_check", user.id_.chat_id) except KeyError: user_has_dnd = False if not user_has_dnd: # shared dnd check bot.send_message_parsed( conv_1on1, _("<b>{}</b> mentioned '{}' in <i>{}</i>:<br />{}").format( event.user.full_name, phrase, conversation_name, event.text)) logging.info(_("subscribe: {} ({}) alerted via 1on1 ({})").format(user.full_name, user.id_.chat_id, conv_1on1.id_)) else: logging.info(_("subscribe: {} ({}) has dnd").format(user.full_name, user.id_.chat_id)) else: logging.warning(_("subscribe: user {} ({}) could not be alerted via 1on1").format(user.full_name, user.id_.chat_id))
def print_conversations(self): print('Conversations:') for c in self.list_conversations(): print(' {} ({}) u:{}'.format(get_conv_name(c, truncate=True), c.id_, len(c.users))) for u in c.users: print(' {} ({}) {}'.format(u.first_name, u.full_name, u.id_.chat_id)) print()
def quit(bot, event, *args): """Oh my God! They killed Kenny! You bastards!""" print( _('HangupsBot killed by user {} from conversation {}').format( event.user.full_name, get_conv_name(event.conv, truncate=True))) yield from event.conv.send_message(text_to_segments(_('Et tu, Brute?'))) yield from bot._client.disconnect()
def conversation_to_channel(conv): """Return channel name for hangups.Conversation.""" # Must be 50 characters max and not contain space or comma. conv_hash = hashlib.sha1(conv.id_.encode()).hexdigest() name = get_conv_name(conv).replace(',', '_').replace(' ', '') return '#{}[{}]'.format(name[:50 - CONV_HASH_LEN - 3], conv_hash[:CONV_HASH_LEN])
def _on_connect(self, initial_data): """Handle connecting for the first time""" print('Connected!') self._message_handler = Handlers.MessageHandler( self, command_char=self._command_char) self._user_list = hangups.UserList( self._client, initial_data.self_entity, initial_data.entities, initial_data.conversation_participants) self._conv_list = hangups.ConversationList( self._client, initial_data.conversation_states, self._user_list, initial_data.sync_timestamp) self._conv_list.on_event.add_observer(self._on_event) print('Conversations:') for c in self.list_conversations(): print(' %s (%s)' % (unidecode(get_conv_name(c, truncate=True)), c.id_)) print() msg = "I'm alive!" for c in self.list_conversations(): try: welcome_enabled = self.config['conversations'][ c.id_]['welcome_enabled'] except KeyError: welcome_enabled = False if welcome_enabled: self.send_message_segments(c, [hangups.ChatMessageSegment(msg)])
def __init__(self, coroutine_queue, conversation, close_callback, keybindings): rename_dialog = RenameConversationDialog( coroutine_queue, conversation, lambda: frame.contents.__setitem__('body', (list_box, None)), close_callback, keybindings ) items = [ urwid.Text( 'Conversation name: {}'.format(get_conv_name(conversation)) ), urwid.Button( 'Change Conversation Name', on_press=lambda _: frame.contents.__setitem__( 'body', (rename_dialog, None) ) ), urwid.Divider('-'), urwid.Button('Back', on_press=lambda _: close_callback()), ] list_walker = urwid.SimpleFocusListWalker(items) list_box = ListBox(keybindings, list_walker) frame = urwid.Frame(list_box) padding = urwid.Padding(frame, left=1, right=1) line_box = urwid.LineBox(padding, title='Conversation Menu') super().__init__(line_box)
def _on_connect(self, initial_data): """Handle connecting for the first time""" print('Connected!') self._user_list = hangups.UserList(self._client, initial_data.self_entity, initial_data.entities, initial_data.conversation_participants) self._conv_list = hangups.ConversationList(self._client, initial_data.conversation_states, self._user_list, initial_data.sync_timestamp) self._conv_list.on_event.add_observer(self._on_event) self._message_handler = Handlers.MessageHandler(self, command_char=self._command_char) print('Conversations:') for c in self.list_conversations(): print((' {} ({})'.format(get_conv_name(c, truncate=True), c.id_)).encode('UTF-8')) print() msg = "I'm alive!" for c in self.list_conversations(): try: welcome_enabled = self.config['conversations'][c.id_]['welcome_enabled'] except KeyError: welcome_enabled = False if welcome_enabled: self.send_message(c, msg)
def whereami(bot, event, *args): """get current conversation id""" bot.send_message_parsed( event.conv, _("You are at <b>{}</b>, conv_id = <i>{}</i>").format( get_conv_name(event.conv, truncate=True), event.conv.id_))
def on_event(conv_event): global conv_list, conv_controllers conv = conv_list.get(conv_event.conversation_id) user = conv.get_user(conv_event.user_id) # is this a new conversation? if conv_event.conversation_id not in conv_controllers.keys(): convs = sorted(conv_list.get_all(), reverse=True, key=lambda c: c.last_modified) for conv in convs: if conv.id_ == conv_event.conversation_id: break conv_data = { "title": get_conv_name(conv), "status_message": "", "icon": get_conv_icon(conv), "id_": conv.id_, "first_message_loaded": False, "unread_count": get_unread_messages_count(conv), "is_quiet": conv.is_quiet, "users": [{ "id_": user.id_[0], "full_name": user.full_name, "first_name": user.first_name, "photo_url": "https:" + user.photo_url if user.photo_url else None, "emails": user.emails, "is_self": user.is_self } for user in conv.users] } pyotherside.send('add-conversation', conv_data, True) ctrl = ConversationController(conv) conv_controllers[conv.id_] = ctrl pyotherside.send('move-conversation-to-top', conv_event.conversation_id) else: pyotherside.send('move-conversation-to-top', conv_event.conversation_id)
def on_event(conv_event): global conv_list, event_queue #pprint(getmembers(conv_event)) if isinstance(conv_event, hangups.ChatMessageEvent): conv = conv_list.get(conv_event.conversation_id) user = conv.get_user(conv_event.user_id) try: msgJson = json.dumps({ 'status': 'success', 'type': 'message', 'content': conv_event.text, 'attachments': conv_event.attachments, 'conversation_id': conv.id_, 'conversation_name': get_conv_name(conv), 'photo_url': user.photo_url, 'user': user.full_name, 'self_user_id': user_list._self_user.id_.chat_id, 'user_id': { 'chat_id': conv_event.user_id.chat_id, 'gaia_id': conv_event.user_id.gaia_id } }) print_jsonmsg(msgJson) except Exception as error: print(repr(error))
def print_debug(self): print('Conversation ID: {}'.format(self.conv_id)) print('Conversation name: {}'.format(get_conv_name(self.conv, truncate=True))) print('User ID: {}'.format(self.user_id)) print('User name: {}'.format(self.user.full_name)) print('Timestamp: {}'.format(self.timestamp.astimezone(tz=None).strftime('%Y-%m-%d %H:%M:%S'))) print('Text: {}'.format(self.text)) print()
def quit(bot, event, *args): """Oh my God! They killed Kenny! You bastards!""" print(_('HangupsBot killed by user {} from conversation {}').format(event.user.full_name, get_conv_name(event.conv, truncate=True))) yield from event.conv.send_message([ hangups.ChatMessageSegment(_('Et tu, Brute?')) ]) yield from bot._client.disconnect()
def on_connect(initial_data): """Handle connecting for the first time.""" global client, disable_notifier, conv_list, user_list print("Building user list") user_list = yield from hangups.build_user_list( client, initial_data ) print("Adding contacts") for user in sorted(user_list.get_all(), key=lambda u: u.full_name): user_data = { "id_": user.id_.chat_id, "name": user.full_name, "first_name": user.first_name, "photo_url": "https:" + user.photo_url if user.photo_url else None, "emails": user.emails, } if not user.is_self: pyotherside.send('add-contact', user_data) print("Creating conversations list") conv_list = hangups.ConversationList( client, initial_data.conversation_states, user_list, initial_data.sync_timestamp ) print("Added conversations oveserver") conv_list.on_event.add_observer(on_event) if not disable_notifier: notifier = Notifier(conv_list) convs = sorted(conv_list.get_all(), reverse=True, key=lambda c: c.last_modified) print("Showing conversations") for conv in convs: conv_data = { "title": get_conv_name(conv), "status_message": "", "icon": get_conv_icon(conv), "id_": conv.id_, "first_message_loaded": False, "unread_count": get_unread_messages_count(conv), "is_quiet": conv.is_quiet, "users": [{ "id_": user.id_[0], "full_name": user.full_name, "first_name": user.first_name, "photo_url": "https:" + user.photo_url if user.photo_url else None, "emails": user.emails, "is_self": user.is_self } for user in conv.users] } pyotherside.send('add-conversation', conv_data) ctrl = ConversationController(conv) conv_controllers[conv.id_] = ctrl pyotherside.send('show-conversations-page')
def quit(bot, event, *args): """ **Quit:** Usage: /quit Purpose: Closes the Bot. """ print('HangupsBot killed by user {} from conversation {}'.format(event.user.full_name, get_conv_name(event.conv, truncate=True))) yield from bot._client.disconnect()
def find_conversations(self, conv_name): """Find conversations by name or ID in list of all active conversations""" conv_name = conv_name.strip() conv_name_lower = conv_name.lower() if conv_name_lower.startswith("id:"): return [self._conv_list.get(conv_name[3:])] convs = [c for c in self.list_conversations() if conv_name_lower in get_conv_name(c, truncate=True).lower()] return convs
def print_debug(self): """Print informations about conversation event""" print(_('eid/dtime: {}/{}').format(self.event_id, self.timestamp.astimezone(tz=None).strftime('%Y-%m-%d %H:%M:%S'))) print(_('cid/cname: {}/{}').format(self.conv_id, get_conv_name(self.conv, truncate=True))) if(self.user_id.chat_id == self.user_id.gaia_id): print(_('uid/uname: {}/{}').format(self.user_id.chat_id, self.user.full_name)) else: print(_('uid/uname: {}!{}/{}').format(self.user_id.chat_id, self.user_id.gaia_id, self.user.full_name)) print(_('txtlen/tx: {}/{}').format(len(self.text), self.text)) print(_('eventdump: completed --8<--'))
def rpicenter(bot, event, *args): sentence = ' '.join(args) __conv_name__ = get_conv_name(event.conv, truncate=True).lower() #print("Conv name: " + str(__conv_name__)) #send MQTT msg to the rpicenter bot.mqtt.reply(requestID=str(__conv_name__),msg=str(sentence)) status = "Request Sent to rpicenter: " + str(__conv_name__) yield from event.conv.send_message(text_to_segments(str(status)))
def set_title(self): """Update this conversation's tab title.""" title = get_conv_name(self.conv, truncate=True) conv_widget_id = self.tab_parent.conversationsTabWidget.indexOf(self) num_unread = self.get_num_unread() if num_unread > 0: title += ' ({})'.format(num_unread) self.tab_parent.conversationsTabWidget.tabBar().setTabTextColor(conv_widget_id, QtCore.Qt.darkBlue) else: self.tab_parent.conversationsTabWidget.tabBar().setTabTextColor(conv_widget_id, QtGui.QColor()) self.tab_parent.conversationsTabWidget.setTabText(conv_widget_id, title) self.tab_parent.conversationsTabWidget.setTabToolTip(conv_widget_id, title)
def __init__(self, conversation_list, on_select): # Build buttons for selecting conversations ordered by most recently # modified first. convs = sorted(conversation_list.get_all(), reverse=True, key=lambda c: c.last_modified) on_press = lambda button, conv_id: on_select(conv_id) buttons = [urwid.Button(get_conv_name(conv, show_unread=True), on_press=on_press, user_data=conv.id_) for conv in convs] listbox = urwid.ListBox(urwid.SimpleFocusListWalker(buttons)) widget = urwid.Padding(listbox, left=2, right=2) super().__init__(widget)
def _on_connect(self): """Handle connecting for the first time""" print(_('Connected!')) self._retry = 0 self._user_list, self._conv_list = ( yield from hangups.build_user_conversation_list(self._client)) self._conv_list.on_event.add_observer(self._on_event) print(_('Conversations:')) for c in self.list_conversations(): print(' {} ({})'.format(get_conv_name(c, truncate=True), c.id_)) print()
def _on_connect(self): """Handle connecting for the first time""" print(_('Connected!')) self._retry = 0 self._user_list, self._conv_list = ( yield from hangups.build_user_conversation_list(self._client) ) self._conv_list.on_event.add_observer(self._on_event) print(_('Conversations:')) for c in self.list_conversations(): print(' {} ({})'.format(get_conv_name(c, truncate=True), c.id_)) print()
def hangout(bot, event, *args): """list all hangouts matching search text""" text_search = ' '.join(args) if not text_search: return text_message = _('<b>results for hangouts named "{}"</b><br />').format(text_search) for conv in bot.list_conversations(): conv_name = get_conv_name(conv) if text_search.lower() in conv_name.lower(): text_message = text_message + "<i>" + conv_name + "</i>" text_message = text_message + " ... " + conv.id_ text_message = text_message + "<br />" bot.send_message_parsed(event.conv.id_, text_message)
def __init__(self, conversation, on_cancel, on_save): self._conversation = conversation edit = urwid.Edit(edit_text=get_conv_name(conversation)) items = [ urwid.Text('Rename conversation:'), edit, urwid.Button( 'Save', on_press=lambda _: self._rename(edit.edit_text, on_save)), urwid.Button('Cancel', on_press=lambda _: on_cancel()), ] list_walker = urwid.SimpleFocusListWalker(items) list_box = urwid.ListBox(list_walker) super().__init__(list_box)
def hangout(bot, event, *args): """list all hangouts matching search text""" text_search = ' '.join(args) if not text_search: return text_message = _('<b>results for hangouts named "{}"</b><br />').format( text_search) for conv in bot.list_conversations(): conv_name = get_conv_name(conv) if text_search.lower() in conv_name.lower(): text_message = text_message + "<i>" + conv_name + "</i>" text_message = text_message + " ... " + conv.id_ text_message = text_message + "<br />" bot.send_message_parsed(event.conv.id_, text_message)
def _handle_syncrooms_membership_change(bot, event, command): if not bot.get_config_option('syncing_enabled'): return # Don't handle events caused by the bot himself if event.user.is_self: return syncouts = bot.get_config_option('sync_rooms') if not syncouts: return # Sync rooms not configured, returning # are we in a sync room? sync_room_list = None for _rooms in syncouts: if event.conv_id in _rooms: sync_room_list = _rooms break if sync_room_list is None: return # Generate list of added or removed users for current ROOM (NOT SYNCROOMS!) event_users = [ event.conv.get_user(user_id) for user_id in event.conv_event.participant_ids ] names = ', '.join([user.full_name for user in event_users]) syncroom_name = '<b>' + get_conv_name(event.conv) + '</b>' # JOIN a specific room if event.conv_event.type_ == hangups.MembershipChangeType.JOIN: print( _("SYNCROOMS: {} user(s) added to {}").format( len(event_users), event.conv_id)) if syncroom_name: bot.send_message_parsed( event.conv, '<i>{} has added {} to {}</i>'.format(event.user.full_name, names, syncroom_name)) # LEAVE a specific room else: print( _("SYNCROOMS: {} user(s) left {}").format(len(event_users), event.conv_id)) if syncroom_name: bot.send_message_parsed( event.conv, '<i>{} has left {}</i>'.format(names, syncroom_name))
def hangouts(bot, event, *args): """Výpis všech aktivních Hangoutů, v kterých řádí bot Vysvětlivky: c ... commands, f ... forwarding, a ... autoreplies""" segments = [hangups.ChatMessageSegment('List of active hangouts:', is_bold=True), hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)] for c in bot.list_conversations(): s = '{} [c: {:d}, f: {:d}, a: {:d}]'.format(get_conv_name(c, truncate=True), bot.get_config_suboption(c.id_, 'commands_enabled'), bot.get_config_suboption(c.id_, 'forwarding_enabled'), bot.get_config_suboption(c.id_, 'autoreplies_enabled')) segments.append(hangups.ChatMessageSegment(s)) segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)) bot.send_message_segments(event.conv, segments)
def __init__(self, conversation, on_cancel, on_save): self._conversation = conversation edit = urwid.Edit(edit_text=get_conv_name(conversation)) items = [ urwid.Text('Rename conversation:'), edit, urwid.Button( 'Save', on_press=lambda _: self._rename(edit.edit_text, on_save) ), urwid.Button('Cancel', on_press=lambda _: on_cancel()), ] list_walker = urwid.SimpleFocusListWalker(items) list_box = urwid.ListBox(list_walker) super().__init__(list_box)
def leave(bot, event, conversation=None, *args): """exits current or other specified hangout""" convs = [] if not conversation: convs.append(event.conv) else: conversation = conversation.strip().lower() for c in bot.list_conversations(): if conversation in get_conv_name(c, truncate=True).lower(): convs.append(c) for c in convs: yield from c.send_message( [hangups.ChatMessageSegment('I\'ll be back!')]) yield from bot._conv_list.leave_conversation(c.id_)
def __init__(self, conversation_list, on_select): # Build buttons for selecting conversations ordered by most recently # modified first. convs = sorted(conversation_list.get_all(), reverse=True, key=lambda c: c.last_modified) on_press = lambda button, conv_id: on_select(conv_id) buttons = [ urwid.Button(get_conv_name(conv, show_unread=True), on_press=on_press, user_data=conv.id_) for conv in convs ] listbox = urwid.ListBox(urwid.SimpleFocusListWalker(buttons)) widget = urwid.Padding(listbox, left=2, right=2) super().__init__(widget)
def conversation_to_channel(conv): """Return channel name for hangups.Conversation.""" # Must be 50 characters max and not contain space or comma. name = get_conv_name(conv).replace(',', '_').replace(' ', '') name = "#{}".format(name[:49]) conv_hash = hashlib.sha1(conv.id_.encode()).hexdigest() # Avoid name collisions. if name in hashes and hashes[name] != conv_hash: while name in hashes: if len(name) > 50: name = "{}_".format(name[:-1]) else: name = "{}_".format(name) hashes[name] = conv_hash return name
def on_rename(event): event_timestamp = event.timestamp conversation_id = event.conv_id conversation_name = get_conv_name(event.conv) conversation_text = event.text user_full_name = event.user.full_name user_id = event.user_id text = "--- {}\n{} :: {}\nCONVERSATION RENAMED: {}\n".format( conversation_name, event_timestamp, user_full_name, conversation_name) logger._append_to_file(conversation_id, text)
def on_chat_message(event): event_timestamp = event.timestamp conversation_id = event.conv_id conversation_name = get_conv_name(event.conv) conversation_text = event.text user_full_name = event.user.full_name user_id = event.user_id text = "--- {}\n{} :: {}\n{}\n".format(conversation_name, event_timestamp, user_full_name, conversation_text) logger._append_to_file(conversation_id, text)
def _on_connect(self, initial_data): """Handle connecting for the first time""" print(_('Connected!')) self._retry = 0 self._user_list = yield from hangups.build_user_list( self._client, initial_data) self._conv_list = hangups.ConversationList( self._client, initial_data.conversation_states, self._user_list, initial_data.sync_timestamp) self._conv_list.on_event.add_observer(self._on_event) print(_('Conversations:')) for c in self.list_conversations(): print(' {} ({})'.format(get_conv_name(c, truncate=True), c.id_)) print()
def on_event(self, conv, conv_event): """Create notification for new messages.""" user = conv.get_user(conv_event.user_id) # Ignore non-messages or messages sent by yourself. show_notification = all(( isinstance(conv_event, hangups.ChatMessageEvent), not user.is_self, not conv.is_quiet, )) if show_notification: # terminal bell sys.stderr.write('\a') sys.stderr.flush() # We have to escape angle brackets because freedesktop.org # notifications support markup. if self._discreet_notification: user = NOTIFY_ESCAPER("hangups") message = NOTIFY_ESCAPER("New message") else: user = NOTIFY_ESCAPER(user.full_name) message = NOTIFY_ESCAPER(conv_event.text) cmd = [arg.format( sender_name=user, msg_text=message, replaces_id=self._replaces_id, convo_name=NOTIFY_ESCAPER(get_conv_name(conv)), ) for arg in NOTIFY_CMD] # Run the notification and parse out the replaces_id. Since the # command is a list of arguments, and we're not using a shell, this # should be safe. logger.info('Creating notification with command: {}'.format(cmd)) try: output = subprocess.check_output( cmd, stderr=subprocess.STDOUT ).decode() except (subprocess.CalledProcessError, FileNotFoundError) as e: # Only log this at INFO level to prevent log spam when gdbus # isn't available. logger.info('Notification command failed: {}'.format(e)) return try: self._replaces_id = RESULT_RE.match(output).groups()[0] except (AttributeError, IndexError) as e: logger.warning('Failed to parse notification command ' 'result: {}'.format(e))
def set_title(self): """Update this conversation's tab title.""" title = get_conv_name(self.conv, truncate=True) conv_widget_id = self.tab_parent.conversationsTabWidget.indexOf(self) num_unread = self.get_num_unread() if num_unread > 0: title += ' ({})'.format(num_unread) self.tab_parent.conversationsTabWidget.tabBar().setTabTextColor( conv_widget_id, QtCore.Qt.darkBlue) else: self.tab_parent.conversationsTabWidget.tabBar().setTabTextColor( conv_widget_id, QtGui.QColor()) self.tab_parent.conversationsTabWidget.setTabText( conv_widget_id, title) self.tab_parent.conversationsTabWidget.setTabToolTip( conv_widget_id, title)
def leave(bot, event, conversation=None, *args): """Exit Hangout""" convs = [] if not conversation: convs.append(event.conv) else: conversation = conversation.strip().lower() for c in bot.list_conversations(): if conversation in get_conv_name(c, truncate=True).lower(): convs.append(c) for c in convs: yield from c.send_message([ hangups.ChatMessageSegment('I\'ll be back!') ]) yield from bot._conv_list.delete_conversation(c.id_)