diff --git a/daemon.py b/daemon.py index cb69c19d..5161c267 100644 --- a/daemon.py +++ b/daemon.py @@ -11981,7 +11981,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None: tokensLookup[token] = nickname -def runDaemon(allowNewsFollowers: bool, +def runDaemon(maxFollowers: int, + allowNewsFollowers: bool, maxNewsPosts: int, maxMirroredArticles: int, maxNewswireFeedSizeKb: int, @@ -12132,6 +12133,9 @@ def runDaemon(allowNewsFollowers: bool, # attached to RSS feeds pulled in via the newswire httpd.maxTags = 32 + # maximum number of followers per account + httpd.maxFollowers = maxFollowers + if registration == 'open': httpd.registration = True else: @@ -12274,7 +12278,8 @@ def runDaemon(allowNewsFollowers: bool, httpd.translate, unitTest, httpd.YTReplacementDomain, httpd.showPublishedDateOnly, - httpd.allowNewsFollowers), daemon=True) + httpd.allowNewsFollowers, + httpd.maxFollowers), daemon=True) print('Creating scheduled post thread') httpd.thrPostSchedule = \ diff --git a/epicyon.py b/epicyon.py index ca2d653c..4477a419 100644 --- a/epicyon.py +++ b/epicyon.py @@ -130,6 +130,11 @@ parser.add_argument('--maxNewsPosts', default=0, help='Maximum number of news timeline posts to keep. ' + 'Zero for no expiry.') +parser.add_argument('--maxFollowers', + dest='maxFollowers', type=int, + default=2000, + help='Maximum number of followers per account. ' + + 'Zero for no limit.') parser.add_argument('--postcache', dest='maxRecentPosts', type=int, default=512, help='The maximum number of recent posts to store in RAM') @@ -1970,6 +1975,11 @@ maxNewsPosts = \ if maxNewsPosts is not None: args.maxNewsPosts = int(maxNewsPosts) +maxFollowers = \ + getConfigParam(baseDir, 'maxFollowers') +if maxFollowers is not None: + args.maxFollowers = int(maxFollowers) + allowNewsFollowers = \ getConfigParam(baseDir, 'allowNewsFollowers') if allowNewsFollowers is not None: @@ -1988,7 +1998,8 @@ if setTheme(baseDir, themeName, domain): print('Theme set to ' + themeName) if __name__ == "__main__": - runDaemon(args.allowNewsFollowers, + runDaemon(args.maxFollowers, + args.allowNewsFollowers, args.maxNewsPosts, args.maxMirroredArticles, args.maxNewswireFeedSizeKb, diff --git a/follow.py b/follow.py index b8cdf1a9..36d815d0 100644 --- a/follow.py +++ b/follow.py @@ -253,13 +253,14 @@ def getNoOfFollows(baseDir: str, nickname: str, domain: str, with open(filename, "r") as f: lines = f.readlines() for line in lines: - if '#' not in line: - if '@' in line and \ - '.' in line and \ - not line.startswith('http'): - ctr += 1 - elif line.startswith('http') and '/users/' in line: - ctr += 1 + if '#' in line: + continue + if '@' in line and \ + '.' in line and \ + not line.startswith('http'): + ctr += 1 + elif line.startswith('http') and '/users/' in line: + ctr += 1 return ctr @@ -521,7 +522,8 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str, cachedWebfingers: {}, personCache: {}, messageJson: {}, federationList: [], debug: bool, projectVersion: str, - allowNewsFollowers: bool) -> bool: + allowNewsFollowers: bool, + maxFollowers: int) -> bool: """Receives a follow request within the POST section of HTTPServer """ if not messageJson['type'].startswith('Follow'): @@ -588,6 +590,13 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str, print('DEBUG: Cannot follow system account - ' + nicknameToFollow) return True + if maxFollowers > 0: + if getNoOfFollowers(baseDir, + nicknameToFollow, domainToFollow, + True) > maxFollowers: + print('WARN: ' + nicknameToFollow + + ' has reached their maximum number of followers') + return True handleToFollow = nicknameToFollow + '@' + domainToFollow if domainToFollow == domain: if not os.path.isdir(baseDir + '/accounts/' + handleToFollow): diff --git a/inbox.py b/inbox.py index dda62813..a15b9f9c 100644 --- a/inbox.py +++ b/inbox.py @@ -2437,7 +2437,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int, maxEmoji: int, translate: {}, unitTest: bool, YTReplacementDomain: str, showPublishedDateOnly: bool, - allowNewsFollowers: bool) -> None: + allowNewsFollowers: bool, + maxFollowers: int) -> None: """Processes received items and moves them to the appropriate directories """ @@ -2724,7 +2725,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int, queueJson['post'], federationList, debug, projectVersion, - allowNewsFollowers): + allowNewsFollowers, + maxFollowers): if os.path.isfile(queueFilename): os.remove(queueFilename) if len(queue) > 0: diff --git a/tests.py b/tests.py index d1da2219..8450d2f9 100644 --- a/tests.py +++ b/tests.py @@ -290,7 +290,7 @@ def createServerAlice(path: str, domain: str, port: int, onionDomain = None i2pDomain = None print('Server running: Alice') - runDaemon(False, 0, 100, 1024, 5, False, + runDaemon(10, False, 0, 100, 1024, 5, False, 0, False, 1, False, False, False, 5, True, True, 'en', __version__, "instanceId", False, path, domain, @@ -354,7 +354,7 @@ def createServerBob(path: str, domain: str, port: int, onionDomain = None i2pDomain = None print('Server running: Bob') - runDaemon(False, 0, 100, 1024, 5, False, 0, + runDaemon(10, False, 0, 100, 1024, 5, False, 0, False, 1, False, False, False, 5, True, True, 'en', __version__, "instanceId", False, path, domain, @@ -392,7 +392,7 @@ def createServerEve(path: str, domain: str, port: int, federationList: [], onionDomain = None i2pDomain = None print('Server running: Eve') - runDaemon(False, 0, 100, 1024, 5, False, 0, + runDaemon(10, False, 0, 100, 1024, 5, False, 0, False, 1, False, False, False, 5, True, True, 'en', __version__, "instanceId", False, path, domain,