From f537c2f96fb2ea0c22da70f6b80910029d1fe90e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 12:58:32 +0100 Subject: [PATCH 01/12] Manually approve followers by default --- person.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/person.py b/person.py index 2196b68b3..7c2909925 100644 --- a/person.py +++ b/person.py @@ -184,7 +184,8 @@ def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, domain = domain + ':' + str(port) personType = 'Person' - approveFollowers = False + # Enable follower approval by default + approveFollowers = True personName = nickname personId = httpPrefix + '://' + domain + '/users/' + nickname inboxStr = personId + '/inbox' From 9bc6f1691ea9dd036316cd4d3fc12efa70d54f77 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 13:31:28 +0100 Subject: [PATCH 02/12] Configurable default follower approval --- daemon.py | 8 ++++++-- epicyon.py | 17 ++++++++++------- person.py | 18 ++++++++++++------ tests.py | 55 +++++++++++++++++++++++++++++++----------------------- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/daemon.py b/daemon.py index 15ecc1c5a..679aadeb3 100644 --- a/daemon.py +++ b/daemon.py @@ -5842,7 +5842,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.httpPrefix, self.server.domain, self.server.port, - loginNickname, loginPassword): + loginNickname, + loginPassword, + self.server.manualFollowerApproval): self.server.POSTbusy = False if callingDomain.endswith('.onion') and \ self.server.onionDomain: @@ -8324,7 +8326,8 @@ def runDaemon(blogsInstance: bool, mediaInstance: bool, domainMaxPostsPerDay=8640, accountMaxPostsPerDay=864, allowDeletion=False, debug=False, unitTest=False, instanceOnlySkillsSearch=False, sendThreads=[], - useBlurHash=False) -> None: + useBlurHash=False, + manualFollowerApproval=True) -> None: if len(domain) == 0: domain = 'localhost' if '.' not in domain: @@ -8356,6 +8359,7 @@ def runDaemon(blogsInstance: bool, mediaInstance: bool, httpd.blocklistUpdateInterval = 100 httpd.domainBlocklist = getDomainBlocklist(baseDir) + httpd.manualFollowerApproval = manualFollowerApproval httpd.onionDomain = onionDomain httpd.i2pDomain = i2pDomain httpd.useBlurHash = useBlurHash diff --git a/epicyon.py b/epicyon.py index 791c1e1cf..c8271e636 100644 --- a/epicyon.py +++ b/epicyon.py @@ -163,6 +163,9 @@ parser.add_argument('--json', dest='json', type=str, default=None, help='Show the json for a given activitypub url') parser.add_argument('-f', '--federate', nargs='+', dest='federationList', help='Specify federation list separated by spaces') +parser.add_argument("--noapproval", type=str2bool, nargs='?', + const=True, default=False, + help="Allow followers without approval") parser.add_argument("--mediainstance", type=str2bool, nargs='?', const=True, default=False, help="Media Instance - favor media over text") @@ -1265,7 +1268,7 @@ if args.addaccount: print('Account is deactivated') sys.exit() createPerson(baseDir, nickname, domain, port, httpPrefix, - True, args.password.strip()) + True, not args.noapproval, args.password.strip()) if os.path.isdir(baseDir + '/accounts/' + nickname + '@' + domain): print('Account created for ' + nickname + '@' + domain) else: @@ -1696,16 +1699,16 @@ if args.testdata: str(maxRegistrations)) createPerson(baseDir, 'maxboardroom', domain, port, httpPrefix, - True, password) + True, False, password) createPerson(baseDir, 'ultrapancake', domain, port, httpPrefix, - True, password) + True, False, password) createPerson(baseDir, 'drokk', domain, port, httpPrefix, - True, password) + True, False, password) createPerson(baseDir, 'sausagedog', domain, port, httpPrefix, - True, password) + True, False, password) createPerson(baseDir, nickname, domain, port, httpPrefix, - True, 'likewhateveryouwantscoob') + True, False, 'likewhateveryouwantscoob') setSkillLevel(baseDir, nickname, domain, 'testing', 60) setSkillLevel(baseDir, nickname, domain, 'typing', 50) setRole(baseDir, nickname, domain, 'instance', 'admin') @@ -1807,4 +1810,4 @@ runDaemon(args.blogsinstance, args.mediainstance, args.accountMaxPostsPerDay, args.allowdeletion, debug, False, args.instanceOnlySkillsSearch, [], - args.blurhash) + args.blurhash, not args.noapproval) diff --git a/person.py b/person.py index 7c2909925..075180ecd 100644 --- a/person.py +++ b/person.py @@ -165,6 +165,7 @@ def randomizeActorImages(personJson: {}) -> None: def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, httpPrefix: str, saveToFile: bool, + manualFollowerApproval: bool, password=None) -> (str, str, {}, {}): """Returns the private key, public key, actor and webfinger endpoint """ @@ -185,7 +186,7 @@ def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, personType = 'Person' # Enable follower approval by default - approveFollowers = True + approveFollowers = manualFollowerApproval personName = nickname personId = httpPrefix + '://' + domain + '/users/' + nickname inboxStr = personId + '/inbox' @@ -352,7 +353,8 @@ def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, def registerAccount(baseDir: str, httpPrefix: str, domain: str, port: int, - nickname: str, password: str) -> bool: + nickname: str, password: str, + manualFollowerApproval: bool) -> bool: """Registers a new account from the web interface """ if accountExists(baseDir, nickname, domain): @@ -367,6 +369,7 @@ def registerAccount(baseDir: str, httpPrefix: str, domain: str, port: int, newPerson, webfingerEndpoint) = createPerson(baseDir, nickname, domain, port, httpPrefix, True, + manualFollowerApproval, password) if privateKeyPem: return True @@ -382,7 +385,7 @@ def createGroup(baseDir: str, nickname: str, domain: str, port: int, newPerson, webfingerEndpoint) = createPerson(baseDir, nickname, domain, port, httpPrefix, saveToFile, - password) + False, password) newPerson['type'] = 'Group' return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint @@ -407,6 +410,7 @@ def savePersonQrcode(baseDir: str, def createPerson(baseDir: str, nickname: str, domain: str, port: int, httpPrefix: str, saveToFile: bool, + manualFollowerApproval: bool, password=None) -> (str, str, {}, {}): """Returns the private key, public key, actor and webfinger endpoint """ @@ -425,7 +429,9 @@ def createPerson(baseDir: str, nickname: str, domain: str, port: int, newPerson, webfingerEndpoint) = createPersonBase(baseDir, nickname, domain, port, httpPrefix, - saveToFile, password) + saveToFile, + manualFollowerApproval, + password) if noOfAccounts(baseDir) == 1: # print(nickname+' becomes the instance admin and a moderator') setRole(baseDir, nickname, domain, 'instance', 'admin') @@ -470,7 +476,7 @@ def createSharedInbox(baseDir: str, nickname: str, domain: str, port: int, """Generates the shared inbox """ return createPersonBase(baseDir, nickname, domain, port, httpPrefix, - True, None) + True, True, None) def createCapabilitiesInbox(baseDir: str, nickname: str, @@ -479,7 +485,7 @@ def createCapabilitiesInbox(baseDir: str, nickname: str, """Generates the capabilities inbox to sign requests """ return createPersonBase(baseDir, nickname, domain, port, - httpPrefix, True, None) + httpPrefix, True, True, None) def personUpgradeActor(baseDir: str, personJson: {}, diff --git a/tests.py b/tests.py index 12faa4634..0d47268dd 100644 --- a/tests.py +++ b/tests.py @@ -101,7 +101,8 @@ def testHttpsigBase(withDigest): port = 5576 password = 'SuperSecretPassword' privateKeyPem, publicKeyPem, person, wfEndpoint = \ - createPerson(path, nickname, domain, port, httpPrefix, False, password) + createPerson(path, nickname, domain, port, httpPrefix, + False, False, password) assert privateKeyPem messageBodyJson = { "a key": "a value", @@ -253,7 +254,8 @@ def createServerAlice(path: str, domain: str, port: int, accountMaxPostsPerDay = 1000 allowDeletion = True privateKeyPem, publicKeyPem, person, wfEndpoint = \ - createPerson(path, nickname, domain, port, httpPrefix, True, password) + createPerson(path, nickname, domain, port, httpPrefix, True, + False, password) deleteAllPosts(path, nickname, domain, 'inbox') deleteAllPosts(path, nickname, domain, 'outbox') assert setSkillLevel(path, nickname, domain, 'hacking', 90) @@ -289,7 +291,8 @@ def createServerAlice(path: str, domain: str, port: int, noreply, nolike, nopics, noannounce, cw, ocapAlways, proxyType, maxReplies, domainMaxPostsPerDay, accountMaxPostsPerDay, - allowDeletion, True, True, False, sendThreads, False) + allowDeletion, True, True, False, sendThreads, False, + False) def createServerBob(path: str, domain: str, port: int, @@ -317,7 +320,8 @@ def createServerBob(path: str, domain: str, port: int, accountMaxPostsPerDay = 1000 allowDeletion = True privateKeyPem, publicKeyPem, person, wfEndpoint = \ - createPerson(path, nickname, domain, port, httpPrefix, True, password) + createPerson(path, nickname, domain, port, httpPrefix, True, + False, password) deleteAllPosts(path, nickname, domain, 'inbox') deleteAllPosts(path, nickname, domain, 'outbox') assert setRole(path, nickname, domain, 'bandname', 'bass player') @@ -352,7 +356,8 @@ def createServerBob(path: str, domain: str, port: int, noreply, nolike, nopics, noannounce, cw, ocapAlways, proxyType, maxReplies, domainMaxPostsPerDay, accountMaxPostsPerDay, - allowDeletion, True, True, False, sendThreads, False) + allowDeletion, True, True, False, sendThreads, False, + False) def createServerEve(path: str, domain: str, port: int, federationList: [], @@ -375,7 +380,8 @@ def createServerEve(path: str, domain: str, port: int, federationList: [], maxReplies = 64 allowDeletion = True privateKeyPem, publicKeyPem, person, wfEndpoint = \ - createPerson(path, nickname, domain, port, httpPrefix, True, password) + createPerson(path, nickname, domain, port, httpPrefix, True, + False, password) deleteAllPosts(path, nickname, domain, 'inbox') deleteAllPosts(path, nickname, domain, 'outbox') global testServerEveRunning @@ -391,7 +397,7 @@ def createServerEve(path: str, domain: str, port: int, federationList: [], httpPrefix, federationList, maxMentions, maxEmoji, False, noreply, nolike, nopics, noannounce, cw, ocapAlways, proxyType, maxReplies, allowDeletion, True, True, False, - sendThreads, False) + sendThreads, False, False) def testPostMessageBetweenServers(): @@ -840,15 +846,15 @@ def testFollowersOfPerson(): os.mkdir(baseDir) os.chdir(baseDir) createPerson(baseDir, nickname, domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'maxboardroom', domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'ultrapancake', domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'drokk', domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'sausagedog', domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) clearFollows(baseDir, nickname, domain) followPerson(baseDir, nickname, domain, 'maxboardroom', domain, @@ -889,15 +895,16 @@ def testNoOfFollowersOnDomain(): shutil.rmtree(baseDir) os.mkdir(baseDir) os.chdir(baseDir) - createPerson(baseDir, nickname, domain, port, httpPrefix, True, password) + createPerson(baseDir, nickname, domain, port, httpPrefix, True, + False, password) createPerson(baseDir, 'maxboardroom', otherdomain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'ultrapancake', otherdomain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'drokk', otherdomain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) createPerson(baseDir, 'sausagedog', otherdomain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) followPerson(baseDir, 'drokk', otherdomain, nickname, domain, federationList, False) @@ -949,7 +956,8 @@ def testGroupFollowers(): shutil.rmtree(baseDir) os.mkdir(baseDir) os.chdir(baseDir) - createPerson(baseDir, nickname, domain, port, httpPrefix, True, password) + createPerson(baseDir, nickname, domain, port, httpPrefix, True, + False, password) clearFollowers(baseDir, nickname, domain) followerOfPerson(baseDir, nickname, domain, 'badger', 'wild.domain', @@ -992,7 +1000,8 @@ def testFollows(): shutil.rmtree(baseDir) os.mkdir(baseDir) os.chdir(baseDir) - createPerson(baseDir, nickname, domain, port, httpPrefix, True, password) + createPerson(baseDir, nickname, domain, port, httpPrefix, True, + False, password) clearFollows(baseDir, nickname, domain) followPerson(baseDir, nickname, domain, 'badger', 'wild.com', @@ -1072,7 +1081,7 @@ def testCreatePerson(): privateKeyPem, publicKeyPem, person, wfEndpoint = \ createPerson(baseDir, nickname, domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) assert os.path.isfile(baseDir + '/accounts/passwords') deleteAllPosts(baseDir, nickname, domain, 'inbox') deleteAllPosts(baseDir, nickname, domain, 'outbox') @@ -1106,10 +1115,10 @@ def testDelegateRoles(): privateKeyPem, publicKeyPem, person, wfEndpoint = \ createPerson(baseDir, nickname, domain, port, - httpPrefix, True, password) + httpPrefix, True, False, password) privateKeyPem, publicKeyPem, person, wfEndpoint = \ createPerson(baseDir, nicknameDelegated, domain, port, - httpPrefix, True, 'insecure') + httpPrefix, True, False, 'insecure') httpPrefix = 'http' project = 'artechoke' @@ -1702,7 +1711,7 @@ def testAddEmoji(): os.chdir(baseDir) privateKeyPem, publicKeyPem, person, wfEndpoint = \ createPerson(baseDir, nickname, domain, port, - httpPrefix, True, 'password') + httpPrefix, True, False, 'password') contentModified = \ addHtmlTags(baseDir, httpPrefix, nickname, domain, content, From 26086ab1d0cca2f76c984ecee3648949cc0d06f1 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 14:28:03 +0100 Subject: [PATCH 03/12] Don't allow DMs from randos by default --- person.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/person.py b/person.py index 075180ecd..0e6252b49 100644 --- a/person.py +++ b/person.py @@ -439,6 +439,12 @@ def createPerson(baseDir: str, nickname: str, domain: str, port: int, setRole(baseDir, nickname, domain, 'instance', 'delegator') setConfigParam(baseDir, 'admin', nickname) + if manualFollowerApproval: + followDMsFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/.followDMs' + with open(followDMsFilename, "w") as fFile: + fFile.write('\n') + if not os.path.isdir(baseDir + '/accounts'): os.mkdir(baseDir + '/accounts') if not os.path.isdir(baseDir + '/accounts/' + nickname + '@' + domain): From 6b124a255a3679798fed81da76efd14fc00cf831 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 19:33:20 +0100 Subject: [PATCH 04/12] Preload font --- webinterface.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/webinterface.py b/webinterface.py index 85faa020b..4565be48b 100644 --- a/webinterface.py +++ b/webinterface.py @@ -2242,10 +2242,24 @@ def htmlNewPost(mediaInstance: bool, translate: {}, return newPostForm +def getFontFromCss(css: str) -> (str, str): + """Returns the font name and format + """ + if 'src: url(' not in css: + return None, None + fontName = css.split("src: url('")[1].split("')")[0] + fontFormat = css.split(" format('")[1].split("')")[0] + return fontName, fontFormat + + def htmlHeader(cssFilename: str, css: str, lang='en') -> str: htmlStr = '\n' htmlStr += '\n' htmlStr += ' \n' + fontName, fontFormat = getFontFromCss(css) + if fontName: + htmlStr += ' ' htmlStr += ' \n' htmlStr += ' \n' return htmlStr From b0bb73c5bec0f9a441324f06d603fd8e47b22bbe Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 19:42:42 +0100 Subject: [PATCH 05/12] Carriage return --- webinterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webinterface.py b/webinterface.py index 4565be48b..c8393e586 100644 --- a/webinterface.py +++ b/webinterface.py @@ -2259,7 +2259,7 @@ def htmlHeader(cssFilename: str, css: str, lang='en') -> str: fontName, fontFormat = getFontFromCss(css) if fontName: htmlStr += ' ' + fontFormat + '" href="' + fontName + '" crossorigin>\n' htmlStr += ' \n' htmlStr += ' \n' return htmlStr From 950bda0039c9878e3b751fe78fa39c470b74f9bd Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 19:53:58 +0100 Subject: [PATCH 06/12] Head section --- webinterface.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/webinterface.py b/webinterface.py index c8393e586..079632c27 100644 --- a/webinterface.py +++ b/webinterface.py @@ -2255,12 +2255,14 @@ def getFontFromCss(css: str) -> (str, str): def htmlHeader(cssFilename: str, css: str, lang='en') -> str: htmlStr = '\n' htmlStr += '\n' - htmlStr += ' \n' + htmlStr += ' \n' + htmlStr += ' \n' fontName, fontFormat = getFontFromCss(css) if fontName: - htmlStr += ' \n' - htmlStr += ' \n' + htmlStr += ' \n' + htmlStr += ' \n' htmlStr += ' \n' return htmlStr From e1347efb2056f31e45a6ae75f84284e4414bb304 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 19:36:29 +0000 Subject: [PATCH 07/12] Block until web font loads --- epicyon-blog.css | 2 +- epicyon-calendar.css | 2 +- epicyon-follow.css | 2 +- epicyon-login.css | 2 +- epicyon-profile.css | 2 +- epicyon-suspended.css | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index 6d289bdaa..a2ceee5d8 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -48,7 +48,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } diff --git a/epicyon-calendar.css b/epicyon-calendar.css index 4a1148133..cbf3471d3 100644 --- a/epicyon-calendar.css +++ b/epicyon-calendar.css @@ -19,7 +19,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } diff --git a/epicyon-follow.css b/epicyon-follow.css index 6981ea92a..a9f8a5333 100644 --- a/epicyon-follow.css +++ b/epicyon-follow.css @@ -36,7 +36,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } diff --git a/epicyon-login.css b/epicyon-login.css index c0279dc8b..bda7b678a 100644 --- a/epicyon-login.css +++ b/epicyon-login.css @@ -25,7 +25,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } diff --git a/epicyon-profile.css b/epicyon-profile.css index 247b8449e..ef1796cc0 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -56,7 +56,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } diff --git a/epicyon-suspended.css b/epicyon-suspended.css index 550fa7c87..7ace9ba3f 100644 --- a/epicyon-suspended.css +++ b/epicyon-suspended.css @@ -25,7 +25,7 @@ font-family: 'Bedstead'; font-style: normal; font-weight: normal; - font-display: swap; + font-display: block; src: url('./fonts/bedstead.otf') format('opentype'); } From fe5e21ee7d98bc4cd64af7b35e57285caba20eee Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 20:04:58 +0000 Subject: [PATCH 08/12] File write style --- blocking.py | 6 +++--- bookmarks.py | 4 ++-- daemon.py | 12 ++++++------ epicyon.py | 2 +- filters.py | 2 +- followingCalendar.py | 8 ++++---- inbox.py | 22 ++++++++++++++-------- media.py | 2 +- migrate.py | 2 +- person.py | 4 ++-- petnames.py | 4 ++-- posts.py | 4 ++-- shares.py | 2 +- theme.py | 10 +++++----- utils.py | 2 +- webinterface.py | 2 +- 16 files changed, 47 insertions(+), 41 deletions(-) diff --git a/blocking.py b/blocking.py index fed8af9a5..836f85ca2 100644 --- a/blocking.py +++ b/blocking.py @@ -67,7 +67,7 @@ def removeGlobalBlock(baseDir: str, if os.path.isfile(unblockingFilename): if unblockHandle in open(unblockingFilename).read(): with open(unblockingFilename, 'r') as fp: - with open(unblockingFilename + '.new', 'w') as fpnew: + with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: handle = line.replace('\n', '').replace('\r', '') if unblockHandle not in line: @@ -80,7 +80,7 @@ def removeGlobalBlock(baseDir: str, if os.path.isfile(unblockingFilename): if unblockHashtag + '\n' in open(unblockingFilename).read(): with open(unblockingFilename, 'r') as fp: - with open(unblockingFilename + '.new', 'w') as fpnew: + with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: blockLine = \ line.replace('\n', '').replace('\r', '') @@ -104,7 +104,7 @@ def removeBlock(baseDir: str, nickname: str, domain: str, if os.path.isfile(unblockingFilename): if unblockHandle in open(unblockingFilename).read(): with open(unblockingFilename, 'r') as fp: - with open(unblockingFilename + '.new', 'w') as fpnew: + with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: handle = line.replace('\n', '').replace('\r', '') if unblockHandle not in line: diff --git a/bookmarks.py b/bookmarks.py index 0039a6d89..22387d395 100644 --- a/bookmarks.py +++ b/bookmarks.py @@ -57,7 +57,7 @@ def undoBookmarksCollectionEntry(recentPostsCache: {}, indexStr = '' with open(bookmarksIndexFilename, 'r') as indexFile: indexStr = indexFile.read().replace(bookmarkIndex + '\n', '') - bookmarksIndexFile = open(bookmarksIndexFilename, 'w') + bookmarksIndexFile = open(bookmarksIndexFilename, 'w+') if bookmarksIndexFile: bookmarksIndexFile.write(indexStr) bookmarksIndexFile.close() @@ -213,7 +213,7 @@ def updateBookmarksCollection(recentPostsCache: {}, print('WARN: Failed to write entry to bookmarks index ' + bookmarksIndexFilename + ' ' + str(e)) else: - bookmarksIndexFile = open(bookmarksIndexFilename, 'w') + bookmarksIndexFile = open(bookmarksIndexFilename, 'w+') if bookmarksIndexFile: bookmarksIndexFile.write(bookmarkIndex + '\n') bookmarksIndexFile.close() diff --git a/daemon.py b/daemon.py index 679aadeb3..6795a1504 100644 --- a/daemon.py +++ b/daemon.py @@ -292,7 +292,7 @@ class PubServer(BaseHTTPRequestHandler): if not minimal and minimalFileExists: os.remove(minimalFilename) elif minimal and not minimalFileExists: - with open(minimalFilename, 'w') as fp: + with open(minimalFilename, 'w+') as fp: fp.write('\n') def _sendReplyToQuestion(self, nickname: str, messageId: str, @@ -539,7 +539,7 @@ class PubServer(BaseHTTPRequestHandler): if not etag: etag = sha1(data).hexdigest() # nosec try: - with open(mediaFilename + '.etag', 'w') as etagFile: + with open(mediaFilename + '.etag', 'w+') as etagFile: etagFile.write(etag) except BaseException: pass @@ -5108,7 +5108,7 @@ class PubServer(BaseHTTPRequestHandler): mediaBinary = avFile.read() etag = sha1(mediaBinary).hexdigest() # nosec try: - with open(mediaTagFilename, 'w') as etagFile: + with open(mediaTagFilename, 'w+') as etagFile: etagFile.write(etag) except BaseException: pass @@ -5255,7 +5255,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.baseDir + '/accounts/' + \ nickname + '@' + self.server.domain + '/.lastUsed' try: - lastUsedFile = open(lastUsedFilename, 'w') + lastUsedFile = open(lastUsedFilename, 'w+') if lastUsedFile: lastUsedFile.write(str(int(time.time()))) lastUsedFile.close() @@ -5903,7 +5903,7 @@ class PubServer(BaseHTTPRequestHandler): loginNickname + ' ' + str(e)) else: try: - with open(saltFilename, 'w') as fp: + with open(saltFilename, 'w+') as fp: fp.write(salt) except Exception as e: print('WARN: Unable to save salt for ' + @@ -5917,7 +5917,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.baseDir+'/accounts/' + \ loginHandle + '/.token' try: - with open(tokenFilename, 'w') as fp: + with open(tokenFilename, 'w+') as fp: fp.write(token) except Exception as e: print('WARN: Unable to save token for ' + diff --git a/epicyon.py b/epicyon.py index c8271e636..a6a8bd900 100644 --- a/epicyon.py +++ b/epicyon.py @@ -479,7 +479,7 @@ if args.socnet: httpPrefix, debug, __version__) try: - with open('socnet.dot', 'w') as fp: + with open('socnet.dot', 'w+') as fp: fp.write(dotGraph) print('Saved to socnet.dot') except BaseException: diff --git a/filters.py b/filters.py index 81335234b..744e28775 100644 --- a/filters.py +++ b/filters.py @@ -32,7 +32,7 @@ def removeFilter(baseDir: str, nickname: str, domain: str, if os.path.isfile(filtersFilename): if words in open(filtersFilename).read(): with open(filtersFilename, 'r') as fp: - with open(filtersFilename + '.new', 'w') as fpnew: + with open(filtersFilename + '.new', 'w+') as fpnew: for line in fp: line = line.replace('\n', '') if line != words: diff --git a/followingCalendar.py b/followingCalendar.py index f414634b7..10c5ae39e 100644 --- a/followingCalendar.py +++ b/followingCalendar.py @@ -29,7 +29,7 @@ def receivingCalendarEvents(baseDir: str, nickname: str, domain: str, # create a new calendar file from the following file with open(followingFilename, 'r') as followingFile: followingHandles = followingFile.read() - with open(calendarFilename, 'w') as fp: + with open(calendarFilename, 'w+') as fp: fp.write(followingHandles) return handle + '\n' in open(calendarFilename).read() @@ -65,7 +65,7 @@ def receiveCalendarEvents(baseDir: str, nickname: str, domain: str, # create a new calendar file from the following file with open(followingFilename, 'r') as followingFile: followingHandles = followingFile.read() - with open(calendarFilename, 'w') as fp: + with open(calendarFilename, 'w+') as fp: fp.write(followingHandles) # already in the calendar file? @@ -75,14 +75,14 @@ def receiveCalendarEvents(baseDir: str, nickname: str, domain: str, return # remove from calendar file followingHandles = followingHandles.replace(handle + '\n', '') - with open(calendarFilename, 'w') as fp: + with open(calendarFilename, 'w+') as fp: fp.write(followingHandles) else: # not already in the calendar file if add: # append to the list of handles followingHandles += handle + '\n' - with open(calendarFilename, 'w') as fp: + with open(calendarFilename, 'w+') as fp: fp.write(followingHandles) diff --git a/inbox.py b/inbox.py index c8545e49a..ffeaed505 100644 --- a/inbox.py +++ b/inbox.py @@ -1702,7 +1702,7 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None: return dmFile = accountDir + '/.newDM' if not os.path.isfile(dmFile): - with open(dmFile, 'w') as fp: + with open(dmFile, 'w+') as fp: fp.write(url) @@ -1748,10 +1748,16 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str, prevLikeStr = likeFile.read() if prevLikeStr == likeStr: return - with open(prevLikeFile, 'w') as fp: - fp.write(likeStr) - with open(likeFile, 'w') as fp: - fp.write(likeStr) + try: + with open(prevLikeFile, 'w+') as fp: + fp.write(likeStr) + except BaseException: + pass + try: + with open(likeFile, 'w+') as fp: + fp.write(likeStr) + except BaseException: + pass def replyNotify(baseDir: str, handle: str, url: str) -> None: @@ -1762,7 +1768,7 @@ def replyNotify(baseDir: str, handle: str, url: str) -> None: return replyFile = accountDir + '/.newReply' if not os.path.isfile(replyFile): - with open(replyFile, 'w') as fp: + with open(replyFile, 'w+') as fp: fp.write(url) @@ -1777,7 +1783,7 @@ def gitPatchNotify(baseDir: str, handle: str, patchFile = accountDir + '/.newPatch' subject = subject.replace('[PATCH]', '').strip() handle = '@' + fromNickname + '@' + fromDomain - with open(patchFile, 'w') as fp: + with open(patchFile, 'w+') as fp: fp.write('git ' + handle + ' ' + subject) @@ -1949,7 +1955,7 @@ def inboxUpdateCalendar(baseDir: str, handle: str, postJsonObject: {}) -> None: calendarNotificationFilename = \ baseDir + '/accounts/' + handle + '/.newCalendar' calendarNotificationFile = \ - open(calendarNotificationFilename, 'w') + open(calendarNotificationFilename, 'w+') if calendarNotificationFile: calendarNotificationFile.write('/calendar?year=' + str(eventYear) + diff --git a/media.py b/media.py index 4afa96571..7c6b87306 100644 --- a/media.py +++ b/media.py @@ -122,7 +122,7 @@ def updateEtag(mediaFilename: str) -> None: etag = sha1(data).hexdigest() # nosec # save the hash try: - with open(mediaFilename + '.etag', 'w') as etagFile: + with open(mediaFilename + '.etag', 'w+') as etagFile: etagFile.write(etag) except BaseException: pass diff --git a/migrate.py b/migrate.py index ac9502e03..6fb8bee28 100644 --- a/migrate.py +++ b/migrate.py @@ -25,7 +25,7 @@ def migrateFollows(followFilename: str, oldHandle: str, newFollowData = followData.replace(oldHandle, newHandle) if followData == newFollowData: return - with open(followFilename, 'w') as followFile: + with open(followFilename, 'w+') as followFile: followFile.write(newFollowData) diff --git a/person.py b/person.py index 0e6252b49..78b20a01e 100644 --- a/person.py +++ b/person.py @@ -1004,7 +1004,7 @@ def isPersonSnoozed(baseDir: str, nickname: str, domain: str, with open(snoozedFilename, 'r') as snoozedFile: content = snoozedFile.read().replace(replaceStr, '') if content: - writeSnoozedFile = open(snoozedFilename, 'w') + writeSnoozedFile = open(snoozedFilename, 'w+') if writeSnoozedFile: writeSnoozedFile.write(content) writeSnoozedFile.close() @@ -1057,7 +1057,7 @@ def personUnsnooze(baseDir: str, nickname: str, domain: str, with open(snoozedFilename, 'r') as snoozedFile: content = snoozedFile.read().replace(replaceStr, '') if content: - writeSnoozedFile = open(snoozedFilename, 'w') + writeSnoozedFile = open(snoozedFilename, 'w+') if writeSnoozedFile: writeSnoozedFile.write(content) writeSnoozedFile.close() diff --git a/petnames.py b/petnames.py index e28048250..7046a5d94 100644 --- a/petnames.py +++ b/petnames.py @@ -40,7 +40,7 @@ def setPetName(baseDir: str, nickname: str, domain: str, else: newPetnamesStr += entry # save the updated petnames file - with open(petnamesFilename, 'w') as petnamesFile: + with open(petnamesFilename, 'w+') as petnamesFile: petnamesFile.write(newPetnamesStr) return True # entry does not exist in the petnames file @@ -49,7 +49,7 @@ def setPetName(baseDir: str, nickname: str, domain: str, return True # first entry - with open(petnamesFilename, 'w') as petnamesFile: + with open(petnamesFilename, 'w+') as petnamesFile: petnamesFile.write(entry) return True diff --git a/posts.py b/posts.py index dfcfc100f..fdca227b5 100644 --- a/posts.py +++ b/posts.py @@ -599,7 +599,7 @@ def addSchedulePost(baseDir: str, nickname: str, domain: str, print('WARN: Failed to write entry to scheduled posts index ' + scheduleIndexFilename + ' ' + str(e)) else: - scheduleFile = open(scheduleIndexFilename, 'w') + scheduleFile = open(scheduleIndexFilename, 'w+') if scheduleFile: scheduleFile.write(indexStr + '\n') scheduleFile.close() @@ -1337,7 +1337,7 @@ def createReportPost(baseDir: str, if os.path.isfile(newReportFile): continue try: - with open(newReportFile, 'w') as fp: + with open(newReportFile, 'w+') as fp: fp.write(toUrl + '/moderation') except BaseException: pass diff --git a/shares.py b/shares.py index a20fb8055..af300d223 100644 --- a/shares.py +++ b/shares.py @@ -181,7 +181,7 @@ def addShare(baseDir: str, if not os.path.isfile(newShareFile): nickname = handle.split('@')[0] try: - with open(newShareFile, 'w') as fp: + with open(newShareFile, 'w+') as fp: fp.write(httpPrefix + '://' + domainFull + '/users/' + nickname + '/tlshares') except BaseException: diff --git a/theme.py b/theme.py index 786f49584..c1a323c17 100644 --- a/theme.py +++ b/theme.py @@ -105,7 +105,7 @@ def setThemeFromDict(baseDir: str, name: str, themeParams: {}) -> None: for paramName, paramValue in themeParams.items(): css = setCSSparam(css, paramName, paramValue) filename = baseDir + '/' + filename - with open(filename, 'w') as cssfile: + with open(filename, 'w+') as cssfile: cssfile.write(css) @@ -124,11 +124,11 @@ def enableGrayscale(baseDir: str) -> None: css.replace('body, html {', 'body, html {\n filter: grayscale(100%);') filename = baseDir + '/' + filename - with open(filename, 'w') as cssfile: + with open(filename, 'w+') as cssfile: cssfile.write(css) grayscaleFilename = baseDir + '/accounts/.grayscale' if not os.path.isfile(grayscaleFilename): - with open(grayscaleFilename, 'w') as grayfile: + with open(grayscaleFilename, 'w+') as grayfile: grayfile.write(' ') @@ -146,7 +146,7 @@ def disableGrayscale(baseDir: str) -> None: css = \ css.replace('\n filter: grayscale(100%);', '') filename = baseDir + '/' + filename - with open(filename, 'w') as cssfile: + with open(filename, 'w+') as cssfile: cssfile.write(css) grayscaleFilename = baseDir + '/accounts/.grayscale' if os.path.isfile(grayscaleFilename): @@ -187,7 +187,7 @@ def setCustomFont(baseDir: str): customFontType + "')") css = setCSSparam(css, "*font-family", "'CustomFont'") filename = baseDir + '/' + filename - with open(filename, 'w') as cssfile: + with open(filename, 'w+') as cssfile: cssfile.write(css) diff --git a/utils.py b/utils.py index c53811f26..abdb67be7 100644 --- a/utils.py +++ b/utils.py @@ -51,7 +51,7 @@ def saveJson(jsonObject: {}, filename: str) -> bool: tries = 0 while tries < 5: try: - with open(filename, 'w') as fp: + with open(filename, 'w+') as fp: fp.write(json.dumps(jsonObject)) return True except BaseException: diff --git a/webinterface.py b/webinterface.py index 079632c27..4907b1d95 100644 --- a/webinterface.py +++ b/webinterface.py @@ -3337,7 +3337,7 @@ def saveIndividualPostAsHtmlToCache(baseDir: str, os.mkdir(htmlPostCacheDir) try: - with open(cachedPostFilename, 'w') as fp: + with open(cachedPostFilename, 'w+') as fp: fp.write(postHtml) return True except Exception as e: From 3ebf0a3b031451c80f94c4d6e4272a9ac005d0a7 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 20:49:09 +0000 Subject: [PATCH 09/12] More general --- webinterface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webinterface.py b/webinterface.py index 4907b1d95..ecc49606b 100644 --- a/webinterface.py +++ b/webinterface.py @@ -2245,9 +2245,9 @@ def htmlNewPost(mediaInstance: bool, translate: {}, def getFontFromCss(css: str) -> (str, str): """Returns the font name and format """ - if 'src: url(' not in css: + if ' url(' not in css: return None, None - fontName = css.split("src: url('")[1].split("')")[0] + fontName = css.split(" url('")[1].split("')")[0] fontFormat = css.split(" format('")[1].split("')")[0] return fontName, fontFormat From 792052a8147440435af3e07bf1c988a4cb7b7824 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 12 Jul 2020 21:15:27 +0000 Subject: [PATCH 10/12] Test woff --- fonts/bgrove.woff | Bin 0 -> 12244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fonts/bgrove.woff diff --git a/fonts/bgrove.woff b/fonts/bgrove.woff new file mode 100644 index 0000000000000000000000000000000000000000..0953886adfe529ce96318674e0e54a6b65688d70 GIT binary patch literal 12244 zcmZX)18`REJ&7)ua)}jBy*B1cH z+{V)k0DzDI04M|jfS=if-1N&9riLcp_1JuKIR3*`<;9xCxAEIn{H+szgB)@T)W*Wr z<-1ML@4kUZeq&>|9_7)--uRmbuJg^g{tqIP%CNSE9^dVP41eoH-yjBz0&?vPZA}3H znuPE2xZi#Ma=W7Ta9X9WN}vW*Q)3=H&c>jFulUbg)&zf7mnumeb`^YH=I zTu^fV>!&s!H{CG>fKU>fnE)cWnN9-10eC(jrvG30?$PJaz?8t?ifBttFfd`H5VP)C zgYog<{{G?q(J25JF(yI-G$}dVU>GdzU<1+|aw|Kx z#wt;PR`*Bu-(81X|6|_SxAoFe9bpPuX*bGK#axPHcS+NYYNbnLJq4+*KS0xnoe8h0 z`{a39CTN`4EGVTdwUkEpIYAyoe`Vl)n*_h$mT7NEbEbv<#QcyRmp%l7nYBTz2h4>& zc$=&qmEJ&^Ot;{>^am(*xmZ^_C&oWjYdlQoBg(mCz zUL4=g%a%n2qMjnu<)Nnr{Y`@fKe0BQJ9iLA^ZOOfb_Al`HF5D-Sz4YAd;KE*JqBr- zD&yvfd`qN1r+R!mz62I)kTe}=FPEvGoeLi5H&4c3W_*#S`>HNzG{d}mQBhVUIFMqH$mJln*aJS8Vc^8{gTw%ILy*QZY)oc4bB&4m zI76}_Khct}uYofRY)lq9uxPu0D3(wE_phBV->;|7?HB*CujQv-1(e1BF%HOfbTYIA z10i*Q3oaZj9uE{17AF!TQC~oQLVZMedV5H5a&t^|c6U%=Qe#wQW@lJwYHM6=Zf{^g zVnbv_Mn`B#N=s}_PET;r@22Rgtgi5~w6^%VJbwWL1qTTW4G$3$6&D#B9Umc5w{Vi+ z7?Us+;*{J}gkAGODRT-G4$$vC(IU@6_C3JwJ^G!~0CfK62?G>@(14VJT!Sir8iB@u zwt@+OIf3PawSp~y-GcLiJArpY5JQ+j)I!`tazXk*E=`yRD8J|Cyy@Uh+PlakoEW*l-ZR4|X$6*$gcLf^g3{zU z$cYzM`oOm%2t9VfgYb_SD+I6n227qzjb2V8VoR+i7*&n18J*c6)wD(OO067yj=|G- z>(W_kd4~&VU8YGEj;Li^4UsG0cw7~&~>TDd=pfwpjchNbf zAX|b&iSZb89R@1Z)XSTfafUA?k_C*>s?Nz%mx2v$CEEA6Zu;^dr0sOe5Ca>69a?Fq z{edNBGSRI^{-e5g#`>35IHEBA1Uthvhe+aQRuUh+W=s}{_Z*>dwr3dFWkluEz3alqQja`>-atsXutnHP0V>Wy)KOJTb&4x0DF}91~s-(AnpoP$pDgU$7eD`p(Ct~ijv)2w;YzrHrW&w01sxLOz@)rRSDy+{WdF9j$IN!p?;_e=;IC1=T;$%H$_SA(3rkn*>%⪼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 R_rGlULbUxq`G3cd{~w)xH(>w( literal 0 HcmV?d00001 From 092bc00d1eb3d45affbe344fc901b9a5342d238e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 13 Jul 2020 09:56:24 +0100 Subject: [PATCH 11/12] Show errors if like notification cannot be saved --- inbox.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inbox.py b/inbox.py index ffeaed505..fa9e0ca94 100644 --- a/inbox.py +++ b/inbox.py @@ -1752,11 +1752,15 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str, with open(prevLikeFile, 'w+') as fp: fp.write(likeStr) except BaseException: + print('ERROR: unable to save previous like notification ' + + prevLikeFile) pass try: with open(likeFile, 'w+') as fp: fp.write(likeStr) except BaseException: + print('ERROR: unable to write like notification file ' + + likeFile) pass From 94b4529cf60c6ba175738c80f51a8e5653306e68 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 13 Jul 2020 10:34:04 +0100 Subject: [PATCH 12/12] Bad variable reuse --- inbox.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inbox.py b/inbox.py index fa9e0ca94..864def14e 100644 --- a/inbox.py +++ b/inbox.py @@ -1744,8 +1744,8 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str, # was there a previous like notification? if os.path.isfile(prevLikeFile): # is it the same as the current notification ? - with open(prevLikeFile, 'r') as likeFile: - prevLikeStr = likeFile.read() + with open(prevLikeFile, 'r') as fp: + prevLikeStr = fp.read() if prevLikeStr == likeStr: return try: