Improve Filter performance.

This commit is contained in:
ccd0 2019-03-19 14:20:03 -07:00
parent 35213df61e
commit 569ae9b06b

View File

@ -22,17 +22,26 @@ Filter =
# Comma-separated list of the boards this filter applies to. # Comma-separated list of the boards this filter applies to.
# Defaults to global. # Defaults to global.
boards = filter.match(/boards:([^;]+)/)?[1].toLowerCase() or 'global' boardsRaw = filter.match(/boards:([^;]+)/)?[1].toLowerCase()
boards = boards.replace('nsfw', nsfwBoards).replace('sfw', sfwBoards) if boardsRaw
boards = if boards is 'global' then null else boards.split(',') boards = {}
for board in boardsRaw.replace('nsfw', nsfwBoards).replace('sfw', sfwBoards).split(',')
boards[board] = true
else
boards = false
# boards to exclude from an otherwise global rule # boards to exclude from an otherwise global rule
# due to the sfw and nsfw keywords, also works on all filters # due to the sfw and nsfw keywords, also works on all filters
# replaces 'nsfw' and 'sfw' for consistency # replaces 'nsfw' and 'sfw' for consistency
excludes = filter.match(/exclude:([^;]+)/)?[1].toLowerCase() or null excludesRaw = filter.match(/exclude:([^;]+)/)?[1].toLowerCase()
excludes = if excludes is null then null else excludes.replace('nsfw', nsfwBoards).replace('sfw', sfwBoards).split(',') if excludesRaw
excludes = {}
for board in excludesRaw.replace('nsfw', nsfwBoards).replace('sfw', sfwBoards).split(',')
excludes[board] = true
else
excludes = false
if key in ['uniqueID', 'MD5'] if (isstring = (key in ['uniqueID', 'MD5']))
# MD5 filter will use strings instead of regular expressions. # MD5 filter will use strings instead of regular expressions.
regexp = regexp[1] regexp = regexp[1]
else else
@ -67,11 +76,10 @@ Filter =
# Desktop notification # Desktop notification
noti = /notify/.test filter noti = /notify/.test filter
# Highlight the post, or hide it. # Highlight the post.
# If not specified, the highlight class will be filter-highlight. # If not specified, the highlight class will be filter-highlight.
# Defaults to post hiding. if (hl = /highlight/.test filter)
if hl = /highlight/.test filter hl = filter.match(/highlight:([\w-]+)/)?[1] or 'filter-highlight'
hl = filter.match(/highlight:([\w-]+)/)?[1] or 'filter-highlight'
# Put highlighted OP's thread on top of the board page or not. # Put highlighted OP's thread on top of the board page or not.
# Defaults to on top. # Defaults to on top.
top = filter.match(/top:(yes|no)/)?[1] or 'yes' top = filter.match(/top:(yes|no)/)?[1] or 'yes'
@ -85,7 +93,10 @@ Filter =
else else
types = ['subject', 'name', 'filename', 'comment'] types = ['subject', 'name', 'filename', 'comment']
filter = @createFilter regexp, boards, excludes, op, stub, hl, top, noti # Hide the post (default case).
hide = !(hl or noti)
filter = {isstring, regexp, boards, excludes, op, hide, stub, hl, top, noti}
if key is 'general' if key is 'general'
for type in types for type in types
(@filters[type] or= []).push filter (@filters[type] or= []).push filter
@ -97,32 +108,6 @@ Filter =
name: 'Filter' name: 'Filter'
cb: @node cb: @node
createFilter: (regexp, boards, excludes, op, stub, hl, top, noti) ->
test =
if typeof regexp is 'string'
# MD5 checking
(value) -> regexp is value
else
(value) -> regexp.test value
settings =
hide: !(hl or noti)
stub: stub
class: hl
top: top
noti: noti
(value, boardID, isReply) ->
if boards and boardID not in boards
return false
if excludes and boardID in excludes
return false
if isReply and op is 'only' or !isReply and op is 'no'
return false
unless test value
return false
settings
test: (post, hideable=true) -> test: (post, hideable=true) ->
return post.filterResults if post.filterResults return post.filterResults if post.filterResults
hide = false hide = false
@ -134,16 +119,22 @@ Filter =
hideable = false hideable = false
for key of Filter.filters when ((value = Filter[key] post)?) for key of Filter.filters when ((value = Filter[key] post)?)
# Continue if there's nothing to filter (no tripcode for example). # Continue if there's nothing to filter (no tripcode for example).
for filter in Filter.filters[key] when (result = filter value, post.boardID, post.isReply) for filter in Filter.filters[key]
if result.hide continue if (
(filter.boards and !filter.boards[post.boardID]) or
(filter.excludes and filter.excludes[post.boardID]) or
filter.op is (if post.isReply then 'only' else 'no') or
(if filter.isstring then (filter.regexp isnt value) else !filter.regexp.test(value))
)
if filter.hide
if hideable if hideable
hide = true hide = true
stub and= result.stub stub and= filter.stub
else else
unless hl and result.class in hl unless hl and filter.hl in hl
(hl or= []).push result.class (hl or= []).push filter.hl
top or= result.top top or= filter.top
if result.noti if filter.noti
noti = true noti = true
if hide if hide
{hide, stub} {hide, stub}