interactive bots: Create xkcd bot.
This commit is contained in:
		
							parent
							
								
									2a8c57d77a
								
							
						
					
					
						commit
						db39b52d3f
					
				
					 8 changed files with 171 additions and 0 deletions
				
			
		
							
								
								
									
										131
									
								
								contrib_bots/lib/xkcd.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								contrib_bots/lib/xkcd.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,131 @@ | |||
| from random import randint | ||||
| 
 | ||||
| import logging | ||||
| import requests | ||||
| 
 | ||||
| XKCD_TEMPLATE_URL = 'https://xkcd.com/%s/info.0.json' | ||||
| LATEST_XKCD_URL = 'https://xkcd.com/info.0.json' | ||||
| 
 | ||||
| class XkcdHandler(object): | ||||
|     ''' | ||||
|     This plugin provides several commands that can be used for fetch a comic | ||||
|     strip from https://xkcd.com. The bot looks for messages starting with | ||||
|     "@xkcd" and responds with a message with the comic based on provided | ||||
|     commands. | ||||
|     ''' | ||||
| 
 | ||||
|     def usage(self): | ||||
|         return ''' | ||||
|             This plugin allows users to fetch a comic strip provided by | ||||
|             https://xkcd.com. Users should preface the command with "@xkcd". | ||||
| 
 | ||||
|             There are several commands to use this bot: | ||||
|             - @xkcd help -> To show all commands the bot supports. | ||||
|             - @xkcd latest -> To fetch the latest comic strip from xkcd. | ||||
|             - @xkcd random -> To fetch a random comic strip from xkcd. | ||||
|             - @xkcd <comic_id> -> To fetch a comic strip based on | ||||
|             `<comic_id>`, e.g `@xkcd 1234`. | ||||
|             ''' | ||||
| 
 | ||||
|     def triage_message(self, message, client): | ||||
|         # Return True if we want to (possibly) response to this message | ||||
|         original_content = message['content'] | ||||
|         is_xkcd_called = original_content.startswith('@xkcd ') | ||||
|         is_xkcd_called_without_command = original_content == '@xkcd' | ||||
| 
 | ||||
|         return is_xkcd_called or is_xkcd_called_without_command | ||||
| 
 | ||||
|     def handle_message(self, message, client, state_handler): | ||||
|         xkcd_bot_response = get_xkcd_bot_response(message) | ||||
| 
 | ||||
|         client.send_message(dict( | ||||
|             type='stream', | ||||
|             to=message['display_recipient'], | ||||
|             subject=message['subject'], | ||||
|             content=xkcd_bot_response, | ||||
|         )) | ||||
| 
 | ||||
| class XkcdBotCommand(object): | ||||
|     LATEST = 0 | ||||
|     RANDOM = 1 | ||||
|     COMIC_ID = 2 | ||||
| 
 | ||||
| class XkcdNotFoundError(Exception): | ||||
|     pass | ||||
| 
 | ||||
| class XkcdServerError(Exception): | ||||
|     pass | ||||
| 
 | ||||
| def get_xkcd_bot_response(message): | ||||
|     original_content = message['content'].strip() | ||||
|     cropped = original_content[len('@xkcd '):] | ||||
|     command = cropped.strip() | ||||
| 
 | ||||
|     xkcd_called_without_command = original_content == '@xkcd' | ||||
| 
 | ||||
|     commands_help = ("%s" | ||||
|                      "\n* `@xkcd help` to show this help message." | ||||
|                      "\n* `@xkcd latest` to fetch the latest comic strip from xkcd." | ||||
|                      "\n* `@xkcd random` to fetch a random comic strip from xkcd." | ||||
|                      "\n* `@xkcd <comic id>` to fetch a comic strip based on `<comic id>` " | ||||
|                      "e.g `@xkcd 1234`.") | ||||
| 
 | ||||
|     try: | ||||
|         if command == 'help' or xkcd_called_without_command: | ||||
|             return commands_help % ('xkcd bot supports these commands:') | ||||
|         elif command == 'latest': | ||||
|             fetched = fetch_xkcd_query(XkcdBotCommand.LATEST) | ||||
|         elif command == 'random': | ||||
|             fetched = fetch_xkcd_query(XkcdBotCommand.RANDOM) | ||||
|         elif command.isdigit(): | ||||
|             fetched = fetch_xkcd_query(XkcdBotCommand.COMIC_ID, cropped.strip()) | ||||
|         else: | ||||
|             return commands_help % ('xkcd bot only supports these commands:') | ||||
|     except (requests.exceptions.ConnectionError, XkcdServerError): | ||||
|         logging.exception('Connection error occurred when trying to connect to xkcd server') | ||||
|         return 'Sorry, I cannot process your request right now, please try again later!' | ||||
|     except XkcdNotFoundError: | ||||
|         logging.exception('XKCD server responded 404 when trying to fetch comic with id %s' | ||||
|                           % (command)) | ||||
|         return 'Sorry, there is likely no xkcd comic strip with id: #%s' % (command) | ||||
|     else: | ||||
|         return ("#%s: **%s**\n[%s](%s)" % (fetched['num'], | ||||
|                                            fetched['title'], | ||||
|                                            fetched['alt'], | ||||
|                                            fetched['img'])) | ||||
| 
 | ||||
| def fetch_xkcd_query(mode, comic_id=None): | ||||
|     try: | ||||
|         if mode == XkcdBotCommand.LATEST:  # Fetch the latest comic strip. | ||||
|             url = LATEST_XKCD_URL | ||||
| 
 | ||||
|         elif mode == XkcdBotCommand.RANDOM:  # Fetch a random comic strip. | ||||
|             latest = requests.get(LATEST_XKCD_URL) | ||||
| 
 | ||||
|             if latest.status_code != 200: | ||||
|                 raise XkcdServerError() | ||||
| 
 | ||||
|             latest_id = latest.json()['num'] | ||||
|             random_id = randint(1, latest_id) | ||||
|             url = XKCD_TEMPLATE_URL % (str(random_id)) | ||||
| 
 | ||||
|         elif mode == XkcdBotCommand.COMIC_ID:  # Fetch specific comic strip by id number. | ||||
|             if comic_id is None: | ||||
|                 raise Exception('Missing comic_id argument') | ||||
|             url = XKCD_TEMPLATE_URL % (comic_id) | ||||
| 
 | ||||
|         fetched = requests.get(url) | ||||
| 
 | ||||
|         if fetched.status_code == 404: | ||||
|             raise XkcdNotFoundError() | ||||
|         elif fetched.status_code != 200: | ||||
|             raise XkcdServerError() | ||||
| 
 | ||||
|         xkcd_json = fetched.json() | ||||
|     except requests.exceptions.ConnectionError as e: | ||||
|         logging.warning(e) | ||||
|         raise | ||||
| 
 | ||||
|     return xkcd_json | ||||
| 
 | ||||
| handler_class = XkcdHandler | ||||
							
								
								
									
										40
									
								
								contrib_bots/lib/xkcd/docs.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								contrib_bots/lib/xkcd/docs.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| # xkcd bot | ||||
| 
 | ||||
| xkcd bot is a Zulip bot that can fetch a comic strip from xkcd. To use xkcd | ||||
| bot you can simply call it with `@xkcd` followed by a command. Like this: | ||||
| 
 | ||||
| ``` | ||||
| @xkcd <command> | ||||
| ``` | ||||
| 
 | ||||
| xkcd bot has four commands:   | ||||
| 
 | ||||
| 1. `help`   | ||||
| This command is used to list all commands that can be used with this bot. | ||||
| You can use this command by typing `@xkcd help` in a stream.   | ||||
|  | ||||
| 
 | ||||
| 2. `latest`   | ||||
| This command is used to fetch the latest comic strip from xkcd. You can use | ||||
| this command by typing `@xkcd latest` in a stream.   | ||||
|  | ||||
| 
 | ||||
| 3. `random`   | ||||
| This command is used to fetch a random comic strip from xkcd. You can use | ||||
| this command by typing `@xkcd random` in a stream, xkcd bot will post a | ||||
| random xkcd comic strip.   | ||||
|  | ||||
| 
 | ||||
| 4. `<comic_id>`   | ||||
| To fetch a comic strip based on id, you can directly use `@xkcd <comic_id>`, | ||||
| for example if you want to fetch a comic strip with id 1234, you can type | ||||
| `@xkcd 1234`, xkcd bot will post a comic strip with id 1234.   | ||||
|    | ||||
| 
 | ||||
| If you type a wrong command to xkcd bot, xkcd bot will post information | ||||
| you'd get from `@xkcd help`.   | ||||
|  | ||||
| 
 | ||||
| And if you type a wrong id, xkcd bot will post a message that an xkcd comic | ||||
| strip with that id is not available.   | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-help.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-help.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 30 KiB | 
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-latest.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-latest.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 43 KiB | 
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-random.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-random.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 45 KiB | 
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-specific-id.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-specific-id.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 44 KiB | 
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-wrong-command.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-wrong-command.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 31 KiB | 
							
								
								
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-wrong-id.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib_bots/lib/xkcd/xkcd-wrong-id.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rafid Aslam
						Rafid Aslam