all repos — tnt-search @ e4a7499891618963e068e07e6aadf42a6c9d3dfc

A search tool for TNTVillage's dump.

main.py (view raw)

  1#!/usr/local/bin/python3
  2import os, csv, json
  3from datetime import datetime
  4from flask import Flask, request, render_template
  5
  6INPUT_PATH = os.path.join("tntvillage-release-dump", "tntvillage-release-dump.csv")
  7CSV_SEPARATOR = ","
  8HEADER = [ "DATA", "HASH", "TOPIC", "POST", "AUTORE", "TITOLO", "DESCRIZIONE", "DIMENSIONE", "CATEGORIA" ]
  9TABLE_HEADER = [ "DATA", "CATEGORIA", "TITOLO", "DESCRIZIONE", "AUTORE", "DIMENSIONE", "HASH" ]
 10CATEGORIE = {
 11    1: "Film TV e programmi",
 12    2: "Musica",
 13    3: "E Books",
 14    4: "Film",
 15    6: "Linux",
 16    7: "Anime",
 17    8: "Cartoni",
 18    9: "Macintosh",
 19    10: "Windows Software",
 20    11: "Pc Game",
 21    12: "Playstation",
 22    13: "Students Releases",
 23    14: "Documentari",
 24    21: "Video Musicali",
 25    22: "Sport",
 26    23: "Teatro",
 27    24: "Wrestling",
 28    25: "Varie",
 29    26: "Xbox",
 30    27: "Immagini sfondi",
 31    28: "Altri Giochi",
 32    29: "Serie TV",
 33    30: "Fumetteria",
 34    31: "Trash",
 35    32: "Nintendo",
 36    34: "A Book",
 37    35: "Podcast",
 38    36: "Edicola",
 39    37: "Mobile"
 40}
 41MAGNET_STR = '<button onclick=\"location.href=\'magnet:?xt=urn:btih:{}\'\" class="btn btn-danger">n</button>'
 42
 43def handle_content(content: str):
 44    return { x: content[idx] for idx, x in enumerate(HEADER) }
 45    
 46def search_keyword(content, keyword: str, category=0):
 47    results = [ x for x in content if keyword.lower() in x['TITOLO'].lower()]
 48    if category == 0:
 49        return results
 50    return [ x for x in results if category == x['CATEGORIA']]
 51
 52def get_last_torrents(content, page=1, amt=50):
 53    tmp = sorted(content, key=lambda x:x['DATA'], reverse=True)
 54    tmp_length = len(content)
 55    
 56    offset = amt * page
 57    start_from = offset - amt
 58    start_from = 0 if start_from < 0 else start_from
 59    end_with = start_from + amt
 60    end_with = tmp_length if end_with > tmp_length else end_with
 61    return tmp[start_from:end_with]
 62
 63def load_content(input_path=INPUT_PATH):
 64    with open(input_path, "r", encoding="utf-8") as in_file:
 65        csv_iterator = csv.reader(in_file, quotechar='"', delimiter=',', quoting=csv.QUOTE_NONNUMERIC, skipinitialspace=True)
 66        next(csv_iterator)
 67        return [ handle_content(x) for x in csv_iterator ]
 68
 69def sizeof_fmt(num, suffix="B"):
 70    for unit in ("", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"):
 71        if abs(num) < 1024.0:
 72            return f"{num:3.1f}{unit}{suffix}"
 73        num /= 1024.0
 74    return f"{num:.1f}Yi{suffix}"
 75
 76def parse_values(result):
 77    tmp = result.copy()
 78    tmp['DATA'] = datetime.strptime(tmp['DATA'], "%Y-%m-%dT%H:%M:%S").strftime("%d/%m/%Y")
 79    tmp['CATEGORIA'] = CATEGORIE[int(tmp['CATEGORIA'])]
 80    tmp['HASH'] = MAGNET_STR.format(tmp['HASH'])
 81    tmp['DIMENSIONE'] = sizeof_fmt(tmp['DIMENSIONE'])
 82    return tmp
 83
 84def format_results(results, headers=HEADER):
 85    contents = [parse_values(x) for x in results]
 86    return [[result[header] for header in headers] for result in contents]
 87
 88def get_args(args):
 89    keywords = args.get("keywords") or ""
 90    category = args.get("category") or 0
 91    page = args.get("page") or 1
 92    return keywords, category, page
 93
 94content = load_content()
 95app = Flask(__name__)
 96
 97@app.route('/api/header')
 98def route_api_header():
 99    return json.dumps(HEADER)
100
101@app.route('/api')
102def route_api():
103    keywords, category, page = get_args(request.args)
104    results = search_keyword(content, keywords, int(category))
105    results = get_last_torrents(results, page=int(page))
106    return json.dumps(results)
107
108@app.route('/')
109def route_main():
110    keywords, category, page = get_args(request.args)
111    results = search_keyword(content, keywords, int(category))
112    results = get_last_torrents(results, page=int(page))
113    results = format_results(results, headers=TABLE_HEADER)
114    return render_template("index.html", headers=TABLE_HEADER, content=results, categories=CATEGORIE.items(), page=page)  
115
116if __name__ == '__main__':
117    app.run()