Mark dormant followed accounts on profile

merge-requests/8/head
Bob Mottram 2020-12-13 12:44:17 +00:00
parent 9ba729c6fd
commit d6e60ff3d3
5 changed files with 76 additions and 13 deletions

View File

@ -6491,6 +6491,7 @@ class PubServer(BaseHTTPRequestHandler):
YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
actorJson['roles'],
None, None)
msg = msg.encode('utf-8')
@ -6570,6 +6571,7 @@ class PubServer(BaseHTTPRequestHandler):
YTReplacementDomain,
showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
actorJson['skills'],
None, None)
msg = msg.encode('utf-8')
@ -8258,6 +8260,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
shares,
pageNumber, sharesPerPage)
msg = msg.encode('utf-8')
@ -8349,6 +8352,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
following,
pageNumber,
followsPerPage).encode('utf-8')
@ -8440,6 +8444,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
followers,
pageNumber,
followsPerPage).encode('utf-8')
@ -8506,6 +8511,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.newswire,
self.server.dormantMonths,
None, None).encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -12926,7 +12932,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
tokensLookup[token] = nickname
def runDaemon(maxNewswirePosts: int,
def runDaemon(dormantMonths: int,
maxNewswirePosts: int,
allowLocalNetworkAccess: bool,
maxFeedItemSizeKb: int,
publishButtonAtTop: bool,
@ -13120,6 +13127,10 @@ def runDaemon(maxNewswirePosts: int,
# maximum size of a hashtag category, in K
httpd.maxCategoriesFeedItemSizeKb = 1024
# how many months does a followed account need to be unseen
# for it to be considered dormant?
httpd.dormantMonths = dormantMonths
if registration == 'open':
httpd.registration = True
else:

View File

@ -116,6 +116,11 @@ parser.add_argument('--postsPerSource',
dest='maxNewswirePostsPerSource', type=int,
default=4,
help='Maximum newswire posts per feed or account')
parser.add_argument('--dormantMonths',
dest='dormantMonths', type=int,
default=3,
help='How many months does a followed account need to ' +
'be unseen for before being considered dormant')
parser.add_argument('--maxNewswirePosts',
dest='maxNewswirePosts', type=int,
default=20,
@ -2080,7 +2085,8 @@ if setTheme(baseDir, themeName, domain, args.allowLocalNetworkAccess):
print('Theme set to ' + themeName)
if __name__ == "__main__":
runDaemon(args.maxNewswirePosts,
runDaemon(args.dormantMonths,
args.maxNewswirePosts,
args.allowLocalNetworkAccess,
args.maxFeedItemSizeKb,
args.publishButtonAtTop,

View File

@ -296,8 +296,10 @@ def createServerAlice(path: str, domain: str, port: int,
i2pDomain = None
allowLocalNetworkAccess = True
maxNewswirePosts = 20
dormantMonths = 3
print('Server running: Alice')
runDaemon(maxNewswirePosts, allowLocalNetworkAccess,
runDaemon(dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False,
0, 100, 1024, 5, False,
0, False, 1, False, False, False,
@ -364,8 +366,10 @@ def createServerBob(path: str, domain: str, port: int,
i2pDomain = None
allowLocalNetworkAccess = True
maxNewswirePosts = 20
dormantMonths = 3
print('Server running: Bob')
runDaemon(maxNewswirePosts, allowLocalNetworkAccess,
runDaemon(dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False,
0, 100, 1024, 5, False, 0,
False, 1, False, False, False,
@ -406,8 +410,10 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
i2pDomain = None
allowLocalNetworkAccess = True
maxNewswirePosts = 20
dormantMonths = 3
print('Server running: Eve')
runDaemon(maxNewswirePosts, allowLocalNetworkAccess,
runDaemon(dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False,
0, 100, 1024, 5, False, 0,
False, 1, False, False, False,

View File

@ -19,6 +19,33 @@ from calendar import monthrange
from followingCalendar import addPersonToCalendar
def isDormant(baseDir: str, nickname: str, domain: str, actor: str,
dormantMonths=3) -> bool:
"""Is the given followed actor dormant, from the standpoint
of the given account
"""
lastSeenFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + \
'/lastseen/' + actor.replace('/', '#') + '.txt'
if not os.path.isfile(lastSeenFilename):
return False
with open(lastSeenFilename, 'r') as lastSeenFile:
daysSinceEpochStr = lastSeenFile.read()
if not daysSinceEpochStr:
return False
if not daysSinceEpochStr.isdigit():
return False
currTime = datetime.datetime.utcnow()
currDaysSinceEpoch = (currTime - datetime.datetime(1970, 1, 1)).days
timeDiffMonths = \
int((currDaysSinceEpoch - int(daysSinceEpochStr)) / 30)
if timeDiffMonths >= dormantMonths:
return True
return False
def getHashtagCategory(baseDir: str, hashtag: str) -> str:
"""Returns the category for the hashtag
"""

View File

@ -8,6 +8,7 @@ __status__ = "Production"
import os
from pprint import pprint
from utils import isDormant
from utils import getNicknameFromActor
from utils import getDomainFromActor
from utils import isSystemAccount
@ -364,8 +365,9 @@ def htmlProfile(rssIconAtTop: bool,
session, wfRequest: {}, personCache: {},
YTReplacementDomain: str,
showPublishedDateOnly: bool,
newswire: {}, extraJson=None,
pageNumber=None, maxItemsPerPage=None) -> str:
newswire: {}, dormantMonths: int,
extraJson=None, pageNumber=None,
maxItemsPerPage=None) -> str:
"""Show the profile page as html
"""
nickname = profileJson['preferredUsername']
@ -628,7 +630,8 @@ def htmlProfile(rssIconAtTop: bool,
domain, port, session,
wfRequest, personCache, extraJson,
projectVersion, ["unfollow"], selected,
usersPath, pageNumber, maxItemsPerPage)
usersPath, pageNumber, maxItemsPerPage,
dormantMonths)
elif selected == 'followers':
profileStr += \
htmlProfileFollowing(translate, baseDir, httpPrefix,
@ -637,7 +640,7 @@ def htmlProfile(rssIconAtTop: bool,
wfRequest, personCache, extraJson,
projectVersion, ["block"],
selected, usersPath, pageNumber,
maxItemsPerPage)
maxItemsPerPage, dormantMonths)
elif selected == 'roles':
profileStr += \
htmlProfileRoles(translate, nickname, domainFull,
@ -719,7 +722,8 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
buttons: [],
feedName: str, actor: str,
pageNumber: int,
maxItemsPerPage: int) -> str:
maxItemsPerPage: int,
dormantMonths: int) -> str:
"""Shows following on the profile screen
"""
profileStr = ''
@ -737,12 +741,18 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
translate['Page up'] + '"></a>\n' + \
' </center>\n'
for item in followingJson['orderedItems']:
for followingActor in followingJson['orderedItems']:
dormant = False
if feedName == 'following':
dormant = \
isDormant(baseDir, nickname, domain, followingActor,
dormantMonths)
profileStr += \
individualFollowAsHtml(translate, baseDir, session,
wfRequest, personCache,
domain, item, authorized, nickname,
httpPrefix, projectVersion,
domain, followingActor,
authorized, nickname,
httpPrefix, projectVersion, dormant,
buttons)
if authorized and maxItemsPerPage and pageNumber:
if len(followingJson['orderedItems']) >= maxItemsPerPage:
@ -1436,12 +1446,15 @@ def individualFollowAsHtml(translate: {},
actorNickname: str,
httpPrefix: str,
projectVersion: str,
dormant: bool,
buttons=[]) -> str:
"""An individual follow entry on the profile screen
"""
nickname = getNicknameFromActor(followUrl)
domain, port = getDomainFromActor(followUrl)
titleStr = '@' + nickname + '@' + domain
if dormant:
titleStr += '💤'
avatarUrl = getPersonAvatarUrl(baseDir, followUrl, personCache, True)
if not avatarUrl:
avatarUrl = followUrl + '/avatar.png'