diff --git a/newsdaemon.py b/newsdaemon.py index d67732dc4..a36f22c3d 100644 --- a/newsdaemon.py +++ b/newsdaemon.py @@ -73,7 +73,7 @@ def removeControlCharacters(content: str) -> str: return content -def hashtagRuleResolve(tree: [], hashtags: []) -> bool: +def hashtagRuleResolve(tree: [], hashtags: [], moderated: bool) -> bool: """Returns whether the tree for a hashtag rule evaluates to true or false """ if not tree: @@ -84,7 +84,7 @@ def hashtagRuleResolve(tree: [], hashtags: []) -> bool: if isinstance(tree[1], str): return tree[1] not in hashtags elif isinstance(tree[1], list): - return not hashtagRuleResolve(tree[1], hashtags) + return not hashtagRuleResolve(tree[1], hashtags, moderated) elif tree[0] == 'and': if len(tree) == 3: @@ -92,13 +92,13 @@ def hashtagRuleResolve(tree: [], hashtags: []) -> bool: if isinstance(tree[1], str): firstArg = (tree[1] in hashtags) elif isinstance(tree[1], list): - firstArg = (hashtagRuleResolve(tree[1], hashtags)) + firstArg = (hashtagRuleResolve(tree[1], hashtags, moderated)) secondArg = False if isinstance(tree[2], str): secondArg = (tree[2] in hashtags) elif isinstance(tree[2], list): - secondArg = (hashtagRuleResolve(tree[2], hashtags)) + secondArg = (hashtagRuleResolve(tree[2], hashtags, moderated)) return firstArg and secondArg elif tree[0] == 'or': if len(tree) == 3: @@ -107,28 +107,33 @@ def hashtagRuleResolve(tree: [], hashtags: []) -> bool: if isinstance(tree[1], str): firstArg = (tree[1] in hashtags) elif isinstance(tree[1], list): - firstArg = (hashtagRuleResolve(tree[1], hashtags)) + firstArg = (hashtagRuleResolve(tree[1], hashtags, moderated)) secondArg = False if isinstance(tree[2], str): secondArg = (tree[2] in hashtags) elif isinstance(tree[2], list): - secondArg = (hashtagRuleResolve(tree[2], hashtags)) + secondArg = (hashtagRuleResolve(tree[2], hashtags, moderated)) return firstArg or secondArg elif tree[0].startswith('#') and len(tree) == 1: return tree[0] in hashtags + elif tree[0].startswith('moderated'): + return moderated return False def hashtagRuleTree(operators: [], conditionsStr: str, - tagsInConditions: []) -> []: + tagsInConditions: [], + moderated: bool) -> []: """Walks the tree """ if not operators and conditionsStr: conditionsStr = conditionsStr.strip() - if conditionsStr.startswith('#') or conditionsStr in operators: + if conditionsStr.startswith('#') or \ + conditionsStr in operators or \ + conditionsStr == 'moderated': if conditionsStr.startswith('#'): if conditionsStr not in tagsInConditions: if ' ' not in conditionsStr: @@ -140,7 +145,9 @@ def hashtagRuleTree(operators: [], return None tree = None conditionsStr = conditionsStr.strip() - if conditionsStr.startswith('#') or conditionsStr in operators: + if conditionsStr.startswith('#') or \ + conditionsStr in operators or \ + conditionsStr == 'moderated': if conditionsStr.startswith('#'): if conditionsStr not in tagsInConditions: if ' ' not in conditionsStr: @@ -157,7 +164,7 @@ def hashtagRuleTree(operators: [], sections = conditionsStr.split(op) for subConditionStr in sections: result = hashtagRuleTree(operators[ctr + 1:], subConditionStr, - tagsInConditions) + tagsInConditions, moderated) if result: tree.append(result) break @@ -170,7 +177,8 @@ def newswireHashtagProcessing(session, baseDir: str, postJsonObject: {}, personCache: {}, cachedWebfingers: {}, federationList: [], - sendThreads: [], postLog: []) -> bool: + sendThreads: [], postLog: [], + moderated: bool) -> bool: """Applies hashtag rules to a news post. Returns true if the post should be saved to the news timeline of this instance @@ -199,11 +207,12 @@ def newswireHashtagProcessing(session, baseDir: str, postJsonObject: {}, conditionsStr = ruleStr.split('if ', 1)[1] conditionsStr = conditionsStr.split(' then ')[0] tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) # does the rule contain any hashtags? if not tagsInConditions: continue - if not hashtagRuleResolve(tree, hashtags): + if not hashtagRuleResolve(tree, hashtags, moderated): continue # the condition matches, so do something actionStr = ruleStr.split(' then ')[1].strip() @@ -413,7 +422,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str, httpPrefix, domain, port, personCache, cachedWebfingers, federationList, - sendThreads, postLog) + sendThreads, postLog, moderated) # save the post and update the index if savePost: diff --git a/tests.py b/tests.py index 956d9efe5..e433fd837 100644 --- a/tests.py +++ b/tests.py @@ -83,7 +83,7 @@ from theme import setCSSparam from jsonldsig import testSignJsonld from jsonldsig import jsonldVerify from newsdaemon import hashtagRuleTree -from newsdaemon import hasttagRuleResolve +from newsdaemon import hashtagRuleResolve testServerAliceRunning = False testServerBobRunning = False @@ -2179,55 +2179,87 @@ def testHashtagRuleTree(): print('testHashtagRuleTree') operators = ('not', 'and', 'or') + moderated = True conditionsStr = '#foo or #bar' tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) assert str(tree) == str(['or', ['#foo'], ['#bar']]) assert str(tagsInConditions) == str(['#foo', '#bar']) hashtags = ['#foo'] - assert hasttagRuleResolve(tree, hashtags) + assert hashtagRuleResolve(tree, hashtags, moderated) hashtags = ['#carrot', '#stick'] - assert not hasttagRuleResolve(tree, hashtags) + assert not hashtagRuleResolve(tree, hashtags, moderated) + + moderated = False + conditionsStr = 'not moderated and #foo or #bar' + tagsInConditions = [] + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) + assert str(tree) == \ + str(['not', ['and', ['moderated'], ['or', ['#foo'], ['#bar']]]]) + assert str(tagsInConditions) == str(['#foo', '#bar']) + hashtags = ['#foo'] + assert hashtagRuleResolve(tree, hashtags, moderated) + hashtags = ['#carrot', '#stick'] + assert hashtagRuleResolve(tree, hashtags, moderated) + + moderated = True + conditionsStr = 'moderated and #foo or #bar' + tagsInConditions = [] + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) + assert str(tree) == \ + str(['and', ['moderated'], ['or', ['#foo'], ['#bar']]]) + assert str(tagsInConditions) == str(['#foo', '#bar']) + hashtags = ['#foo'] + assert hashtagRuleResolve(tree, hashtags, moderated) + hashtags = ['#carrot', '#stick'] + assert not hashtagRuleResolve(tree, hashtags, moderated) conditionsStr = 'x' tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) assert tree is None assert tagsInConditions == [] hashtags = ['#foo'] - assert not hasttagRuleResolve(tree, hashtags) + assert not hashtagRuleResolve(tree, hashtags, moderated) conditionsStr = '#x' tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) assert str(tree) == str(['#x']) assert str(tagsInConditions) == str(['#x']) hashtags = ['#x'] - assert hasttagRuleResolve(tree, hashtags) + assert hashtagRuleResolve(tree, hashtags, moderated) hashtags = ['#y', '#z'] - assert not hasttagRuleResolve(tree, hashtags) + assert not hashtagRuleResolve(tree, hashtags, moderated) conditionsStr = 'not #b' tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) assert str(tree) == str(['not', ['#b']]) assert str(tagsInConditions) == str(['#b']) hashtags = ['#y', '#z'] - assert hasttagRuleResolve(tree, hashtags) + assert hashtagRuleResolve(tree, hashtags, moderated) hashtags = ['#a', '#b', '#c'] - assert not hasttagRuleResolve(tree, hashtags) + assert not hashtagRuleResolve(tree, hashtags, moderated) conditionsStr = '#foo or #bar and #a' tagsInConditions = [] - tree = hashtagRuleTree(operators, conditionsStr, tagsInConditions) + tree = hashtagRuleTree(operators, conditionsStr, + tagsInConditions, moderated) assert str(tree) == str(['and', ['or', ['#foo'], ['#bar']], ['#a']]) assert str(tagsInConditions) == str(['#foo', '#bar', '#a']) hashtags = ['#bar', '#a'] - assert hasttagRuleResolve(tree, hashtags) + assert hashtagRuleResolve(tree, hashtags, moderated) hashtags = ['#foo', '#a'] - assert hasttagRuleResolve(tree, hashtags) + assert hashtagRuleResolve(tree, hashtags, moderated) hashtags = ['#x', '#a'] - assert not hasttagRuleResolve(tree, hashtags) + assert not hashtagRuleResolve(tree, hashtags, moderated) def runAllTests():