Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main

main
Bob Mottram 2020-12-26 13:32:52 +00:00
commit 4c83f60a69
54 changed files with 94 additions and 59 deletions

View File

@ -2237,8 +2237,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.cachedWebfingers, self.server.cachedWebfingers,
self.server.personCache, self.server.personCache,
debug, debug,
self.server.projectVersion, self.server.projectVersion)
self.server.allowNewsFollowers)
if callingDomain.endswith('.onion') and onionDomain: if callingDomain.endswith('.onion') and onionDomain:
originPathStr = 'http://' + onionDomain + usersPath originPathStr = 'http://' + onionDomain + usersPath
elif (callingDomain.endswith('.i2p') and i2pDomain): elif (callingDomain.endswith('.i2p') and i2pDomain):
@ -13364,7 +13363,6 @@ def runDaemon(sendThreadsTimeoutMins: int,
fullWidthTimelineButtonHeader: bool, fullWidthTimelineButtonHeader: bool,
showPublishAsIcon: bool, showPublishAsIcon: bool,
maxFollowers: int, maxFollowers: int,
allowNewsFollowers: bool,
maxNewsPosts: int, maxNewsPosts: int,
maxMirroredArticles: int, maxMirroredArticles: int,
maxNewswireFeedSizeKb: int, maxNewswireFeedSizeKb: int,
@ -13515,9 +13513,6 @@ def runDaemon(sendThreadsTimeoutMins: int,
# maximum number of posts in the news timeline/outbox # maximum number of posts in the news timeline/outbox
httpd.maxNewsPosts = maxNewsPosts httpd.maxNewsPosts = maxNewsPosts
# whether or not to allow followers of the news account
httpd.allowNewsFollowers = allowNewsFollowers
# The maximum number of tags per post which can be # The maximum number of tags per post which can be
# attached to RSS feeds pulled in via the newswire # attached to RSS feeds pulled in via the newswire
httpd.maxTags = 32 httpd.maxTags = 32
@ -13704,7 +13699,6 @@ def runDaemon(sendThreadsTimeoutMins: int,
httpd.translate, unitTest, httpd.translate, unitTest,
httpd.YTReplacementDomain, httpd.YTReplacementDomain,
httpd.showPublishedDateOnly, httpd.showPublishedDateOnly,
httpd.allowNewsFollowers,
httpd.maxFollowers, httpd.maxFollowers,
httpd.allowLocalNetworkAccess, httpd.allowLocalNetworkAccess,
httpd.peertubeInstances), daemon=True) httpd.peertubeInstances), daemon=True)

View File

@ -999,11 +999,17 @@ div.container {
color: var(--column-right-fg-color); color: var(--column-right-fg-color);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItem img {
width: 20px;
}
.newswireItemModerated { .newswireItemModerated {
font-size: var(--font-size-newswire); font-size: var(--font-size-newswire);
color: var(--newswire-item-moderated-color); color: var(--newswire-item-moderated-color);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItemModerated img {
width: 20px;
}
.newswireDateModerated { .newswireDateModerated {
font-size: var(--font-size-newswire); font-size: var(--font-size-newswire);
font-weight: bold; font-weight: bold;
@ -1019,6 +1025,9 @@ div.container {
color: var(--column-right-fg-color-voted-on); color: var(--column-right-fg-color-voted-on);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItemVotedOn img {
width: 20px;
}
.newswireDate { .newswireDate {
font-size: var(--font-size-newswire); font-size: var(--font-size-newswire);
color: var(--newswire-date-color); color: var(--newswire-date-color);
@ -1685,11 +1694,17 @@ div.container {
color: var(--column-right-fg-color); color: var(--column-right-fg-color);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItem img {
width: 40px;
}
.newswireItemModerated { .newswireItemModerated {
font-size: var(--font-size-newswire-mobile); font-size: var(--font-size-newswire-mobile);
color: var(--newswire-item-moderated-color); color: var(--newswire-item-moderated-color);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItemModerated img {
width: 40px;
}
.newswireDateModerated { .newswireDateModerated {
font-size: var(--font-size-newswire-mobile); font-size: var(--font-size-newswire-mobile);
font-weight: bold; font-weight: bold;
@ -1705,6 +1720,9 @@ div.container {
color: var(--column-right-fg-color-voted-on); color: var(--column-right-fg-color-voted-on);
line-height: var(--line-spacing-newswire); line-height: var(--line-spacing-newswire);
} }
.newswireItemVotedOn img {
width: 40px;
}
.newswireDate { .newswireDate {
font-size: var(--font-size-newswire-mobile); font-size: var(--font-size-newswire-mobile);
color: var(--newswire-date-color); color: var(--newswire-date-color);

View File

@ -243,11 +243,6 @@ parser.add_argument("--fullWidthTimelineButtonHeader",
help="Whether to show the timeline " + help="Whether to show the timeline " +
"button header containing inbox and outbox " + "button header containing inbox and outbox " +
"as the full width of the screen") "as the full width of the screen")
parser.add_argument("--allowNewsFollowers",
dest='allowNewsFollowers',
type=str2bool, nargs='?',
const=True, default=False,
help="Whether to allow the news account to be followed")
parser.add_argument("--iconsAsButtons", parser.add_argument("--iconsAsButtons",
dest='iconsAsButtons', dest='iconsAsButtons',
type=str2bool, nargs='?', type=str2bool, nargs='?',
@ -2095,11 +2090,6 @@ sendThreadsTimeoutMins = \
if sendThreadsTimeoutMins is not None: if sendThreadsTimeoutMins is not None:
args.sendThreadsTimeoutMins = int(sendThreadsTimeoutMins) args.sendThreadsTimeoutMins = int(sendThreadsTimeoutMins)
allowNewsFollowers = \
getConfigParam(baseDir, 'allowNewsFollowers')
if allowNewsFollowers is not None:
args.allowNewsFollowers = bool(allowNewsFollowers)
showPublishAsIcon = \ showPublishAsIcon = \
getConfigParam(baseDir, 'showPublishAsIcon') getConfigParam(baseDir, 'showPublishAsIcon')
if showPublishAsIcon is not None: if showPublishAsIcon is not None:
@ -2154,7 +2144,6 @@ if __name__ == "__main__":
args.fullWidthTimelineButtonHeader, args.fullWidthTimelineButtonHeader,
args.showPublishAsIcon, args.showPublishAsIcon,
args.maxFollowers, args.maxFollowers,
args.allowNewsFollowers,
args.maxNewsPosts, args.maxNewsPosts,
args.maxMirroredArticles, args.maxMirroredArticles,
args.maxNewswireFeedSizeKb, args.maxNewswireFeedSizeKb,

View File

@ -68,14 +68,9 @@ def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None:
def _preApprovedFollower(baseDir: str, def _preApprovedFollower(baseDir: str,
nickname: str, domain: str, nickname: str, domain: str,
approveHandle: str, approveHandle: str) -> bool:
allowNewsFollowers: bool) -> bool:
"""Is the given handle an already manually approved follower? """Is the given handle an already manually approved follower?
""" """
# optionally allow the news account to be followed
if nickname == 'news' and allowNewsFollowers:
return True
handle = nickname + '@' + domain handle = nickname + '@' + domain
accountDir = baseDir + '/accounts/' + handle accountDir = baseDir + '/accounts/' + handle
approvedFilename = accountDir + '/approved.txt' approvedFilename = accountDir + '/approved.txt'
@ -460,13 +455,12 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str,
def _followApprovalRequired(baseDir: str, nicknameToFollow: str, def _followApprovalRequired(baseDir: str, nicknameToFollow: str,
domainToFollow: str, debug: bool, domainToFollow: str, debug: bool,
followRequestHandle: str, followRequestHandle: str) -> bool:
allowNewsFollowers: bool) -> bool:
""" Returns the policy for follower approvals """ Returns the policy for follower approvals
""" """
# has this handle already been manually approved? # has this handle already been manually approved?
if _preApprovedFollower(baseDir, nicknameToFollow, domainToFollow, if _preApprovedFollower(baseDir, nicknameToFollow, domainToFollow,
followRequestHandle, allowNewsFollowers): followRequestHandle):
return False return False
manuallyApproveFollows = False manuallyApproveFollows = False
@ -600,7 +594,6 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
cachedWebfingers: {}, personCache: {}, cachedWebfingers: {}, personCache: {},
messageJson: {}, federationList: [], messageJson: {}, federationList: [],
debug: bool, projectVersion: str, debug: bool, projectVersion: str,
allowNewsFollowers: bool,
maxFollowers: int) -> bool: maxFollowers: int) -> bool:
"""Receives a follow request within the POST section of HTTPServer """Receives a follow request within the POST section of HTTPServer
""" """
@ -651,11 +644,10 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
'nickname for the account followed') 'nickname for the account followed')
return True return True
if isSystemAccount(nicknameToFollow): if isSystemAccount(nicknameToFollow):
if not (nicknameToFollow == 'news' and allowNewsFollowers): if debug:
if debug: print('DEBUG: Cannot follow system account - ' +
print('DEBUG: Cannot follow system account - ' + nicknameToFollow)
nicknameToFollow) return True
return True
if maxFollowers > 0: if maxFollowers > 0:
if _getNoOfFollowers(baseDir, if _getNoOfFollowers(baseDir,
nicknameToFollow, domainToFollow, nicknameToFollow, domainToFollow,
@ -683,8 +675,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
# what is the followers policy? # what is the followers policy?
approveHandle = nickname + '@' + domainFull approveHandle = nickname + '@' + domainFull
if _followApprovalRequired(baseDir, nicknameToFollow, if _followApprovalRequired(baseDir, nicknameToFollow,
domainToFollow, debug, approveHandle, domainToFollow, debug, approveHandle):
allowNewsFollowers):
print('Follow approval is required') print('Follow approval is required')
if domain.endswith('.onion'): if domain.endswith('.onion'):
if _noOfFollowRequests(baseDir, if _noOfFollowRequests(baseDir,
@ -877,7 +868,7 @@ def sendFollowRequest(session, baseDir: str,
clientToServer: bool, federationList: [], clientToServer: bool, federationList: [],
sendThreads: [], postLog: [], cachedWebfingers: {}, sendThreads: [], postLog: [], cachedWebfingers: {},
personCache: {}, debug: bool, personCache: {}, debug: bool,
projectVersion: str, allowNewsFollowers: bool) -> {}: projectVersion: str) -> {}:
"""Gets the json object for sending a follow request """Gets the json object for sending a follow request
""" """
if not domainPermitted(followDomain, federationList): if not domainPermitted(followDomain, federationList):
@ -910,7 +901,7 @@ def sendFollowRequest(session, baseDir: str,
} }
if _followApprovalRequired(baseDir, nickname, domain, debug, if _followApprovalRequired(baseDir, nickname, domain, debug,
followHandle, allowNewsFollowers): followHandle):
# Remove any follow requests rejected for the account being followed. # Remove any follow requests rejected for the account being followed.
# It's assumed that if you are following someone then you are # It's assumed that if you are following someone then you are
# ok with them following back. If this isn't the case then a rejected # ok with them following back. If this isn't the case then a rejected

Binary file not shown.

View File

@ -1,6 +1,7 @@
# Font Licenses # Font Licenses
Absortile is under GPL. See https://www.ffonts.net/Absortile.font Absortile is under GPL. See https://www.ffonts.net/Absortile.font
Barlow-Regular is under SIL Open Font License. See https://tribby.com/fonts/barlow
Bedstead is under CC0. See below and https://fontlibrary.org/en/font/bedstead Bedstead is under CC0. See below and https://fontlibrary.org/en/font/bedstead
bgrove is under GPL. See http://www.free-fonts-download.com/basic/bloominggrove-font bgrove is under GPL. See http://www.free-fonts-download.com/basic/bloominggrove-font
CheGuevaraTextSans-Regular is under CC0. See https://fonts2u.com/cheguevara-text-sans-regular.font CheGuevaraTextSans-Regular is under CC0. See https://fonts2u.com/cheguevara-text-sans-regular.font

View File

@ -2449,7 +2449,6 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
maxEmoji: int, translate: {}, unitTest: bool, maxEmoji: int, translate: {}, unitTest: bool,
YTReplacementDomain: str, YTReplacementDomain: str,
showPublishedDateOnly: bool, showPublishedDateOnly: bool,
allowNewsFollowers: bool,
maxFollowers: int, allowLocalNetworkAccess: bool, maxFollowers: int, allowLocalNetworkAccess: bool,
peertubeInstances: []) -> None: peertubeInstances: []) -> None:
"""Processes received items and moves them to the appropriate """Processes received items and moves them to the appropriate
@ -2739,7 +2738,6 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
queueJson['post'], queueJson['post'],
federationList, federationList,
debug, projectVersion, debug, projectVersion,
allowNewsFollowers,
maxFollowers): maxFollowers):
if os.path.isfile(queueFilename): if os.path.isfile(queueFilename):
os.remove(queueFilename) os.remove(queueFilename)

View File

@ -322,11 +322,12 @@ def createServerAlice(path: str, domain: str, port: int,
maxNewswirePosts = 20 maxNewswirePosts = 20
dormantMonths = 3 dormantMonths = 3
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10
print('Server running: Alice') print('Server running: Alice')
runDaemon(sendThreadsTimeoutMins, runDaemon(sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False, 2048, False, True, False, False, True, maxFollowers,
0, 100, 1024, 5, False, 0, 100, 1024, 5, False,
0, False, 1, False, False, False, 0, False, 1, False, False, False,
5, True, True, 'en', __version__, 5, True, True, 'en', __version__,
@ -418,11 +419,12 @@ def createServerBob(path: str, domain: str, port: int,
maxNewswirePosts = 20 maxNewswirePosts = 20
dormantMonths = 3 dormantMonths = 3
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10
print('Server running: Bob') print('Server running: Bob')
runDaemon(sendThreadsTimeoutMins, runDaemon(sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False, 2048, False, True, False, False, True, maxFollowers,
0, 100, 1024, 5, False, 0, 0, 100, 1024, 5, False, 0,
False, 1, False, False, False, False, 1, False, False, False,
5, True, True, 'en', __version__, 5, True, True, 'en', __version__,
@ -464,11 +466,12 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
maxNewswirePosts = 20 maxNewswirePosts = 20
dormantMonths = 3 dormantMonths = 3
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10
print('Server running: Eve') print('Server running: Eve')
runDaemon(sendThreadsTimeoutMins, runDaemon(sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,
2048, False, True, False, False, True, 10, False, 2048, False, True, False, False, True, maxFollowers,
0, 100, 1024, 5, False, 0, 0, 100, 1024, 5, False, 0,
False, 1, False, False, False, False, 1, False, False, False,
5, True, True, 'en', __version__, 5, True, True, 'en', __version__,
@ -851,7 +854,7 @@ def testFollowBetweenServers():
clientToServer, federationList, clientToServer, federationList,
aliceSendThreads, alicePostLog, aliceSendThreads, alicePostLog,
aliceCachedWebfingers, alicePersonCache, aliceCachedWebfingers, alicePersonCache,
True, __version__, False) True, __version__)
print('sendResult: ' + str(sendResult)) print('sendResult: ' + str(sendResult))
for t in range(16): for t in range(16):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,4 +1,17 @@
{ {
"dropdown-bg-color-hover": "#463b35",
"main-fg-color": "#d5c7b7",
"column-left-fg-color": "#d5c7b7",
"button-text": "#d5c7b7",
"button-selected-text": "#d5c7b7",
"login-bg-color": "#212e3f",
"lines-color": "#b6a188",
"day-number": "black",
"day-number2": "#bbb",
"column-left-header-background": "#8b674e",
"column-left-header-color": "#d5c7b7",
"post-separator-margin-top": "10px",
"post-separator-margin-bottom": "10px",
"newswire-publish-icon": "True", "newswire-publish-icon": "True",
"full-width-timeline-buttons": "False", "full-width-timeline-buttons": "False",
"icons-as-buttons": "False", "icons-as-buttons": "False",
@ -6,9 +19,9 @@
"publish-button-at-top": "False", "publish-button-at-top": "False",
"banner-height": "25vh", "banner-height": "25vh",
"banner-height-mobile": "10vh", "banner-height-mobile": "10vh",
"newswire-date-color": "yellow", "newswire-date-color": "#ffd974",
"main-bg-color": "#5c4e41", "main-bg-color": "#5c4e41",
"login-bg-color": "#5c4e41", "calendar-bg-color": "#5c4e41",
"options-bg-color": "#5c4e41", "options-bg-color": "#5c4e41",
"post-bg-color": "#5c4e41", "post-bg-color": "#5c4e41",
"timeline-posts-background-color": "#5c4e41", "timeline-posts-background-color": "#5c4e41",
@ -18,23 +31,24 @@
"link-bg-color": "#5c4e41", "link-bg-color": "#5c4e41",
"main-bg-color-reply": "#5c4e41", "main-bg-color-reply": "#5c4e41",
"main-bg-color-report": "#5c4e41", "main-bg-color-report": "#5c4e41",
"day-number2": "#5c4e41",
"border-color": "#463b35", "border-color": "#463b35",
"border-width": "7px", "border-width": "7px",
"border-width-header": "7px", "border-width-header": "7px",
"main-link-color": "#dddddd", "main-link-color": "#d5c7b7",
"main-link-color-hover": "white", "main-link-color-hover": "white",
"options-main-link-color": "#dddddd", "options-main-link-color": "#d5c7b7",
"options-main-link-color-hover": "white", "options-main-link-color-hover": "white",
"title-color": "#dddddd", "title-color": "#d5c7b7",
"main-visited-color": "#dddddd", "main-visited-color": "#d5c7b7",
"options-main-visited-color": "#dddddd", "options-main-visited-color": "#d5c7b7",
"button-background-hover": "#a63b35", "button-background-hover": "#5f3b00",
"publish-button-background": "#463b35", "publish-button-background": "#463b35",
"button-background": "#463b35", "button-background": "#463b35",
"button-selected": "#26201d", "button-selected": "#26201d",
"main-bg-color-dm": "#5c4a40", "main-bg-color-dm": "#5c4a40",
"main-header-color-roles": "#5c4e41", "main-header-color-roles": "#5c4e41",
"dropdown-bg-color": "#504e41", "dropdown-bg-color": "#504e41",
"dropdown-bg-color-hover": "#444" "header-font": "'Barlow-Regular'",
"*font-family": "'Barlow-Regular'",
"*src": "url('fonts/Barlow-Regular.woff2') format('woff2')"
} }

View File

@ -187,6 +187,25 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
return htmlStr return htmlStr
def getBrokenFavSubstitute() -> str:
"""Substitute link used if a favicon is not available
"""
return " onerror=\"this.onerror=null; this.src=''\""
def getFavicon(url: str) -> str:
"""Returns a favicon url from the given article link
"""
if '://' not in url:
return None
domain = url.split('://')[1]
if '/' not in domain:
return url + '/favicon.ico'
else:
domain = domain.split('/')[0]
return url.split('://')[0] + '://' + domain + '/favicon.ico'
def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool, def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
translate: {}, positiveVoting: bool) -> str: translate: {}, positiveVoting: bool) -> str:
"""Converts a newswire dict into html """Converts a newswire dict into html
@ -212,6 +231,13 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
dateStrLink = dateStr.replace('T', ' ') dateStrLink = dateStr.replace('T', ' ')
dateStrLink = dateStrLink.replace('Z', '') dateStrLink = dateStrLink.replace('Z', '')
url = item[1]
faviconUrl = getFavicon(url)
faviconLink = ''
if faviconUrl:
faviconLink = \
'<img loading="lazy" src="' + faviconUrl + '" ' + \
getBrokenFavSubstitute() + '/>'
moderatedItem = item[5] moderatedItem = item[5]
htmlStr += separatorStr htmlStr += separatorStr
if moderatedItem and 'vote:' + nickname in item[2]: if moderatedItem and 'vote:' + nickname in item[2]:
@ -224,9 +250,10 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
title = removeLongWords(item[0], 16, []).replace('\n', '<br>') title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
htmlStr += '<p class="newswireItemVotedOn">' + \ htmlStr += '<p class="newswireItemVotedOn">' + \
'<a href="' + item[1] + '" target="_blank" ' + \ '<a href="' + url + '" target="_blank" ' + \
'rel="nofollow noopener noreferrer">' + \ 'rel="nofollow noopener noreferrer">' + \
'<span class="newswireItemVotedOn">' + title + \ '<span class="newswireItemVotedOn">' + \
faviconLink + title + \
'</span></a>' + totalVotesStr '</span></a>' + totalVotesStr
if moderator: if moderator:
htmlStr += \ htmlStr += \
@ -252,9 +279,9 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
title = removeLongWords(item[0], 16, []).replace('\n', '<br>') title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
if moderator and moderatedItem: if moderator and moderatedItem:
htmlStr += '<p class="newswireItemModerated">' + \ htmlStr += '<p class="newswireItemModerated">' + \
'<a href="' + item[1] + '" target="_blank" ' + \ '<a href="' + url + '" target="_blank" ' + \
'rel="nofollow noopener noreferrer">' + \ 'rel="nofollow noopener noreferrer">' + \
title + '</a>' + totalVotesStr faviconLink + title + '</a>' + totalVotesStr
htmlStr += ' ' + dateShown htmlStr += ' ' + dateShown
htmlStr += '<a href="/users/' + nickname + \ htmlStr += '<a href="/users/' + nickname + \
'/newswirevote=' + dateStrLink + '" ' + \ '/newswirevote=' + dateStrLink + '" ' + \
@ -264,9 +291,9 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
htmlStr += '</p>\n' htmlStr += '</p>\n'
else: else:
htmlStr += '<p class="newswireItem">' + \ htmlStr += '<p class="newswireItem">' + \
'<a href="' + item[1] + '" target="_blank" ' + \ '<a href="' + url + '" target="_blank" ' + \
'rel="nofollow noopener noreferrer">' + \ 'rel="nofollow noopener noreferrer">' + \
title + '</a>' + \ faviconLink + title + '</a>' + \
totalVotesStr totalVotesStr
htmlStr += ' <span class="newswireDate">' htmlStr += ' <span class="newswireDate">'
htmlStr += dateShown + '</span></p>\n' htmlStr += dateShown + '</span></p>\n'