1 | import aiohttp |
||
2 | import asyncio |
||
3 | import html |
||
4 | import random |
||
5 | import re |
||
6 | import string |
||
7 | |||
8 | import bs4 |
||
9 | |||
10 | import fizzbotz.util as util |
||
11 | from fizzbotz.exceptions import StringLengthError, EmptyStringError |
||
12 | |||
13 | |||
14 | class TwitchChat: |
||
15 | def __init__(self): |
||
16 | self._bestoftwitchchat_url = \ |
||
17 | 'http://www.thebestoftwitch.com/feeds/posts/summary?' \ |
||
18 | 'start-index={}&max-results=1' |
||
19 | self._bestoftwitchchat_regex = re.compile( |
||
20 | '<summary type="text">(.*)</summary>', re.DOTALL) |
||
21 | |||
22 | self._twitchquotes_url = 'http://www.twitchquotes.com/random' |
||
23 | self._twitchquotes_regex = re.compile( |
||
24 | '<img class="emoticon" data-emote="(.*?)" src=".*?"/>', re.DOTALL) |
||
25 | |||
26 | @asyncio.coroutine |
||
27 | def get_bestoftwitchchat_pasta(self, from_html=None): |
||
28 | # TODO: programmatically discover max index |
||
29 | index = random.randint(1, 1104) |
||
30 | url = self._bestoftwitchchat_url.format(index) |
||
31 | if from_html is None: |
||
32 | text = yield from util.get_markup(url) |
||
33 | else: |
||
34 | text = from_html |
||
35 | |||
36 | raw_pasta = self._bestoftwitchchat_regex.search(text) |
||
37 | pasta = raw_pasta.group(1) |
||
38 | return html.unescape(pasta.strip()) |
||
39 | |||
40 | @asyncio.coroutine |
||
41 | def get_twitchquotes_pasta(self, from_html=None): |
||
42 | if from_html is None: |
||
43 | text = yield from util.get_markup(self._twitchquotes_url) |
||
44 | else: |
||
45 | text = from_html |
||
46 | |||
47 | raw_quote = self._twitchquotes_regex.sub(r'\1', text) |
||
48 | parsed_quote = bs4.BeautifulSoup(raw_quote, 'html.parser') |
||
49 | pasta = parsed_quote.find('div', class_='show_quote_text_area') |
||
50 | if pasta is None: |
||
51 | pasta = parsed_quote.find('span', id="quote_content_") |
||
52 | return pasta.string.replace(' ', '\n').\ |
||
53 | strip(string.whitespace + "\"") |
||
54 | |||
55 | return pasta.string.strip(string.whitespace + "\"") |
||
56 | |||
57 | @asyncio.coroutine |
||
58 | def get(self): |
||
59 | pasta_funcs = (self.get_bestoftwitchchat_pasta, |
||
60 | self.get_twitchquotes_pasta) |
||
61 | result = yield from random.choice(pasta_funcs)() |
||
62 | return result |
||
63 | |||
64 | |||
65 | class Joke: |
||
66 | def __init__(self): |
||
67 | self._url = 'http://www.randomjoke.com/topic/oneliners.php' |
||
68 | self._joke_regex = re.compile('(.*?)\n{6}', re.DOTALL) |
||
69 | |||
70 | @asyncio.coroutine |
||
71 | def get_oneliner(self, from_html=None): |
||
72 | if from_html is None: |
||
73 | text = yield from util.get_markup(self._url) |
||
74 | else: |
||
75 | text = from_html |
||
76 | |||
77 | parsed_content = bs4.BeautifulSoup(text, 'html.parser') |
||
78 | |||
79 | raw_joke = parsed_content.find_all('p')[6].get_text() |
||
80 | match = self._joke_regex.search(raw_joke) |
||
81 | return match.group(1).strip() |
||
82 | |||
83 | @asyncio.coroutine |
||
84 | def get(self): |
||
85 | result = yield from self.get_oneliner() |
||
86 | return result |
||
87 | |||
88 | |||
89 | class Square: |
||
90 | @asyncio.coroutine |
||
91 | def get(self, string_literal): |
||
92 | if len(string_literal) > 31: |
||
93 | raise StringLengthError |
||
94 | |||
95 | if not string_literal: |
||
96 | raise EmptyStringError |
||
97 | |||
98 | lookup_string = string_literal + string_literal[:-1][::-1] |
||
99 | |||
100 | string_length = len(string_literal) |
||
101 | string_list = [] |
||
102 | |||
103 | for idx in range(string_length): |
||
104 | row_string = lookup_string[idx:string_length + idx] |
||
105 | string_list.append(' '.join(row_string)) |
||
106 | |||
107 | square = '\n'.join(string_list).upper() |
||
108 | |||
109 | return '```\n{}\n```'.format(square) |
||
110 | |||
111 | |||
112 | class Imgur: |
||
113 | def __init__(self, id_length=5): |
||
114 | self.id_length = id_length |
||
115 | |||
116 | self._valid_characters = string.ascii_letters + string.digits |
||
117 | self._removed_url = 'https://i.imgur.com/removed.png' |
||
118 | self._base_url = 'https://i.imgur.com/{}.png' |
||
119 | |||
120 | @asyncio.coroutine |
||
121 | def get(self): |
||
122 | while True: |
||
123 | image_id = ''.join(random.choice(self._valid_characters) |
||
124 | for _ in range(self.id_length)) |
||
125 | image_url = self._base_url.format(image_id) |
||
126 | |||
127 | r = None |
||
0 ignored issues
–
show
|
|||
128 | try: |
||
129 | r = yield from aiohttp.get(image_url) |
||
0 ignored issues
–
show
The name
r does not conform to the variable naming conventions ([a-z_][a-z0-9_]{2,30}$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
130 | except aiohttp.errors.ClientResponseError: |
||
131 | continue |
||
132 | finally: |
||
133 | if r is not None: |
||
134 | r.close() |
||
135 | |||
136 | if r.url != self._removed_url: |
||
137 | return image_url |
||
138 | |||
139 | |||
140 | class Insult: |
||
141 | def __init__(self): |
||
142 | self._insult_url = 'http://www.insultgenerator.org/' |
||
143 | |||
144 | @asyncio.coroutine |
||
145 | def get(self, from_html=None): |
||
146 | if from_html is None: |
||
147 | text = yield from util.get_markup(self._insult_url) |
||
148 | else: |
||
149 | text = from_html |
||
150 | |||
151 | parsed_insult = bs4.BeautifulSoup(text, 'html.parser') |
||
152 | return parsed_insult.find('div', class_='wrap').get_text().lstrip() |
||
153 | |||
154 | |||
155 | class Roll: |
||
156 | def __init__(self, dice_limit=5000): |
||
157 | self._dice_limit = dice_limit |
||
158 | |||
159 | @asyncio.coroutine |
||
160 | def get(self, dice=None): |
||
161 | if not dice: |
||
162 | return str(random.randint(1, 6)) |
||
163 | |||
164 | dice = dice.lower() |
||
165 | |||
166 | try: |
||
167 | rolls, limit = map(int, dice.split('d')) |
||
168 | except ValueError: |
||
169 | dice = int(dice) |
||
170 | if dice < 2: |
||
171 | raise |
||
172 | return str(random.randint(1, dice)) |
||
173 | |||
174 | if rolls < 1 or limit < 2: |
||
175 | raise ValueError |
||
176 | |||
177 | num_limit_digits = int(len(str(limit))) |
||
178 | if rolls * num_limit_digits > self._dice_limit: |
||
179 | raise StringLengthError |
||
180 | |||
181 | return ', '.join(str(random.randint(1, limit)) |
||
182 | for _ in range(rolls)) |
||
183 |
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.