forked from indymedia/epicyon
Functions for image attachments
parent
050ce03ad0
commit
83b172d046
|
@ -206,7 +206,7 @@ Even if Eve has an account on Alice's instance this won't help her very much unl
|
|||
## Install
|
||||
|
||||
``` bash
|
||||
sudo pacman -S tor python-pip python-pysocks python-pycryptodome python-beautifulsoup4 imagemagick
|
||||
sudo pacman -S tor python-pip python-pysocks python-pycryptodome python-beautifulsoup4 imagemagick python-pillow python-numpy
|
||||
sudo pip install commentjson
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
"""
|
||||
Copyright (c) 2019 Lorenz Diener
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
* You and any organization you work for may not promote white supremacy, hate
|
||||
speech and homo- or transphobia - this license is void if you do.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
https://github.com/halcy/blurhash-python
|
||||
|
||||
Pure python blurhash decoder with no additional dependencies, for
|
||||
both de- and encoding.
|
||||
|
||||
Very close port of the original Swift implementation by Dag Ågren.
|
||||
"""
|
||||
|
||||
import math
|
||||
|
||||
# Alphabet for base 83
|
||||
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"
|
||||
alphabet_values = dict(zip(alphabet, range(len(alphabet))))
|
||||
|
||||
def base83_decode(base83_str):
|
||||
"""
|
||||
Decodes a base83 string, as used in blurhash, to an integer.
|
||||
"""
|
||||
value = 0
|
||||
for base83_char in base83_str:
|
||||
value = value * 83 + alphabet_values[base83_char]
|
||||
return value
|
||||
|
||||
def base83_encode(value, length):
|
||||
"""
|
||||
Decodes an integer to a base83 string, as used in blurhash.
|
||||
|
||||
Length is how long the resulting string should be. Will complain
|
||||
if the specified length is too short.
|
||||
"""
|
||||
if int(value) // (83 ** (length)) != 0:
|
||||
raise ValueError("Specified length is too short to encode given value.")
|
||||
|
||||
result = ""
|
||||
for i in range(1, length + 1):
|
||||
digit = int(value) // (83 ** (length - i)) % 83
|
||||
result += alphabet[int(digit)]
|
||||
return result
|
||||
|
||||
def srgb_to_linear(value):
|
||||
"""
|
||||
srgb 0-255 integer to linear 0.0-1.0 floating point conversion.
|
||||
"""
|
||||
value = float(value) / 255.0
|
||||
if value <= 0.04045:
|
||||
return value / 12.92
|
||||
return math.pow((value + 0.055) / 1.055, 2.4)
|
||||
|
||||
def sign_pow(value, exp):
|
||||
"""
|
||||
Sign-preserving exponentiation.
|
||||
"""
|
||||
return math.copysign(math.pow(abs(value), exp), value)
|
||||
|
||||
def linear_to_srgb(value):
|
||||
"""
|
||||
linear 0.0-1.0 floating point to srgb 0-255 integer conversion.
|
||||
"""
|
||||
value = max(0.0, min(1.0, value))
|
||||
if value <= 0.0031308:
|
||||
return int(value * 12.92 * 255 + 0.5)
|
||||
return int((1.055 * math.pow(value, 1 / 2.4) - 0.055) * 255 + 0.5)
|
||||
|
||||
def blurhash_components(blurhash):
|
||||
"""
|
||||
Decodes and returns the number of x and y components in the given blurhash.
|
||||
"""
|
||||
if len(blurhash) < 6:
|
||||
raise ValueError("BlurHash must be at least 6 characters long.")
|
||||
|
||||
# Decode metadata
|
||||
size_info = base83_decode(blurhash[0])
|
||||
size_y = int(size_info / 9) + 1
|
||||
size_x = (size_info % 9) + 1
|
||||
|
||||
return size_x, size_y
|
||||
|
||||
def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
|
||||
"""
|
||||
Decodes the given blurhash to an image of the specified size.
|
||||
|
||||
Returns the resulting image a list of lists of 3-value sRGB 8 bit integer
|
||||
lists. Set linear to True if you would prefer to get linear floating point
|
||||
RGB back.
|
||||
|
||||
The punch parameter can be used to de- or increase the contrast of the
|
||||
resulting image.
|
||||
|
||||
As per the original implementation it is suggested to only decode
|
||||
to a relatively small size and then scale the result up, as it
|
||||
basically looks the same anyways.
|
||||
"""
|
||||
if len(blurhash) < 6:
|
||||
raise ValueError("BlurHash must be at least 6 characters long.")
|
||||
|
||||
# Decode metadata
|
||||
size_info = base83_decode(blurhash[0])
|
||||
size_y = int(size_info / 9) + 1
|
||||
size_x = (size_info % 9) + 1
|
||||
|
||||
quant_max_value = base83_decode(blurhash[1])
|
||||
real_max_value = (float(quant_max_value + 1) / 166.0) * punch
|
||||
|
||||
# Make sure we at least have the right number of characters
|
||||
if len(blurhash) != 4 + 2 * size_x * size_y:
|
||||
raise ValueError("Invalid BlurHash length.")
|
||||
|
||||
# Decode DC component
|
||||
dc_value = base83_decode(blurhash[2:6])
|
||||
colours = [(
|
||||
srgb_to_linear(dc_value >> 16),
|
||||
srgb_to_linear((dc_value >> 8) & 255),
|
||||
srgb_to_linear(dc_value & 255)
|
||||
)]
|
||||
|
||||
# Decode AC components
|
||||
for component in range(1, size_x * size_y):
|
||||
ac_value = base83_decode(blurhash[4+component*2:4+(component+1)*2])
|
||||
colours.append((
|
||||
sign_pow((float(int(ac_value / (19 * 19))) - 9.0) / 9.0, 2.0) * real_max_value,
|
||||
sign_pow((float(int(ac_value / 19) % 19) - 9.0) / 9.0, 2.0) * real_max_value,
|
||||
sign_pow((float(ac_value % 19) - 9.0) / 9.0, 2.0) * real_max_value
|
||||
))
|
||||
|
||||
# Return image RGB values, as a list of lists of lists,
|
||||
# consumable by something like numpy or PIL.
|
||||
pixels = []
|
||||
for y in range(height):
|
||||
pixel_row = []
|
||||
for x in range(width):
|
||||
pixel = [0.0, 0.0, 0.0]
|
||||
|
||||
for j in range(size_y):
|
||||
for i in range(size_x):
|
||||
basis = math.cos(math.pi * float(x) * float(i) / float(width)) * \
|
||||
math.cos(math.pi * float(y) * float(j) / float(height))
|
||||
colour = colours[i + j * size_x]
|
||||
pixel[0] += colour[0] * basis
|
||||
pixel[1] += colour[1] * basis
|
||||
pixel[2] += colour[2] * basis
|
||||
if linear == False:
|
||||
pixel_row.append([
|
||||
linear_to_srgb(pixel[0]),
|
||||
linear_to_srgb(pixel[1]),
|
||||
linear_to_srgb(pixel[2]),
|
||||
])
|
||||
else:
|
||||
pixel_row.append(pixel)
|
||||
pixels.append(pixel_row)
|
||||
return pixels
|
||||
|
||||
def blurhash_encode(image, components_x = 4, components_y = 4, linear = False):
|
||||
"""
|
||||
Calculates the blurhash for an image using the given x and y component counts.
|
||||
|
||||
Image should be a 3-dimensional array, with the first dimension being y, the second
|
||||
being x, and the third being the three rgb components that are assumed to be 0-255
|
||||
srgb integers (incidentally, this is the format you will get from a PIL RGB image).
|
||||
|
||||
You can also pass in already linear data - to do this, set linear to True. This is
|
||||
useful if you want to encode a version of your image resized to a smaller size (which
|
||||
you should ideally do in linear colour).
|
||||
"""
|
||||
if components_x < 1 or components_x > 9 or components_y < 1 or components_y > 9:
|
||||
raise ValueError("x and y component counts must be between 1 and 9 inclusive.")
|
||||
height = float(len(image))
|
||||
width = float(len(image[0]))
|
||||
|
||||
# Convert to linear if neeeded
|
||||
image_linear = []
|
||||
if linear == False:
|
||||
for y in range(int(height)):
|
||||
image_linear_line = []
|
||||
for x in range(int(width)):
|
||||
image_linear_line.append([
|
||||
srgb_to_linear(image[y][x][0]),
|
||||
srgb_to_linear(image[y][x][1]),
|
||||
srgb_to_linear(image[y][x][2])
|
||||
])
|
||||
image_linear.append(image_linear_line)
|
||||
else:
|
||||
image_linear = image
|
||||
|
||||
# Calculate components
|
||||
components = []
|
||||
max_ac_component = 0.0
|
||||
for j in range(components_y):
|
||||
for i in range(components_x):
|
||||
norm_factor = 1.0 if (i == 0 and j == 0) else 2.0
|
||||
component = [0.0, 0.0, 0.0]
|
||||
for y in range(int(height)):
|
||||
for x in range(int(width)):
|
||||
basis = norm_factor * math.cos(math.pi * float(i) * float(x) / width) * \
|
||||
math.cos(math.pi * float(j) * float(y) / height)
|
||||
component[0] += basis * image_linear[y][x][0]
|
||||
component[1] += basis * image_linear[y][x][1]
|
||||
component[2] += basis * image_linear[y][x][2]
|
||||
|
||||
component[0] /= (width * height)
|
||||
component[1] /= (width * height)
|
||||
component[2] /= (width * height)
|
||||
components.append(component)
|
||||
|
||||
if not (i == 0 and j == 0):
|
||||
max_ac_component = max(max_ac_component, abs(component[0]), abs(component[1]), abs(component[2]))
|
||||
|
||||
# Encode components
|
||||
dc_value = (linear_to_srgb(components[0][0]) << 16) + \
|
||||
(linear_to_srgb(components[0][1]) << 8) + \
|
||||
linear_to_srgb(components[0][2])
|
||||
|
||||
quant_max_ac_component = int(max(0, min(82, math.floor(max_ac_component * 166 - 0.5))))
|
||||
ac_component_norm_factor = float(quant_max_ac_component + 1) / 166.0
|
||||
|
||||
ac_values = []
|
||||
for r, g, b in components[1:]:
|
||||
ac_values.append(
|
||||
int(max(0.0, min(18.0, math.floor(sign_pow(r / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 * 19 + \
|
||||
int(max(0.0, min(18.0, math.floor(sign_pow(g / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 + \
|
||||
int(max(0.0, min(18.0, math.floor(sign_pow(b / ac_component_norm_factor, 0.5) * 9.0 + 9.5))))
|
||||
)
|
||||
|
||||
# Build final blurhash
|
||||
blurhash = ""
|
||||
blurhash += base83_encode((components_x - 1) + (components_y - 1) * 9, 1)
|
||||
blurhash += base83_encode(quant_max_ac_component, 1)
|
||||
blurhash += base83_encode(dc_value, 4)
|
||||
for ac_value in ac_values:
|
||||
blurhash += base83_encode(ac_value, 2)
|
||||
|
||||
return blurhash
|
18
epicyon.py
18
epicyon.py
|
@ -6,6 +6,7 @@ __maintainer__ = "Bob Mottram"
|
|||
__email__ = "bob@freedombone.net"
|
||||
__status__ = "Production"
|
||||
|
||||
|
||||
from person import createPerson
|
||||
from person import createSharedInbox
|
||||
from person import createCapabilitiesInbox
|
||||
|
@ -442,6 +443,7 @@ if not os.path.isdir(baseDir+'/accounts/'+nickname+'@'+domain):
|
|||
createPerson(baseDir,nickname,domain,port,httpPrefix,True,adminPassword)
|
||||
|
||||
if args.testdata:
|
||||
useBlurhash=False
|
||||
nickname='testuser567'
|
||||
print('Generating some test data for user: '+nickname)
|
||||
createPerson(baseDir,nickname,domain,port,httpPrefix,True,'likewhateveryouwantscoob')
|
||||
|
@ -449,14 +451,14 @@ if args.testdata:
|
|||
deleteAllPosts(baseDir,nickname,domain,'outbox')
|
||||
followPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
||||
followerOfPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"like, this is totally just a test, man",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Zoiks!!!",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Hey scoob we need like a hundred more milkshakes",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Getting kinda spooky around here",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"And they would have gotten away with it too if it wasn't for those pesky hackers",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"man, these centralized sites are, like, the worst!",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"another mystery solved hey",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"let's go bowling",False,True,False)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"like, this is totally just a test, man",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Zoiks!!!",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Hey scoob we need like a hundred more milkshakes",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Getting kinda spooky around here",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"And they would have gotten away with it too if it wasn't for those pesky hackers",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"man, these centralized sites are, like, the worst!",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"another mystery solved hey",False,True,False,None,None,useBlurhash)
|
||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"let's go bowling",False,True,False,None,None,useBlurhash)
|
||||
|
||||
runDaemon(baseDir,domain,port,httpPrefix,federationList, \
|
||||
args.noreply,args.nolike,args.nopics, \
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
__filename__ = "media.py"
|
||||
__author__ = "Bob Mottram"
|
||||
__license__ = "AGPL3+"
|
||||
__version__ = "0.0.1"
|
||||
__maintainer__ = "Bob Mottram"
|
||||
__email__ = "bob@freedombone.net"
|
||||
__status__ = "Production"
|
||||
|
||||
from blurhash import blurhash_encode as blurencode
|
||||
from PIL import Image
|
||||
import numpy
|
||||
import os
|
||||
import json
|
||||
import commentjson
|
||||
import datetime
|
||||
from auth import createPassword
|
||||
from shutil import copyfile
|
||||
|
||||
def getImageHash(imageFilename: str):
|
||||
return blurencode(numpy.array(Image.open("img/logo.png").convert("RGB")))
|
||||
|
||||
def isImage(imageFilename: str) -> bool:
|
||||
if imageFilename.endswith('.png') or \
|
||||
imageFilename.endswith('.jpg') or \
|
||||
imageFilename.endswith('.gif'):
|
||||
return True
|
||||
return False
|
||||
|
||||
def createMediaPath(baseDir: str,weeksSinceEpoch: int) -> None:
|
||||
if not os.path.isdir(baseDir+'/media'):
|
||||
os.mkdir(baseDir+'/media')
|
||||
if not os.path.isdir(baseDir+'/media/'+str(weeksSinceEpoch)):
|
||||
os.mkdir(baseDir+'/media/'+str(weeksSinceEpoch))
|
||||
|
||||
def attachImage(baseDir: str,httpPrefix: str,domain: str,port: int, \
|
||||
postJson: {},imageFilename: str,description: str, \
|
||||
useBlurhash: bool) -> {}:
|
||||
"""Attaches an image to a json object post
|
||||
The description can be None
|
||||
Blurhash is optional, since low power systems may take a long time to calculate it
|
||||
"""
|
||||
if not isImage(imageFilename):
|
||||
return postJson
|
||||
|
||||
mediaType='image/png'
|
||||
fileExtension='png'
|
||||
if imageFilename.endswith('.jpg'):
|
||||
mediaType='image/jpeg'
|
||||
fileExtension='jpg'
|
||||
if imageFilename.endswith('.gif'):
|
||||
mediaType='image/gif'
|
||||
fileExtension='gif'
|
||||
|
||||
if port!=80 and port!=443:
|
||||
if ':' not in domain:
|
||||
domain=domain+':'+str(port)
|
||||
|
||||
currTime=datetime.datetime.utcnow()
|
||||
weeksSinceEpoch=(currTime - datetime.datetime(1970,1,1)).days/7
|
||||
createMediaPath(baseDir,weeksSinceEpoch)
|
||||
mediaPath='media/'+str(weeksSinceEpoch)+'/'+createPassword(32)+'.'+fileExtension
|
||||
mediaFilename=baseDir+'/'+mediaPath
|
||||
|
||||
attachmentJson={
|
||||
'mediaType': mediaType,
|
||||
'name': description,
|
||||
'type': 'Document',
|
||||
'url': httpPrefix+'://'+domain+'/'+mediaPath
|
||||
}
|
||||
if useBlurhash:
|
||||
attachmentJson['blurhash']=getImageHash(imageFilename)
|
||||
postJson['attachment']=[attachmentJson]
|
||||
|
||||
copyfile(imageFilename,mediaFilename)
|
||||
|
||||
return postJson
|
||||
|
||||
def removeAttachment(baseDir: str,httpPrefix: str,domain: str,postJson: {}):
|
||||
if not postJson.get('attachment'):
|
||||
return
|
||||
if not postJson['attachment'][0].get('url'):
|
||||
return
|
||||
if port!=80 and port!=443:
|
||||
if ':' not in domain:
|
||||
domain=domain+':'+str(port)
|
||||
attachmentUrl=postJson['attachment'][0]['url']
|
||||
if not attachmentUrl:
|
||||
return
|
||||
mediaFilename=baseDir+'/'+attachmentUrl.replace(httpPrefix+'://'+domain+'/','')
|
||||
if os.path.isfile(mediaFilename):
|
||||
os.remove(mediaFilename)
|
||||
postJson['attachment']=[]
|
28
posts.py
28
posts.py
|
@ -34,6 +34,7 @@ from utils import getNicknameFromActor
|
|||
from utils import getDomainFromActor
|
||||
from capabilities import getOcapFilename
|
||||
from capabilities import capabilitiesUpdate
|
||||
from media import attachImage
|
||||
try:
|
||||
from BeautifulSoup import BeautifulSoup
|
||||
except ImportError:
|
||||
|
@ -321,7 +322,8 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
|
|||
|
||||
def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
|
||||
followersOnly: bool, saveToFile: bool, clientToServer: bool, \
|
||||
followersOnly: bool, saveToFile: bool, clientToServer: bool,
|
||||
attachImageFilename: str,imageDescription: str,useBlurhash: bool, \
|
||||
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
||||
"""Creates a message
|
||||
"""
|
||||
|
@ -396,6 +398,11 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
|||
}
|
||||
}
|
||||
}
|
||||
if attachImageFilename:
|
||||
newPost['object']= \
|
||||
attachImage(baseDir,httpPrefix,domain,port, \
|
||||
postJson['object'],attachImageFilename, \
|
||||
imageDescription,useBlurhash)
|
||||
else:
|
||||
newPost = {
|
||||
'id': newPostId,
|
||||
|
@ -417,8 +424,21 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
|||
},
|
||||
'attachment': [],
|
||||
'tag': [],
|
||||
'replies': {}
|
||||
'replies': {
|
||||
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
||||
'type': 'Collection',
|
||||
'first': {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
||||
'items': []
|
||||
}
|
||||
}
|
||||
}
|
||||
if attachImageFilename:
|
||||
newPost= \
|
||||
attachImage(baseDir,httpPrefix,domain,port, \
|
||||
postJson,attachImageFilename, \
|
||||
imageDescription,useBlurhash)
|
||||
if ccUrl:
|
||||
if len(ccUrl)>0:
|
||||
newPost['cc']=ccUrl
|
||||
|
@ -490,6 +510,7 @@ def createPublicPost(baseDir: str,
|
|||
nickname: str, domain: str, port: int,httpPrefix: str, \
|
||||
content: str, followersOnly: bool, saveToFile: bool,
|
||||
clientToServer: bool,\
|
||||
attachImageFilename: str,imageDescription: str,useBlurhash: bool, \
|
||||
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
||||
"""Public post to the outbox
|
||||
"""
|
||||
|
@ -498,6 +519,7 @@ def createPublicPost(baseDir: str,
|
|||
httpPrefix+'://'+domain+'/users/'+nickname+'/followers', \
|
||||
httpPrefix, content, followersOnly, saveToFile, \
|
||||
clientToServer, \
|
||||
attachImageFilename,imageDescription,useBlurhash, \
|
||||
inReplyTo, inReplyToAtomUri, subject)
|
||||
|
||||
def threadSendPost(session,postJsonObject: {},federationList: [],\
|
||||
|
@ -536,6 +558,7 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
|
|||
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
||||
httpPrefix: str, content: str, followersOnly: bool, \
|
||||
saveToFile: bool, clientToServer: bool, \
|
||||
attachImageFilename: str,imageDescription: str,useBlurhash: bool, \
|
||||
federationList: [],\
|
||||
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \
|
||||
debug=False,inReplyTo=None,inReplyToAtomUri=None,subject=None) -> int:
|
||||
|
@ -585,6 +608,7 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
|
|||
createPostBase(baseDir,nickname,domain,port, \
|
||||
toPersonId,cc,httpPrefix,content, \
|
||||
followersOnly,saveToFile,clientToServer, \
|
||||
attachImageFilename,imageDescription,useBlurhash, \
|
||||
inReplyTo,inReplyToAtomUri,subject)
|
||||
|
||||
# get the senders private key
|
||||
|
|
27
tests.py
27
tests.py
|
@ -131,6 +131,7 @@ def createServerAlice(path: str,domain: str,port: int,federationList: [],hasFoll
|
|||
nopics=False
|
||||
noannounce=False
|
||||
cw=False
|
||||
useBlurhash=True
|
||||
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(path,nickname,domain,port,httpPrefix,True,password)
|
||||
deleteAllPosts(path,nickname,domain,'inbox')
|
||||
deleteAllPosts(path,nickname,domain,'outbox')
|
||||
|
@ -138,9 +139,9 @@ def createServerAlice(path: str,domain: str,port: int,federationList: [],hasFoll
|
|||
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
||||
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
||||
if hasPosts:
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "In the gardens of memory, in the palace of dreams, that is where you and I shall meet", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer,None,None,useBlurhash)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer,None,None,useBlurhash)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "In the gardens of memory, in the palace of dreams, that is where you and I shall meet", False, True, clientToServer,None,None,useBlurhash)
|
||||
global testServerAliceRunning
|
||||
testServerAliceRunning = True
|
||||
print('Server running: Alice')
|
||||
|
@ -162,6 +163,7 @@ def createServerBob(path: str,domain: str,port: int,federationList: [],hasFollow
|
|||
nopics=False
|
||||
noannounce=False
|
||||
cw=False
|
||||
useBlurhash=False
|
||||
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(path,nickname,domain,port,httpPrefix,True,password)
|
||||
deleteAllPosts(path,nickname,domain,'inbox')
|
||||
deleteAllPosts(path,nickname,domain,'outbox')
|
||||
|
@ -169,9 +171,9 @@ def createServerBob(path: str,domain: str,port: int,federationList: [],hasFollow
|
|||
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
||||
followerOfPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
||||
if hasPosts:
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer,None,None,useBlurhash)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer,None,None,useBlurhash)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer,None,None,useBlurhash)
|
||||
global testServerBobRunning
|
||||
testServerBobRunning = True
|
||||
print('Server running: Bob')
|
||||
|
@ -257,12 +259,12 @@ def testPostMessageBetweenServers():
|
|||
ccUrl=None
|
||||
alicePersonCache={}
|
||||
aliceCachedWebfingers={}
|
||||
|
||||
useBlurhash=False
|
||||
# nothing in Alice's outbox
|
||||
outboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/outbox'
|
||||
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==0
|
||||
|
||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Why is a mouse when it spins?', followersOnly, saveToFile, clientToServer, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Why is a mouse when it spins?', followersOnly, saveToFile, clientToServer,None,None,useBlurhash, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
print('sendResult: '+str(sendResult))
|
||||
|
||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||
|
@ -469,7 +471,8 @@ def testFollowBetweenServers():
|
|||
eveCachedWebfingers={}
|
||||
eveSendThreads=[]
|
||||
evePostLog=[]
|
||||
sendResult = sendPost(sessionEve,eveDir,'eve', eveDomain, evePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Eve message', followersOnly, saveToFile, clientToServer, federationList, eveSendThreads, evePostLog, eveCachedWebfingers,evePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
useBlurhash=False
|
||||
sendResult = sendPost(sessionEve,eveDir,'eve', eveDomain, evePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Eve message', followersOnly, saveToFile, clientToServer,None,None,useBlurhash, federationList, eveSendThreads, evePostLog, eveCachedWebfingers,evePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
print('sendResult: '+str(sendResult))
|
||||
|
||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||
|
@ -495,7 +498,8 @@ def testFollowBetweenServers():
|
|||
aliceCachedWebfingers={}
|
||||
aliceSendThreads=[]
|
||||
alicePostLog=[]
|
||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Alice message', followersOnly, saveToFile, clientToServer, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
useBlurhash=False
|
||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Alice message', followersOnly, saveToFile, clientToServer,None,None,useBlurhash, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
print('sendResult: '+str(sendResult))
|
||||
|
||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||
|
@ -783,6 +787,7 @@ def testCreatePerson():
|
|||
port=80
|
||||
httpPrefix='https'
|
||||
clientToServer=False
|
||||
useBlurhash=False
|
||||
baseDir=currDir+'/.tests_createperson'
|
||||
if os.path.isdir(baseDir):
|
||||
shutil.rmtree(baseDir)
|
||||
|
@ -797,7 +802,7 @@ def testCreatePerson():
|
|||
setBio(baseDir,nickname,domain,'Randomly roaming in your backyard')
|
||||
archivePosts(nickname,domain,baseDir,'inbox',4)
|
||||
archivePosts(nickname,domain,baseDir,'outbox',4)
|
||||
createPublicPost(baseDir,nickname, domain, port,httpPrefix, "G'day world!", False, True, clientToServer, None, None, 'Not suitable for Vogons')
|
||||
createPublicPost(baseDir,nickname, domain, port,httpPrefix, "G'day world!", False, True, clientToServer,None,None,useBlurhash, None, None, 'Not suitable for Vogons')
|
||||
|
||||
os.chdir(currDir)
|
||||
shutil.rmtree(baseDir)
|
||||
|
|
Loading…
Reference in New Issue