diff --git a/blog.py b/blog.py index c01d11af2..724e7d783 100644 --- a/blog.py +++ b/blog.py @@ -1,21 +1,13 @@ -__filename__="blog.py" -__author__="Bob Mottram" -__license__="AGPL3+" -__version__="1.1.0" -__maintainer__="Bob Mottram" -__email__="bob@freedombone.net" -__status__="Production" +__filename__ = "blog.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.1.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@freedombone.net" +__status__ = "Production" -import json -import time import os -from collections import OrderedDict from datetime import datetime -from datetime import date -from dateutil.parser import parse -from shutil import copyfile -from shutil import copyfileobj -from pprint import pprint from content import replaceEmojiFromTags from webinterface import contentWarningScriptOpen @@ -31,142 +23,141 @@ from utils import loadJson from posts import createBlogsTimeline -def noOfBlogReplies(baseDir: str,httpPrefix: str,translate: {}, \ - nickname: str,domain: str,domainFull: str, \ - postId: str,depth=0) -> int: +def noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {}, + nickname: str, domain: str, domainFull: str, + postId: str, depth=0) -> int: """Returns the number of replies on the post This is recursive, so can handle replies to replies """ - if depth>4: + if depth > 4: return 0 if not postId: return 0 - tryPostBox=('tlblogs','inbox','outbox') - boxFound=False + tryPostBox = ('tlblogs', 'inbox', 'outbox') + boxFound = False for postBox in tryPostBox: - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+'/'+postBox+'/'+ \ - postId.replace('/','#')+'.replies' + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/' + postBox + '/' + \ + postId.replace('/', '#') + '.replies' if os.path.isfile(postFilename): - boxFound=True + boxFound = True break if not boxFound: # post may exist but has no replies for postBox in tryPostBox: - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+'/'+postBox+'/'+ \ - postId.replace('/','#') + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/' + postBox + '/' + \ + postId.replace('/', '#') if os.path.isfile(postFilename): return 1 return 0 - replies=0 + replies = 0 with open(postFilename, "r") as f: - lines=f.readlines() + lines = f.readlines() for replyPostId in lines: - replyPostId= \ - replyPostId.replace('\n','').replace('.json','').replace('.replies','') - replies+= \ - 1+ \ - noOfBlogReplies(baseDir,httpPrefix,translate, \ - nickname,domain,domainFull, \ - replyPostId,depth+1) + replyPostId = replyPostId.replace('\n', '').replace('.json', '') + replyPostId = replyPostId.replace('.replies', '') + replies += 1 + noOfBlogReplies(baseDir, httpPrefix, translate, + nickname, domain, domainFull, + replyPostId, depth+1) return replies -def getBlogReplies(baseDir: str,httpPrefix: str,translate: {}, \ - nickname: str,domain: str,domainFull: str, \ - postId: str,depth=0) -> str: +def getBlogReplies(baseDir: str, httpPrefix: str, translate: {}, + nickname: str, domain: str, domainFull: str, + postId: str, depth=0) -> str: """Returns the number of replies on the post """ - if depth>4: + if depth > 4: return '' if not postId: return '' - tryPostBox=('tlblogs','inbox','outbox') - boxFound=False + tryPostBox = ('tlblogs', 'inbox', 'outbox') + boxFound = False for postBox in tryPostBox: - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+'/'+postBox+'/'+ \ - postId.replace('/','#')+'.replies' + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/' + postBox + '/' + \ + postId.replace('/', '#') + '.replies' if os.path.isfile(postFilename): - boxFound=True + boxFound = True break if not boxFound: # post may exist but has no replies for postBox in tryPostBox: - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+'/'+postBox+'/'+ \ - postId.replace('/','#') + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/' + postBox + '/' + \ + postId.replace('/', '#') if os.path.isfile(postFilename): - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+ \ - '/postcache/'+ \ - postId.replace('/','#')+'.html' + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + \ + '/postcache/' + \ + postId.replace('/', '#') + '.html' if os.path.isfile(postFilename): with open(postFilename, "r") as postFile: - return postFile.read()+'\n' + return postFile.read() + '\n' return '' with open(postFilename, "r") as f: - lines=f.readlines() - repliesStr='' + lines = f.readlines() + repliesStr = '' for replyPostId in lines: - replyPostId= \ - replyPostId.replace('\n','').replace('.json','').replace('.replies','') - postFilename= \ - baseDir+'/accounts/'+nickname+'@'+domain+ \ - '/postcache/'+ \ - replyPostId.replace('\n','').replace('/','#')+'.html' + replyPostId = replyPostId.replace('\n', '').replace('.json', '') + replyPostId = replyPostId.replace('.replies', '') + postFilename = baseDir + '/accounts/' + \ + nickname + '@' + domain + \ + '/postcache/' + \ + replyPostId.replace('\n', '').replace('/', '#') + '.html' if not os.path.isfile(postFilename): continue with open(postFilename, "r") as postFile: - repliesStr+=postFile.read()+'\n' - repliesStr+= \ - getBlogReplies(baseDir,httpPrefix,translate, \ - nickname,domain,domainFull, \ - replyPostId,depth+1) + repliesStr += postFile.read() + '\n' + repliesStr += getBlogReplies(baseDir, httpPrefix, translate, + nickname, domain, domainFull, + replyPostId, depth+1) # indicate the reply indentation level - indentStr='>' + indentStr = '>' for indentLevel in range(depth): - indentStr+=' >' + indentStr += ' >' - return repliesStr.replace(translate['SHOW MORE'],indentStr).replace('?tl=outbox','?tl=tlblogs') + repliesStr = repliesStr.replace(translate['SHOW MORE'], indentStr) + return repliesStr.replace('?tl=outbox', '?tl=tlblogs') return '' -def htmlBlogPostContent(authorized: bool, \ - baseDir: str,httpPrefix: str,translate: {}, \ - nickname: str,domain: str,domainFull: str, \ - postJsonObject: {}, \ - handle: str,restrictToDomain: bool) -> str: +def htmlBlogPostContent(authorized: bool, + baseDir: str, httpPrefix: str, translate: {}, + nickname: str, domain: str, domainFull: str, + postJsonObject: {}, + handle: str, restrictToDomain: bool) -> str: """Returns the content for a single blog post """ - linkedAuthor=False - actor='' - blogStr='' - messageLink='' + linkedAuthor = False + actor = '' + blogStr = '' + messageLink = '' if postJsonObject['object'].get('id'): - messageLink=postJsonObject['object']['id'].replace('/statuses/','/') - titleStr='' + messageLink = postJsonObject['object']['id'].replace('/statuses/', '/') + titleStr = '' if postJsonObject['object'].get('summary'): - titleStr=postJsonObject['object']['summary'] - blogStr+='
'+translate['About the author']+'
\n' + blogStr += '' + translate['About the author'] + \ + '
\n' - replies= \ - noOfBlogReplies(baseDir,httpPrefix,translate, \ - nickname,domain,domainFull, \ - postJsonObject['object']['id']) - if replies>0: + replies = noOfBlogReplies(baseDir, httpPrefix, translate, + nickname, domain, domainFull, + postJsonObject['object']['id']) + if replies > 0: if not authorized: - blogStr+= \ - ''+ \ - translate['Replies'].lower()+': '+str(replies)+'
\n' + blogStr += '' + \ + translate['Replies'].lower() + ': ' + str(replies) + '
\n' else: - blogStr+='' - blogStr+='' - blogStr+='' - blogStr+='
' + iconsDir = getIconsDir(baseDir) + blogStr += '' + blogStr += '' + blogStr += '' + blogStr += '
' - return blogStr+htmlFooter() + return blogStr + htmlFooter() return None -def htmlBlogPage(authorized: bool, session, \ - baseDir: str,httpPrefix: str,translate: {}, \ - nickname: str,domain: str,port: int, \ - noOfItems: int,pageNumber: int) -> str: + +def htmlBlogPage(authorized: bool, session, + baseDir: str, httpPrefix: str, translate: {}, + nickname: str, domain: str, port: int, + noOfItems: int, pageNumber: int) -> str: """Returns a html blog page containing posts """ if ' ' in nickname or '@' in nickname or '\n' in nickname: return None - blogStr='' + blogStr = '' - cssFilename=baseDir+'/epicyon-profile.css' - if os.path.isfile(baseDir+'/epicyon.css'): - cssFilename=baseDir+'/epicyon.css' + cssFilename = baseDir + '/epicyon-profile.css' + if os.path.isfile(baseDir + '/epicyon.css'): + cssFilename = baseDir + '/epicyon.css' with open(cssFilename, 'r') as cssFile: - blogCSS=cssFile.read() - blogStr=htmlHeader(cssFilename,blogCSS) - blogStr=blogStr.replace('.cwText','.cwTextInactive') + blogCSS = cssFile.read() + blogStr = htmlHeader(cssFilename, blogCSS) + blogStr = blogStr.replace('.cwText', '.cwTextInactive') - blogsIndex= \ - baseDir+'/accounts/'+nickname+'@'+domain+'/tlblogs.index' + blogsIndex = baseDir + '/accounts/' + \ + nickname + '@' + domain + '/tlblogs.index' if not os.path.isfile(blogsIndex): - return blogStr+htmlFooter() + return blogStr + htmlFooter() - timelineJson= \ - createBlogsTimeline(session,baseDir, \ - nickname,domain,port,httpPrefix, \ - noOfItems,False,False,pageNumber) + timelineJson = createBlogsTimeline(session, baseDir, + nickname, domain, port, + httpPrefix, + noOfItems, False, False, + pageNumber) if not timelineJson: - return blogStr+htmlFooter() + return blogStr + htmlFooter() - domainFull=domain + domainFull = domain if port: - if port!=80 and port!=443: - domainFull=domain+':'+str(port) + if port != 80 and port != 443: + domainFull = domain + ':' + str(port) # show previous and next buttons - if pageNumber!=None: - iconsDir=getIconsDir(baseDir) - navigateStr='' - if pageNumber>1: + if pageNumber is not None: + iconsDir = getIconsDir(baseDir) + navigateStr = '
' + if pageNumber > 1: # show previous button - navigateStr+= \ - ''+ \ - '' + \ + '\n' - if len(timelineJson['orderedItems'])>=noOfItems: + if len(timelineJson['orderedItems']) >= noOfItems: # show next button - navigateStr+= \ - ''+ \ - '' + \ + '\n' - navigateStr+='
' - blogStr+=navigateStr + navigateStr += '' + blogStr += navigateStr for item in timelineJson['orderedItems']: - if item['type']!='Create': + if item['type'] != 'Create': continue - blogStr+= \ - htmlBlogPostContent(authorized,baseDir,httpPrefix,translate, \ - nickname,domain,domainFull,item, \ - None,True) + blogStr += htmlBlogPostContent(authorized, baseDir, + httpPrefix, translate, + nickname, domain, + domainFull, item, + None, True) - if len(timelineJson['orderedItems'])>=noOfItems: - blogStr+=navigateStr + if len(timelineJson['orderedItems']) >= noOfItems: + blogStr += navigateStr # show rss link - blogStr+='' - blogStr+='' - blogStr+='' - blogStr+='
' + blogStr += '' + blogStr += '' + blogStr += '' + blogStr += '
' - return blogStr+htmlFooter() + return blogStr + htmlFooter() return None -def rssHeader(httpPrefix: str,nickname: str,domainFull: str,translate: {}) -> str: - rssStr="" - rssStr+="' - blogStr+= \ - ''+acct+'' - blogStr+='
' + blogStr += '' + blogStr += '' + acct + '' + blogStr += '
' - return blogStr+htmlFooter() + return blogStr + htmlFooter() return None -def htmlEditBlog(mediaInstance: bool,translate: {}, \ - baseDir: str,httpPrefix: str, \ - path: str, \ - pageNumber: int, \ - nickname: str,domain: str, \ + +def htmlEditBlog(mediaInstance: bool, translate: {}, + baseDir: str, httpPrefix: str, + path: str, + pageNumber: int, + nickname: str, domain: str, postUrl: str) -> str: """Edit a blog post after it was created """ - postFilename=locatePost(baseDir,nickname,domain,postUrl) + postFilename = locatePost(baseDir, nickname, domain, postUrl) if not postFilename: - print('Edit blog: Filename not found for '+postUrl) + print('Edit blog: Filename not found for ' + postUrl) return None - postJsonObject=loadJson(postFilename) + postJsonObject = loadJson(postFilename) if not postJsonObject: - print('Edit blog: json not loaded for '+postFilename) + print('Edit blog: json not loaded for ' + postFilename) return None - iconsDir=getIconsDir(baseDir) + iconsDir = getIconsDir(baseDir) - editBlogText= \ - ''+ \ - translate['Write your post text below.']+'
' + editBlogText = '' + \ + translate['Write your post text below.'] + '
' - if os.path.isfile(baseDir+'/accounts/newpost.txt'): - with open(baseDir+'/accounts/newpost.txt', 'r') as file: - editBlogText=''+file.read()+'
' + if os.path.isfile(baseDir + '/accounts/newpost.txt'): + with open(baseDir + '/accounts/newpost.txt', 'r') as file: + editBlogText = '' + file.read() + '
' - cssFilename=baseDir+'/epicyon-profile.css' - if os.path.isfile(baseDir+'/epicyon.css'): - cssFilename=baseDir+'/epicyon.css' + cssFilename = baseDir + '/epicyon-profile.css' + if os.path.isfile(baseDir + '/epicyon.css'): + cssFilename = baseDir + '/epicyon.css' with open(cssFilename, 'r') as cssFile: - editBlogCSS=cssFile.read() - if httpPrefix!='https': - editBlogCSS=editBlogCSS.replace('https://',httpPrefix+'://') + editBlogCSS = cssFile.read() + if httpPrefix != 'https': + editBlogCSS = editBlogCSS.replace('https://', httpPrefix+'://') if '?' in path: - path=path.split('?')[0] - pathBase=path + path = path.split('?')[0] + pathBase = path - editBlogImageSection ='' - dateAndLocation+='' - dateAndLocation+='' - dateAndLocation+='
' - dateAndLocation+='' + dateAndLocation += '' + dateAndLocation += '' + dateAndLocation += '
' + dateAndLocation += '