2021-10-15 14:08:27 +00:00
from files . helpers . wrappers import *
import re
from sqlalchemy import *
from flask import *
from files . __main__ import app
2022-02-04 09:15:59 +00:00
query_regex = re . compile ( " ( \ w+):( \ S+) " , re . A )
2021-10-15 14:08:27 +00:00
valid_params = [
' author ' ,
' domain ' ,
' over18 '
]
def searchparse ( text ) :
criteria = { x [ 0 ] : x [ 1 ] for x in query_regex . findall ( text ) }
for x in criteria :
if x in valid_params :
text = text . replace ( f " { x } : { criteria [ x ] } " , " " )
text = text . strip ( )
if text :
criteria [ ' q ' ] = text
return criteria
@app.get ( " /search/posts " )
2022-01-11 21:54:41 +00:00
@auth_required
2021-10-15 14:08:27 +00:00
def searchposts ( v ) :
query = request . values . get ( " q " , ' ' ) . strip ( )
page = max ( 1 , int ( request . values . get ( " page " , 1 ) ) )
2021-10-16 09:42:05 +00:00
sort = request . values . get ( " sort " , " new " ) . lower ( )
2021-10-15 14:08:27 +00:00
t = request . values . get ( ' t ' , ' all ' ) . lower ( )
criteria = searchparse ( query )
2021-11-17 13:19:25 +00:00
posts = g . db . query ( Submission . id )
if not ( v and v . paid_dues ) : posts = posts . filter ( Submission . club == False )
2021-10-15 14:08:27 +00:00
2021-11-15 22:13:29 +00:00
if not ( v and v . admin_level > 1 ) : posts = posts . filter ( Submission . private == False )
2021-10-15 14:08:27 +00:00
2021-12-29 07:08:10 +00:00
if ' author ' in criteria :
2022-02-04 04:10:31 +00:00
posts = posts . filter ( Submission . ghost == None )
2021-12-29 07:08:10 +00:00
author = get_user ( criteria [ ' author ' ] )
2022-02-06 10:54:05 +00:00
if not author : return { " error " : " User not found " }
2022-01-11 20:21:50 +00:00
if author . is_private and author . id != v . id and v . admin_level < 2 and not v . eye :
2021-12-29 07:08:10 +00:00
if request . headers . get ( " Authorization " ) :
return { " error " : f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them " }
2022-01-14 12:04:35 +00:00
return render_template ( " search.html " ,
2021-12-29 07:08:10 +00:00
v = v ,
query = query ,
total = 0 ,
page = page ,
listing = [ ] ,
sort = sort ,
t = t ,
next_exists = False ,
domain = None ,
domain_obj = None ,
error = f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them. "
)
else : posts = posts . filter ( Submission . author_id == author . id )
2021-10-15 14:08:27 +00:00
if ' q ' in criteria :
words = criteria [ ' q ' ] . split ( )
words = [ Submission . title . ilike ( ' % ' + x + ' % ' ) for x in words ]
words = tuple ( words )
posts = posts . filter ( * words )
if ' over18 ' in criteria : posts = posts . filter ( Submission . over_18 == True )
if ' domain ' in criteria :
domain = criteria [ ' domain ' ]
posts = posts . filter (
or_ (
Submission . url . ilike ( " https:// " + domain + ' / % ' ) ,
Submission . url . ilike ( " https:// " + domain + ' / % ' ) ,
Submission . url . ilike ( " https:// " + domain ) ,
Submission . url . ilike ( " https:// " + domain ) ,
Submission . url . ilike ( " https://www. " + domain + ' / % ' ) ,
Submission . url . ilike ( " https://www. " + domain + ' / % ' ) ,
Submission . url . ilike ( " https://www. " + domain ) ,
Submission . url . ilike ( " https://www. " + domain ) ,
Submission . url . ilike ( " https://old. " + domain + ' / % ' ) ,
Submission . url . ilike ( " https://old. " + domain + ' / % ' ) ,
Submission . url . ilike ( " https://old. " + domain ) ,
Submission . url . ilike ( " https://old. " + domain )
)
)
2021-12-19 21:41:57 +00:00
if not ( v and v . admin_level > 1 ) : posts = posts . filter ( Submission . deleted_utc == 0 , Submission . is_banned == False )
2021-10-15 14:08:27 +00:00
2021-11-18 20:02:26 +00:00
if v and v . admin_level > 1 : pass
2021-10-15 14:08:27 +00:00
elif v :
blocking = [ x [ 0 ] for x in g . db . query (
2021-11-06 15:52:48 +00:00
UserBlock . target_id ) . filter_by (
2021-10-15 14:08:27 +00:00
user_id = v . id ) . all ( ) ]
blocked = [ x [ 0 ] for x in g . db . query (
2021-11-06 15:52:48 +00:00
UserBlock . user_id ) . filter_by (
2021-10-15 14:08:27 +00:00
target_id = v . id ) . all ( ) ]
posts = posts . filter (
Submission . author_id . notin_ ( blocking ) ,
Submission . author_id . notin_ ( blocked ) ,
)
if t :
now = int ( time . time ( ) )
if t == ' hour ' :
cutoff = now - 3600
elif t == ' day ' :
cutoff = now - 86400
elif t == ' week ' :
cutoff = now - 604800
elif t == ' month ' :
cutoff = now - 2592000
elif t == ' year ' :
cutoff = now - 31536000
else :
cutoff = 0
posts = posts . filter ( Submission . created_utc > = cutoff )
if sort == " new " :
posts = posts . order_by ( Submission . created_utc . desc ( ) )
elif sort == " old " :
posts = posts . order_by ( Submission . created_utc . asc ( ) )
elif sort == " controversial " :
2022-02-09 23:08:55 +00:00
posts = posts . order_by ( Submission . upvotes / Submission . downvotes + Submission . downvotes / Submission . upvotes )
2021-10-15 14:08:27 +00:00
elif sort == " top " :
2021-11-30 23:21:29 +00:00
posts = posts . order_by ( Submission . downvotes - Submission . upvotes )
2021-10-15 14:08:27 +00:00
elif sort == " bottom " :
2021-11-30 23:21:29 +00:00
posts = posts . order_by ( Submission . upvotes - Submission . downvotes )
2021-10-15 14:08:27 +00:00
elif sort == " comments " :
posts = posts . order_by ( Submission . comment_count . desc ( ) )
total = posts . count ( )
posts = posts . offset ( 25 * ( page - 1 ) ) . limit ( 26 ) . all ( )
ids = [ x [ 0 ] for x in posts ]
next_exists = ( len ( ids ) > 25 )
ids = ids [ : 25 ]
posts = get_posts ( ids , v = v )
if v and v . admin_level > 3 and " domain " in criteria :
domain = criteria [ ' domain ' ]
domain_obj = get_domain ( domain )
else :
domain = None
domain_obj = None
2021-12-14 23:38:07 +00:00
if request . headers . get ( " Authorization " ) : return { " total " : total , " data " : [ x . json for x in posts ] }
2021-12-29 07:08:10 +00:00
2022-01-14 12:04:35 +00:00
return render_template ( " search.html " ,
2021-10-15 14:08:27 +00:00
v = v ,
query = query ,
total = total ,
page = page ,
listing = posts ,
sort = sort ,
t = t ,
next_exists = next_exists ,
domain = domain ,
domain_obj = domain_obj
)
@app.get ( " /search/comments " )
2022-01-28 20:13:18 +00:00
@auth_required
2021-10-15 14:08:27 +00:00
def searchcomments ( v ) :
query = request . values . get ( " q " , ' ' ) . strip ( )
try : page = max ( 1 , int ( request . values . get ( " page " , 1 ) ) )
except : page = 1
sort = request . values . get ( " sort " , " new " ) . lower ( )
2022-01-04 13:13:02 +00:00
t = request . values . get ( ' t ' , ' month ' ) . lower ( )
2021-10-15 14:08:27 +00:00
2022-01-04 13:13:02 +00:00
criteria = searchparse ( query )
2021-10-15 14:08:27 +00:00
2021-12-29 07:08:10 +00:00
comments = g . db . query ( Comment . id ) . filter ( Comment . parent_submission != None )
2021-10-15 14:08:27 +00:00
2021-12-29 07:08:10 +00:00
if ' author ' in criteria :
2022-02-04 04:10:31 +00:00
comments = comments . filter ( Comment . ghost == None )
2021-12-29 07:08:10 +00:00
author = get_user ( criteria [ ' author ' ] )
2022-02-06 10:54:05 +00:00
if not author : return { " error " : " User not found " }
2022-01-11 20:21:50 +00:00
if author . is_private and author . id != v . id and v . admin_level < 2 and not v . eye :
2021-12-29 07:08:10 +00:00
if request . headers . get ( " Authorization " ) :
return { " error " : f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them " }
2021-10-15 14:08:27 +00:00
2022-01-14 12:04:35 +00:00
return render_template ( " search_comments.html " , v = v , query = query , total = 0 , page = page , comments = [ ] , sort = sort , t = t , next_exists = False , error = f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them. " )
2021-10-15 14:08:27 +00:00
2021-12-29 07:08:10 +00:00
else : comments = comments . filter ( Comment . author_id == author . id )
2021-10-15 14:08:27 +00:00
if ' q ' in criteria :
2022-01-04 13:13:02 +00:00
words = criteria [ ' q ' ] . split ( )
words = [ Comment . body . ilike ( ' % ' + x + ' % ' ) for x in words ]
words = tuple ( words )
comments = comments . filter ( * words )
2021-10-15 14:08:27 +00:00
2022-01-04 13:13:02 +00:00
if ' over18 ' in criteria : comments = comments . filter ( Comment . over_18 == True )
2021-10-15 14:08:27 +00:00
2022-01-04 13:13:02 +00:00
if not ( v and v . admin_level > 1 ) : comments = comments . filter ( Comment . deleted_utc == 0 , Comment . is_banned == False )
2021-10-15 14:08:27 +00:00
if t :
now = int ( time . time ( ) )
if t == ' hour ' :
cutoff = now - 3600
elif t == ' day ' :
cutoff = now - 86400
elif t == ' week ' :
cutoff = now - 604800
elif t == ' month ' :
cutoff = now - 2592000
elif t == ' year ' :
cutoff = now - 31536000
else :
cutoff = 0
comments = comments . filter ( Comment . created_utc > = cutoff )
if sort == " new " :
comments = comments . order_by ( Comment . created_utc . desc ( ) )
elif sort == " old " :
comments = comments . order_by ( Comment . created_utc . asc ( ) )
elif sort == " controversial " :
2022-02-09 23:08:55 +00:00
comments = comments . order_by ( Comment . upvotes / Comment . downvotes + Comment . downvotes / Comment . upvotes )
2021-10-15 14:08:27 +00:00
elif sort == " top " :
2022-01-17 11:06:12 +00:00
comments = comments . order_by ( Comment . downvotes - Comment . upvotes )
2021-10-15 14:08:27 +00:00
elif sort == " bottom " :
2021-11-30 23:21:29 +00:00
comments = comments . order_by ( Comment . upvotes - Comment . downvotes )
2021-10-15 14:08:27 +00:00
total = comments . count ( )
comments = comments . offset ( 25 * ( page - 1 ) ) . limit ( 26 ) . all ( )
2022-01-04 13:13:02 +00:00
ids = [ x [ 0 ] for x in comments ]
2021-10-15 14:08:27 +00:00
next_exists = ( len ( ids ) > 25 )
ids = ids [ : 25 ]
comments = get_comments ( ids , v = v )
2021-12-14 23:38:07 +00:00
if request . headers . get ( " Authorization " ) : return { " total " : total , " data " : [ x . json for x in comments ] }
2022-01-14 12:04:35 +00:00
return render_template ( " search_comments.html " , v = v , query = query , total = total , page = page , comments = comments , sort = sort , t = t , next_exists = next_exists )
2021-10-15 14:08:27 +00:00
@app.get ( " /search/users " )
2022-01-11 21:54:41 +00:00
@auth_required
2021-10-15 14:08:27 +00:00
def searchusers ( v ) :
query = request . values . get ( " q " , ' ' ) . strip ( )
page = max ( 1 , int ( request . values . get ( " page " , 1 ) ) )
sort = request . values . get ( " sort " , " new " ) . lower ( )
t = request . values . get ( ' t ' , ' all ' ) . lower ( )
term = query . lstrip ( ' @ ' )
term = term . replace ( ' \\ ' , ' ' )
term = term . replace ( ' _ ' , ' \ _ ' )
2021-11-06 15:52:48 +00:00
users = g . db . query ( User ) . filter ( User . username . ilike ( f ' % { term } % ' ) )
2021-10-15 14:08:27 +00:00
users = users . order_by ( User . username . ilike ( term ) . desc ( ) , User . stored_subscriber_count . desc ( ) )
total = users . count ( )
users = [ x for x in users . offset ( 25 * ( page - 1 ) ) . limit ( 26 ) ]
next_exists = ( len ( users ) > 25 )
users = users [ : 25 ]
2022-01-02 13:22:12 +00:00
if request . headers . get ( " Authorization " ) : return { " data " : [ x . json for x in users ] }
2022-01-14 12:04:35 +00:00
return render_template ( " search_users.html " , v = v , query = query , total = total , page = page , users = users , sort = sort , t = t , next_exists = next_exists )