def cam(bot, event, *args): """Upload a picture from a webcam. Store a new webcam by giving it a webcam name followed by a url to the camera. Usage: cam [webcam] [url]""" cams = bot.config.get_by_path(["webcams"]) if not cams: cams = dict() bot.config.set_by_path(["webcams"], cams) bot.config.save() # See if we're storing a webcam if len(args) > 1 and args[-1].startswith('http'): cam = ' '.join(args[:-1]) url = args[-1] bot.config.set_by_paths(["webcams", cam], url) bot.config.save() yield from event.conv.send_message(text_to_segments('{} saved!'.format(bold(cam)))) else: cam = ' '.join(args) url = cams.get(cam) if url: image_id = yield from bot.upload_images([url]) yield from event.conv.send_message([], image_id=image_id[0]) else: if not cams: yield from event.conv.send_message(text_to_segments('No webcams saved!')) else: text = '{}\n{}'.format(bold('webcams'), ', '.join(cams.keys())) yield from event.conv.send_message(text_to_segments(text))
def cam(bot, event, *args): """Upload a picture from a webcam. Store a new webcam by giving it a webcam name followed by a url to the camera. Usage: cam [webcam] [url]""" cams = bot.config.get_by_path(["webcams"]) if not cams: cams = dict() bot.config.set_by_path(["webcams"], cams) bot.config.save() # See if we're storing a webcam if len(args) > 1 and args[-1].startswith('http'): cam = ' '.join(args[:-1]) url = args[-1] bot.config.set_by_paths(["webcams", cam], url) bot.config.save() yield from event.conv.send_message( text_to_segments('{} saved!'.format(bold(cam)))) else: cam = ' '.join(args) url = cams.get(cam) if url: image_id = yield from bot.upload_images([url]) yield from event.conv.send_message([], image_id=image_id[0]) else: if not cams: yield from event.conv.send_message( text_to_segments('No webcams saved!')) else: text = '{}\n{}'.format(bold('webcams'), ', '.join(cams.keys())) yield from event.conv.send_message(text_to_segments(text))
def torrents(bot, event, *args): """Get a list of torrents being downloaded / seeded Usage: torrents""" torrents = rpc_client.get_torrents() texts = [] for torrent in torrents: text = "{} {:0.1f}%".format(bold(torrent.name), torrent.progress) if torrent.status == 'downloading': seconds = torrent.eta.seconds % 60 minutes = int(torrent.eta.seconds / 60) hours = int(minutes / 60) if minutes > 60: minutes = minutes % 60 times = [ str(hours) + "h" if hours else "", str(minutes) + "m" if minutes else "", str(seconds) + "s" ] text += " *({})*".format(" ".join(times).strip()) else: text += " " + italicize(torrent.status) texts.append(text) yield from event.conv.send_message(text_to_segments("\n".join(texts)))
def notes(bot, event, *args): """Display all saved notes Usage: notes""" config_args = ["notes"] # Make sure there's a notes dictionary try: saved = bot.config.get_by_path(config_args) except: yield from event.conv.send_message(text_to_segments('No notes saved!')) return if not saved: yield from event.conv.send_message(text_to_segments('No notes saved!')) return # Get all of the notes and their infos response = [] for subject in saved: note = saved[subject] text = '{} *by {} at {}*'.format(bold(subject), note['author'], note['timestamp']) response.append(text) yield from event.conv.send_message(text_to_segments('\n'.join(response)))
def define(bot, event, *args): """Define a word using Merriam-Webster Usage: define tautologous""" query = ' '.join(args) url = 'http://www.merriam-webster.com/dictionary/{}'.format(quote(query)) req = requests.get(url) tree = html.fromstring(req.text) # Get the simple definition try: el = tree.xpath('//span[@class="intro-colon"]')[0] except: yield from event.conv.send_message(text_to_segments("Word not found!")) definition = el.getparent().text_content().strip() # Get the word attributes el = tree.xpath('//div[@class="word-attributes"]')[0] attrs = [x.text_content().strip() for x in el.xpath('span')] attrs = ' | '.join(attrs).replace('\\', '/') text = _('{}\n{}\n{}').format(bold(query), italicize(escape_formatting(attrs)), definition) yield from event.conv.send_message(text_to_segments(text))
def notes(bot, event, *args): """Display all saved notes Usage: notes""" config_args = ["notes"] # Make sure there's a notes dictionary try: saved = bot.config.get_by_path(config_args) except: yield from event.conv.send_message(text_to_segments('No notes saved!')) return if not saved: yield from event.conv.send_message(text_to_segments('No notes saved!')) return # Get all of the notes and their infos response = [] for subject in saved: note = saved[subject] text = '{} *by {} at {}*'.format(bold(subject), note['author'], note['timestamp']) response.append(text) yield from event.conv.send_message(text_to_segments('\n'.join(response)))
def translate_all(bot, event, cmd=None, *args): """Translate all messages in the chat Usage: translate_all [on | off] [en | fr | es | ... ]""" conv_args = ["conversations", event.conv_id, "translate_all"] # Get the chat options for translating messages opts = bot.get_config_suboption(event.conv_id, 'translate_all') if not opts: opts = {'language': 'es', 'enabled': False} bot.config.set_by_paths(conv_args, opts) # Toggle the enabled state if no command is given if not cmd: cmd = 'on' if not opts.get('enabled') else 'off' cmd = cmd.lower() if cmd == 'on': if opts.get('enabled'): return bot.config.set_by_paths(conv_args + ['enabled'], True) text = 'Translating all messages to {}'.format( bold(ggl.translate._get_translate_lang(opts['language']))) elif cmd == 'off': if not opts.get('enabled'): return bot.config.set_by_paths(conv_args + ['enabled'], False) text = 'No more speaky in {}'.format( ggl.translate._get_translate_lang(opts['language'])) else: # Set the language to translate to the language given as a language code matched = False for (language, code) in ggl.translate._translate_codes: if cmd == code: matched = True bot.config.set_by_paths(conv_args + ['language'], code) text = 'Automatic translations set to {}'.format( bold(ggl.translate._get_translate_lang(opts['language']))) break if not matched: text = 'Sorry, but {} isn\'t a supported language code. Use "translate" to view supported languages.'.format( bold(cmd)) bot.config.save() yield from event.conv.send_message(text_to_segments(text))
def directions(bot, event, *args): """Get directions from point A to point B Usage: directions [mode] from [origin] to [destination] Example: directions walking from Atlanta, GA to Windsor, ON Example: directions from Los Angeles, CA to San Francisco, CA""" line = ' '.join(args) [(modespace, mode, origin, destination)] = _directions_regex.findall(line) if not mode: mode = 'driving' md = ggl.maps.MapsDirections(origin, destination, mode=mode) text = '{} to {}\n{}, {}\n'.format(bold(md.origin), bold(md.destination), italicize(md.route.distance), italicize(md.route.duration)) steps = _steps_to_text(md.route) text += '\n'.join(steps) yield from event.conv.send_message(text_to_segments(text))
def torrent(bot, event, *args): """Start torrenting a result from the last list of torrents searched Usage: torrent 3""" magnets = bot.config.get_by_path(["conversations", event.conv_id, "torrent_links"]) if magnets: magnet = magnets.get(int(args[0])) if magnet: torrent = rpc_client.add_torrent(magnet) text = "Added {}".format(bold(torrent.name)) yield from event.conv.send_message(text_to_segments(text)) return else: yield from event.conv.send_message(text_to_segments("No such search result")) else: yield from event.conv.send_message(text_to_segments('No recent torrent searches'))
def note(bot, event, subject=None, *args): """Save notes with subjects. Delete a note with "-" Usage: subject [body] Usage: -subject""" config_args = ["notes"] # Make sure there's a notes dictionary try: bot.config.get_by_path(config_args) except: bot.config.set_by_paths(config_args, dict()) if subject.startswith('-'): subject = subject[1:] try: bot.config.del_by_path(config_args + [subject]) except: response = italicize('No such note.') else: response = italicize('Note deleted.') elif args: # Save a new note content = ' '.join(args) note = { 'content': content, 'author': event.user.full_name, 'timestamp': event.timestamp.astimezone(tz=None).strftime('%Y-%m-%d %H:%M:%S') } bot.config.set_by_paths(config_args + [subject], note) response = italicize('Note saved') else: # If no args given, display a note try: note = bot.config.get_by_path(config_args + [subject]) response = '{}'.format(note['content']) except: response = italicize('No such note') text = _('{}\n{}').format(bold(subject), response) yield from event.conv.send_message(text_to_segments(text)) bot.config.save()
def translate(bot, event, *args): """Translate text to english. If no text is given, all supported languages are displayed Usage: translate hola mundo""" # Display a list of languages if no args are given if not args: languages = [': '.join(x) for x in ggl.translate._translate_codes] text = '{}\n{}'.format(bold('language codes'), languages) yield from event.conv.send_message(text_to_segments(text)) return # Get the default language lang_to = bot.get_config_suboption(event.conv_id, 'translate_default') if not lang_to: lang_to = "en" yield from event.conv.send_message( text_to_segments(_translate(args, lang_to)))
def scrabble(bot, event, *args): """10 letters are chosen at random, and you have a limited time to form words with them. Points are awarded based on word length. Usage: scrabble [seconds]""" # Determine if a game is ongoing scrabble_args = ['conversations', event.conv_id, 'scrabble'] try: scrabble_opts = bot.config.get_by_path(scrabble_args) except: scrabble_opts = { 'letters': list(), 'guesses': list(), 'points': { 'current': dict(), 'overall': dict() } } bot.config.set_by_paths(scrabble_args, scrabble_opts) if not scrabble_opts.get('letters'): # Start a new game letters = list() for i in range(0, 10): letters.append(random.choice(_scrabble_letters)) scrabble_opts['letters'] = letters # Get the duration of the current game if args: seconds = int(args[0]) else: seconds = bot.get_config_suboption(event.conv_id, "scrabble_duration") or 15 # Start a timer for the current game asyncio. async (_kill_scrabble( bot, event, seconds)).add_done_callback(lambda future: future.result()) # Display a message about the game text = '{}\nYou have {} seconds to make words!'.format( bold(' '.join(letters)), seconds) yield from event.conv.send_message(text_to_segments(_(text)))
def note(bot, event, subject=None, *args): """Save notes with subjects. Delete a note with "-" Usage: subject [body] Usage: -subject""" config_args = ["notes"] # Make sure there's a notes dictionary try: bot.config.get_by_path(config_args) except: bot.config.set_by_paths(config_args, dict()) if subject.startswith('-'): subject = subject[1:] try: bot.config.del_by_path(config_args + [subject]) except: response = italicize('No such note.') else: response = italicize('Note deleted.') elif args: # Save a new note content = ' '.join(args) note = { 'content': content, 'author': event.user.full_name, 'timestamp': event.timestamp.astimezone(tz=None).strftime('%Y-%m-%d %H:%M:%S') } bot.config.set_by_paths(config_args + [subject], note) response = italicize('Note saved') else: # If no args given, display a note try: note = bot.config.get_by_path(config_args + [subject]) response = '{}'.format(note['content']) except: response = italicize('No such note') text = _('{}\n{}').format(bold(subject), response) yield from event.conv.send_message(text_to_segments(text)) bot.config.save()
def scrabble(bot, event, *args): """10 letters are chosen at random, and you have a limited time to form words with them. Points are awarded based on word length. Usage: scrabble [seconds]""" # Determine if a game is ongoing scrabble_args = ['conversations', event.conv_id, 'scrabble'] try: scrabble_opts = bot.config.get_by_path(scrabble_args) except: scrabble_opts = {'letters': list(), 'guesses': list(), 'points': {'current': dict(), 'overall': dict()}} bot.config.set_by_paths(scrabble_args, scrabble_opts) if not scrabble_opts.get('letters'): # Start a new game letters = list() for i in range(0, 10): letters.append(random.choice(_scrabble_letters)) scrabble_opts['letters'] = letters # Get the duration of the current game if args: seconds = int(args[0]) else: seconds = bot.get_config_suboption(event.conv_id, "scrabble_duration") or 15 # Start a timer for the current game asyncio.async( _kill_scrabble(bot, event, seconds) ).add_done_callback(lambda future: future.result()) # Display a message about the game text = '{}\nYou have {} seconds to make words!'.format( bold(' '.join(letters)), seconds ) yield from event.conv.send_message(text_to_segments(_(text)))
def define(bot, event, *args): """Define a word using Merriam-Webster Usage: define tautologous""" query = ' '.join(args) url = 'http://www.merriam-webster.com/dictionary/{}'.format(quote(query)) req = requests.get(url) tree = html.fromstring(req.text) # Get the simple definition try: el = tree.xpath('//span[@class="intro-colon"]')[0] except: yield from event.conv.send_message(text_to_segments("Word not found!")) definition = el.getparent().text_content().strip() # Get the word attributes el = tree.xpath('//div[@class="word-attributes"]')[0] attrs = [x.text_content().strip() for x in el.xpath('span')] attrs = ' | '.join(attrs).replace('\\', '/') text = _('{}\n{}\n{}').format(bold(query), italicize(escape_formatting(attrs)), definition) yield from event.conv.send_message(text_to_segments(text))
def scrabble_responder(bot, event): """Handle clever replies to messages""" # Test if message is not empty if not event.text: return # Define some shit scrabble_args = ['conversations', event.conv_id, 'scrabble'] word = event.text.lower() # Test if message is one word if ' ' in event.text: return # Test if a scrabble game is ongoing try: letters = bot.config.get_by_path(scrabble_args + ['letters']) except: letters = None if not letters: return # Don't process anything that begins with the command character commands_character = bot.get_config_suboption(event.conv_id, 'commands_character') if event.text.startswith(commands_character): return # Make sure that the word hasn't been guessed yet if word in bot.config.get_by_path(scrabble_args + ['guesses']): text = '{}\n{} has already been guessed!'.format( bold(' '.join(letters)), italicize(word)) yield from event.conv.send_message(text_to_segments(text)) raise StopEventHandling # Determine if the letters given match the current set remaining = letters.copy() for letter in word: try: remaining.remove(letter) except: # yield from event.conv.send_message(text_to_segments("Those letters don't even match...")) # raise StopEventHandling return # Determine if the word is an english word if dictionary.check(word): # Add the word to the list of guessed words bot.config.append_by_path(scrabble_args + ['guesses'], word) # Award the user with points try: points = bot.config.get_by_path( scrabble_args + ['points', 'current', event.user.full_name]) except: points = 0 points += len(word) bot.config.set_by_paths( scrabble_args + ['points', 'current', event.user.full_name], points) text = '{}\n{} puts {} at {} point{}!'.format( bold(' '.join(letters)), italicize(word), event.user.full_name, points, 's' if points > 1 else '') yield from event.conv.send_message(text_to_segments(text)) # Stop other handlers from processing event raise StopEventHandling
def scrabble_responder(bot, event): """Handle clever replies to messages""" # Test if message is not empty if not event.text: return # Define some shit scrabble_args = ['conversations', event.conv_id, 'scrabble'] word = event.text.lower() # Test if message is one word if ' ' in event.text: return # Test if a scrabble game is ongoing try: letters = bot.config.get_by_path(scrabble_args + ['letters']) except: letters = None if not letters: return # Don't process anything that begins with the command character commands_character = bot.get_config_suboption(event.conv_id, 'commands_character') if event.text.startswith(commands_character): return # Make sure that the word hasn't been guessed yet if word in bot.config.get_by_path(scrabble_args + ['guesses']): text = '{}\n{} has already been guessed!'.format( bold(' '.join(letters)), italicize(word) ) yield from event.conv.send_message(text_to_segments(text)) raise StopEventHandling # Determine if the letters given match the current set remaining = letters.copy() for letter in word: try: remaining.remove(letter) except: # yield from event.conv.send_message(text_to_segments("Those letters don't even match...")) # raise StopEventHandling return # Determine if the word is an english word if dictionary.check(word): # Add the word to the list of guessed words bot.config.append_by_path(scrabble_args + ['guesses'], word) # Award the user with points try: points = bot.config.get_by_path(scrabble_args + ['points', 'current', event.user.full_name]) except: points = 0 points += len(word) bot.config.set_by_paths(scrabble_args + ['points', 'current', event.user.full_name], points) text = '{}\n{} puts {} at {} point{}!'.format( bold(' '.join(letters)), italicize(word), event.user.full_name, points, 's' if points > 1 else '' ) yield from event.conv.send_message(text_to_segments(text)) # Stop other handlers from processing event raise StopEventHandling
def tpb(bot, event, *args): """Search the Pirate Bay for a magnet link""" # Get parser options try: (opts, largs) = parser.parse_args(list(args)) except: yield from event.conv.send_message(text_to_segments('Error parsing search query!')) # Query thepiratebay query = ' '.join(largs) url = 'https://thepiratebay.se/search/{}/0/99/0'.format(quote(query)) req = requests.get(url) tree = html.fromstring(req.text) # Get each result element in the tree els = tree.xpath('//td[@class="vertTh"]') # Format the size if that option is provided if opts.size: # Strip the number size = "" s = str(options.size) while s and s[0:1].isdigit() or s[0:1] == ".": size += s[0] s = s[1:] size = float(size) # Get the unit unit = s.lower() # Multiply into bytes multiplier = _filesize_multipliers.get(unit) max_size = multiplier * size # Parse each result element results = [] for el in els: result = PirateResult(el) # See if the result meets our criteria if opts.author and result.author.lower() != opts.author.lower(): continue if opts.size and max_size > opts.size: continue if opts.seeders and result.seeders < opts.seeders: continue results.append(PirateResult(el)) # Stop after we've gotten enough results if len(results) == opts.results: break # Make sure we got results if not results: yield from event.conv.send_message(text_to_segments('No results found!')) return text = [] magnets = [] for i in range(0, len(results)): result = results[i] result_text = '{}) {}\n{} {}\nSeeders: {}\nSize: {}\nUploaded {} by {}'.format( i + 1, bold(link(result.magnet, result.title)), italicize(result.category), italicize(result.subcategory), result.seeders, result.size, result.date, result.author, link(result.magnet, "magnet")) text.append(result_text) magnets.append(result.magnet) # Store this batch of magnet links locally to be able to grab the magnet link later magnet_dict = dict(list(zip(list(range(1, len(magnets)+1)), magnets))) bot.config.set_by_paths(["conversations", event.conv_id, "torrent_links"], magnet_dict) bot.config.save() yield from event.conv.send_message(text_to_segments('\n\n'.join(text)))