2016-11-01 05:17:54 +01:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2017-01-01 20:27:31 +01:00
from flask import Flask , abort , escape , make_response , redirect , request , send_from_directory , url_for , Response
2016-11-01 05:17:54 +01:00
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate , MigrateCommand
from hashlib import sha256
from humanize import naturalsize
from magic import Magic
from mimetypes import guess_extension
import os , sys
import requests
from short_url import UrlEncoder
from validators import url as url_valid
app = Flask ( __name__ )
app . config [ " SQLALCHEMY_TRACK_MODIFICATIONS " ] = False
app . config [ " SQLALCHEMY_DATABASE_URI " ] = " sqlite:///db.sqlite " # "postgresql://0x0@/0x0"
app . config [ " PREFERRED_URL_SCHEME " ] = " https " # nginx users: make sure to have 'uwsgi_param UWSGI_SCHEME $scheme;' in your config
2019-06-30 04:22:52 +02:00
app . config [ " MAX_CONTENT_LENGTH " ] = 512 * 1024 * 1024
2016-11-01 05:17:54 +01:00
app . config [ " MAX_URL_LENGTH " ] = 4096
app . config [ " FHOST_STORAGE_PATH " ] = " up "
app . config [ " FHOST_USE_X_ACCEL_REDIRECT " ] = True # expect nginx by default
app . config [ " USE_X_SENDFILE " ] = False
app . config [ " FHOST_EXT_OVERRIDE " ] = {
2018-01-09 08:26:11 +01:00
" audio/flac " : " .flac " ,
2016-11-01 05:17:54 +01:00
" image/gif " : " .gif " ,
" image/jpeg " : " .jpg " ,
" image/png " : " .png " ,
" image/svg+xml " : " .svg " ,
" video/webm " : " .webm " ,
" video/x-matroska " : " .mkv " ,
" application/octet-stream " : " .bin " ,
2017-12-22 21:41:51 +01:00
" text/plain " : " .txt " ,
" text/x-diff " : " .diff " ,
2016-11-01 05:17:54 +01:00
}
# default blacklist to avoid AV mafia extortion
app . config [ " FHOST_MIME_BLACKLIST " ] = [
" application/x-dosexec " ,
" application/java-archive " ,
" application/java-vm "
]
2017-02-03 04:10:58 +01:00
app . config [ " FHOST_UPLOAD_BLACKLIST " ] = " tornodes.txt "
2018-12-22 19:50:32 +01:00
app . config [ " NSFW_DETECT " ] = False
2017-10-27 09:38:19 +02:00
app . config [ " NSFW_THRESHOLD " ] = 0.608
2017-10-27 05:22:11 +02:00
if app . config [ " NSFW_DETECT " ] :
from nsfw_detect import NSFWDetector
nsfw = NSFWDetector ( )
2016-11-01 05:17:54 +01:00
try :
mimedetect = Magic ( mime = True , mime_encoding = False )
except :
print ( """ Error: You have installed the wrong version of the ' magic ' module.
Please install python - magic . """ )
sys . exit ( 1 )
if not os . path . exists ( app . config [ " FHOST_STORAGE_PATH " ] ) :
os . mkdir ( app . config [ " FHOST_STORAGE_PATH " ] )
db = SQLAlchemy ( app )
migrate = Migrate ( app , db )
manager = Manager ( app )
manager . add_command ( " db " , MigrateCommand )
su = UrlEncoder ( alphabet = ' DEQhd2uFteibPwq0SWBInTpA_jcZL5GKz3YCR14Ulk87Jors9vNHgfaOmMXy6Vx- ' , block_size = 16 )
class URL ( db . Model ) :
id = db . Column ( db . Integer , primary_key = True )
url = db . Column ( db . UnicodeText , unique = True )
def __init__ ( self , url ) :
self . url = url
def getname ( self ) :
return su . enbase ( self . id , 1 )
2017-10-27 05:22:11 +02:00
def geturl ( self ) :
return url_for ( " get " , path = self . getname ( ) , _external = True ) + " \n "
2016-11-01 05:17:54 +01:00
class File ( db . Model ) :
id = db . Column ( db . Integer , primary_key = True )
sha256 = db . Column ( db . String , unique = True )
ext = db . Column ( db . UnicodeText )
mime = db . Column ( db . UnicodeText )
addr = db . Column ( db . UnicodeText )
removed = db . Column ( db . Boolean , default = False )
2017-10-27 05:22:11 +02:00
nsfw_score = db . Column ( db . Float )
2016-11-01 05:17:54 +01:00
2017-10-27 05:22:11 +02:00
def __init__ ( self , sha256 , ext , mime , addr , nsfw_score ) :
2016-11-01 05:17:54 +01:00
self . sha256 = sha256
self . ext = ext
self . mime = mime
self . addr = addr
2017-10-27 05:22:11 +02:00
self . nsfw_score = nsfw_score
2016-11-01 05:17:54 +01:00
def getname ( self ) :
return u " {0} {1} " . format ( su . enbase ( self . id , 1 ) , self . ext )
2017-10-27 05:22:11 +02:00
def geturl ( self ) :
n = self . getname ( )
if self . nsfw_score and self . nsfw_score > app . config [ " NSFW_THRESHOLD " ] :
return url_for ( " get " , path = n , _external = True , _anchor = " nsfw " ) + " \n "
else :
return url_for ( " get " , path = n , _external = True ) + " \n "
2016-11-01 05:17:54 +01:00
2017-10-27 08:52:45 +02:00
def pprint ( self ) :
print ( " url: {} " . format ( self . getname ( ) ) )
vals = vars ( self )
for v in vals :
if not v . startswith ( " _sa " ) :
print ( " {} : {} " . format ( v , vals [ v ] ) )
2016-11-01 05:17:54 +01:00
def getpath ( fn ) :
return os . path . join ( app . config [ " FHOST_STORAGE_PATH " ] , fn )
2017-01-01 20:26:09 +01:00
def fhost_url ( scheme = None ) :
if not scheme :
return url_for ( " .fhost " , _external = True ) . rstrip ( " / " )
else :
return url_for ( " .fhost " , _external = True , _scheme = scheme ) . rstrip ( " / " )
def is_fhost_url ( url ) :
return url . startswith ( fhost_url ( ) ) or url . startswith ( fhost_url ( " https " ) )
2016-11-01 05:17:54 +01:00
def shorten ( url ) :
2019-07-26 23:59:10 +02:00
# handler to convert gopher links to HTTP(S) proxy
gopher = " gopher:// "
length = len ( gopher )
if url [ : length ] == gopher :
2019-10-05 18:47:27 +02:00
url = " https://gopher.envs.net/ {} " . format ( url [ length : ] )
2019-07-26 23:59:10 +02:00
2016-11-01 05:17:54 +01:00
if len ( url ) > app . config [ " MAX_URL_LENGTH " ] :
abort ( 414 )
2017-01-01 21:03:38 +01:00
if not url_valid ( url ) or is_fhost_url ( url ) or " \n " in url :
2016-11-01 05:17:54 +01:00
abort ( 400 )
existing = URL . query . filter_by ( url = url ) . first ( )
if existing :
2017-10-27 05:22:11 +02:00
return existing . geturl ( )
2016-11-01 05:17:54 +01:00
else :
u = URL ( url )
db . session . add ( u )
db . session . commit ( )
2017-10-27 05:22:11 +02:00
return u . geturl ( )
2016-11-01 05:17:54 +01:00
2017-02-03 04:10:58 +01:00
def in_upload_bl ( addr ) :
if os . path . isfile ( app . config [ " FHOST_UPLOAD_BLACKLIST " ] ) :
with open ( app . config [ " FHOST_UPLOAD_BLACKLIST " ] , " r " ) as bl :
check = addr . lstrip ( " ::ffff: " )
for l in bl . readlines ( ) :
if not l . startswith ( " # " ) :
if check == l . rstrip ( ) :
return True
return False
2016-11-01 05:17:54 +01:00
def store_file ( f , addr ) :
2017-02-03 04:10:58 +01:00
if in_upload_bl ( addr ) :
return " Your host is blocked from uploading files. \n " , 451
2016-11-01 05:17:54 +01:00
data = f . stream . read ( )
digest = sha256 ( data ) . hexdigest ( )
existing = File . query . filter_by ( sha256 = digest ) . first ( )
if existing :
if existing . removed :
return legal ( )
epath = getpath ( existing . sha256 )
if not os . path . exists ( epath ) :
with open ( epath , " wb " ) as of :
of . write ( data )
2017-10-27 05:22:11 +02:00
if existing . nsfw_score == None :
if app . config [ " NSFW_DETECT " ] :
existing . nsfw_score = nsfw . detect ( epath )
2016-11-01 05:17:54 +01:00
os . utime ( epath , None )
existing . addr = addr
db . session . commit ( )
2017-10-27 05:22:11 +02:00
return existing . geturl ( )
2016-11-01 05:17:54 +01:00
else :
guessmime = mimedetect . from_buffer ( data )
if not f . content_type or not " / " in f . content_type or f . content_type == " application/octet-stream " :
mime = guessmime
else :
mime = f . content_type
if mime in app . config [ " FHOST_MIME_BLACKLIST " ] or guessmime in app . config [ " FHOST_MIME_BLACKLIST " ] :
abort ( 415 )
2016-11-23 01:03:49 +01:00
if mime . startswith ( " text/ " ) and not " charset " in mime :
2016-11-01 05:17:54 +01:00
mime + = " ; charset=utf-8 "
ext = os . path . splitext ( f . filename ) [ 1 ]
if not ext :
gmime = mime . split ( " ; " ) [ 0 ]
if not gmime in app . config [ " FHOST_EXT_OVERRIDE " ] :
ext = guess_extension ( gmime )
else :
ext = app . config [ " FHOST_EXT_OVERRIDE " ] [ gmime ]
else :
ext = ext [ : 8 ]
if not ext :
ext = " .bin "
2017-10-27 05:22:11 +02:00
spath = getpath ( digest )
with open ( spath , " wb " ) as of :
2016-11-01 05:17:54 +01:00
of . write ( data )
2017-10-27 05:22:11 +02:00
if app . config [ " NSFW_DETECT " ] :
nsfw_score = nsfw . detect ( spath )
else :
nsfw_score = None
sf = File ( digest , ext , mime , addr , nsfw_score )
2016-11-01 05:17:54 +01:00
db . session . add ( sf )
db . session . commit ( )
2017-10-27 05:22:11 +02:00
return sf . geturl ( )
2016-11-01 05:17:54 +01:00
def store_url ( url , addr ) :
2019-07-26 23:59:10 +02:00
# handler to convert gopher links to HTTP(S) proxy
gopher = " gopher:// "
length = len ( gopher )
if url [ : length ] == gopher :
2019-10-05 18:47:27 +02:00
url = " https://gopher.envs.net/ {} " . format ( url [ length : ] )
2019-07-26 23:59:10 +02:00
2017-01-01 20:26:09 +01:00
if is_fhost_url ( url ) :
2016-11-01 05:17:54 +01:00
return segfault ( 508 )
2017-10-30 05:36:03 +01:00
h = { " Accept-Encoding " : " identity " }
r = requests . get ( url , stream = True , verify = False , headers = h )
2016-11-01 05:17:54 +01:00
try :
r . raise_for_status ( )
2017-03-27 22:18:38 +02:00
except requests . exceptions . HTTPError as e :
2016-11-01 05:17:54 +01:00
return str ( e ) + " \n "
if " content-length " in r . headers :
l = int ( r . headers [ " content-length " ] )
if l < app . config [ " MAX_CONTENT_LENGTH " ] :
def urlfile ( * * kwargs ) :
return type ( ' ' , ( ) , kwargs ) ( )
f = urlfile ( stream = r . raw , content_type = r . headers [ " content-type " ] , filename = " " )
return store_file ( f , addr )
else :
hl = naturalsize ( l , binary = True )
hml = naturalsize ( app . config [ " MAX_CONTENT_LENGTH " ] , binary = True )
return " Remote file too large ( {0} > {1} ). \n " . format ( hl , hml ) , 413
else :
return " Could not determine remote file size (no Content-Length in response header; shoot admin). \n " , 411
@app.route ( " /<path:path> " )
def get ( path ) :
p = os . path . splitext ( path )
id = su . debase ( p [ 0 ] )
if p [ 1 ] :
f = File . query . get ( id )
if f and f . ext == p [ 1 ] :
if f . removed :
return legal ( )
fpath = getpath ( f . sha256 )
if not os . path . exists ( fpath ) :
abort ( 404 )
fsize = os . path . getsize ( fpath )
if app . config [ " FHOST_USE_X_ACCEL_REDIRECT " ] :
response = make_response ( )
response . headers [ " Content-Type " ] = f . mime
response . headers [ " Content-Length " ] = fsize
response . headers [ " X-Accel-Redirect " ] = " / " + fpath
return response
else :
return send_from_directory ( app . config [ " FHOST_STORAGE_PATH " ] , f . sha256 , mimetype = f . mime )
else :
u = URL . query . get ( id )
if u :
return redirect ( u . url )
abort ( 404 )
2017-01-01 20:27:31 +01:00
@app.route ( " /dump_urls/ " )
@app.route ( " /dump_urls/<int:start> " )
def dump_urls ( start = 0 ) :
meta = " #FORMAT: BEACON \n #PREFIX: {} / \n \n " . format ( fhost_url ( " https " ) )
def gen ( ) :
yield meta
for url in URL . query . order_by ( URL . id . asc ( ) ) . offset ( start ) :
if url . url . startswith ( " http " ) or url . url . startswith ( " https " ) :
bar = " | "
else :
bar = " || "
yield url . getname ( ) + bar + url . url + " \n "
return Response ( gen ( ) , mimetype = " text/plain " )
2016-11-01 05:17:54 +01:00
@app.route ( " / " , methods = [ " GET " , " POST " ] )
def fhost ( ) :
if request . method == " POST " :
2019-09-18 15:41:00 +02:00
out = None
2016-11-01 05:17:54 +01:00
if " file " in request . files :
2019-09-18 15:41:00 +02:00
out = store_file ( request . files [ " file " ] , request . remote_addr )
2016-11-01 05:17:54 +01:00
elif " url " in request . form :
2019-09-18 15:41:00 +02:00
out = store_url ( request . form [ " url " ] , request . remote_addr )
2016-11-01 05:17:54 +01:00
elif " shorten " in request . form :
2019-09-18 15:41:00 +02:00
out = shorten ( request . form [ " shorten " ] )
if not out == None :
return Response ( out , mimetype = " text/plain " )
2016-11-01 05:17:54 +01:00
abort ( 400 )
else :
fmts = list ( app . config [ " FHOST_EXT_OVERRIDE " ] )
fmts . sort ( )
maxsize = naturalsize ( app . config [ " MAX_CONTENT_LENGTH " ] , binary = True )
maxsizenum , maxsizeunit = maxsize . split ( " " )
maxsizenum = float ( maxsizenum )
maxsizehalf = maxsizenum / 2
if maxsizenum . is_integer ( ) :
maxsizenum = int ( maxsizenum )
if maxsizehalf . is_integer ( ) :
maxsizehalf = int ( maxsizehalf )
2019-07-06 02:21:03 +02:00
return """ <!DOCTYPE html>
2019-09-09 16:02:01 +02:00
< html lang = " en " >
2019-07-05 15:58:35 +02:00
< head >
< title > { 6 } < / title >
< meta http - equiv = " content-type " content = " text/html; charset=utf-8 " / >
2019-08-06 19:09:16 +02:00
< meta name = " description " content = " envs.sh | Null Pointer " / >
2019-07-10 01:47:33 +02:00
< link rel = " stylesheet " href = " https://envs.net/css/css_style.css " / >
2019-07-05 15:58:35 +02:00
< / head >
2019-09-08 19:50:21 +02:00
< body id = " body " class = " dark-mode " >
2019-10-05 18:35:06 +02:00
< div class = " clear " style = " min-width: 1150px; " >
2019-07-08 22:17:42 +02:00
2019-10-05 18:35:06 +02:00
< div id = " main " >
< div class = " block_head " >
< pre >
2019-10-05 18:37:53 +02:00
< h1 > < em > envs . sh & #124; THE NULL POINTER</em></h1>
< h3 > < em > file hosting and URL shortening service . < / em > < / h3 >
2019-10-05 18:35:06 +02:00
< / pre >
2019-10-05 18:36:20 +02:00
< / div >
2019-10-05 18:35:06 +02:00
< pre >
2019-07-06 02:21:03 +02:00
< h3 > USAGE < / h3 >
2016-11-01 05:17:54 +01:00
HTTP POST files here :
2019-07-08 22:17:42 +02:00
< code > curl - F ' file=@yourfile.png ' { 0 } < / code >
2020-01-14 17:22:01 +01:00
post your text directly :
< code > echo " text here " | curl - F ' file=@-; ' { 0 } < / code >
2019-07-17 00:42:33 +02:00
you can also POST remote URLs :
2019-07-13 16:22:00 +02:00
< code > curl - F ' url=https://example.com/image.jpg ' { 0 } < / code >
2019-07-17 00:42:33 +02:00
or you can shorten URLs :
2019-07-05 15:58:35 +02:00
< code > curl - F ' shorten=http://example.com/some/long/url ' { 0 } < / code >
2016-11-01 05:17:54 +01:00
2019-07-17 00:42:33 +02:00
file URLs are valid for at least 30 days and up to a year ( see below ) .
shortened URLs do not expire .
not allowed : { 5 }
maximum file size : { 1 }
2016-11-01 05:17:54 +01:00
2019-09-25 02:14:15 +02:00
< h3 > ACCEPTABLE USE POLICY < / h3 >
please do not post any informations that
may violate law ( login / password lists , email lists , personal information ) .
2019-08-03 22:25:06 +02:00
envs . sh is NOT a platform for :
2019-09-23 11:05:13 +02:00
< ul >
< li > child pornography < / li >
< li > malware , including “ potentially unwanted applications ” < / li >
< li > botnet command and control schemes involving this service < / li >
< li > anything even remotely related to crypto currencies < / li >
< li > hosting your backups < / li >
< li > spamming the service with CI build artifacts < / li >
< li > piracy < / li >
< li > alt - right shitposting < / li >
< / ul >
2019-07-06 02:21:03 +02:00
< h3 > REQUIREMENTS < / h3 >
2019-07-17 00:42:33 +02:00
there is only one thing you need to use this service - curl .
curl is available on most platforms , including Windows , Mac OS X and Linux .
2019-07-05 15:58:35 +02:00
2019-07-17 00:42:33 +02:00
if you run a server and like this site , clone it ! centralization is bad .
2019-07-13 16:23:04 +02:00
< small > < a href = " https://github.com/envs-net/0x0 " target = " _blank " > https : / / github . com / envs - net / 0x0 < / a > < / small >
2019-07-17 00:42:33 +02:00
you can also support it financially via liberapay .
2019-07-25 12:17:38 +02:00
< a href = " https://en.liberapay.com/creme/donate " target = " _blank " style = " border-bottom-color: transparent; " > < img alt = " Donate using Liberapay " src = " https://img.shields.io/liberapay/receives/creme.svg?logo=liberapay " > < / a >
2019-06-30 04:22:52 +02:00
2019-07-06 02:21:03 +02:00
< h3 > ALIAS < / h3 >
2019-07-17 00:42:33 +02:00
to make your life easier , you can add aliases to your < code > . bash_aliases < / code > on Linux
and < code > . bash_profile < / code > on Mac OS X . just remember to reset your terminal session after that .
2019-07-08 22:17:42 +02:00
< code > 0 file & #40;) { curl -F"file=@$1" {0} ; }
2020-01-14 17:22:01 +01:00
0 pb & #40;) { curl -F'file=@-;' {0} ; }
2019-07-08 22:17:42 +02:00
0 url & #40;) { curl -F"url=$1" {0} ; }
0 short & #40;) { curl -F"shorten=$1" {0} ; }</code>
2019-07-06 02:21:03 +02:00
2019-07-10 14:25:20 +02:00
now you can use :
2020-01-14 17:22:01 +01:00
< code > 0 file " yourfile.png "
2020-01-14 17:25:31 +01:00
& #35; or
2020-01-14 17:22:01 +01:00
echo " text here " | 0 pb < / code >
2019-07-06 02:21:03 +02:00
2019-08-15 00:25:19 +02:00
< em > if you want a nice wrapper , try < a href = " https://git.envs.net/envs/pb " > ~ tomasino ' s pb</a></em>
2019-07-25 12:17:38 +02:00
2019-07-05 15:58:35 +02:00
< h3 > FILE RETENTION PERIOD < / h3 >
2016-11-01 05:17:54 +01:00
retention = min_age + ( - max_age + min_age ) * pow ( ( file_size / max_size - 1 ) , 3 )
days
365 | \\
| \\
| \\
| \\
| \\
| \\
| . .
| \\
197.5 | - - - - - - - - - - . . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| . .
| \\
| . .
| . . .
| . .
| . . .
| . . . .
| . . . . . .
30 | . . . . . . . . . . . . . . . . . . . .
0 { 2 } { 3 }
{ 4 }
2019-07-05 15:58:35 +02:00
< h3 > ABUSE < / h3 >
2019-07-17 00:42:33 +02:00
if you would like to request permanent deletion , please
2019-08-03 22:25:06 +02:00
send an email to < a href = " mailto:hostmaster@envs.net?subject=Abuse %200x 0 % 20- %20e nvs.sh " target = " _blank " > hostmaster & #64;envs.net</a>.
2016-11-01 05:17:54 +01:00
2019-07-17 00:42:33 +02:00
please allow up to 24 hours for a response .
2016-11-01 05:17:54 +01:00
< / pre >
2019-07-10 01:47:33 +02:00
< / div >
2019-07-06 02:21:03 +02:00
2019-07-10 01:47:33 +02:00
< ! - - UPLOAD - - >
2019-07-06 02:21:03 +02:00
2019-09-27 17:40:19 +02:00
< div id = " sidebar " >
2019-10-05 18:47:27 +02:00
< div class = " block " >
< pre >
2019-07-06 02:21:03 +02:00
< h3 > UPLOAD DIRECTLY < / h3 >
< form action = " {0} " method = " POST " enctype = " multipart/form-data " >
< label for = " file " > File : < / label >
2019-07-08 22:17:42 +02:00
< input class = " form-control " type = " file " name = " file " style = " width:250px; " >
2019-07-06 02:21:03 +02:00
< input class = " form-control " type = " submit " value = " Submit " >
2019-10-05 18:47:27 +02:00
< / form > < / pre >
< / div >
2019-07-10 01:47:33 +02:00
< / div >
2019-07-08 22:17:42 +02:00
2019-07-10 01:47:33 +02:00
< / div >
2019-07-08 22:17:42 +02:00
2019-07-05 15:58:35 +02:00
< / body >
< / html >
2019-06-30 04:22:52 +02:00
2017-01-01 20:26:09 +01:00
""" .format(fhost_url(),
2016-11-01 05:17:54 +01:00
maxsize , str ( maxsizehalf ) . rjust ( 27 ) , str ( maxsizenum ) . rjust ( 27 ) ,
maxsizeunit . rjust ( 54 ) ,
2019-06-30 04:22:52 +02:00
" , " . join ( app . config [ " FHOST_MIME_BLACKLIST " ] ) , fhost_url ( ) . split ( " / " , 2 ) [ 2 ] )
2016-11-01 05:17:54 +01:00
@app.route ( " /robots.txt " )
def robots ( ) :
return """ User-agent: *
Disallow : /
"""
def legal ( ) :
return " 451 Unavailable For Legal Reasons \n " , 451
@app.errorhandler ( 400 )
@app.errorhandler ( 404 )
@app.errorhandler ( 414 )
@app.errorhandler ( 415 )
def segfault ( e ) :
return " Segmentation fault \n " , e . code
@app.errorhandler ( 404 )
def notfound ( e ) :
return u """ <pre>Process {0} stopped
* thread #1: tid = {0}, {1:#018x}, name = '{2}'
frame #0:
Process { 0 } stopped
* thread #8: tid = {0}, {3:#018x} fhost`get(path='{4}') + 27 at fhost.c:139, name = 'fhost/responder', stop reason = invalid address (fault address: 0x30)
frame #0: {3:#018x} fhost`get(path='{4}') + 27 at fhost.c:139
136 get ( SrvContext * ctx , const char * path )
137 { {
138 StoredObj * obj = ctx - > store - > query ( shurl_debase ( path ) ) ;
- > 139 switch ( obj - > type ) { {
140 case ObjTypeFile :
141 ctx - > serve_file_id ( obj - > id ) ;
142 break ;
( lldb ) q < / pre >
""" .format(os.getpid(), id(app), " fhost " , id(get), escape(request.path)), e.code
@manager.command
def debug ( ) :
app . config [ " FHOST_USE_X_ACCEL_REDIRECT " ] = False
app . run ( debug = True , port = 4562 , host = " 0.0.0.0 " )
@manager.command
def permadelete ( name ) :
id = su . debase ( name )
f = File . query . get ( id )
if f :
if os . path . exists ( getpath ( f . sha256 ) ) :
os . remove ( getpath ( f . sha256 ) )
f . removed = True
db . session . commit ( )
@manager.command
def query ( name ) :
id = su . debase ( name )
f = File . query . get ( id )
if f :
2017-10-27 08:52:45 +02:00
f . pprint ( )
2016-11-01 05:17:54 +01:00
@manager.command
def queryhash ( h ) :
f = File . query . filter_by ( sha256 = h ) . first ( )
2017-10-27 08:52:45 +02:00
2016-11-01 05:17:54 +01:00
if f :
2017-10-27 08:52:45 +02:00
f . pprint ( )
2016-11-01 05:17:54 +01:00
@manager.command
2017-10-27 08:52:45 +02:00
def queryaddr ( a , nsfw = False , removed = False ) :
2016-11-01 05:17:54 +01:00
res = File . query . filter_by ( addr = a )
2017-10-27 08:52:45 +02:00
if not removed :
res = res . filter ( File . removed != True )
2017-10-27 08:36:36 +02:00
if nsfw :
res = res . filter ( File . nsfw_score > app . config [ " NSFW_THRESHOLD " ] )
2016-11-01 05:17:54 +01:00
for f in res :
2017-10-27 08:52:45 +02:00
f . pprint ( )
2016-11-01 05:17:54 +01:00
2017-11-08 11:29:02 +01:00
@manager.command
def deladdr ( a ) :
res = File . query . filter_by ( addr = a ) . filter ( File . removed != True )
for f in res :
if os . path . exists ( getpath ( f . sha256 ) ) :
os . remove ( getpath ( f . sha256 ) )
f . removed = True
db . session . commit ( )
2017-10-27 05:22:11 +02:00
def nsfw_detect ( f ) :
try :
open ( f [ " path " ] , ' r ' ) . close ( )
f [ " nsfw_score " ] = nsfw . detect ( f [ " path " ] )
return f
except :
return None
@manager.command
def update_nsfw ( ) :
if not app . config [ " NSFW_DETECT " ] :
print ( " NSFW detection is disabled in app config " )
return 1
from multiprocessing import Pool
import tqdm
res = File . query . filter_by ( nsfw_score = None , removed = False )
with Pool ( ) as p :
results = [ ]
work = [ { " path " : getpath ( f . sha256 ) , " id " : f . id } for f in res ]
for r in tqdm . tqdm ( p . imap_unordered ( nsfw_detect , work ) , total = len ( work ) ) :
if r :
results . append ( { " id " : r [ " id " ] , " nsfw_score " : r [ " nsfw_score " ] } )
db . session . bulk_update_mappings ( File , results )
db . session . commit ( )
2017-10-27 02:21:33 +02:00
@manager.command
2017-10-27 08:52:45 +02:00
def querybl ( nsfw = False , removed = False ) :
blist = [ ]
2017-10-27 02:21:33 +02:00
if os . path . isfile ( app . config [ " FHOST_UPLOAD_BLACKLIST " ] ) :
with open ( app . config [ " FHOST_UPLOAD_BLACKLIST " ] , " r " ) as bl :
for l in bl . readlines ( ) :
if not l . startswith ( " # " ) :
if not " : " in l :
2017-10-27 08:52:45 +02:00
blist . append ( " ::ffff: " + l . rstrip ( ) )
2017-10-27 02:21:33 +02:00
else :
2017-10-27 08:52:45 +02:00
blist . append ( l . strip ( ) )
res = File . query . filter ( File . addr . in_ ( blist ) )
if not removed :
res = res . filter ( File . removed != True )
if nsfw :
res = res . filter ( File . nsfw_score > app . config [ " NSFW_THRESHOLD " ] )
2017-11-08 11:20:46 +01:00
for f in res :
f . pprint ( )
2017-10-27 02:21:33 +02:00
2016-11-01 05:17:54 +01:00
if __name__ == " __main__ " :
manager . run ( )