2022-05-04 23:09:46 +00:00
from files . helpers . wrappers import *
import re
from sqlalchemy import *
from flask import *
from files . __main__ import app
2022-06-24 14:30:59 +00:00
from files . helpers . regex import *
2022-05-04 23:09:46 +00:00
2022-06-23 09:02:49 +00:00
search_operator_hole = HOLE_NAME
2022-06-22 06:35:50 +00:00
valid_params = [
2022-05-04 23:09:46 +00:00
' author ' ,
' domain ' ,
2022-06-22 06:35:50 +00:00
' over18 ' ,
2022-07-01 11:11:23 +00:00
" post " ,
2022-06-23 09:02:49 +00:00
search_operator_hole ,
2022-05-04 23:09:46 +00:00
]
def searchparse ( text ) :
2022-06-21 05:31:31 +00:00
text = text . lower ( )
2022-05-04 23:09:46 +00:00
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 ] } " , " " )
2022-07-04 08:19:41 +00:00
text = text . strip ( )
2022-05-04 23:09:46 +00:00
if text :
2022-07-04 08:19:41 +00:00
criteria [ ' q ' ] = [ ]
2022-07-06 11:49:13 +00:00
for m in search_token_regex . finditer ( text ) :
2022-07-04 08:19:41 +00:00
token = m [ 1 ] if m [ 1 ] else m [ 2 ]
# Escape SQL pattern matching special characters
token = token . replace ( ' \\ ' , ' ' ) . replace ( ' _ ' , ' \ _ ' ) . replace ( ' % ' , ' \ % ' )
criteria [ ' q ' ] . append ( token )
2022-05-04 23:09:46 +00:00
return criteria
@app.get ( " /search/posts " )
@auth_required
def searchposts ( 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 ( )
criteria = searchparse ( query )
2022-05-24 20:43:49 +00:00
posts = g . db . query ( Submission . id ) . filter ( Submission . author_id . notin_ ( v . userblocks ) )
2022-05-04 23:09:46 +00:00
if not v . paid_dues : posts = posts . filter_by ( club = False )
if v . admin_level < 2 :
2022-05-24 20:43:49 +00:00
posts = posts . filter ( Submission . deleted_utc == 0 , Submission . is_banned == False , Submission . private == False )
2022-05-04 23:09:46 +00:00
2022-07-04 08:19:41 +00:00
2022-05-04 23:09:46 +00:00
if ' author ' in criteria :
posts = posts . filter ( Submission . ghost == False )
author = get_user ( criteria [ ' author ' ] )
if not author : return { " error " : " User not found " }
if author . is_private and author . id != v . id and v . admin_level < 2 and not v . eye :
if request . headers . get ( " Authorization " ) :
return { " error " : f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them " }
return render_template ( " search.html " ,
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 )
if ' q ' in criteria :
2022-07-04 08:19:41 +00:00
words = [ or_ ( Submission . title . ilike ( ' % ' + x + ' % ' ) , Submission . body . ilike ( ' % ' + x + ' % ' ) ) \
for x in criteria [ ' q ' ] ]
2022-06-13 17:33:20 +00:00
posts = posts . filter ( * words )
2022-05-04 23:09:46 +00:00
if ' over18 ' in criteria : posts = posts . filter ( Submission . over_18 == True )
if ' domain ' in criteria :
domain = criteria [ ' domain ' ]
domain = domain . replace ( ' \\ ' , ' ' ) . replace ( ' _ ' , ' \ _ ' ) . replace ( ' % ' , ' ' ) . strip ( )
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 )
)
)
2022-06-23 09:02:49 +00:00
if search_operator_hole in criteria :
posts = posts . filter ( Submission . sub == criteria [ search_operator_hole ] )
2022-05-04 23:09:46 +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
posts = posts . filter ( Submission . created_utc > = cutoff )
2022-06-22 19:57:57 +00:00
posts = sort_posts ( sort , posts )
2022-05-04 23:09:46 +00:00
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 request . headers . get ( " Authorization " ) : return { " total " : total , " data " : [ x . json for x in posts ] }
return render_template ( " search.html " ,
v = v ,
query = query ,
total = total ,
page = page ,
listing = posts ,
sort = sort ,
t = t ,
next_exists = next_exists
)
@app.get ( " /search/comments " )
@auth_required
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 ( )
t = request . values . get ( ' t ' , ' all ' ) . lower ( )
criteria = searchparse ( query )
2022-06-23 06:11:03 +00:00
comments = g . db . query ( Comment . id ) . join ( Comment . post ) \
. filter ( Comment . parent_submission != None , Comment . author_id . notin_ ( v . userblocks ) )
2022-05-04 23:09:46 +00:00
2022-07-01 11:11:23 +00:00
if ' post ' in criteria :
try : post = int ( criteria [ ' post ' ] )
except : return { " error " : f " Post with id { post } does not exist. " }
comments = comments . filter ( Comment . parent_submission == post )
2022-05-04 23:09:46 +00:00
if ' author ' in criteria :
comments = comments . filter ( Comment . ghost == False )
author = get_user ( criteria [ ' author ' ] )
if not author : return { " error " : " User not found " }
if author . is_private and author . id != v . id and v . admin_level < 2 and not v . eye :
if request . headers . get ( " Authorization " ) :
return { " error " : f " @ { author . username } ' s profile is private; You can ' t use the ' author ' syntax on them " }
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. " )
else : comments = comments . filter ( Comment . author_id == author . id )
if ' q ' in criteria :
2022-07-04 08:19:41 +00:00
words = [ Comment . body . ilike ( ' % ' + x + ' % ' ) for x in criteria [ ' q ' ] ]
2022-05-04 23:09:46 +00:00
comments = comments . filter ( * words )
if ' over18 ' in criteria : comments = comments . filter ( Comment . over_18 == True )
2022-06-23 09:02:49 +00:00
if search_operator_hole in criteria :
comments = comments . filter ( Submission . sub == criteria [ search_operator_hole ] )
2022-06-23 06:11:03 +00:00
2022-05-04 23:09:46 +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 v . admin_level < 2 :
private = [ x [ 0 ] for x in g . db . query ( Submission . id ) . filter ( Submission . private == True ) . all ( ) ]
2022-05-24 20:43:49 +00:00
comments = comments . filter ( Comment . is_banned == False , Comment . deleted_utc == 0 , Comment . parent_submission . notin_ ( private ) )
2022-05-04 23:09:46 +00:00
if not v . paid_dues :
club = [ x [ 0 ] for x in g . db . query ( Submission . id ) . filter ( Submission . club == True ) . all ( ) ]
comments = comments . filter ( Comment . parent_submission . notin_ ( club ) )
2022-06-22 19:50:20 +00:00
comments = sort_comments ( sort , comments )
2022-05-04 23:09:46 +00:00
total = comments . count ( )
comments = comments . offset ( 25 * ( page - 1 ) ) . limit ( 26 ) . all ( )
ids = [ x [ 0 ] for x in comments ]
next_exists = ( len ( ids ) > 25 )
ids = ids [ : 25 ]
comments = get_comments ( ids , v = v )
if request . headers . get ( " Authorization " ) : return { " total " : total , " data " : [ x . json for x in comments ] }
return render_template ( " search_comments.html " , v = v , query = query , total = total , page = page , comments = comments , sort = sort , t = t , next_exists = next_exists , standalone = True )
@app.get ( " /search/users " )
@auth_required
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 ( ' \\ ' , ' ' ) . replace ( ' _ ' , ' \ _ ' ) . replace ( ' % ' , ' ' )
users = g . db . query ( User ) . filter ( User . username . ilike ( f ' % { term } % ' ) )
users = users . order_by ( User . username . ilike ( term ) . desc ( ) , User . stored_subscriber_count . desc ( ) )
total = users . count ( )
2022-05-25 20:16:26 +00:00
users = users . offset ( 25 * ( page - 1 ) ) . limit ( 26 ) . all ( )
2022-05-04 23:09:46 +00:00
next_exists = ( len ( users ) > 25 )
users = users [ : 25 ]
if request . headers . get ( " Authorization " ) : return { " data " : [ x . json for x in users ] }
2022-06-13 17:33:20 +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 )