mirror of https://gitlab.com/bashrc2/epicyon
				
				
				
			
		
			
				
	
	
		
			194 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Python
		
	
	
| __filename__ = "migrate.py"
 | |
| __author__ = "Bob Mottram"
 | |
| __license__ = "AGPL3+"
 | |
| __version__ = "1.2.0"
 | |
| __maintainer__ = "Bob Mottram"
 | |
| __email__ = "bob@freedombone.net"
 | |
| __status__ = "Production"
 | |
| __module_group__ = "Core"
 | |
| 
 | |
| import os
 | |
| from utils import isAccountDir
 | |
| from utils import getNicknameFromActor
 | |
| from utils import getDomainFromActor
 | |
| from utils import acctDir
 | |
| from utils import hasGroupType
 | |
| from webfinger import webfingerHandle
 | |
| from blocking import isBlocked
 | |
| from posts import getUserUrl
 | |
| from follow import unfollowAccount
 | |
| from person import getActorJson
 | |
| 
 | |
| 
 | |
| 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
 | |
|     """
 | |
|     ctr = 0
 | |
|     followingFilename = acctDir(baseDir, 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
 | |
|     """
 | |
|     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,
 | |
|                                 None, __version__, debug, False)
 | |
|     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
 | |
| 
 | |
|     if not personUrl:
 | |
|         personUrl = getUserUrl(wfRequest, 0, debug)
 | |
|         if not personUrl:
 | |
|             return ctr
 | |
| 
 | |
|     gnunet = False
 | |
|     if httpPrefix == 'gnunet':
 | |
|         gnunet = True
 | |
|     personJson = \
 | |
|         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)
 | |
|     groupAccount = hasGroupType(baseDir, movedToUrl, None)
 | |
|     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,
 | |
|                         debug, groupAccount, 'following.txt')
 | |
|         return ctr
 | |
| 
 | |
|     followingFilename = acctDir(baseDir, 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 = \
 | |
|                 acctDir(baseDir, 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,
 | |
|                                         debug, groupAccount, 'following.txt')
 | |
|                         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 = \
 | |
|         acctDir(baseDir, 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
 | |
|     """
 | |
|     # update followers and following lists for each account
 | |
|     ctr = 0
 | |
|     for subdir, dirs, files in os.walk(baseDir + '/accounts'):
 | |
|         for handle in dirs:
 | |
|             if not isAccountDir(handle):
 | |
|                 continue
 | |
|             nickname = handle.split('@')[0]
 | |
|             domain = handle.split('@')[1]
 | |
|             ctr += \
 | |
|                 _moveFollowingHandlesForAccount(baseDir, nickname, domain,
 | |
|                                                 session, httpPrefix,
 | |
|                                                 cachedWebfingers, debug)
 | |
|         break
 | |
|     return ctr
 |