diff --git a/README.md b/README.md index 7109f8e..7a18a15 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,26 @@ # fleast Least-favourite twitch streamers here -## Change-log -### 1.04 +## Change Log +### 1.5 +- IRL section is back with IRL query +- Fixed bug when games with `&` symbol could not found correctly. + +### 1.4 - Polished internal code and now cherrypy server configuration is independent from nginx reverse proxy -### 1.03 +### 1.3 - Fixed bug when VOD-streams appear in list of live streams -### 1.02 +### 1.2 - Fixed some typos in text - Fixed bug with chinese language streams - Fixed bug when 0 streams are found if game name contains whitespaces in the end - Fixed bug with stream list if stream name contains '<' and '>' symbols -### 1.01 +### 1.1 - Form data now saved between querries -### 1.00 +### 1.0 - Initial release diff --git a/main.py b/main.py index b0755c8..0a7e2db 100755 --- a/main.py +++ b/main.py @@ -2,11 +2,10 @@ # -*- coding: utf-8 -*- import cherrypy -import json from cherrypy.process.plugins import Daemonizer from twitch import TwitchClient -ver = '1.04' +ver = '1.5' class FleastServer(object): @@ -65,7 +64,10 @@ class FleastServer(object): _opt_langs_=self.set_templ_lang('ru')) game = game.rstrip() cherrypy.log('Getting game:"{}" language:{}'.format(game, lang)) - data = self.client.get_live_streams(game.replace(' ', '%20').replace('&', '%26'), lang) + if game == "IRL": + data = self.client.get_irl_live_streams_v6(lang) + else: + data = self.client.get_live_streams(game.replace(' ', '%20').replace('&', '%26'), lang) if data is None: return 'Internal Error
Tell me more at ' \ @@ -80,14 +82,25 @@ class FleastServer(object): cherrypy.log('Found %d streams' % data['_total']) - streams = sorted(data['streams'], key=lambda k: k['viewers']) - result_str = '' - for s in streams: - result_str += self.templ_stream.format(s['channel']['url'], - s['preview']['medium'], - self.to_html(s['channel']['status']), - s['channel']['display_name'], - s['viewers']) + '\n' + if game == "IRL": + streams = sorted(data['streams'], key=lambda k: k['viewer_count']) + result_str = '' + irl_url = 'https://twitch.tv/{}' + for s in streams: + result_str += self.templ_stream.format(irl_url.format(s['user_name']), + s['thumbnail_url'].format(width=320, height=180), + self.to_html(s['title']), + s['user_name'], + s['viewer_count']) + '\n' + else: + streams = sorted(data['streams'], key=lambda k: k['viewers']) + result_str = '' + for s in streams: + result_str += self.templ_stream.format(s['channel']['url'], + s['preview']['medium'], + self.to_html(s['channel']['status']), + s['channel']['display_name'], + s['viewers']) + '\n' return self.templ_main.format(_stream_num_=data['_total'], _game_name_=game, diff --git a/twitch.py b/twitch.py index 5fde71d..d105edc 100644 --- a/twitch.py +++ b/twitch.py @@ -16,7 +16,7 @@ class TwitchClient: self.urlbase_v6 = 'https://api.twitch.tv/helix' self.last_q = time.time() - self.delay = 1/freq + self.delay = 1 / freq def do_q(self, base, header): """ @@ -25,12 +25,12 @@ class TwitchClient: :param header: dictionary of http headers :return: string with response or None """ - self.lock.acquire() # Lock for 1 at time query + self.lock.acquire() # Lock for 1 at time query try: cherrypy.log('Request: %s' % base) - delta = time.time() - self.last_q # Delta for correct query freq + delta = time.time() - self.last_q # Delta for correct query freq if delta < self.delay: - time.sleep(delta) # Sleep remaining time + time.sleep(delta) # Sleep remaining time r = requests.get(base, headers=header).json() self.last_q = time.time() cherrypy.log('Request: OK') @@ -39,9 +39,9 @@ class TwitchClient: cherrypy.log('Error: {}'.format(e)) r = None finally: - self.lock.release() # Do not forget to release lock + self.lock.release() # Do not forget to release lock return r - + def get_base(self, ver): """ Get base which is depended on API version @@ -57,7 +57,7 @@ class TwitchClient: raise ValueError('Not supported API version') # - # - # - + def raw_query_v6(self, q): """ Do a query with API v6 @@ -65,7 +65,7 @@ class TwitchClient: :return: string with get query result or None """ header, base = self.get_base('v6') - return self.do_q(base+q, header) + return self.do_q(base + q, header) def raw_query_v5(self, q): """ @@ -74,7 +74,7 @@ class TwitchClient: :return: string with get query result or None """ header, base = self.get_base('v5') - return self.do_q(base+q, header) + return self.do_q(base + q, header) def get_game_id(self, name): """ @@ -134,3 +134,22 @@ class TwitchClient: data['_total'] = len(data['streams']) return data + def get_irl_live_streams_v6(self, lang): + header, base = self.get_base('v6') + init_q_template = "{}/streams?language={}&first={}{}" + q_template = "{}/streams?language={}&first={}&after={}{}" + + game_id = '' + irl_ids = ["509660", "509673", "509667", "509669", "509670", "509658", + "509672", "509671", "509664", "509663", "417752", "509659"] + for irl_id in irl_ids: + game_id += '&game_id={}'.format(irl_id) + + result = {'_total': 0, 'streams': []} + data = self.do_q(init_q_template.format(base, lang, 100, game_id), header) + result['streams'].extend(data['data']) + while len(data['data']) == 100: + data = self.do_q(q_template.format(base, lang, 100, data['pagination']['cursor'], game_id), header) + result['streams'].extend(data['data']) + result['_total'] = len(result['streams']) + return result