| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-03 17:01:25 +00:00
										 |  |  | __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 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  | from utils import getDomainFromActor | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  | from utils import acct_dir | 
					
						
							| 
									
										
										
										
											2021-07-31 11:56:28 +00:00
										 |  |  | from utils import hasGroupType | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  | 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  | def _moveFollowingHandlesForAccount(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                                     session, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                                     http_prefix: str, cached_webfingers: {}, | 
					
						
							| 
									
										
										
										
											2021-08-31 14:17:11 +00:00
										 |  |  |                                     debug: bool, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                                     signing_priv_key_pem: str) -> int: | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     """Goes through all follows for an account and updates any that have moved
 | 
					
						
							| 
									
										
										
										
											2019-10-31 10:36:35 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |     followingFilename = acct_dir(base_dir, nickname, domain) + '/following.txt' | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     if not os.path.isfile(followingFilename): | 
					
						
							|  |  |  |         return ctr | 
					
						
							| 
									
										
										
										
											2021-07-13 14:40:49 +00:00
										 |  |  |     with open(followingFilename, 'r') as f: | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |         followingHandles = f.readlines() | 
					
						
							|  |  |  |         for followHandle in followingHandles: | 
					
						
							|  |  |  |             followHandle = followHandle.strip("\n").strip("\r") | 
					
						
							|  |  |  |             ctr += \ | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |                 _updateMovedHandle(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                                    followHandle, session, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                                    http_prefix, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                                    debug, signing_priv_key_pem) | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  | def _updateMovedHandle(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                        handle: str, session, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                        http_prefix: str, cached_webfingers: {}, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                        debug: bool, signing_priv_key_pem: str) -> int: | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     """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
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +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, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                                 http_prefix, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2021-09-08 12:34:13 +00:00
										 |  |  |                                 domain, __version__, debug, False, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                                 signing_priv_key_pem) | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     if not personUrl: | 
					
						
							| 
									
										
										
										
											2021-03-14 20:41:37 +00:00
										 |  |  |         personUrl = getUserUrl(wfRequest, 0, debug) | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |         if not personUrl: | 
					
						
							|  |  |  |             return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 21:42:26 +00:00
										 |  |  |     gnunet = False | 
					
						
							| 
									
										
										
										
											2021-12-25 17:09:22 +00:00
										 |  |  |     if http_prefix == 'gnunet': | 
					
						
							| 
									
										
										
										
											2021-07-03 21:42:26 +00:00
										 |  |  |         gnunet = True | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     personJson = \ | 
					
						
							| 
									
										
										
										
											2021-12-25 17:09:22 +00:00
										 |  |  |         getActorJson(domain, personUrl, http_prefix, gnunet, debug, False, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                      signing_priv_key_pem, None) | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = hasGroupType(base_dir, movedToUrl, None) | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |     if isBlocked(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                  movedToNickname, movedToDomain): | 
					
						
							|  |  |  |         # someone that you follow has moved to a blocked domain | 
					
						
							|  |  |  |         # so just unfollow them | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |         unfollowAccount(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                         movedToNickname, movedToDomainFull, | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |                         debug, group_account, 'following.txt') | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |         return ctr | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |     followingFilename = acct_dir(base_dir, nickname, domain) + '/following.txt' | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |     if os.path.isfile(followingFilename): | 
					
						
							| 
									
										
										
										
											2021-07-13 14:40:49 +00:00
										 |  |  |         with open(followingFilename, 'r') as f: | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |             followingHandles = f.readlines() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             movedToHandle = movedToNickname + '@' + movedToDomainFull | 
					
						
							|  |  |  |             handleLower = handle.lower() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             refollowFilename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |                 acct_dir(base_dir, nickname, domain) + '/refollow.txt' | 
					
						
							| 
									
										
										
										
											2021-01-09 17:41:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |             # 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) | 
					
						
							| 
									
										
										
										
											2021-01-09 18:12:36 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |                         handleNickname = handle.split('@')[0] | 
					
						
							|  |  |  |                         handleDomain = handle.split('@')[1] | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |                         unfollowAccount(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |                                         handleNickname, | 
					
						
							|  |  |  |                                         handleDomain, | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |                                         debug, group_account, 'following.txt') | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |                         ctr += 1 | 
					
						
							|  |  |  |                         print('Unfollowed ' + handle + ' who has moved to ' + | 
					
						
							|  |  |  |                               movedToHandle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         # save the new handles to the refollow list | 
					
						
							|  |  |  |                         if os.path.isfile(refollowFilename): | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |                             with open(refollowFilename, 'a+') as f: | 
					
						
							|  |  |  |                                 f.write(movedToHandle + '\n') | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |                             with open(refollowFilename, 'w+') as f: | 
					
						
							|  |  |  |                                 f.write(movedToHandle + '\n') | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     followersFilename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + '/followers.txt' | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |     if os.path.isfile(followersFilename): | 
					
						
							| 
									
										
										
										
											2021-07-13 14:40:49 +00:00
										 |  |  |         with open(followersFilename, 'r') as f: | 
					
						
							| 
									
										
										
										
											2021-01-09 20:27:17 +00:00
										 |  |  |             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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  | def migrateAccounts(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                     http_prefix: str, cached_webfingers: {}, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                     debug: bool, signing_priv_key_pem: str) -> int: | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     """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 | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |     for subdir, dirs, files in os.walk(base_dir + '/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): | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             nickname = handle.split('@')[0] | 
					
						
							|  |  |  |             domain = handle.split('@')[1] | 
					
						
							|  |  |  |             ctr += \ | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |                 _moveFollowingHandlesForAccount(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-25 17:09:22 +00:00
										 |  |  |                                                 session, http_prefix, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:28:18 +00:00
										 |  |  |                                                 cached_webfingers, debug, | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |                                                 signing_priv_key_pem) | 
					
						
							| 
									
										
										
										
											2020-12-13 22:13:45 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2021-01-09 15:08:26 +00:00
										 |  |  |     return ctr |