Files
reelbox/tool/catalogue_deployment_smoke.py
T

86 lines
4.6 KiB
Python

"""Read-only deployed API checks; never requests any returned media URL."""
import argparse
import hashlib
import json
from pathlib import Path
import sqlite3
import time
from urllib.error import HTTPError
from urllib.request import Request, urlopen
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--origin', default='https://reelbox.dartty.top:8443')
parser.add_argument('--database', default='/root/moviebox-export/catalog.sqlite')
parser.add_argument('--output', required=True)
args = parser.parse_args()
db = sqlite3.connect(Path(args.database).resolve().as_uri() + '?mode=ro', uri=True)
timings = {}
def get(path):
start = time.monotonic()
with urlopen(args.origin + path, timeout=40) as response:
assert response.status == 200
assert 'application/json' in response.headers['Content-Type']
value = json.load(response)
timings[path.split('?')[0]] = round(time.monotonic() - start, 3)
return value
health = get('/api/health')
assert health['status'] == 'ok' and health['media_proxy'] is False and health['offline'] is True
for table in ('titles', 'episodes', 'seasons', 'movie_sources', 'episode_sources'):
assert health['counts'][table] == db.execute('SELECT count(*) FROM ' + table).fetchone()[0]
home = get('/api/first/public/')
assert home['genres'][0]['posters']
movies = get('/api/movie/by/filtres/0/created/0/public/')
series = get('/api/serie/by/filtres/0/created/0/public/')
assert movies and series
movie = next((get('/api/movie/by/' + str(row['id']) + '/public/') for row in movies
if db.execute('SELECT 1 FROM movie_sources WHERE title_id=? LIMIT 1', (row['id'],)).fetchone()), None)
assert movie and movie['sources']
expected = [json.loads(r[0]) for r in db.execute('SELECT raw_json FROM movie_sources WHERE title_id=? ORDER BY source_index', (movie['id'],))]
assert movie['sources'] == expected, 'Movie source records changed'
seasons = get('/api/season/by/serie/' + str(series[0]['id']) + '/public/')
expected_seasons = [json.loads(r[0]) for r in db.execute('SELECT raw_json FROM seasons WHERE series_id=? ORDER BY season_index', (series[0]['id'],))]
actual_urls = [source['url'] for season in seasons for ep in season.get('episodes', []) for source in ep.get('sources', [])]
expected_urls = [source['url'] for season in expected_seasons for ep in season.get('episodes', []) for source in ep.get('sources', [])]
assert actual_urls and actual_urls == expected_urls, 'Episode source URLs changed'
for url in actual_urls + [source['url'] for source in movie['sources']]:
from urllib.parse import urlsplit
assert urlsplit(url).hostname not in {'reelbox.dartty.top', '87.107.110.187'}
search = get('/api-user/newapi/like.php?action=search-movie-en&q=Matrix&pageno=1')
assert search
assert get('/api-user/newapi/filter.php?action=pishnahad&garid=2&pageno=1')
assert get('/api/genre/all/public/') and get('/api/country/all/public/')
assert get('/api-user/newapi/pishnahad.php')
rejected = {}
for method, path in [('GET', '/api/proxy?url=https://media.example/movie.mkv'),
('GET', '/api/movie.mkv'), ('GET', '/api/comments/by/poster/1/public/'),
('GET', '/api-user/newapi/like.php?action=search-movie&url=http://127.0.0.1/'),
('GET', '/catalog.sqlite'), ('POST', '/api/health')]:
try:
with urlopen(Request(args.origin + path, method=method), timeout=15) as response:
raise AssertionError('Unexpected accepted request: ' + path + ' status=' + str(response.status))
except HTTPError as error:
assert error.code in {400, 403, 404, 405}
rejected[method + ' ' + path] = error.code
error.close()
with urlopen(args.origin + '/', timeout=15) as response:
assert response.status == 200 and b'Reelbox' in response.read()
report = {'passed': True, 'origin': args.origin, 'health': health,
'movie_id': movie['id'], 'series_id': series[0]['id'],
'movie_source_records_match_snapshot': len(expected),
'episode_source_urls_match_snapshot': len(actual_urls),
'search_matches': len(search), 'rejected_routes': rejected,
'website_still_available': True, 'media_downloaded': False, 'seconds_by_route': timings}
output = Path(args.output)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(report, indent=2) + '\n')
print(json.dumps(report, indent=2))
db.close()
if __name__ == '__main__':
main()