| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | __filename__ = "bookmarks.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2021-01-26 10:07:42 +00:00
										 |  |  | __version__ = "1.2.0" | 
					
						
							| 
									
										
										
										
											2020-04-01 22:22:51 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | from pprint import pprint | 
					
						
							| 
									
										
										
										
											2020-12-23 10:57:44 +00:00
										 |  |  | from utils import hasUsersPath | 
					
						
							| 
									
										
										
										
											2020-12-16 10:30:54 +00:00
										 |  |  | from utils import getFullDomain | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-12-22 18:06:23 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _noOfBookmarks(postJsonObject: {}) -> int: | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |     """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() | 
					
						
							| 
									
										
										
										
											2020-12-29 20:22:28 +00:00
										 |  |  |                         if bookmarkIndex + '\n' not in content: | 
					
						
							|  |  |  |                             bmIndexFile.seek(0, 0) | 
					
						
							|  |  |  |                             bmIndexFile.write(bookmarkIndex + '\n' + content) | 
					
						
							|  |  |  |                             if debug: | 
					
						
							|  |  |  |                                 print('DEBUG: bookmark added to index') | 
					
						
							| 
									
										
										
										
											2019-11-17 14:01:49 +00:00
										 |  |  |                 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-12-16 10:30:54 +00:00
										 |  |  |     fullDomain = getFullDomain(domain, 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: | 
					
						
							| 
									
										
										
										
											2020-12-23 10:57:44 +00:00
										 |  |  |         if hasUsersPath(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 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-12-16 10:30:54 +00:00
										 |  |  |     fullDomain = getFullDomain(domain, 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: | 
					
						
							| 
									
										
										
										
											2020-12-23 10:57:44 +00:00
										 |  |  |         if hasUsersPath(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 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) |