86 lines
4.6 KiB
Python
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()
|