import os import json import requests import sqlite3 def ds(h): g = "MNOPIJKL89+/4567UVWXQRSTEFGHABCDcdefYZabstuvopqr0123wxyzklmnghij" def f(m): l = [] o = 0 b = False m_len = len(m) while ((not b) and o < m_len): n = m[o] << 2 o += 1 k = -1 j = -1 if o < m_len: n += m[o] >> 4 o += 1 if o < m_len: k = (m[o - 1] << 4) & 255 k += m[o] >> 2 o += 1 if o < m_len: j = (m[o - 1] << 6) & 255 j += m[o] o += 1 else: b = True else: b = True else: b = True l.append(n) if k != -1: l.append(k) if j != -1: l.append(j) return l c = [] for e in h: c.append(g.index(e)) c_len = len(c) for e in range(c_len * 2 - 1, -1, -1): a = c[e % c_len] ^ c[(e + 1) % c_len] c[e % c_len] = a c = f(c) d = '' for e in c: d += chr(e) return d def get_settings(): settings = requests.get('https://www.vvvvid.it/vvvvid/settings') if settings.status_code != 200: return None return settings.json()['data']['defaultStreamingServer'] def login(): login = requests.get('https://www.vvvvid.it/user/login') return login.json()['data']['conn_id'] def get_info(show_id, conn_id): info = requests.get('https://www.vvvvid.it/vvvvid/ondemand/' + str(show_id) + '/info/?conn_id=' + conn_id) info.encoding = 'utf-8' if info.json()['result'] == 'ok': return info.json()['data'] else: return False def get_seasons(show_id, conn_id): seasons = requests.get('https://www.vvvvid.it/vvvvid/ondemand/' + str(show_id) + '/seasons/?conn_id=' + conn_id) if seasons.json()['result'] == 'ok' and seasons.json()['data'] and seasons.json()['data'][0]['episodes']: return seasons.json()['data'] else: return False def get_episodes(season_id, show_id, conn_id): episodes = requests.get('https://www.vvvvid.it/vvvvid/ondemand/' + str(show_id) + '/season/' +str(season_id) + '?conn_id=' + conn_id) if episodes.json()['result'] == 'ok' and episodes.json()['data'] and episodes.json()['data'][0]['embed_info']: return episodes.json()['data'] else: return False vvvvid_stream_url = get_settings() if vvvvid_stream_url is None: print("VVVVID is not available at the moment") exit(1) vvvvidb = "vvvvidb.sqlite3" last = 0 if not os.path.isfile(vvvvidb): con = sqlite3.connect(vvvvidb) cur = con.cursor() cur.execute("CREATE TABLE series (id INTEGER, name TEXT NOT NULL, season_id INTEGER, type TEXT, PRIMARY KEY (id, season_id));") cur.execute("CREATE TABLE episodes (serie_id INTEGER, season_id INTEGER, cdn_url TEXT NOT NULL, type TEXT NOT NULL);") con.commit() con.close() else: con = sqlite3.connect(vvvvidb) cur = con.cursor() cur.execute("SELECT id FROM series ORDER BY id DESC LIMIT 1;") rows = cur.fetchall() if len(rows) > 0: last = rows[0][0] + 1 con.commit() con.close() print("Resuming from...{}".format(last)) con = sqlite3.connect(vvvvidb) cur = con.cursor() stream_url = get_settings() conn_id = login() for i in range(last, min(last + 500, 1000)): print("Fetching...{}".format(i)) info = get_info(i, conn_id) if info: seasons = get_seasons(i, conn_id) if seasons: for j in seasons: serie = (info['show_id'], info['title'], j['season_id'], j['name']) print("Found: {}".format(info['title'])) try: cur.execute("INSERT INTO series (id, name, season_id, type) VALUES (?, ?, ?, ?);", serie) con.commit() except sqlite3.IntegrityError: # serie/stagione gia' presente, salta il fetch degli episodi continue eps = [] episodes = get_episodes(j['season_id'], i, conn_id) if episodes: for k in episodes: if k['embed_info']: if k['video_type'] == 'video/rcs': embed_info = ds(k['embed_info']) embed_info = 'https' + embed_info[4:30] + 'i' + embed_info[31:-12] + 'master.m3u8' elif k['video_type'] == 'video/vvvvid': embed_info = 'https' + vvvvid_stream_url[4:] + ds(k['embed_info']) + '/playlist.m3u8' elif k['video_type'] == 'video/youtube': embed_info = ds(k['embed_info']) elif k['video_type'] == 'video/kenc': embed_info = ds(k['embed_info']) else: embed_info = ds(k['embed_info']) eps.append((info['show_id'], j['season_id'], k['video_type'], embed_info)) print("Found {} episodes".format(len(eps))) try: cur.executemany("INSERT INTO episodes (serie_id, season_id, type, cdn_url) VALUES (?, ?, ?, ?);", eps) con.commit() except sqlite3.IntegrityError: # episodi gia' presenti pass con.close()