| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | __filename__ = "blog.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							|  |  |  | __version__ = "1.1.0" | 
					
						
							|  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | import os | 
					
						
							|  |  |  | from datetime import datetime | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from content import replaceEmojiFromTags | 
					
						
							| 
									
										
										
										
											2020-11-14 13:03:09 +00:00
										 |  |  | from webapp import getIconsWebPath | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  | from webapp import htmlHeaderWithExternalStyle | 
					
						
							| 
									
										
										
										
											2020-11-09 13:18:28 +00:00
										 |  |  | from webapp import htmlFooter | 
					
						
							| 
									
										
										
										
											2020-11-09 19:41:01 +00:00
										 |  |  | from webapp_media import addEmbeddedElements | 
					
						
							|  |  |  | from webapp_utils import getPostAttachmentsAsHtml | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  | from utils import getDomainFromActor | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  | from utils import locatePost | 
					
						
							|  |  |  | from utils import loadJson | 
					
						
							| 
									
										
										
										
											2020-11-08 10:45:33 +00:00
										 |  |  | from utils import firstParagraphFromString | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | from posts import createBlogsTimeline | 
					
						
							| 
									
										
										
										
											2020-10-04 12:29:07 +00:00
										 |  |  | from newswire import rss2Header | 
					
						
							|  |  |  | from newswire import rss2Footer | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | def noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                     nickname: str, domain: str, domainFull: str, | 
					
						
							|  |  |  |                     postId: str, depth=0) -> int: | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  |     """Returns the number of replies on the post
 | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |     This is recursive, so can handle replies to replies | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     if depth > 4: | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |         return 0 | 
					
						
							|  |  |  |     if not postId: | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     tryPostBox = ('tlblogs', 'inbox', 'outbox') | 
					
						
							|  |  |  |     boxFound = False | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |     for postBox in tryPostBox: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |             nickname + '@' + domain + '/' + postBox + '/' + \ | 
					
						
							|  |  |  |             postId.replace('/', '#') + '.replies' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |         if os.path.isfile(postFilename): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             boxFound = True | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |             break | 
					
						
							|  |  |  |     if not boxFound: | 
					
						
							| 
									
										
										
										
											2020-02-26 10:26:04 +00:00
										 |  |  |         # post may exist but has no replies | 
					
						
							|  |  |  |         for postBox in tryPostBox: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |                 nickname + '@' + domain + '/' + postBox + '/' + \ | 
					
						
							|  |  |  |                 postId.replace('/', '#') | 
					
						
							| 
									
										
										
										
											2020-02-26 10:26:04 +00:00
										 |  |  |             if os.path.isfile(postFilename): | 
					
						
							|  |  |  |                 return 1 | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 09:42:02 +00:00
										 |  |  |     removals = [] | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     replies = 0 | 
					
						
							| 
									
										
										
										
											2020-05-18 09:42:02 +00:00
										 |  |  |     lines = [] | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  |     with open(postFilename, "r") as f: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         lines = f.readlines() | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |         for replyPostId in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |             replyPostId = replyPostId.replace('\n', '').replace('\r', '') | 
					
						
							|  |  |  |             replyPostId = replyPostId.replace('.json', '') | 
					
						
							| 
									
										
										
										
											2020-05-18 09:42:02 +00:00
										 |  |  |             if locatePost(baseDir, nickname, domain, replyPostId): | 
					
						
							|  |  |  |                 replyPostId = replyPostId.replace('.replies', '') | 
					
						
							|  |  |  |                 replies += 1 + noOfBlogReplies(baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                                                nickname, domain, domainFull, | 
					
						
							|  |  |  |                                                replyPostId, depth+1) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 # remove post which no longer exists | 
					
						
							|  |  |  |                 removals.append(replyPostId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # remove posts from .replies file if they don't exist | 
					
						
							|  |  |  |     if lines and removals: | 
					
						
							|  |  |  |         print('Rewriting ' + postFilename + ' to remove ' + | 
					
						
							|  |  |  |               str(len(removals)) + ' entries') | 
					
						
							| 
									
										
										
										
											2020-08-29 11:14:19 +00:00
										 |  |  |         with open(postFilename, 'w+') as f: | 
					
						
							| 
									
										
										
										
											2020-05-18 09:42:02 +00:00
										 |  |  |             for replyPostId in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |                 replyPostId = replyPostId.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2020-05-18 09:42:02 +00:00
										 |  |  |                 if replyPostId not in removals: | 
					
						
							|  |  |  |                     f.write(replyPostId + '\n') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |     return replies | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | def getBlogReplies(baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                    nickname: str, domain: str, domainFull: str, | 
					
						
							|  |  |  |                    postId: str, depth=0) -> str: | 
					
						
							| 
									
										
										
										
											2020-05-18 14:00:47 +00:00
										 |  |  |     """Returns a string containing html blog posts
 | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     if depth > 4: | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |         return '' | 
					
						
							|  |  |  |     if not postId: | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     tryPostBox = ('tlblogs', 'inbox', 'outbox') | 
					
						
							|  |  |  |     boxFound = False | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |     for postBox in tryPostBox: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |             nickname + '@' + domain + '/' + postBox + '/' + \ | 
					
						
							|  |  |  |             postId.replace('/', '#') + '.replies' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |         if os.path.isfile(postFilename): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             boxFound = True | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  |             break | 
					
						
							|  |  |  |     if not boxFound: | 
					
						
							| 
									
										
										
										
											2020-02-26 10:26:04 +00:00
										 |  |  |         # post may exist but has no replies | 
					
						
							|  |  |  |         for postBox in tryPostBox: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |                 nickname + '@' + domain + '/' + postBox + '/' + \ | 
					
						
							| 
									
										
										
										
											2020-05-18 14:00:47 +00:00
										 |  |  |                 postId.replace('/', '#') + '.json' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:26:04 +00:00
										 |  |  |             if os.path.isfile(postFilename): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |                     nickname + '@' + domain + \ | 
					
						
							|  |  |  |                     '/postcache/' + \ | 
					
						
							|  |  |  |                     postId.replace('/', '#') + '.html' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:26:04 +00:00
										 |  |  |                 if os.path.isfile(postFilename): | 
					
						
							|  |  |  |                     with open(postFilename, "r") as postFile: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                         return postFile.read() + '\n' | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:10:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |     with open(postFilename, "r") as f: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         lines = f.readlines() | 
					
						
							|  |  |  |         repliesStr = '' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:04:38 +00:00
										 |  |  |         for replyPostId in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |             replyPostId = replyPostId.replace('\n', '').replace('\r', '') | 
					
						
							|  |  |  |             replyPostId = replyPostId.replace('.json', '') | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             replyPostId = replyPostId.replace('.replies', '') | 
					
						
							|  |  |  |             postFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |                 nickname + '@' + domain + \ | 
					
						
							|  |  |  |                 '/postcache/' + \ | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |                 replyPostId.replace('/', '#') + '.html' | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |             if not os.path.isfile(postFilename): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             with open(postFilename, "r") as postFile: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 repliesStr += postFile.read() + '\n' | 
					
						
							| 
									
										
										
										
											2020-05-18 16:12:57 +00:00
										 |  |  |             rply = getBlogReplies(baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                                   nickname, domain, domainFull, | 
					
						
							|  |  |  |                                   replyPostId, depth+1) | 
					
						
							|  |  |  |             if rply not in repliesStr: | 
					
						
							|  |  |  |                 repliesStr += rply | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # indicate the reply indentation level | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         indentStr = '>' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  |         for indentLevel in range(depth): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             indentStr += ' >' | 
					
						
							| 
									
										
										
										
											2020-02-26 10:03:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         repliesStr = repliesStr.replace(translate['SHOW MORE'], indentStr) | 
					
						
							|  |  |  |         return repliesStr.replace('?tl=outbox', '?tl=tlblogs') | 
					
						
							| 
									
										
										
										
											2020-02-25 20:53:02 +00:00
										 |  |  |     return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | def htmlBlogPostContent(authorized: bool, | 
					
						
							|  |  |  |                         baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                         nickname: str, domain: str, domainFull: str, | 
					
						
							|  |  |  |                         postJsonObject: {}, | 
					
						
							| 
									
										
										
										
											2020-05-18 11:32:28 +00:00
										 |  |  |                         handle: str, restrictToDomain: bool, | 
					
						
							|  |  |  |                         blogSeparator='<hr>') -> str: | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     """Returns the content for a single blog post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     linkedAuthor = False | 
					
						
							|  |  |  |     actor = '' | 
					
						
							|  |  |  |     blogStr = '' | 
					
						
							|  |  |  |     messageLink = '' | 
					
						
							| 
									
										
										
										
											2020-02-25 15:32:43 +00:00
										 |  |  |     if postJsonObject['object'].get('id'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         messageLink = postJsonObject['object']['id'].replace('/statuses/', '/') | 
					
						
							|  |  |  |     titleStr = '' | 
					
						
							| 
									
										
										
										
											2020-11-08 13:01:01 +00:00
										 |  |  |     articleAdded = False | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     if postJsonObject['object'].get('summary'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         titleStr = postJsonObject['object']['summary'] | 
					
						
							| 
									
										
										
										
											2020-11-08 13:01:01 +00:00
										 |  |  |         blogStr += '<article><h1><a href="' + messageLink + '">' + \ | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             titleStr + '</a></h1>\n' | 
					
						
							| 
									
										
										
										
											2020-11-08 13:01:01 +00:00
										 |  |  |         articleAdded = True | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the handle of the author | 
					
						
							|  |  |  |     if postJsonObject['object'].get('attributedTo'): | 
					
						
							| 
									
										
										
										
											2020-08-06 16:21:46 +00:00
										 |  |  |         authorNickname = None | 
					
						
							|  |  |  |         if isinstance(postJsonObject['object']['attributedTo'], str): | 
					
						
							|  |  |  |             actor = postJsonObject['object']['attributedTo'] | 
					
						
							|  |  |  |             authorNickname = getNicknameFromActor(actor) | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         if authorNickname: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             authorDomain, authorPort = getDomainFromActor(actor) | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |             if authorDomain: | 
					
						
							|  |  |  |                 # author must be from the given domain | 
					
						
							|  |  |  |                 if restrictToDomain and authorDomain != domain: | 
					
						
							|  |  |  |                     return '' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 handle = authorNickname + '@' + authorDomain | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         # posts from the domain are expected to have an attributedTo field | 
					
						
							|  |  |  |         if restrictToDomain: | 
					
						
							|  |  |  |             return '' | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     if postJsonObject['object'].get('published'): | 
					
						
							|  |  |  |         if 'T' in postJsonObject['object']['published']: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             blogStr += '<h3>' + \ | 
					
						
							|  |  |  |                 postJsonObject['object']['published'].split('T')[0] | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |             if handle: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 if handle.startswith(nickname + '@' + domain): | 
					
						
							|  |  |  |                     blogStr += ' <a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |                         domainFull + \ | 
					
						
							|  |  |  |                         '/users/' + nickname + '">' + handle + '</a>' | 
					
						
							|  |  |  |                     linkedAuthor = True | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                     if actor: | 
					
						
							|  |  |  |                         blogStr += ' <a href="' + actor + '">' + \ | 
					
						
							|  |  |  |                             handle + '</a>' | 
					
						
							|  |  |  |                         linkedAuthor = True | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                         blogStr += ' ' + handle | 
					
						
							|  |  |  |             blogStr += '</h3>\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     avatarLink = '' | 
					
						
							|  |  |  |     replyStr = '' | 
					
						
							|  |  |  |     announceStr = '' | 
					
						
							|  |  |  |     likeStr = '' | 
					
						
							|  |  |  |     bookmarkStr = '' | 
					
						
							|  |  |  |     deleteStr = '' | 
					
						
							|  |  |  |     muteStr = '' | 
					
						
							|  |  |  |     isMuted = False | 
					
						
							|  |  |  |     attachmentStr, galleryStr = getPostAttachmentsAsHtml(postJsonObject, | 
					
						
							|  |  |  |                                                          'tlblogs', translate, | 
					
						
							|  |  |  |                                                          isMuted, avatarLink, | 
					
						
							|  |  |  |                                                          replyStr, announceStr, | 
					
						
							|  |  |  |                                                          likeStr, bookmarkStr, | 
					
						
							|  |  |  |                                                          deleteStr, muteStr) | 
					
						
							| 
									
										
										
										
											2020-02-25 16:57:25 +00:00
										 |  |  |     if attachmentStr: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         blogStr += '<br><center>' + attachmentStr + '</center>' | 
					
						
							| 
									
										
										
										
											2020-02-25 16:57:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     if postJsonObject['object'].get('content'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         contentStr = addEmbeddedElements(translate, | 
					
						
							|  |  |  |                                          postJsonObject['object']['content']) | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         if postJsonObject['object'].get('tag'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             contentStr = replaceEmojiFromTags(contentStr, | 
					
						
							|  |  |  |                                               postJsonObject['object']['tag'], | 
					
						
							|  |  |  |                                               'content') | 
					
						
							| 
									
										
										
										
											2020-11-08 13:01:01 +00:00
										 |  |  |         if articleAdded: | 
					
						
							|  |  |  |             blogStr += '<br>' + contentStr + '</article>\n' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             blogStr += '<br><article>' + contentStr + '</article>\n' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 14:04:09 +00:00
										 |  |  |     citationsStr = '' | 
					
						
							|  |  |  |     if postJsonObject['object'].get('tag'): | 
					
						
							|  |  |  |         for tagJson in postJsonObject['object']['tag']: | 
					
						
							|  |  |  |             if not isinstance(tagJson, dict): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if not tagJson.get('type'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if tagJson['type'] != 'Article': | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if not tagJson.get('name'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if not tagJson.get('url'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             citationsStr += \ | 
					
						
							|  |  |  |                 '<li><a href="' + tagJson['url'] + '">' + \ | 
					
						
							|  |  |  |                 '<cite>' + tagJson['name'] + '</cite></a></li>\n' | 
					
						
							|  |  |  |         if citationsStr: | 
					
						
							|  |  |  |             citationsStr = '<p><b>' + translate['Citations'] + \ | 
					
						
							|  |  |  |                 ':</b></p>' + \ | 
					
						
							|  |  |  |                 '<ul>\n' + citationsStr + '</ul>\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blogStr += '<br>\n' + citationsStr | 
					
						
							| 
									
										
										
										
											2020-02-25 20:31:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 20:57:16 +00:00
										 |  |  |     if not linkedAuthor: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         blogStr += '<p class="about"><a class="about" href="' + \ | 
					
						
							|  |  |  |             httpPrefix + '://' + domainFull + \ | 
					
						
							|  |  |  |             '/users/' + nickname + '">' + translate['About the author'] + \ | 
					
						
							|  |  |  |             '</a></p>\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     replies = noOfBlogReplies(baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                               nickname, domain, domainFull, | 
					
						
							|  |  |  |                               postJsonObject['object']['id']) | 
					
						
							| 
									
										
										
										
											2020-05-18 11:32:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # separator between blogs should be centered | 
					
						
							|  |  |  |     if '<center>' not in blogSeparator: | 
					
						
							|  |  |  |         blogSeparator = '<center>' + blogSeparator + '</center>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if replies == 0: | 
					
						
							|  |  |  |         blogStr += blogSeparator + '\n' | 
					
						
							|  |  |  |         return blogStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not authorized: | 
					
						
							|  |  |  |         blogStr += '<p class="blogreplies">' + \ | 
					
						
							|  |  |  |             translate['Replies'].lower() + ': ' + str(replies) + '</p>' | 
					
						
							|  |  |  |         blogStr += '<br><br><br>' + blogSeparator + '\n' | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         blogStr += blogSeparator + '<h1>' + translate['Replies'] + '</h1>\n' | 
					
						
							|  |  |  |         if not titleStr: | 
					
						
							|  |  |  |             blogStr += getBlogReplies(baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                                       nickname, domain, domainFull, | 
					
						
							|  |  |  |                                       postJsonObject['object']['id']) | 
					
						
							| 
									
										
										
										
											2020-02-25 21:40:13 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-05-18 11:32:28 +00:00
										 |  |  |             blogRepliesStr = getBlogReplies(baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                                             nickname, domain, domainFull, | 
					
						
							|  |  |  |                                             postJsonObject['object']['id']) | 
					
						
							|  |  |  |             blogStr += blogRepliesStr.replace('>' + titleStr + '<', '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     return blogStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 09:10:26 +00:00
										 |  |  | def htmlBlogPostRSS2(authorized: bool, | 
					
						
							|  |  |  |                      baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                      nickname: str, domain: str, domainFull: str, | 
					
						
							|  |  |  |                      postJsonObject: {}, | 
					
						
							|  |  |  |                      handle: str, restrictToDomain: bool) -> str: | 
					
						
							|  |  |  |     """Returns the RSS version 2 feed for a single blog post
 | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-11-01 17:18:05 +00:00
										 |  |  |     rssStr = '' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     messageLink = '' | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     if postJsonObject['object'].get('id'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         messageLink = postJsonObject['object']['id'].replace('/statuses/', '/') | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |         if not restrictToDomain or \ | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |            (restrictToDomain and '/' + domain in messageLink): | 
					
						
							| 
									
										
										
										
											2020-09-26 18:23:43 +00:00
										 |  |  |             if postJsonObject['object'].get('summary') and \ | 
					
						
							|  |  |  |                postJsonObject['object'].get('published'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 published = postJsonObject['object']['published'] | 
					
						
							|  |  |  |                 pubDate = datetime.strptime(published, "%Y-%m-%dT%H:%M:%SZ") | 
					
						
							|  |  |  |                 titleStr = postJsonObject['object']['summary'] | 
					
						
							|  |  |  |                 rssDateStr = pubDate.strftime("%a, %d %b %Y %H:%M:%S UT") | 
					
						
							| 
									
										
										
										
											2020-11-08 10:45:33 +00:00
										 |  |  |                 content = postJsonObject['object']['content'] | 
					
						
							|  |  |  |                 description = firstParagraphFromString(content) | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 rssStr = '     <item>' | 
					
						
							|  |  |  |                 rssStr += '         <title>' + titleStr + '</title>' | 
					
						
							|  |  |  |                 rssStr += '         <link>' + messageLink + '</link>' | 
					
						
							| 
									
										
										
										
											2020-11-08 10:30:25 +00:00
										 |  |  |                 rssStr += \ | 
					
						
							|  |  |  |                     '         <description>' + description + '</description>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 rssStr += '         <pubDate>' + rssDateStr + '</pubDate>' | 
					
						
							|  |  |  |                 rssStr += '     </item>' | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     return rssStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  | def htmlBlogPostRSS3(authorized: bool, | 
					
						
							|  |  |  |                      baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                      nickname: str, domain: str, domainFull: str, | 
					
						
							|  |  |  |                      postJsonObject: {}, | 
					
						
							|  |  |  |                      handle: str, restrictToDomain: bool) -> str: | 
					
						
							|  |  |  |     """Returns the RSS version 3 feed for a single blog post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-11-01 17:18:05 +00:00
										 |  |  |     rssStr = '' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  |     messageLink = '' | 
					
						
							|  |  |  |     if postJsonObject['object'].get('id'): | 
					
						
							|  |  |  |         messageLink = postJsonObject['object']['id'].replace('/statuses/', '/') | 
					
						
							|  |  |  |         if not restrictToDomain or \ | 
					
						
							|  |  |  |            (restrictToDomain and '/' + domain in messageLink): | 
					
						
							| 
									
										
										
										
											2020-09-26 18:23:43 +00:00
										 |  |  |             if postJsonObject['object'].get('summary') and \ | 
					
						
							|  |  |  |                postJsonObject['object'].get('published'): | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  |                 published = postJsonObject['object']['published'] | 
					
						
							|  |  |  |                 pubDate = datetime.strptime(published, "%Y-%m-%dT%H:%M:%SZ") | 
					
						
							|  |  |  |                 titleStr = postJsonObject['object']['summary'] | 
					
						
							|  |  |  |                 rssDateStr = pubDate.strftime("%a, %d %b %Y %H:%M:%S UT") | 
					
						
							| 
									
										
										
										
											2020-11-08 10:45:33 +00:00
										 |  |  |                 content = postJsonObject['object']['content'] | 
					
						
							|  |  |  |                 description = firstParagraphFromString(content) | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  |                 rssStr = 'title: ' + titleStr + '\n' | 
					
						
							|  |  |  |                 rssStr += 'link: ' + messageLink + '\n' | 
					
						
							| 
									
										
										
										
											2020-11-08 10:30:25 +00:00
										 |  |  |                 rssStr += 'description: ' + description + '\n' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  |                 rssStr += 'created: ' + rssDateStr + '\n\n' | 
					
						
							|  |  |  |     return rssStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 10:07:11 +00:00
										 |  |  | def htmlBlogRemoveCwButton(blogStr: str, translate: {}) -> str: | 
					
						
							|  |  |  |     """Removes the CW button from blog posts, where the
 | 
					
						
							|  |  |  |     summary field is instead used as the blog title | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     blogStr = blogStr.replace('<details>', '<b>') | 
					
						
							|  |  |  |     blogStr = blogStr.replace('</details>', '</b>') | 
					
						
							|  |  |  |     blogStr = blogStr.replace('<summary>', '') | 
					
						
							|  |  |  |     blogStr = blogStr.replace('</summary>', '') | 
					
						
							|  |  |  |     blogStr = blogStr.replace(translate['SHOW MORE'], '') | 
					
						
							|  |  |  |     return blogStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | def htmlBlogPost(authorized: bool, | 
					
						
							|  |  |  |                  baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                  nickname: str, domain: str, domainFull: str, | 
					
						
							| 
									
										
										
										
											2020-02-25 13:44:10 +00:00
										 |  |  |                  postJsonObject: {}) -> str: | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     """Returns a html blog post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     blogStr = '' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 12:21:46 +00:00
										 |  |  |     cssFilename = baseDir + '/epicyon-blog.css' | 
					
						
							|  |  |  |     if os.path.isfile(baseDir + '/blog.css'): | 
					
						
							|  |  |  |         cssFilename = baseDir + '/blog.css' | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr = htmlHeaderWithExternalStyle(cssFilename) | 
					
						
							|  |  |  |     htmlBlogRemoveCwButton(blogStr, translate) | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr += htmlBlogPostContent(authorized, baseDir, | 
					
						
							|  |  |  |                                    httpPrefix, translate, | 
					
						
							|  |  |  |                                    nickname, domain, | 
					
						
							|  |  |  |                                    domainFull, postJsonObject, | 
					
						
							|  |  |  |                                    None, False) | 
					
						
							| 
									
										
										
										
											2020-02-28 14:51:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     # show rss links | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |     iconsPath = getIconsWebPath(baseDir) | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr += '<p class="rssfeed">' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |         domainFull + '/blog/' + nickname + '/rss.xml">' | 
					
						
							|  |  |  |     blogStr += '<img style="width:3%;min-width:50px" ' + \ | 
					
						
							|  |  |  |         'loading="lazy" alt="RSS 2.0" ' + \ | 
					
						
							|  |  |  |         'title="RSS 2.0" src="/' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |         iconsPath + '/logorss.png" /></a>' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     # blogStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |     #     domainFull + '/blog/' + nickname + '/rss.txt">' | 
					
						
							|  |  |  |     # blogStr += '<img style="width:3%;min-width:50px" ' + \ | 
					
						
							|  |  |  |     #     'loading="lazy" alt="RSS 3.0" ' + \ | 
					
						
							|  |  |  |     #     'title="RSS 3.0" src="/' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |     #     iconsPath + '/rss3.png" /></a>' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr += '</p>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     return blogStr + htmlFooter() | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def htmlBlogPage(authorized: bool, session, | 
					
						
							|  |  |  |                  baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                  nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                  noOfItems: int, pageNumber: int) -> str: | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     """Returns a html blog page containing posts
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |     if ' ' in nickname or '@' in nickname or \ | 
					
						
							|  |  |  |        '\n' in nickname or '\r' in nickname: | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     blogStr = '' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     cssFilename = baseDir + '/epicyon-profile.css' | 
					
						
							|  |  |  |     if os.path.isfile(baseDir + '/epicyon.css'): | 
					
						
							|  |  |  |         cssFilename = baseDir + '/epicyon.css' | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr = htmlHeaderWithExternalStyle(cssFilename) | 
					
						
							|  |  |  |     htmlBlogRemoveCwButton(blogStr, translate) | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogsIndex = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '/tlblogs.index' | 
					
						
							|  |  |  |     if not os.path.isfile(blogsIndex): | 
					
						
							|  |  |  |         return blogStr + htmlFooter() | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     timelineJson = createBlogsTimeline(session, baseDir, | 
					
						
							|  |  |  |                                        nickname, domain, port, | 
					
						
							|  |  |  |                                        httpPrefix, | 
					
						
							|  |  |  |                                        noOfItems, False, | 
					
						
							|  |  |  |                                        pageNumber) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not timelineJson: | 
					
						
							|  |  |  |         return blogStr + htmlFooter() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     domainFull = domain | 
					
						
							|  |  |  |     if port: | 
					
						
							|  |  |  |         if port != 80 and port != 443: | 
					
						
							|  |  |  |             domainFull = domain + ':' + str(port) | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     # show previous and next buttons | 
					
						
							|  |  |  |     if pageNumber is not None: | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |         iconsPath = getIconsWebPath(baseDir) | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |         navigateStr = '<p>' | 
					
						
							|  |  |  |         if pageNumber > 1: | 
					
						
							|  |  |  |             # show previous button | 
					
						
							|  |  |  |             navigateStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |                 domainFull + '/blog/' + \ | 
					
						
							|  |  |  |                 nickname + '?page=' + str(pageNumber-1) + '">' + \ | 
					
						
							|  |  |  |                 '<img loading="lazy" alt="<" title="<" ' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |                 'src="/' + iconsPath + \ | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |                 '/prev.png" class="buttonprev"/></a>\n' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         if len(timelineJson['orderedItems']) >= noOfItems: | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |             # show next button | 
					
						
							|  |  |  |             navigateStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |                 domainFull + '/blog/' + nickname + \ | 
					
						
							|  |  |  |                 '?page=' + str(pageNumber + 1) + '">' + \ | 
					
						
							|  |  |  |                 '<img loading="lazy" alt=">" title=">" ' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |                 'src="/' + iconsPath + \ | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |                 '/prev.png" class="buttonnext"/></a>\n' | 
					
						
							|  |  |  |         navigateStr += '</p>' | 
					
						
							|  |  |  |         blogStr += navigateStr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for item in timelineJson['orderedItems']: | 
					
						
							|  |  |  |         if item['type'] != 'Create': | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-02-25 18:19:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |         blogStr += htmlBlogPostContent(authorized, baseDir, | 
					
						
							|  |  |  |                                        httpPrefix, translate, | 
					
						
							|  |  |  |                                        nickname, domain, | 
					
						
							|  |  |  |                                        domainFull, item, | 
					
						
							|  |  |  |                                        None, True) | 
					
						
							| 
									
										
										
										
											2020-05-23 09:50:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     if len(timelineJson['orderedItems']) >= noOfItems: | 
					
						
							|  |  |  |         blogStr += navigateStr | 
					
						
							| 
									
										
										
										
											2020-05-23 09:50:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     # show rss link | 
					
						
							|  |  |  |     blogStr += '<p class="rssfeed">' | 
					
						
							| 
									
										
										
										
											2020-05-23 09:50:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |         domainFull + '/blog/' + nickname + '/rss.xml">' | 
					
						
							|  |  |  |     blogStr += '<img loading="lazy" alt="RSS 2.0" ' + \ | 
					
						
							|  |  |  |         'title="RSS 2.0" src="/' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |         iconsPath + '/logorss.png" /></a>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     # blogStr += '<a href="' + httpPrefix + '://' + \ | 
					
						
							|  |  |  |     #     domainFull + '/blog/' + nickname + '/rss.txt">' | 
					
						
							|  |  |  |     # blogStr += '<img loading="lazy" alt="RSS 3.0" ' + \ | 
					
						
							|  |  |  |     #     'title="RSS 3.0" src="/' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |     #     iconsPath + '/rss3.png" /></a>' | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     blogStr += '</p>' | 
					
						
							|  |  |  |     return blogStr + htmlFooter() | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 09:10:26 +00:00
										 |  |  | def htmlBlogPageRSS2(authorized: bool, session, | 
					
						
							|  |  |  |                      baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                      nickname: str, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2020-10-13 16:58:45 +00:00
										 |  |  |                      noOfItems: int, pageNumber: int, | 
					
						
							|  |  |  |                      includeHeader: bool) -> str: | 
					
						
							| 
									
										
										
										
											2020-05-23 09:10:26 +00:00
										 |  |  |     """Returns an RSS version 2 feed containing posts
 | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |     if ' ' in nickname or '@' in nickname or \ | 
					
						
							|  |  |  |        '\n' in nickname or '\r' in nickname: | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     domainFull = domain | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     if port: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         if port != 80 and port != 443: | 
					
						
							|  |  |  |             domainFull = domain + ':' + str(port) | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 16:58:45 +00:00
										 |  |  |     blogRSS2 = '' | 
					
						
							|  |  |  |     if includeHeader: | 
					
						
							|  |  |  |         blogRSS2 = rss2Header(httpPrefix, nickname, domainFull, | 
					
						
							|  |  |  |                               'Blog', translate) | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     blogsIndex = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '/tlblogs.index' | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |     if not os.path.isfile(blogsIndex): | 
					
						
							| 
									
										
										
										
											2020-10-13 17:09:22 +00:00
										 |  |  |         if includeHeader: | 
					
						
							|  |  |  |             return blogRSS2 + rss2Footer() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return blogRSS2 | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     timelineJson = createBlogsTimeline(session, baseDir, | 
					
						
							|  |  |  |                                        nickname, domain, port, | 
					
						
							|  |  |  |                                        httpPrefix, | 
					
						
							| 
									
										
										
										
											2020-10-02 12:39:22 +00:00
										 |  |  |                                        noOfItems, False, | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                                        pageNumber) | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not timelineJson: | 
					
						
							| 
									
										
										
										
											2020-10-13 16:58:45 +00:00
										 |  |  |         if includeHeader: | 
					
						
							|  |  |  |             return blogRSS2 + rss2Footer() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return blogRSS2 | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     if pageNumber is not None: | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |         for item in timelineJson['orderedItems']: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             if item['type'] != 'Create': | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 09:10:26 +00:00
										 |  |  |             blogRSS2 += \ | 
					
						
							|  |  |  |                 htmlBlogPostRSS2(authorized, baseDir, | 
					
						
							|  |  |  |                                  httpPrefix, translate, | 
					
						
							|  |  |  |                                  nickname, domain, | 
					
						
							|  |  |  |                                  domainFull, item, | 
					
						
							|  |  |  |                                  None, True) | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 17:09:22 +00:00
										 |  |  |     if includeHeader: | 
					
						
							|  |  |  |         return blogRSS2 + rss2Footer() | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return blogRSS2 | 
					
						
							| 
									
										
										
										
											2020-02-27 20:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  | def htmlBlogPageRSS3(authorized: bool, session, | 
					
						
							|  |  |  |                      baseDir: str, httpPrefix: str, translate: {}, | 
					
						
							|  |  |  |                      nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                      noOfItems: int, pageNumber: int) -> str: | 
					
						
							|  |  |  |     """Returns an RSS version 3 feed containing posts
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if ' ' in nickname or '@' in nickname or \ | 
					
						
							|  |  |  |        '\n' in nickname or '\r' in nickname: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     domainFull = domain | 
					
						
							|  |  |  |     if port: | 
					
						
							|  |  |  |         if port != 80 and port != 443: | 
					
						
							|  |  |  |             domainFull = domain + ':' + str(port) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blogRSS3 = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blogsIndex = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '/tlblogs.index' | 
					
						
							|  |  |  |     if not os.path.isfile(blogsIndex): | 
					
						
							|  |  |  |         return blogRSS3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     timelineJson = createBlogsTimeline(session, baseDir, | 
					
						
							|  |  |  |                                        nickname, domain, port, | 
					
						
							|  |  |  |                                        httpPrefix, | 
					
						
							| 
									
										
										
										
											2020-10-02 12:39:22 +00:00
										 |  |  |                                        noOfItems, False, | 
					
						
							| 
									
										
										
										
											2020-05-23 09:41:50 +00:00
										 |  |  |                                        pageNumber) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not timelineJson: | 
					
						
							|  |  |  |         return blogRSS3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if pageNumber is not None: | 
					
						
							|  |  |  |         for item in timelineJson['orderedItems']: | 
					
						
							|  |  |  |             if item['type'] != 'Create': | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             blogRSS3 += \ | 
					
						
							|  |  |  |                 htmlBlogPostRSS3(authorized, baseDir, | 
					
						
							|  |  |  |                                  httpPrefix, translate, | 
					
						
							|  |  |  |                                  nickname, domain, | 
					
						
							|  |  |  |                                  domainFull, item, | 
					
						
							|  |  |  |                                  None, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return blogRSS3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | def getBlogIndexesForAccounts(baseDir: str) -> {}: | 
					
						
							|  |  |  |     """ Get the index files for blogs for each account
 | 
					
						
							|  |  |  |     and add them to a dict | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     blogIndexes = {} | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(baseDir + '/accounts'): | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         for acct in dirs: | 
					
						
							|  |  |  |             if '@' not in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if 'inbox@' in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             accountDir = os.path.join(baseDir + '/accounts', acct) | 
					
						
							|  |  |  |             blogsIndex = accountDir + '/tlblogs.index' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |             if os.path.isfile(blogsIndex): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 blogIndexes[acct] = blogsIndex | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     return blogIndexes | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | def noOfBlogAccounts(baseDir: str) -> int: | 
					
						
							|  |  |  |     """Returns the number of blog accounts
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     ctr = 0 | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(baseDir + '/accounts'): | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         for acct in dirs: | 
					
						
							|  |  |  |             if '@' not in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-02-25 13:47:04 +00:00
										 |  |  |             if 'inbox@' in acct: | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             accountDir = os.path.join(baseDir + '/accounts', acct) | 
					
						
							|  |  |  |             blogsIndex = accountDir + '/tlblogs.index' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |             if os.path.isfile(blogsIndex): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |                 ctr += 1 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |     return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | def singleBlogAccountNickname(baseDir: str) -> str: | 
					
						
							|  |  |  |     """Returns the nickname of a single blog account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     for subdir, dirs, files in os.walk(baseDir + '/accounts'): | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |         for acct in dirs: | 
					
						
							|  |  |  |             if '@' not in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if 'inbox@' in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |             accountDir = os.path.join(baseDir + '/accounts', acct) | 
					
						
							|  |  |  |             blogsIndex = accountDir + '/tlblogs.index' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |             if os.path.isfile(blogsIndex): | 
					
						
							|  |  |  |                 return acct.split('@')[0] | 
					
						
							|  |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def htmlBlogView(authorized: bool, | 
					
						
							|  |  |  |                  session, baseDir: str, httpPrefix: str, | 
					
						
							|  |  |  |                  translate: {}, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  |                  noOfItems: int) -> str: | 
					
						
							|  |  |  |     """Show the blog main page
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     blogStr = '' | 
					
						
							| 
									
										
										
										
											2020-02-25 13:35:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     cssFilename = baseDir + '/epicyon-profile.css' | 
					
						
							|  |  |  |     if os.path.isfile(baseDir + '/epicyon.css'): | 
					
						
							|  |  |  |         cssFilename = baseDir + '/epicyon.css' | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     blogStr = htmlHeaderWithExternalStyle(cssFilename) | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     if noOfBlogAccounts(baseDir) <= 1: | 
					
						
							|  |  |  |         nickname = singleBlogAccountNickname(baseDir) | 
					
						
							|  |  |  |         if nickname: | 
					
						
							|  |  |  |             return htmlBlogPage(authorized, session, | 
					
						
							|  |  |  |                                 baseDir, httpPrefix, translate, | 
					
						
							|  |  |  |                                 nickname, domain, port, | 
					
						
							|  |  |  |                                 noOfItems, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     domainFull = domain | 
					
						
							|  |  |  |     if port: | 
					
						
							|  |  |  |         if port != 80 and port != 443: | 
					
						
							|  |  |  |             domainFull = domain + ':' + str(port) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(baseDir + '/accounts'): | 
					
						
							|  |  |  |         for acct in dirs: | 
					
						
							|  |  |  |             if '@' not in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if 'inbox@' in acct: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             accountDir = os.path.join(baseDir + '/accounts', acct) | 
					
						
							|  |  |  |             blogsIndex = accountDir + '/tlblogs.index' | 
					
						
							|  |  |  |             if os.path.isfile(blogsIndex): | 
					
						
							|  |  |  |                 blogStr += '<p class="blogaccount">' | 
					
						
							|  |  |  |                 blogStr += '<a href="' + \ | 
					
						
							|  |  |  |                     httpPrefix + '://' + domainFull + '/blog/' + \ | 
					
						
							|  |  |  |                     acct.split('@')[0] + '">' + acct + '</a>' | 
					
						
							|  |  |  |                 blogStr += '</p>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return blogStr + htmlFooter() | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def htmlEditBlog(mediaInstance: bool, translate: {}, | 
					
						
							|  |  |  |                  baseDir: str, httpPrefix: str, | 
					
						
							|  |  |  |                  path: str, | 
					
						
							|  |  |  |                  pageNumber: int, | 
					
						
							|  |  |  |                  nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |                  postUrl: str) -> str: | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  |     """Edit a blog post after it was created
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     postFilename = locatePost(baseDir, nickname, domain, postUrl) | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |     if not postFilename: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         print('Edit blog: Filename not found for ' + postUrl) | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     postJsonObject = loadJson(postFilename) | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |     if not postJsonObject: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         print('Edit blog: json not loaded for ' + postFilename) | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |     iconsPath = getIconsWebPath(baseDir) | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogText = '<p class="new-post-text">' + \ | 
					
						
							|  |  |  |         translate['Write your post text below.'] + '</p>' | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     if os.path.isfile(baseDir + '/accounts/newpost.txt'): | 
					
						
							|  |  |  |         with open(baseDir + '/accounts/newpost.txt', 'r') as file: | 
					
						
							|  |  |  |             editBlogText = '<p class="new-post-text">' + file.read() + '</p>' | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     cssFilename = baseDir + '/epicyon-profile.css' | 
					
						
							|  |  |  |     if os.path.isfile(baseDir + '/epicyon.css'): | 
					
						
							|  |  |  |         cssFilename = baseDir + '/epicyon.css' | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if '?' in path: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         path = path.split('?')[0] | 
					
						
							|  |  |  |     pathBase = path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     editBlogImageSection = '    <div class="container">' | 
					
						
							|  |  |  |     editBlogImageSection += '      <label class="labels">' + \ | 
					
						
							|  |  |  |         translate['Image description'] + '</label>' | 
					
						
							|  |  |  |     editBlogImageSection += '      <input type="text" name="imageDescription">' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogImageSection += \ | 
					
						
							|  |  |  |         '      <input type="file" id="attachpic" name="attachpic"' | 
					
						
							|  |  |  |     editBlogImageSection += \ | 
					
						
							| 
									
										
										
										
											2020-09-09 15:09:38 +00:00
										 |  |  |         '            accept=".png, .jpg, .jpeg, .gif, .webp, .avif, ' + \ | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |         '.mp4, .webm, .ogv, .mp3, .ogg">' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogImageSection += '    </div>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     placeholderMessage = translate['Write something'] + '...' | 
					
						
							|  |  |  |     endpoint = 'editblogpost' | 
					
						
							|  |  |  |     placeholderSubject = translate['Title'] | 
					
						
							|  |  |  |     scopeIcon = 'scope_blog.png' | 
					
						
							|  |  |  |     scopeDescription = translate['Blog'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dateAndLocation = '' | 
					
						
							|  |  |  |     dateAndLocation = '<div class="container">' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     dateAndLocation += \ | 
					
						
							|  |  |  |         '<p><input type="checkbox" class="profilecheckbox" ' + \ | 
					
						
							|  |  |  |         'name="schedulePost"><label class="labels">' + \ | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         translate['This is a scheduled post.'] + '</label></p>' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     dateAndLocation += \ | 
					
						
							|  |  |  |         '<p><img loading="lazy" alt="" title="" ' + \ | 
					
						
							|  |  |  |         'class="emojicalendar" src="/' + \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |         iconsPath + '/calendar.png"/>' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     dateAndLocation += \ | 
					
						
							|  |  |  |         '<label class="labels">' + translate['Date'] + ': </label>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     dateAndLocation += '<input type="date" name="eventDate">' | 
					
						
							|  |  |  |     dateAndLocation += '<label class="labelsright">' + translate['Time'] + ':' | 
					
						
							|  |  |  |     dateAndLocation += '<input type="time" name="eventTime"></label></p>' | 
					
						
							|  |  |  |     dateAndLocation += '</div>' | 
					
						
							|  |  |  |     dateAndLocation += '<div class="container">' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     dateAndLocation += \ | 
					
						
							|  |  |  |         '<br><label class="labels">' + translate['Location'] + ': </label>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     dateAndLocation += '<input type="text" name="location">' | 
					
						
							|  |  |  |     dateAndLocation += '</div>' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:05:45 +00:00
										 |  |  |     editBlogForm = htmlHeaderWithExternalStyle(cssFilename) | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '<form enctype="multipart/form-data" method="POST" ' + \ | 
					
						
							|  |  |  |         'accept-charset="UTF-8" action="' + \ | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         pathBase + '?' + endpoint + '?page=' + str(pageNumber) + '">' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '  <input type="hidden" name="postUrl" value="' + postUrl + '">' | 
					
						
							|  |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '  <input type="hidden" name="pageNumber" value="' + \ | 
					
						
							|  |  |  |         str(pageNumber) + '">' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm += '  <div class="vertical-center">' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '    <label for="nickname"><b>' + editBlogText + '</b></label>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm += '    <div class="container">' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     editBlogForm += '      <div class="dropbtn">' | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							| 
									
										
										
										
											2020-11-14 13:08:34 +00:00
										 |  |  |         '        <img loading="lazy" alt="" title="" src="/' + iconsPath + \ | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |         '/' + scopeIcon + '"/><b class="scope-desc">' + \ | 
					
						
							|  |  |  |         scopeDescription + '</b>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm += '      </div>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     editBlogForm += '      <a href="' + pathBase + \ | 
					
						
							|  |  |  |         '/searchemoji"><img loading="lazy" ' + \ | 
					
						
							|  |  |  |         'class="emojisearch" src="/emoji/1F601.png" title="' + \ | 
					
						
							|  |  |  |         translate['Search for emoji'] + '" alt="' + \ | 
					
						
							|  |  |  |         translate['Search for emoji'] + '"/></a>' | 
					
						
							|  |  |  |     editBlogForm += '    </div>' | 
					
						
							|  |  |  |     editBlogForm += '    <div class="container"><center>' | 
					
						
							|  |  |  |     editBlogForm += '      <a href="' + pathBase + \ | 
					
						
							|  |  |  |         '/inbox"><button class="cancelbtn">' + \ | 
					
						
							|  |  |  |         translate['Cancel'] + '</button></a>' | 
					
						
							|  |  |  |     editBlogForm += '      <input type="submit" name="submitPost" value="' + \ | 
					
						
							|  |  |  |         translate['Submit'] + '">' | 
					
						
							|  |  |  |     editBlogForm += '    </center></div>' | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  |     if mediaInstance: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         editBlogForm += editBlogImageSection | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '    <label class="labels">' + placeholderSubject + '</label><br>' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     titleStr = '' | 
					
						
							| 
									
										
										
										
											2020-03-01 12:33:20 +00:00
										 |  |  |     if postJsonObject['object'].get('summary'): | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         titleStr = postJsonObject['object']['summary'] | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '    <input type="text" name="subject" value="' + titleStr + '">' | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm += '' | 
					
						
							|  |  |  |     editBlogForm += '    <br><label class="labels">' + \ | 
					
						
							|  |  |  |         placeholderMessage + '</label>' | 
					
						
							|  |  |  |     messageBoxHeight = 800 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     contentStr = postJsonObject['object']['content'] | 
					
						
							|  |  |  |     contentStr = contentStr.replace('<p>', '').replace('</p>', '\n') | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 09:33:23 +00:00
										 |  |  |     editBlogForm += \ | 
					
						
							|  |  |  |         '    <textarea id="message" name="message" style="height:' + \ | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         str(messageBoxHeight) + 'px">' + contentStr + '</textarea>' | 
					
						
							|  |  |  |     editBlogForm += dateAndLocation | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  |     if not mediaInstance: | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |         editBlogForm += editBlogImageSection | 
					
						
							|  |  |  |     editBlogForm += '  </div>' | 
					
						
							|  |  |  |     editBlogForm += '</form>' | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm = editBlogForm.replace('<body>', | 
					
						
							|  |  |  |                                         '<body onload="focusOnMessage()">') | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 21:29:04 +00:00
										 |  |  |     editBlogForm += htmlFooter() | 
					
						
							| 
									
										
										
										
											2020-02-29 20:34:44 +00:00
										 |  |  |     return editBlogForm |