mirror of https://gitlab.com/bashrc2/epicyon
Blogs timeline
parent
9b48742ae3
commit
0bd778d553
102
daemon.py
102
daemon.py
|
@ -115,6 +115,7 @@ from webinterface import htmlRemoveSharedItem
|
|||
from webinterface import htmlInboxDMs
|
||||
from webinterface import htmlInboxReplies
|
||||
from webinterface import htmlInboxMedia
|
||||
from webinterface import htmlInboxBlogs
|
||||
from webinterface import htmlUnblockConfirm
|
||||
from webinterface import htmlPersonOptions
|
||||
from webinterface import htmlIndividualPost
|
||||
|
@ -186,6 +187,9 @@ maxPostsInFeed=12
|
|||
# reduced posts for media feed because it can take a while
|
||||
maxPostsInMediaFeed=6
|
||||
|
||||
# Blogs can be longer, so don't show many per page
|
||||
maxPostsInBlogsFeed=4
|
||||
|
||||
# number of follows/followers per page
|
||||
followsPerPage=12
|
||||
|
||||
|
@ -2894,6 +2898,84 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
# get the blogs for a given person
|
||||
if self.path.endswith('/tlblogs') or '/tlblogs?page=' in self.path:
|
||||
if '/users/' in self.path:
|
||||
if authorized:
|
||||
inboxBlogsFeed= \
|
||||
personBoxJson(self.server.recentPostsCache, \
|
||||
self.server.session, \
|
||||
self.server.baseDir, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
self.path, \
|
||||
self.server.httpPrefix, \
|
||||
maxPostsInBlogsFeed, 'tlblogs', \
|
||||
True,self.server.ocapAlways)
|
||||
if not inboxBlogsFeed:
|
||||
inboxBlogsFeed=[]
|
||||
if self._requestHTTP():
|
||||
nickname=self.path.replace('/users/','').replace('/tlblogs','')
|
||||
pageNumber=1
|
||||
if '?page=' in nickname:
|
||||
pageNumber=nickname.split('?page=')[1]
|
||||
nickname=nickname.split('?page=')[0]
|
||||
if pageNumber.isdigit():
|
||||
pageNumber=int(pageNumber)
|
||||
else:
|
||||
pageNumber=1
|
||||
if 'page=' not in self.path:
|
||||
# if no page was specified then show the first
|
||||
inboxBlogsFeed= \
|
||||
personBoxJson(self.server.recentPostsCache, \
|
||||
self.server.session, \
|
||||
self.server.baseDir, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
self.path+'?page=1', \
|
||||
self.server.httpPrefix, \
|
||||
maxPostsInBlogsFeed, 'tlblogs', \
|
||||
True,self.server.ocapAlways)
|
||||
msg=htmlInboxBlogs(self.server.defaultTimeline, \
|
||||
self.server.recentPostsCache, \
|
||||
self.server.maxRecentPosts, \
|
||||
self.server.translate, \
|
||||
pageNumber,maxPostsInBlogsFeed, \
|
||||
self.server.session, \
|
||||
self.server.baseDir, \
|
||||
self.server.cachedWebfingers, \
|
||||
self.server.personCache, \
|
||||
nickname, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
inboxBlogsFeed, \
|
||||
self.server.allowDeletion, \
|
||||
self.server.httpPrefix, \
|
||||
self.server.projectVersion).encode('utf-8')
|
||||
self._set_headers('text/html',len(msg),cookie)
|
||||
self._write(msg)
|
||||
else:
|
||||
# don't need authenticated fetch here because there is
|
||||
# already the authorization check
|
||||
msg=json.dumps(inboxBlogsFeed,ensure_ascii=False).encode('utf-8')
|
||||
self._set_headers('application/json',len(msg),None)
|
||||
self._write(msg)
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
else:
|
||||
if self.server.debug:
|
||||
nickname=self.path.replace('/users/','').replace('/tlblogs','')
|
||||
print('DEBUG: '+nickname+ \
|
||||
' was not authorized to access '+self.path)
|
||||
if self.path!='/tlblogs':
|
||||
# not the blogs inbox
|
||||
if self.server.debug:
|
||||
print('DEBUG: GET access to blogs is unauthorized')
|
||||
self.send_response(405)
|
||||
self.end_headers()
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
self._benchmarkGETtimings(GETstartTime,GETtimings,46)
|
||||
|
||||
# get the shared items timeline for a given person
|
||||
|
@ -4343,6 +4425,20 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.defaultTimeline='inbox'
|
||||
setConfigParam(self.server.baseDir,"mediaInstance", \
|
||||
self.server.mediaInstance)
|
||||
if fields.get('blogsInstance'):
|
||||
self.server.blogsInstance=False
|
||||
self.server.defaultTimeline='inbox'
|
||||
if fields['blogsInstance']=='on':
|
||||
self.server.blogsInstance=True
|
||||
self.server.defaultTimeline='tlblogs'
|
||||
setConfigParam(self.server.baseDir,"blogsInstance", \
|
||||
self.server.blogsInstance)
|
||||
else:
|
||||
if self.server.blogsInstance:
|
||||
self.server.blogsInstance=False
|
||||
self.server.defaultTimeline='inbox'
|
||||
setConfigParam(self.server.baseDir,"blogsInstance", \
|
||||
self.server.blogsInstance)
|
||||
# only receive DMs from accounts you follow
|
||||
followDMsFilename= \
|
||||
self.server.baseDir+'/accounts/'+ \
|
||||
|
@ -5574,7 +5670,8 @@ def loadTokens(baseDir: str,tokensDict: {},tokensLookup: {}) -> None:
|
|||
tokensDict[nickname]=token
|
||||
tokensLookup[token]=nickname
|
||||
|
||||
def runDaemon(mediaInstance: bool,maxRecentPosts: int, \
|
||||
def runDaemon(blogsInstance: bool,mediaInstance: bool, \
|
||||
maxRecentPosts: int, \
|
||||
enableSharedInbox: bool,registration: bool, \
|
||||
language: str,projectVersion: str, \
|
||||
instanceId: str,clientToServer: bool, \
|
||||
|
@ -5615,9 +5712,12 @@ def runDaemon(mediaInstance: bool,maxRecentPosts: int, \
|
|||
|
||||
httpd.useBlurHash=useBlurHash
|
||||
httpd.mediaInstance=mediaInstance
|
||||
httpd.blogsInstance=blogsInstance
|
||||
httpd.defaultTimeline='inbox'
|
||||
if mediaInstance:
|
||||
httpd.defaultTimeline='tlmedia'
|
||||
if blogsInstance:
|
||||
httpd.defaultTimeline='tlblogs'
|
||||
|
||||
# load translations dictionary
|
||||
httpd.translate={}
|
||||
|
|
11
epicyon.py
11
epicyon.py
|
@ -151,6 +151,9 @@ parser.add_argument('-f','--federate', nargs='+',dest='federationList', \
|
|||
parser.add_argument("--mediainstance", type=str2bool, nargs='?', \
|
||||
const=True, default=False, \
|
||||
help="Media Instance - favor media over text")
|
||||
parser.add_argument("--blogsinstance", type=str2bool, nargs='?', \
|
||||
const=True, default=False, \
|
||||
help="Blogs Instance - favor blogs over microblogging")
|
||||
parser.add_argument("--debug", type=str2bool, nargs='?', \
|
||||
const=True, default=False, \
|
||||
help="Show debug messages")
|
||||
|
@ -386,6 +389,11 @@ if not args.mediainstance:
|
|||
mediaInstance=getConfigParam(baseDir,'mediaInstance')
|
||||
if mediaInstance!=None:
|
||||
args.mediainstance=mediaInstance
|
||||
|
||||
if not args.blogsinstance:
|
||||
blogsInstance=getConfigParam(baseDir,'blogsInstance')
|
||||
if blogsInstance!=None:
|
||||
args.blogsinstance=blogsInstance
|
||||
|
||||
# set the instance title in config.json
|
||||
title=getConfigParam(baseDir,'instanceTitle')
|
||||
|
@ -1504,7 +1512,8 @@ if not registration:
|
|||
if setTheme(baseDir,themeName):
|
||||
print('Theme set to '+themeName)
|
||||
|
||||
runDaemon(args.mediainstance,args.maxRecentPosts, \
|
||||
runDaemon(args.blogsinstance,args.mediainstance, \
|
||||
args.maxRecentPosts, \
|
||||
not args.nosharedinbox, \
|
||||
registration,args.language,__version__, \
|
||||
instanceId,args.client,baseDir, \
|
||||
|
|
20
inbox.py
20
inbox.py
|
@ -62,6 +62,23 @@ from webinterface import getIconsDir
|
|||
from question import questionUpdateVotes
|
||||
from media import replaceYouTube
|
||||
|
||||
def isBlogPost(postJsonObject: {}) -> bool:
|
||||
"""Is the given post a blog post?
|
||||
"""
|
||||
if postJsonObject['type']!='Create':
|
||||
return False
|
||||
if not postJsonObject.get('object'):
|
||||
return False
|
||||
if not isinstance(postJsonObject['object'], dict):
|
||||
return False
|
||||
if not postJsonObject['object'].get('type'):
|
||||
return False
|
||||
if not postJsonObject['object'].get('content'):
|
||||
return False
|
||||
if postJsonObject['object']['type']!='Article':
|
||||
return False
|
||||
return True
|
||||
|
||||
def storeHashTags(baseDir: str,nickname: str,postJsonObject: {}) -> None:
|
||||
"""Extracts hashtags from an incoming post and updates the
|
||||
relevant tags files.
|
||||
|
@ -1924,6 +1941,9 @@ def inboxAfterCapabilities(recentPostsCache: {},maxRecentPosts: int, \
|
|||
if isImageMedia(session,baseDir,httpPrefix,nickname,domain,postJsonObject):
|
||||
# media index will be updated
|
||||
updateIndexList.append('tlmedia')
|
||||
if isBlogPost(postJsonObject):
|
||||
# blogs index will be updated
|
||||
updateIndexList.append('tlblogs')
|
||||
|
||||
# get the avatar for a reply/announce
|
||||
obtainAvatarForReplyPost(session,baseDir,httpPrefix,domain,personCache,postJsonObject,debug)
|
||||
|
|
|
@ -21,6 +21,7 @@ from webfinger import storeWebfingerEndpoint
|
|||
from posts import createDMTimeline
|
||||
from posts import createRepliesTimeline
|
||||
from posts import createMediaTimeline
|
||||
from posts import createBlogsTimeline
|
||||
from posts import createBookmarksTimeline
|
||||
from posts import createInbox
|
||||
from posts import createOutbox
|
||||
|
@ -470,6 +471,7 @@ def personBoxJson(recentPostsCache: {}, \
|
|||
"""
|
||||
if boxname!='inbox' and boxname!='dm' and \
|
||||
boxname!='tlreplies' and boxname!='tlmedia' and \
|
||||
boxname!='tlblogs' and \
|
||||
boxname!='outbox' and boxname!='moderation' and \
|
||||
boxname!='tlbookmarks':
|
||||
return None
|
||||
|
@ -521,6 +523,9 @@ def personBoxJson(recentPostsCache: {}, \
|
|||
elif boxname=='tlmedia':
|
||||
return createMediaTimeline(session,baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||
elif boxname=='tlblogs':
|
||||
return createBlogsTimeline(session,baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||
elif boxname=='outbox':
|
||||
return createOutbox(session,baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,authorized,pageNumber)
|
||||
|
|
20
posts.py
20
posts.py
|
@ -1956,6 +1956,13 @@ def createInbox(recentPostsCache: {}, \
|
|||
session,baseDir,'inbox',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createBlogsTimeline(recentPostsCache: {}, \
|
||||
session,baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
return createBoxIndexed(recentPostsCache, \
|
||||
session,baseDir,'tlblogs',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createBookmarksTimeline(session,baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
return createBoxIndexed({},session,baseDir,'tlbookmarks',nickname,domain,port,httpPrefix, \
|
||||
|
@ -2240,6 +2247,11 @@ def addPostStringToTimeline(postStr: str,boxname: str, \
|
|||
elif boxname=='tlreplies':
|
||||
if boxActor not in postStr:
|
||||
return False
|
||||
elif boxname=='tlblogs':
|
||||
if '"Create"' not in postStr:
|
||||
return False
|
||||
if '"Article"' not in postStr:
|
||||
return False
|
||||
elif boxname=='tlmedia':
|
||||
if '"Create"' in postStr:
|
||||
if 'mediaType' not in postStr or 'image/' not in postStr:
|
||||
|
@ -2270,11 +2282,13 @@ def createBoxIndexed(recentPostsCache: {}, \
|
|||
|
||||
if boxname!='inbox' and boxname!='dm' and \
|
||||
boxname!='tlreplies' and boxname!='tlmedia' and \
|
||||
boxname!='tlblogs' and \
|
||||
boxname!='outbox' and boxname!='tlbookmarks':
|
||||
return None
|
||||
|
||||
if boxname!='dm' and boxname!='tlreplies' and \
|
||||
boxname!='tlmedia' and boxname!='tlbookmarks':
|
||||
boxname!='tlmedia' and boxname!='tlblogs' and \
|
||||
boxname!='tlbookmarks':
|
||||
boxDir = createPersonDir(nickname,domain,baseDir,boxname)
|
||||
else:
|
||||
# extract DMs or replies or media from the inbox
|
||||
|
@ -2284,7 +2298,7 @@ def createBoxIndexed(recentPostsCache: {}, \
|
|||
|
||||
sharedBoxDir=None
|
||||
if boxname=='inbox' or boxname=='tlreplies' or \
|
||||
boxname=='tlmedia':
|
||||
boxname=='tlmedia' or boxname=='tlblogs':
|
||||
sharedBoxDir = createPersonDir('inbox',domain,baseDir,boxname)
|
||||
|
||||
# bookmarks timeline is like the inbox but has its own separate index
|
||||
|
@ -2297,6 +2311,8 @@ def createBoxIndexed(recentPostsCache: {}, \
|
|||
indexBoxName='tlreplies'
|
||||
elif boxname=='tlmedia':
|
||||
indexBoxName='tlmedia'
|
||||
elif boxname=='tlblogs':
|
||||
indexBoxName='tlblogs'
|
||||
|
||||
if port:
|
||||
if port!=80 and port!=443:
|
||||
|
|
6
tests.py
6
tests.py
|
@ -236,7 +236,7 @@ def createServerAlice(path: str,domain: str,port: int,bobAddress: str,federation
|
|||
maxMentions=10
|
||||
maxEmoji=10
|
||||
print('Server running: Alice')
|
||||
runDaemon(False,5,True,True,'en',__version__, \
|
||||
runDaemon(False,False,5,True,True,'en',__version__, \
|
||||
"instanceId",False,path,domain,port,port, \
|
||||
httpPrefix,federationList,maxMentions,maxEmoji,False, \
|
||||
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
|
||||
|
@ -292,7 +292,7 @@ def createServerBob(path: str,domain: str,port: int,aliceAddress: str,federation
|
|||
maxMentions=10
|
||||
maxEmoji=10
|
||||
print('Server running: Bob')
|
||||
runDaemon(False,5,True,True,'en',__version__, \
|
||||
runDaemon(False,False,5,True,True,'en',__version__, \
|
||||
"instanceId",False,path,domain,port,port, \
|
||||
httpPrefix,federationList,maxMentions,maxEmoji,False, \
|
||||
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
|
||||
|
@ -328,7 +328,7 @@ def createServerEve(path: str,domain: str,port: int,federationList: [], \
|
|||
maxMentions=10
|
||||
maxEmoji=10
|
||||
print('Server running: Eve')
|
||||
runDaemon(False,5,True,True,'en',__version__, \
|
||||
runDaemon(False,False,5,True,True,'en',__version__, \
|
||||
"instanceId",False,path,domain,port,port, \
|
||||
httpPrefix,federationList,maxMentions,maxEmoji,False, \
|
||||
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
|
||||
|
|
2
utils.py
2
utils.py
|
@ -429,7 +429,7 @@ def validNickname(domain: str,nickname: str) -> bool:
|
|||
return False
|
||||
if nickname==domain:
|
||||
return False
|
||||
reservedNames=['inbox','dm','outbox','following','public','followers','profile','channel','capabilities','calendar','tlreplies','tlmedia','moderation','activity','undo','reply','replies','question','like','likes','users','statuses','updates','repeat','announce','shares']
|
||||
reservedNames=['inbox','dm','outbox','following','public','followers','profile','channel','capabilities','calendar','tlreplies','tlmedia','tlblogs','moderation','activity','undo','reply','replies','question','like','likes','users','statuses','updates','repeat','announce','shares']
|
||||
if nickname in reservedNames:
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -3395,6 +3395,7 @@ def htmlTimeline(defaultTimeline: str, \
|
|||
moderator=isModerator(baseDir,nickname)
|
||||
|
||||
inboxButton='button'
|
||||
blogsButton='button'
|
||||
dmButton='button'
|
||||
if newDM:
|
||||
dmButton='buttonhighlighted'
|
||||
|
@ -3412,6 +3413,8 @@ def htmlTimeline(defaultTimeline: str, \
|
|||
moderationButton='buttonhighlighted'
|
||||
if boxName=='inbox':
|
||||
inboxButton='buttonselected'
|
||||
elif boxName=='tlblogs':
|
||||
blogsButton='buttonselected'
|
||||
elif boxName=='dm':
|
||||
dmButton='buttonselected'
|
||||
if newDM:
|
||||
|
@ -3511,16 +3514,24 @@ def htmlTimeline(defaultTimeline: str, \
|
|||
tlStr+='<div class="timeline-banner">'
|
||||
tlStr+='</div></a>'
|
||||
tlStr+='<div class="container">\n'
|
||||
if defaultTimeline!='tlmedia':
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/inbox"><button class="'+ \
|
||||
inboxButton+'"><span>'+ \
|
||||
translate['Inbox']+'</span></button></a>'
|
||||
else:
|
||||
|
||||
# first button
|
||||
if defaultTimeline=='tlmedia':
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/tlmedia"><button class="'+ \
|
||||
mediaButton+'"><span>'+translate['Media']+ \
|
||||
'</span></button></a>'
|
||||
elif defaultTimeline=='tlblogs':
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/tlblogs"><button class="'+ \
|
||||
blogsButton+'"><span>'+translate['Blogs']+ \
|
||||
'</span></button></a>'
|
||||
else:
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/inbox"><button class="'+ \
|
||||
inboxButton+'"><span>'+ \
|
||||
translate['Inbox']+'</span></button></a>'
|
||||
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/dm"><button class="'+dmButton+ \
|
||||
'"><span>'+translate['DM']+'</span></button></a>'
|
||||
|
@ -3528,6 +3539,8 @@ def htmlTimeline(defaultTimeline: str, \
|
|||
' <a href="'+actor+'/tlreplies"><button class="'+ \
|
||||
repliesButton+'"><span>'+translate['Replies']+ \
|
||||
'</span></button></a>'
|
||||
|
||||
# typically the media button
|
||||
if defaultTimeline!='tlmedia':
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/tlmedia"><button class="'+ \
|
||||
|
@ -3538,6 +3551,19 @@ def htmlTimeline(defaultTimeline: str, \
|
|||
' <a href="'+actor+'/inbox"><button class="'+ \
|
||||
inboxButton+'"><span>'+translate['Inbox']+ \
|
||||
'</span></button></a>'
|
||||
|
||||
# typically the blogs button
|
||||
if defaultTimeline!='tlblogs':
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/tlblogs"><button class="'+ \
|
||||
blogsButton+'"><span>'+translate['Blogs']+ \
|
||||
'</span></button></a>'
|
||||
else:
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/inbox"><button class="'+ \
|
||||
inboxButton+'"><span>'+translate['Inbox']+ \
|
||||
'</span></button></a>'
|
||||
|
||||
tlStr+= \
|
||||
' <a href="'+actor+'/outbox"><button class="'+ \
|
||||
sentButton+'"><span>'+translate['Outbox']+ \
|
||||
|
@ -3792,6 +3818,21 @@ def htmlInboxMedia(defaultTimeline: str, \
|
|||
nickname,domain,port,inboxJson,'tlmedia',allowDeletion, \
|
||||
httpPrefix,projectVersion,False)
|
||||
|
||||
def htmlInboxBlogs(defaultTimeline: str, \
|
||||
recentPostsCache: {},maxRecentPosts: int, \
|
||||
translate: {},pageNumber: int,itemsPerPage: int, \
|
||||
session,baseDir: str,wfRequest: {},personCache: {}, \
|
||||
nickname: str,domain: str,port: int,inboxJson: {}, \
|
||||
allowDeletion: bool, \
|
||||
httpPrefix: str,projectVersion: str) -> str:
|
||||
"""Show the blogs timeline as html
|
||||
"""
|
||||
return htmlTimeline(defaultTimeline,recentPostsCache,maxRecentPosts, \
|
||||
translate,pageNumber, \
|
||||
itemsPerPage,session,baseDir,wfRequest,personCache, \
|
||||
nickname,domain,port,inboxJson,'tlblogs',allowDeletion, \
|
||||
httpPrefix,projectVersion,False)
|
||||
|
||||
def htmlModeration(defaultTimeline: str, \
|
||||
recentPostsCache: {},maxRecentPosts: int, \
|
||||
translate: {},pageNumber: int,itemsPerPage: int, \
|
||||
|
|
Loading…
Reference in New Issue