epicyon/migrate.py

194 lines
7.1 KiB
Python
Raw Normal View History

2020-04-03 17:01:25 +00:00
__filename__ = "migrate.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2021-01-26 10:07:42 +00:00
__version__ = "1.2.0"
2020-04-03 17:01:25 +00:00
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
2021-06-15 15:08:12 +00:00
__module_group__ = "Core"
2019-10-31 10:36:35 +00:00
import os
2021-06-25 18:02:05 +00:00
from utils import isAccountDir
from utils import getNicknameFromActor
from utils import getDomainFromActor
from webfinger import webfingerHandle
from blocking import isBlocked
from posts import getUserUrl
from follow import unfollowAccount
2021-07-03 21:42:26 +00:00
from person import getActorJson
2019-10-31 10:36:35 +00:00
2020-04-03 17:01:25 +00:00
def _moveFollowingHandlesForAccount(baseDir: str, nickname: str, domain: str,
session,
httpPrefix: str, cachedWebfingers: {},
debug: bool) -> int:
"""Goes through all follows for an account and updates any that have moved
2019-10-31 10:36:35 +00:00
"""
ctr = 0
followingFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt'
if not os.path.isfile(followingFilename):
return ctr
with open(followingFilename, "r") as f:
followingHandles = f.readlines()
for followHandle in followingHandles:
followHandle = followHandle.strip("\n").strip("\r")
ctr += \
_updateMovedHandle(baseDir, nickname, domain,
followHandle, session,
httpPrefix, cachedWebfingers,
debug)
return ctr
def _updateMovedHandle(baseDir: str, nickname: str, domain: str,
handle: str, session,
httpPrefix: str, cachedWebfingers: {},
debug: bool) -> int:
"""Check if an account has moved, and if so then alter following.txt
for each account.
Returns 1 if moved, 0 otherwise
2019-10-31 10:36:35 +00:00
"""
ctr = 0
if '@' not in handle:
return ctr
if len(handle) < 5:
return ctr
if handle.startswith('@'):
handle = handle[1:]
wfRequest = webfingerHandle(session, handle,
httpPrefix, cachedWebfingers,
2021-03-14 19:22:58 +00:00
None, __version__, debug)
if not wfRequest:
print('updateMovedHandle unable to webfinger ' + handle)
return ctr
if not isinstance(wfRequest, dict):
print('updateMovedHandle webfinger for ' + handle +
' did not return a dict. ' + str(wfRequest))
return ctr
personUrl = None
if wfRequest.get('errors'):
print('wfRequest error: ' + str(wfRequest['errors']))
return ctr
2019-10-31 10:36:35 +00:00
if not personUrl:
2021-03-14 20:41:37 +00:00
personUrl = getUserUrl(wfRequest, 0, debug)
if not personUrl:
return ctr
2021-07-03 21:42:26 +00:00
gnunet = False
if httpPrefix == 'gnunet':
gnunet = True
personJson = \
2021-07-03 21:42:26 +00:00
getActorJson(domain, personUrl, httpPrefix, gnunet, debug)
if not personJson:
return ctr
if not personJson.get('movedTo'):
return ctr
movedToUrl = personJson['movedTo']
if '://' not in movedToUrl:
return ctr
if '.' not in movedToUrl:
return ctr
movedToNickname = getNicknameFromActor(movedToUrl)
if not movedToNickname:
return ctr
movedToDomain, movedToPort = getDomainFromActor(movedToUrl)
if not movedToDomain:
return ctr
movedToDomainFull = movedToDomain
if movedToPort:
if movedToPort != 80 and movedToPort != 443:
movedToDomainFull = movedToDomain + ':' + str(movedToPort)
if isBlocked(baseDir, nickname, domain,
movedToNickname, movedToDomain):
# someone that you follow has moved to a blocked domain
# so just unfollow them
unfollowAccount(baseDir, nickname, domain,
movedToNickname, movedToDomainFull,
'following.txt', debug)
return ctr
followingFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt'
if os.path.isfile(followingFilename):
with open(followingFilename, "r") as f:
followingHandles = f.readlines()
movedToHandle = movedToNickname + '@' + movedToDomainFull
handleLower = handle.lower()
refollowFilename = \
baseDir + '/accounts/' + \
nickname + '@' + domain + '/refollow.txt'
# unfollow the old handle
with open(followingFilename, 'w+') as f:
for followHandle in followingHandles:
if followHandle.strip("\n").strip("\r").lower() != \
handleLower:
f.write(followHandle)
else:
handleNickname = handle.split('@')[0]
handleDomain = handle.split('@')[1]
unfollowAccount(baseDir, nickname, domain,
handleNickname,
handleDomain,
'following.txt', debug)
ctr += 1
print('Unfollowed ' + handle + ' who has moved to ' +
movedToHandle)
# save the new handles to the refollow list
if os.path.isfile(refollowFilename):
with open(refollowFilename, 'a+') as f:
f.write(movedToHandle + '\n')
else:
with open(refollowFilename, 'w+') as f:
f.write(movedToHandle + '\n')
followersFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/followers.txt'
if os.path.isfile(followersFilename):
with open(followersFilename, "r") as f:
followerHandles = f.readlines()
handleLower = handle.lower()
# remove followers who have moved
with open(followersFilename, 'w+') as f:
for followerHandle in followerHandles:
if followerHandle.strip("\n").strip("\r").lower() != \
handleLower:
f.write(followerHandle)
else:
ctr += 1
print('Removed follower who has moved ' + handle)
return ctr
def migrateAccounts(baseDir: str, session,
httpPrefix: str, cachedWebfingers: {},
debug: bool) -> int:
"""If followed accounts change then this modifies the
following lists for each account accordingly.
Returns the number of accounts migrated
"""
2019-10-31 10:36:35 +00:00
# update followers and following lists for each account
ctr = 0
2020-04-03 17:01:25 +00:00
for subdir, dirs, files in os.walk(baseDir + '/accounts'):
2019-10-31 10:36:35 +00:00
for handle in dirs:
2021-06-25 18:02:05 +00:00
if not isAccountDir(handle):
continue
nickname = handle.split('@')[0]
domain = handle.split('@')[1]
ctr += \
_moveFollowingHandlesForAccount(baseDir, nickname, domain,
session, httpPrefix,
cachedWebfingers, debug)
2020-12-13 22:13:45 +00:00
break
return ctr