2015-02-05 01:02:32 +01:00
#!/usr/bin/python3
2015-02-12 22:06:31 +01:00
#/* vim:set ts=2 set noexpandtab */
2015-02-19 00:50:18 +01:00
import json , uuid , hashlib , sqlite3 , base64
2017-12-28 10:15:00 +01:00
from hashlib import sha1
2017-12-28 08:36:44 +01:00
import bencoder
import requests
from flask import Flask , render_template , url_for , request , send_file
2015-02-15 03:48:39 +01:00
from werkzeug import secure_filename
2015-02-05 22:17:33 +01:00
app = Flask ( __name__ )
2015-02-15 03:48:39 +01:00
strings = None
settings = None
2015-02-05 01:02:32 +01:00
2015-02-05 22:17:33 +01:00
@app.route ( " / " )
def index ( ) :
2015-02-15 03:48:39 +01:00
return render_template ( " search.html " , language = " english " , categories = settings [ " categories " ] , strings = strings )
2015-02-05 22:17:33 +01:00
2015-02-15 03:48:39 +01:00
@app.route ( " /categories " )
2015-02-05 22:17:33 +01:00
def categorys ( ) :
2017-12-28 03:14:12 +01:00
global strings
return render_template ( " categories.html " , categories = settings [ " categories " ] , strings = strings )
2015-02-05 22:17:33 +01:00
2015-02-15 03:48:39 +01:00
@app.route ( " /create " , methods = [ ' GET ' , ' POST ' ] )
2015-02-05 22:38:39 +01:00
def create ( ) :
2015-02-15 03:48:39 +01:00
if request . method == " GET " :
return render_template ( " create.html " , language = " english " , categories = settings [ " categories " ] , strings = strings , errors = None )
elif request . method == " POST " :
2015-02-15 04:51:27 +01:00
errors = createNewTorrent ( request )
if errors == None :
return " It ' s allright "
else :
return render_template ( " create.html " , language = " english " , categories = settings [ " categories " ] , strings = strings , errors = errors )
2015-02-05 22:38:39 +01:00
2017-12-28 08:36:44 +01:00
@app.route ( " /download/<filename> " )
def download ( filename ) :
connection = sqlite3 . connect ( " torrentdb.sqlite " )
c = connection . cursor ( )
c . execute ( " SELECT name FROM torrents WHERE fileid = :fileid " , { ' fileid ' : filename } )
name = c . fetchone ( ) [ 0 ]
return send_file ( " torrentFiles/ " + filename , as_attachment = True , attachment_filename = name + " .torrent " , conditional = True )
2015-02-06 22:03:42 +01:00
@app.route ( " /search " , methods = [ ' GET ' ] )
def search ( ) :
2017-12-28 03:14:12 +01:00
global strings
print ( strings )
2017-12-28 04:19:04 +01:00
connection = sqlite3 . connect ( " torrentdb.sqlite " )
c = connection . cursor ( )
2017-12-28 05:07:42 +01:00
search_params = [ ]
search = " "
fields = list ( request . args . keys ( ) )
for field in fields :
query_list = request . args . getlist ( field )
for query in query_list :
if len ( search ) > 0 :
search + = " AND "
if field is " q " :
names = query . split ( " " )
search_params + = list ( map ( lambda x : " % " + x + " % " , names ) )
2017-12-28 08:36:44 +01:00
search + = " AND " . join ( [ " torrents.name LIKE (?) " ] * len ( query . split ( " " ) ) )
2017-12-28 05:07:42 +01:00
elif field is " c " :
search_params + = query . split ( " " )
2017-12-28 08:36:44 +01:00
search + = " AND " . join ( [ " torrents.category LIKE (?) " ] * len ( query . split ( " " ) ) )
2017-12-28 05:07:42 +01:00
elif field is " s " :
search_params + = query . split ( " " )
2017-12-28 08:36:44 +01:00
search + = " AND " . join ( [ " torrents.subcategory LIKE (?) " ] * len ( query . split ( " " ) ) )
2017-12-29 00:31:28 +01:00
elif field is " h " :
hashes = query . split ( " " )
search_params + = list ( map ( lambda x : x + " % " , hashes ) )
search + = " AND " . join ( [ " torrents.fileid LIKE (?) " ] * len ( query . split ( " " ) ) )
2017-12-28 05:07:42 +01:00
print ( search )
2017-12-28 08:36:44 +01:00
c . execute ( " SELECT torrents.fileid, torrents.name, metadata.torrentsize FROM torrents LEFT JOIN metadata on metadata.fileid = torrents.fileid WHERE " + search , search_params )
2017-12-28 04:19:04 +01:00
results = c . fetchall ( )
return render_template ( " result.html " , results = results , strings = strings , language = " english " , categories = settings [ " categories " ] )
2015-02-15 03:48:39 +01:00
2017-12-28 08:36:44 +01:00
def scrapeAll ( ) :
TRACKER_URL = " http://tracker.lootbox.cf:6969/ "
statedump = requests . get ( TRACKER_URL + " stats " + " ?mode=statedump " )
2017-12-28 10:15:00 +01:00
2017-12-28 08:36:44 +01:00
return
2015-02-15 03:48:39 +01:00
def init ( ) :
global strings
global settings
with open ( " strings.json " ) as stringsJson :
strings = json . load ( stringsJson )
with open ( " settings.json " ) as settingsJson :
settings = json . load ( settingsJson )
2015-02-19 00:50:18 +01:00
initDb ( )
2017-12-29 00:31:28 +01:00
#scrapeAll()
2015-02-19 00:50:18 +01:00
def initDb ( ) :
connection = sqlite3 . connect ( " torrentdb.sqlite " )
c = connection . cursor ( )
2015-02-21 03:01:47 +01:00
c . execute ( ' CREATE TABLE IF NOT EXISTS torrents (fileid TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, category TEXT NOT NULL, subcategory TEXT NOT NULL, description TEXT NOT NULL, audioquality_description TEXT NOT NULL, videoquality_description TEXT NOT NULL); ' )
2017-12-28 08:36:44 +01:00
c . execute ( ' CREATE TABLE IF NOT EXISTS metadata (fileid TEXT PRIMARY KEY NOT NULL, created_by TEXT, creation_date TEXT, announce_url TEXT NOT NULL, source TEXT, torrentsize TEXT NOT NULL, name TEXT NOT NULL, private TEXT NOT NULL) ' )
2015-02-19 00:50:18 +01:00
connection . commit ( )
connection . close ( )
2015-02-15 03:48:39 +01:00
def getLocalString ( language , descriptor ) :
global strings
if language in strings . keys ( ) :
if descriptor in strings [ language ] . keys ( ) :
return strings [ language ] [ descriptor ]
else :
return descriptor
else :
return descriptor
2015-02-15 04:51:27 +01:00
def createNewTorrent ( reuqest ) :
uploadfile = request . files [ " torrentFile " ]
filename = secure_filename ( uploadfile . filename )
2017-12-28 10:15:00 +01:00
content = request . files [ " torrentFile " ] . stream . read ( )
bcoded = bencoder . decode ( content )
info_hash = sha1 ( bencoder . encode ( bcoded [ b ' info ' ] ) ) . hexdigest ( )
with open ( " torrentFiles/ " + info_hash , " wb " ) as torrent_file :
torrent_file . write ( content )
2017-12-28 08:36:44 +01:00
bcoded = bencoder . decode ( content )
size = ( ( len ( bcoded [ b ' info ' ] [ b ' pieces ' ] ) / 20 ) * bcoded [ b ' info ' ] [ b ' piece length ' ] ) / 1024 / 1024
2015-02-15 04:51:27 +01:00
print ( " === CREATE NEW TORRENT FILE === " )
print ( " Name: " + request . form [ " name " ] )
2017-12-28 10:15:00 +01:00
print ( " Torrent file: " + info_hash )
2015-02-15 04:51:27 +01:00
print ( " Category: " + request . form [ " category " ] )
print ( " Subcategory: " + request . form [ " subcategory " ] )
print ( " Description: " + request . form [ " description " ] )
2015-02-19 00:50:18 +01:00
#TODO: Validate the input serverside before writing it to the database
name = request . form [ " name " ]
category = request . form [ " category " ]
subcategory = request . form [ " subcategory " ]
description = request . form [ " description " ]
2015-02-21 03:01:47 +01:00
audioquality_description = request . form [ " audioquality_description " ]
videoquality_description = request . form [ " videoquality_description " ]
2017-12-28 10:15:00 +01:00
newTFile = TorrentFile ( info_hash , name , category , subcategory , description , audioquality_description , videoquality_description )
2017-12-29 00:31:28 +01:00
try :
connection = sqlite3 . connect ( " torrentdb.sqlite " )
newTFile . writeToDb ( connection . cursor ( ) )
newTFile . metadata . writeToDb ( connection . cursor ( ) )
connection . commit ( )
connection . close ( )
return [ " Success " ]
except sqlite3 . IntegrityError as e :
print ( e )
return [ " Torrent <a href= \" /search?h= {} \" > {} </a> does already exist " . format ( info_hash , info_hash [ : - 20 ] ) ]
except Exception as e :
print ( e )
return [ " Unknown error in creation " ]
2015-02-19 00:50:18 +01:00
2017-12-28 08:36:44 +01:00
class Metadata ( ) :
def __init__ ( self , fileid ) :
with open ( " torrentFiles/ " + fileid , " rb " ) as f :
torrent = f . read ( )
self . fileid = fileid
self . bcoded = bencoder . decode ( torrent )
self . created_by = self . bcoded . get ( b ' created by ' , " " )
self . creation_date = self . bcoded . get ( b ' creation date ' , " " )
self . announce_url = self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' ' , " " )
self . source = self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' source ' , " " )
self . torrentsize = ( ( len ( self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' pieces ' , " " ) ) / 20 ) * self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' piece length ' ) )
self . name = self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' name ' , " " )
self . private = self . bcoded . get ( b ' info ' , dict ( ) ) . get ( b ' private ' , " " )
def writeToDb ( self , cursor ) :
c = cursor
b64created_by = base64 . b64encode ( self . created_by )
2017-12-28 10:15:00 +01:00
b64announce_url = base64 . b64encode ( self . announce_url . decode ( ) ) if self . announce_url else " "
b64source = base64 . b64encode ( self . source ) if self . source else " "
2017-12-28 08:36:44 +01:00
b64name = base64 . b64encode ( self . name )
c . execute ( " INSERT INTO metadata(fileid, created_by, creation_date, announce_url, source, torrentsize, name, private) VALUES(:fileid, :created_by, :creation_date, :announce_url, :source, :torrentsize, :name, :private) " , { ' fileid ' : self . fileid , ' created_by ' : b64created_by , ' creation_date ' : self . creation_date , ' announce_url ' : b64announce_url , ' source ' : b64source , ' torrentsize ' : self . torrentsize , ' name ' : b64name , ' private ' : self . private } )
2015-02-19 00:50:18 +01:00
class TorrentFile ( ) :
fileid = None
name = None
category = None
subcategory = None
description = None
2015-02-21 03:01:47 +01:00
audioquality_description = None
videoquality_description = None
def __init__ ( self , fileid = fileid , name = name , category = category , subcategory = subcategory , description = description , audioquality_description = audioquality_description , videoquality_description = videoquality_description ) :
2015-02-19 00:50:18 +01:00
self . fileid = fileid
self . name = name
self . category = category
self . subcategory = subcategory
self . description = description
2015-02-21 03:01:47 +01:00
self . audioquality_description = audioquality_description
self . videoquality_description = videoquality_description
2017-12-28 08:36:44 +01:00
self . metadata = Metadata ( fileid )
2015-02-19 00:50:18 +01:00
def writeToDb ( self , cursor ) :
c = cursor
b64description = base64 . b64encode ( self . description . encode ( ) )
2015-02-21 03:01:47 +01:00
b64audioquality_description = base64 . b64encode ( self . audioquality_description . encode ( ) )
b64videoquality_description = base64 . b64encode ( self . videoquality_description . encode ( ) )
c . execute ( " INSERT INTO torrents(fileid, name, category, subcategory, description, audioquality_description, videoquality_description) VALUES(:fileid, :name, :category, :subcategory, :description, :audioquality_description, :videoquality_description) " , { ' fileid ' : self . fileid , ' name ' : self . name , ' category ' : self . category , ' subcategory ' : self . subcategory , ' description ' : b64description , ' audioquality_description ' : b64audioquality_description , ' videoquality_description ' : b64videoquality_description } )
2015-02-06 22:03:42 +01:00
2015-02-05 22:17:33 +01:00
if __name__ == " __main__ " :
2015-02-15 03:48:39 +01:00
init ( )
app . jinja_env . globals . update ( getLocalString = getLocalString )
app . jinja_env . globals . update ( json = json )
app . jinja_env . globals . update ( sorted = sorted )
2017-12-28 21:51:16 +01:00
app . run ( debug = True , host = " 127.0.0.1 " )