| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | __filename__ = "bookmarks.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							|  |  |  | __version__ = "1.1.0" | 
					
						
							|  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | from pprint import pprint | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  | from utils import removeIdEnding | 
					
						
							| 
									
										
										
										
											2019-11-24 21:50:18 +00:00
										 |  |  | from utils import removePostFromCache | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | from utils import urlPermitted | 
					
						
							|  |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  | from utils import getDomainFromActor | 
					
						
							|  |  |  | from utils import locatePost | 
					
						
							|  |  |  | from utils import getCachedPostFilename | 
					
						
							|  |  |  | from utils import loadJson | 
					
						
							|  |  |  | from utils import saveJson | 
					
						
							|  |  |  | from session import postJson | 
					
						
							|  |  |  | from webfinger import webfingerHandle | 
					
						
							|  |  |  | from auth import createBasicAuthHeader | 
					
						
							|  |  |  | from posts import getPersonBox | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def undoBookmarksCollectionEntry(recentPostsCache: {}, | 
					
						
							|  |  |  |                                  baseDir: str, postFilename: str, | 
					
						
							|  |  |  |                                  objectUrl: str, | 
					
						
							|  |  |  |                                  actor: str, domain: str, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Undoes a bookmark for a particular actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postJsonObject = loadJson(postFilename) | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |     if not postJsonObject: | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     # remove any cached version of this post so that the | 
					
						
							|  |  |  |     # bookmark icon is changed | 
					
						
							|  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |     cachedPostFilename = getCachedPostFilename(baseDir, nickname, | 
					
						
							|  |  |  |                                                domain, postJsonObject) | 
					
						
							| 
									
										
										
										
											2019-11-29 23:04:37 +00:00
										 |  |  |     if cachedPostFilename: | 
					
						
							|  |  |  |         if os.path.isfile(cachedPostFilename): | 
					
						
							|  |  |  |             os.remove(cachedPostFilename) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     removePostFromCache(postJsonObject, recentPostsCache) | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-21 22:12:31 +00:00
										 |  |  |     # remove from the index | 
					
						
							|  |  |  |     bookmarksIndexFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '/bookmarks.index' | 
					
						
							|  |  |  |     if not os.path.isfile(bookmarksIndexFilename): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if '/' in postFilename: | 
					
						
							|  |  |  |         bookmarkIndex = postFilename.split('/')[-1].strip() | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         bookmarkIndex = postFilename.strip() | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |     bookmarkIndex = bookmarkIndex.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2020-05-21 22:12:31 +00:00
										 |  |  |     if bookmarkIndex not in open(bookmarksIndexFilename).read(): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     indexStr = '' | 
					
						
							|  |  |  |     with open(bookmarksIndexFilename, 'r') as indexFile: | 
					
						
							|  |  |  |         indexStr = indexFile.read().replace(bookmarkIndex + '\n', '') | 
					
						
							| 
									
										
										
										
											2020-07-12 20:04:58 +00:00
										 |  |  |         bookmarksIndexFile = open(bookmarksIndexFilename, 'w+') | 
					
						
							| 
									
										
										
										
											2020-05-21 22:12:31 +00:00
										 |  |  |         if bookmarksIndexFile: | 
					
						
							|  |  |  |             bookmarksIndexFile.write(indexStr) | 
					
						
							|  |  |  |             bookmarksIndexFile.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |     if not postJsonObject.get('type'): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if postJsonObject['type'] != 'Create': | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if not postJsonObject.get('object'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             pprint(postJsonObject) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: post ' + objectUrl + ' has no object') | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if not isinstance(postJsonObject['object'], dict): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not postJsonObject['object'].get('bookmarks'): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not isinstance(postJsonObject['object']['bookmarks'], dict): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not postJsonObject['object']['bookmarks'].get('items'): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     totalItems = 0 | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |     if postJsonObject['object']['bookmarks'].get('totalItems'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         totalItems = postJsonObject['object']['bookmarks']['totalItems'] | 
					
						
							|  |  |  |         itemFound = False | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |     for bookmarkItem in postJsonObject['object']['bookmarks']['items']: | 
					
						
							|  |  |  |         if bookmarkItem.get('actor'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             if bookmarkItem['actor'] == actor: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                 if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     print('DEBUG: bookmark was removed for ' + actor) | 
					
						
							|  |  |  |                 bmIt = bookmarkItem | 
					
						
							|  |  |  |                 postJsonObject['object']['bookmarks']['items'].remove(bmIt) | 
					
						
							|  |  |  |                 itemFound = True | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not itemFound: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if totalItems == 1: | 
					
						
							| 
									
										
										
										
											2019-11-18 15:21:35 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: bookmarks was removed from post') | 
					
						
							|  |  |  |         del postJsonObject['object']['bookmarks'] | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         bmItLen = len(postJsonObject['object']['bookmarks']['items']) | 
					
						
							|  |  |  |         postJsonObject['object']['bookmarks']['totalItems'] = bmItLen | 
					
						
							|  |  |  |     saveJson(postJsonObject, postFilename) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def bookmarkedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Returns True if the given post is bookmarked by the given person
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if noOfBookmarks(postJsonObject) == 0: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     actorMatch = domain + '/users/' + nickname | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     for item in postJsonObject['object']['bookmarks']['items']: | 
					
						
							|  |  |  |         if item['actor'].endswith(actorMatch): | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | def noOfBookmarks(postJsonObject: {}) -> int: | 
					
						
							|  |  |  |     """Returns the number of bookmarks ona  given post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not postJsonObject.get('object'): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not isinstance(postJsonObject['object'], dict): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not postJsonObject['object'].get('bookmarks'): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not isinstance(postJsonObject['object']['bookmarks'], dict): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not postJsonObject['object']['bookmarks'].get('items'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         postJsonObject['object']['bookmarks']['items'] = [] | 
					
						
							|  |  |  |         postJsonObject['object']['bookmarks']['totalItems'] = 0 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     return len(postJsonObject['object']['bookmarks']['items']) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def updateBookmarksCollection(recentPostsCache: {}, | 
					
						
							|  |  |  |                               baseDir: str, postFilename: str, | 
					
						
							|  |  |  |                               objectUrl: str, | 
					
						
							|  |  |  |                               actor: str, domain: str, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Updates the bookmarks collection within a post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postJsonObject = loadJson(postFilename) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if postJsonObject: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         # remove any cached version of this post so that the | 
					
						
							|  |  |  |         # bookmark icon is changed | 
					
						
							|  |  |  |         nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |         cachedPostFilename = getCachedPostFilename(baseDir, nickname, | 
					
						
							|  |  |  |                                                    domain, postJsonObject) | 
					
						
							| 
									
										
										
										
											2019-11-29 23:04:37 +00:00
										 |  |  |         if cachedPostFilename: | 
					
						
							|  |  |  |             if os.path.isfile(cachedPostFilename): | 
					
						
							|  |  |  |                 os.remove(cachedPostFilename) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         removePostFromCache(postJsonObject, recentPostsCache) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not postJsonObject.get('object'): | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 pprint(postJsonObject) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 print('DEBUG: post ' + objectUrl + ' has no object') | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             return | 
					
						
							|  |  |  |         if not objectUrl.endswith('/bookmarks'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             objectUrl = objectUrl + '/bookmarks' | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if not postJsonObject['object'].get('bookmarks'): | 
					
						
							|  |  |  |             if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 print('DEBUG: Adding initial bookmarks to ' + objectUrl) | 
					
						
							|  |  |  |             bookmarksJson = { | 
					
						
							| 
									
										
										
										
											2019-11-18 16:03:54 +00:00
										 |  |  |                 "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |                 'id': objectUrl, | 
					
						
							|  |  |  |                 'type': 'Collection', | 
					
						
							|  |  |  |                 "totalItems": 1, | 
					
						
							|  |  |  |                 'items': [{ | 
					
						
							|  |  |  |                     'type': 'Bookmark', | 
					
						
							|  |  |  |                     'actor': actor | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |                 }] | 
					
						
							| 
									
										
										
										
											2019-11-18 16:03:54 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             postJsonObject['object']['bookmarks'] = bookmarksJson | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if not postJsonObject['object']['bookmarks'].get('items'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 postJsonObject['object']['bookmarks']['items'] = [] | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             for bookmarkItem in postJsonObject['object']['bookmarks']['items']: | 
					
						
							|  |  |  |                 if bookmarkItem.get('actor'): | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     if bookmarkItem['actor'] == actor: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     newBookmark = { | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                         'type': 'Bookmark', | 
					
						
							|  |  |  |                         'actor': actor | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     nb = newBookmark | 
					
						
							|  |  |  |                     bmIt = len(postJsonObject['object']['bookmarks']['items']) | 
					
						
							|  |  |  |                     postJsonObject['object']['bookmarks']['items'].append(nb) | 
					
						
							|  |  |  |                     postJsonObject['object']['bookmarks']['totalItems'] = bmIt | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: saving post with bookmarks added') | 
					
						
							|  |  |  |             pprint(postJsonObject) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         saveJson(postJsonObject, postFilename) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # prepend to the index | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         bookmarksIndexFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |             nickname + '@' + domain + '/bookmarks.index' | 
					
						
							|  |  |  |         bookmarkIndex = postFilename.split('/')[-1] | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if os.path.isfile(bookmarksIndexFilename): | 
					
						
							|  |  |  |             if bookmarkIndex not in open(bookmarksIndexFilename).read(): | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     with open(bookmarksIndexFilename, 'r+') as bmIndexFile: | 
					
						
							|  |  |  |                         content = bmIndexFile.read() | 
					
						
							|  |  |  |                         bmIndexFile.seek(0, 0) | 
					
						
							|  |  |  |                         bmIndexFile.write(bookmarkIndex + '\n' + content) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                         if debug: | 
					
						
							|  |  |  |                             print('DEBUG: bookmark added to index') | 
					
						
							|  |  |  |                 except Exception as e: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                     print('WARN: Failed to write entry to bookmarks index ' + | 
					
						
							|  |  |  |                           bookmarksIndexFilename + ' ' + str(e)) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-07-12 20:04:58 +00:00
										 |  |  |             bookmarksIndexFile = open(bookmarksIndexFilename, 'w+') | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if bookmarksIndexFile: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 bookmarksIndexFile.write(bookmarkIndex + '\n') | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                 bookmarksIndexFile.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def bookmark(recentPostsCache: {}, | 
					
						
							|  |  |  |              session, baseDir: str, federationList: [], | 
					
						
							|  |  |  |              nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |              ccList: [], httpPrefix: str, | 
					
						
							|  |  |  |              objectUrl: str, actorBookmarked: str, | 
					
						
							|  |  |  |              clientToServer: bool, | 
					
						
							|  |  |  |              sendThreads: [], postLog: [], | 
					
						
							|  |  |  |              personCache: {}, cachedWebfingers: {}, | 
					
						
							|  |  |  |              debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Creates a bookmark
 | 
					
						
							|  |  |  |     actor is the person doing the bookmarking | 
					
						
							|  |  |  |     'to' might be a specific person (actor) whose post was bookmarked | 
					
						
							|  |  |  |     object is typically the url of the message which was bookmarked | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |     if not urlPermitted(objectUrl, federationList): | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     fullDomain = domain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if port: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if port != 80 and port != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in domain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 fullDomain = domain + ':' + str(port) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     newBookmarkJson = { | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |         'type': 'Bookmark', | 
					
						
							|  |  |  |         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname, | 
					
						
							|  |  |  |         'object': objectUrl | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ccList: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if len(ccList) > 0: | 
					
						
							|  |  |  |             newBookmarkJson['cc'] = ccList | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Extract the domain and nickname from a statuses link | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     bookmarkedPostNickname = None | 
					
						
							|  |  |  |     bookmarkedPostDomain = None | 
					
						
							|  |  |  |     bookmarkedPostPort = None | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if actorBookmarked: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         acBm = actorBookmarked | 
					
						
							|  |  |  |         bookmarkedPostNickname = getNicknameFromActor(acBm) | 
					
						
							|  |  |  |         bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if '/users/' in objectUrl or \ | 
					
						
							| 
									
										
										
										
											2020-08-13 16:19:35 +00:00
										 |  |  |            '/accounts/' in objectUrl or \ | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |            '/channel/' in objectUrl or \ | 
					
						
							|  |  |  |            '/profile/' in objectUrl: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             ou = objectUrl | 
					
						
							|  |  |  |             bookmarkedPostNickname = getNicknameFromActor(ou) | 
					
						
							|  |  |  |             bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if bookmarkedPostNickname: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         postFilename = locatePost(baseDir, nickname, domain, objectUrl) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if not postFilename: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: bookmark baseDir: ' + baseDir) | 
					
						
							|  |  |  |             print('DEBUG: bookmark nickname: ' + nickname) | 
					
						
							|  |  |  |             print('DEBUG: bookmark domain: ' + domain) | 
					
						
							|  |  |  |             print('DEBUG: bookmark objectUrl: ' + objectUrl) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         updateBookmarksCollection(recentPostsCache, | 
					
						
							|  |  |  |                                   baseDir, postFilename, objectUrl, | 
					
						
							|  |  |  |                                   newBookmarkJson['actor'], domain, debug) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return newBookmarkJson | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def bookmarkPost(recentPostsCache: {}, | 
					
						
							|  |  |  |                  session, baseDir: str, federationList: [], | 
					
						
							|  |  |  |                  nickname: str, domain: str, port: int, httpPrefix: str, | 
					
						
							|  |  |  |                  bookmarkNickname: str, bookmarkedomain: str, | 
					
						
							|  |  |  |                  bookmarkPort: int, | 
					
						
							|  |  |  |                  ccList: [], | 
					
						
							|  |  |  |                  bookmarkStatusNumber: int, clientToServer: bool, | 
					
						
							|  |  |  |                  sendThreads: [], postLog: [], | 
					
						
							|  |  |  |                  personCache: {}, cachedWebfingers: {}, | 
					
						
							|  |  |  |                  debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Bookmarks a given status post. This is only used by unit tests
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     bookmarkedomain = bookmarkedomain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if bookmarkPort: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if bookmarkPort != 80 and bookmarkPort != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in bookmarkedomain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 bookmarkedomain = bookmarkedomain + ':' + str(bookmarkPort) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     actorBookmarked = httpPrefix + '://' + bookmarkedomain + \ | 
					
						
							|  |  |  |         '/users/' + bookmarkNickname | 
					
						
							|  |  |  |     objectUrl = actorBookmarked + '/statuses/' + str(bookmarkStatusNumber) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return bookmark(recentPostsCache, | 
					
						
							|  |  |  |                     session, baseDir, federationList, nickname, domain, port, | 
					
						
							|  |  |  |                     ccList, httpPrefix, objectUrl, actorBookmarked, | 
					
						
							|  |  |  |                     clientToServer, | 
					
						
							|  |  |  |                     sendThreads, postLog, personCache, cachedWebfingers, | 
					
						
							|  |  |  |                     debug, projectVersion) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def undoBookmark(recentPostsCache: {}, | 
					
						
							|  |  |  |                  session, baseDir: str, federationList: [], | 
					
						
							|  |  |  |                  nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                  ccList: [], httpPrefix: str, | 
					
						
							|  |  |  |                  objectUrl: str, actorBookmarked: str, | 
					
						
							|  |  |  |                  clientToServer: bool, | 
					
						
							|  |  |  |                  sendThreads: [], postLog: [], | 
					
						
							|  |  |  |                  personCache: {}, cachedWebfingers: {}, | 
					
						
							|  |  |  |                  debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Removes a bookmark
 | 
					
						
							|  |  |  |     actor is the person doing the bookmarking | 
					
						
							|  |  |  |     'to' might be a specific person (actor) whose post was bookmarked | 
					
						
							|  |  |  |     object is typically the url of the message which was bookmarked | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |     if not urlPermitted(objectUrl, federationList): | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     fullDomain = domain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if port: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if port != 80 and port != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in domain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 fullDomain = domain + ':' + str(port) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     newUndoBookmarkJson = { | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |         'type': 'Undo', | 
					
						
							|  |  |  |         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname, | 
					
						
							|  |  |  |         'object': { | 
					
						
							|  |  |  |             'type': 'Bookmark', | 
					
						
							|  |  |  |             'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname, | 
					
						
							|  |  |  |             'object': objectUrl | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ccList: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if len(ccList) > 0: | 
					
						
							|  |  |  |             newUndoBookmarkJson['cc'] = ccList | 
					
						
							|  |  |  |             newUndoBookmarkJson['object']['cc'] = ccList | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Extract the domain and nickname from a statuses link | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     bookmarkedPostNickname = None | 
					
						
							|  |  |  |     bookmarkedPostDomain = None | 
					
						
							|  |  |  |     bookmarkedPostPort = None | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if actorBookmarked: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         acBm = actorBookmarked | 
					
						
							|  |  |  |         bookmarkedPostNickname = getNicknameFromActor(acBm) | 
					
						
							|  |  |  |         bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if '/users/' in objectUrl or \ | 
					
						
							| 
									
										
										
										
											2020-08-13 16:19:35 +00:00
										 |  |  |            '/accounts/' in objectUrl or \ | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |            '/channel/' in objectUrl or \ | 
					
						
							|  |  |  |            '/profile/' in objectUrl: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             ou = objectUrl | 
					
						
							|  |  |  |             bookmarkedPostNickname = getNicknameFromActor(ou) | 
					
						
							|  |  |  |             bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if bookmarkedPostNickname: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         postFilename = locatePost(baseDir, nickname, domain, objectUrl) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if not postFilename: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         undoBookmarksCollectionEntry(recentPostsCache, | 
					
						
							|  |  |  |                                      baseDir, postFilename, objectUrl, | 
					
						
							|  |  |  |                                      newUndoBookmarkJson['actor'], | 
					
						
							|  |  |  |                                      domain, debug) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return newUndoBookmarkJson | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def undoBookmarkPost(session, baseDir: str, federationList: [], | 
					
						
							|  |  |  |                      nickname: str, domain: str, port: int, httpPrefix: str, | 
					
						
							|  |  |  |                      bookmarkNickname: str, bookmarkedomain: str, | 
					
						
							|  |  |  |                      bookmarkPort: int, ccList: [], | 
					
						
							|  |  |  |                      bookmarkStatusNumber: int, clientToServer: bool, | 
					
						
							|  |  |  |                      sendThreads: [], postLog: [], | 
					
						
							|  |  |  |                      personCache: {}, cachedWebfingers: {}, | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                      debug: bool) -> {}: | 
					
						
							|  |  |  |     """Removes a bookmarked post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     bookmarkedomain = bookmarkedomain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if bookmarkPort: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if bookmarkPort != 80 and bookmarkPort != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in bookmarkedomain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 bookmarkedomain = bookmarkedomain + ':' + str(bookmarkPort) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     objectUrl = httpPrefix + '://' + bookmarkedomain + \ | 
					
						
							|  |  |  |         '/users/' + bookmarkNickname + \ | 
					
						
							|  |  |  |         '/statuses/' + str(bookmarkStatusNumber) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     return undoBookmark(session, baseDir, federationList, | 
					
						
							|  |  |  |                         nickname, domain, port, | 
					
						
							|  |  |  |                         ccList, httpPrefix, objectUrl, clientToServer, | 
					
						
							|  |  |  |                         sendThreads, postLog, personCache, | 
					
						
							|  |  |  |                         cachedWebfingers, debug) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def sendBookmarkViaServer(baseDir: str, session, | 
					
						
							|  |  |  |                           fromNickname: str, password: str, | 
					
						
							|  |  |  |                           fromDomain: str, fromPort: int, | 
					
						
							|  |  |  |                           httpPrefix: str, bookmarkUrl: str, | 
					
						
							|  |  |  |                           cachedWebfingers: {}, personCache: {}, | 
					
						
							|  |  |  |                           debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Creates a bookmark via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							|  |  |  |         print('WARN: No session for sendBookmarkViaServer') | 
					
						
							|  |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     fromDomainFull = fromDomain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if fromPort: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if fromPort != 80 and fromPort != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in fromDomain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 fromDomainFull = fromDomain + ':' + str(fromPort) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     newBookmarkJson = { | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |         'type': 'Bookmark', | 
					
						
							|  |  |  |         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname, | 
					
						
							|  |  |  |         'object': bookmarkUrl | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     handle = httpPrefix + '://' + fromDomainFull + '/@' + fromNickname | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     wfRequest = webfingerHandle(session, handle, httpPrefix, | 
					
						
							|  |  |  |                                 cachedWebfingers, | 
					
						
							|  |  |  |                                 fromDomain, projectVersion) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not wfRequest: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: announce webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |     if not isinstance(wfRequest, dict): | 
					
						
							|  |  |  |         print('WARN: Webfinger for ' + handle + ' did not return a dict. ' + | 
					
						
							|  |  |  |               str(wfRequest)) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postToBox = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     (inboxUrl, pubKeyId, pubKey, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |      fromPersonId, sharedInbox, avatarUrl, | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |      displayName) = getPersonBox(baseDir, session, wfRequest, personCache, | 
					
						
							|  |  |  |                                  projectVersion, httpPrefix, fromNickname, | 
					
						
							|  |  |  |                                  fromDomain, postToBox) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not inboxUrl: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: No ' + postToBox + ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 3 | 
					
						
							|  |  |  |     if not fromPersonId: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: No actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     authHeader = createBasicAuthHeader(fromNickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     headers = { | 
					
						
							|  |  |  |         'host': fromDomain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |         'Authorization': authHeader | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postResult = postJson(session, newBookmarkJson, [], | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |                           inboxUrl, headers) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if not postResult: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: POST announce failed for c2s to ' + inboxUrl) | 
					
						
							|  |  |  |         return 5 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST bookmark success') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return newBookmarkJson | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def sendUndoBookmarkViaServer(baseDir: str, session, | 
					
						
							|  |  |  |                               fromNickname: str, password: str, | 
					
						
							|  |  |  |                               fromDomain: str, fromPort: int, | 
					
						
							|  |  |  |                               httpPrefix: str, bookmarkUrl: str, | 
					
						
							|  |  |  |                               cachedWebfingers: {}, personCache: {}, | 
					
						
							|  |  |  |                               debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """Undo a bookmark via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							|  |  |  |         print('WARN: No session for sendUndoBookmarkViaServer') | 
					
						
							|  |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     fromDomainFull = fromDomain | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if fromPort: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if fromPort != 80 and fromPort != 443: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             if ':' not in fromDomain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |                 fromDomainFull = fromDomain + ':' + str(fromPort) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     newUndoBookmarkJson = { | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |         'type': 'Undo', | 
					
						
							|  |  |  |         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname, | 
					
						
							|  |  |  |         'object': { | 
					
						
							|  |  |  |             'type': 'Bookmark', | 
					
						
							|  |  |  |             'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname, | 
					
						
							|  |  |  |             'object': bookmarkUrl | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     handle = httpPrefix + '://' + fromDomainFull + '/@' + fromNickname | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     wfRequest = webfingerHandle(session, handle, httpPrefix, cachedWebfingers, | 
					
						
							|  |  |  |                                 fromDomain, projectVersion) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not wfRequest: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: announce webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |     if not isinstance(wfRequest, dict): | 
					
						
							|  |  |  |         print('WARN: Webfinger for ' + handle + ' did not return a dict. ' + | 
					
						
							|  |  |  |               str(wfRequest)) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postToBox = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     (inboxUrl, pubKeyId, pubKey, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |      fromPersonId, sharedInbox, avatarUrl, | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |      displayName) = getPersonBox(baseDir, session, wfRequest, personCache, | 
					
						
							|  |  |  |                                  projectVersion, httpPrefix, fromNickname, | 
					
						
							|  |  |  |                                  fromDomain, postToBox) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not inboxUrl: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: No ' + postToBox + ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 3 | 
					
						
							|  |  |  |     if not fromPersonId: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |             print('DEBUG: No actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     authHeader = createBasicAuthHeader(fromNickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     headers = { | 
					
						
							|  |  |  |         'host': fromDomain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |         'Authorization': authHeader | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     postResult = postJson(session, newUndoBookmarkJson, [], | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |                           inboxUrl, headers) | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if not postResult: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: POST announce failed for c2s to ' + inboxUrl) | 
					
						
							|  |  |  |         return 5 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST undo bookmark success') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return newUndoBookmarkJson | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def outboxBookmark(recentPostsCache: {}, | 
					
						
							|  |  |  |                    baseDir: str, httpPrefix: str, | 
					
						
							|  |  |  |                    nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                    messageJson: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """ When a bookmark request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not messageJson.get('type'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: bookmark - no type') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if not messageJson['type'] == 'Bookmark': | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a bookmark') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not messageJson.get('object'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: no object in bookmark') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not isinstance(messageJson['object'], str): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: bookmark object is not string') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:39:53 +00:00
										 |  |  |     if messageJson.get('to'): | 
					
						
							|  |  |  |         if not isinstance(messageJson['to'], list): | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if len(messageJson['to']) != 1: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             print('WARN: Bookmark should only be sent to one recipient') | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if messageJson['to'][0] != messageJson['actor']: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             print('WARN: Bookmark should be addressed to the same actor') | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s bookmark request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |     messageId = removeIdEnding(messageJson['object']) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if ':' in domain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         domain = domain.split(':')[0] | 
					
						
							|  |  |  |     postFilename = locatePost(baseDir, nickname, domain, messageId) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not postFilename: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s bookmark post not found in inbox or outbox') | 
					
						
							|  |  |  |             print(messageId) | 
					
						
							|  |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     updateBookmarksCollection(recentPostsCache, | 
					
						
							|  |  |  |                               baseDir, postFilename, messageId, | 
					
						
							|  |  |  |                               messageJson['actor'], domain, debug) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         print('DEBUG: post bookmarked via c2s - ' + postFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | def outboxUndoBookmark(recentPostsCache: {}, | 
					
						
							|  |  |  |                        baseDir: str, httpPrefix: str, | 
					
						
							|  |  |  |                        nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                        messageJson: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """ When an undo bookmark request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not messageJson.get('type'): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if not messageJson['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if not messageJson.get('object'): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not isinstance(messageJson['object'], dict): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo bookmark object is not dict') | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not messageJson['object'].get('type'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo bookmark - no type') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     if not messageJson['object']['type'] == 'Bookmark': | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a undo bookmark') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not messageJson['object'].get('object'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: no object in undo bookmark') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not isinstance(messageJson['object']['object'], str): | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo bookmark object is not string') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:39:53 +00:00
										 |  |  |     if messageJson.get('to'): | 
					
						
							|  |  |  |         if not isinstance(messageJson['to'], list): | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if len(messageJson['to']) != 1: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             print('WARN: Bookmark should only be sent to one recipient') | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         if messageJson['to'][0] != messageJson['actor']: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |             print('WARN: Bookmark should be addressed to the same actor') | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s undo bookmark request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |     messageId = removeIdEnding(messageJson['object']['object']) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if ':' in domain: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         domain = domain.split(':')[0] | 
					
						
							|  |  |  |     postFilename = locatePost(baseDir, nickname, domain, messageId) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if not postFilename: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo bookmark post not found in inbox or outbox') | 
					
						
							|  |  |  |             print(messageId) | 
					
						
							|  |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |     undoBookmarksCollectionEntry(recentPostsCache, | 
					
						
							|  |  |  |                                  baseDir, postFilename, messageId, | 
					
						
							|  |  |  |                                  messageJson['actor'], domain, debug) | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  |         print('DEBUG: post undo bookmarked via c2s - ' + postFilename) |