Proper chronological ordering of posts within boxes

master
Bob Mottram 2019-07-14 10:17:50 +01:00
parent 6eedba4a11
commit b2ecda1b2a
3 changed files with 38 additions and 13 deletions

View File

@ -30,6 +30,7 @@ This project is currently *pre alpha* and not recommended for any real world use
* Data minimization principle. Configurable post expiry time. * Data minimization principle. Configurable post expiry time.
* Likes and repeats only visible to authorized viewers * Likes and repeats only visible to authorized viewers
* ReplyGuy mitigation: maxmimum replies per post or posts per day * ReplyGuy mitigation: maxmimum replies per post or posts per day
* Ability to delete or hide specific conversation threads
* Commandline interface. If there's a GUI it should be a separate project. * Commandline interface. If there's a GUI it should be a separate project.
* Designed for intermittent connectivity. Assume network disruptions. * Designed for intermittent connectivity. Assume network disruptions.
* Suitable for single board computers. * Suitable for single board computers.

View File

@ -963,6 +963,9 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [], \
# copy any posts addressed to followers into the shared inbox # copy any posts addressed to followers into the shared inbox
# this avoid copying file multiple times to potentially many # this avoid copying file multiple times to potentially many
# individual inboxes # individual inboxes
# TODO This obviously bypasses object capabilities and so
# any checking will need to be handled at the time when inbox
# GET happens on individual accounts
if len(recipientsDictFollowers)>0: if len(recipientsDictFollowers)>0:
copyfile(queueFilename, \ copyfile(queueFilename, \
queueJson['destination'].replace(inboxHandle,inboxHandle)) queueJson['destination'].replace(inboxHandle,inboxHandle))

View File

@ -17,6 +17,7 @@ import threading
import sys import sys
import trace import trace
import time import time
from collections import OrderedDict
from threads import threadWithTrace from threads import threadWithTrace
from cache import storePersonInCache from cache import storePersonInCache
from cache import getPersonFromCache from cache import getPersonFromCache
@ -778,10 +779,19 @@ def createOutbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: st
return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \ return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \
itemsPerPage,headerOnly,authorized,pageNumber) itemsPerPage,headerOnly,authorized,pageNumber)
def getStatusNumberFromPostFilename(filename) -> int:
"""Gets the status number from a post filename
eg. https:##testdomain.com:8085#users#testuser567#statuses#1562958506952068.json
returns 156295850695206
"""
if '#statuses#' not in filename:
return None
return int(filename.split('#')[-1].replace('.json',''))
def createBoxBase(baseDir: str,boxname: str, \ def createBoxBase(baseDir: str,boxname: str, \
nickname: str,domain: str,port: int,httpPrefix: str, \ nickname: str,domain: str,port: int,httpPrefix: str, \
itemsPerPage: int,headerOnly: bool,authorized :bool,pageNumber=None) -> {}: itemsPerPage: int,headerOnly: bool,authorized :bool,pageNumber=None) -> {}:
"""Constructs the box feed """Constructs the box feed for a person with the given nickname
""" """
if boxname!='inbox' and boxname!='outbox': if boxname!='inbox' and boxname!='outbox':
return None return None
@ -816,27 +826,38 @@ def createBoxBase(baseDir: str,boxname: str, \
postsOnPageCtr=0 postsOnPageCtr=0
# post filenames sorted in descending order # post filenames sorted in descending order
postsInBox=[] postsInBoxDict={}
postsInPersonInbox=sorted(os.listdir(boxDir), reverse=True) postsCtr=0
postsInPersonInbox=os.listdir(boxDir)
for postFilename in postsInPersonInbox: for postFilename in postsInPersonInbox:
postsInBox.append(os.path.join(boxDir, postFilename)) # extract the status number
statusNumber=getStatusNumberFromPostFilename(postFilename)
if statusNumber:
postsInBoxDict[statusNumber]=os.path.join(boxDir, postFilename)
postsCtr+=1
# combine the inbox for the account with the shared inbox # combine the inbox for the account with the shared inbox
if sharedBoxDir: if sharedBoxDir:
postsInSharedInbox=sorted(os.listdir(sharedBoxDir), reverse=True) postsInSharedInbox=os.listdir(sharedBoxDir)
for postFilename in postsInSharedInbox: for postFilename in postsInSharedInbox:
postsInBox.append(os.path.join(sharedBoxDir, postFilename)) statusNumber=getStatusNumberFromPostFilename(postFilename)
if statusNumber:
postsInBoxDict[statusNumber]=os.path.join(sharedBoxDir, postFilename)
postsCtr+=1
# sort the list in descending order of date
postsInBox=OrderedDict(sorted(postsInBoxDict.items(),reverse=True))
# number of posts in box # number of posts in box
boxHeader['totalItems']=len(postsInBox) boxHeader['totalItems']=postsCtr
prevPostFilename=None prevPostFilename=None
if not pageNumber: if not pageNumber:
pageNumber=1 pageNumber=1
# Generate first and last entries within header # Generate first and last entries within header
if len(postsInBox)>0: if postsCtr>0:
lastPage=int(len(postsInBox)/itemsPerPage) lastPage=int(postsCtr/itemsPerPage)
if lastPage<1: if lastPage<1:
lastPage=1 lastPage=1
boxHeader['last']= \ boxHeader['last']= \
@ -845,7 +866,7 @@ def createBoxBase(baseDir: str,boxname: str, \
# Insert posts # Insert posts
currPage=1 currPage=1
postsCtr=0 postsCtr=0
for postFilename in postsInBox: for statusNumber,postFilename in postsInBox.items():
# Are we at the starting page yet? # Are we at the starting page yet?
if prevPostFilename and currPage==pageNumber and postsCtr==0: if prevPostFilename and currPage==pageNumber and postsCtr==0:
# update the prev entry for the last message id # update the prev entry for the last message id