2024-03-04 11:24:29 +00:00
|
|
|
__filename__ = "daemon_post_image.py"
|
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
|
__license__ = "AGPL3+"
|
2026-01-02 11:36:24 +00:00
|
|
|
__version__ = "1.7.0"
|
2024-03-04 11:24:29 +00:00
|
|
|
__maintainer__ = "Bob Mottram"
|
|
|
|
|
__email__ = "bob@libreserver.org"
|
|
|
|
|
__status__ = "Production"
|
2024-12-25 14:31:14 +00:00
|
|
|
__module_group__ = "Daemon POST"
|
2024-03-04 11:24:29 +00:00
|
|
|
|
2026-05-07 12:00:48 +00:00
|
|
|
import os
|
2024-03-04 11:24:29 +00:00
|
|
|
import errno
|
|
|
|
|
from socket import error as SocketError
|
|
|
|
|
from httpcodes import http_404
|
|
|
|
|
from utils import acct_dir
|
|
|
|
|
from utils import binary_is_image
|
2025-05-29 20:06:28 +00:00
|
|
|
from formats import get_image_extension_from_mime_type
|
2026-04-27 14:46:03 +00:00
|
|
|
from data import save_binary
|
2026-05-02 11:59:08 +00:00
|
|
|
from data import is_a_dir
|
2026-05-07 12:26:36 +00:00
|
|
|
from data import is_a_file
|
2024-03-04 11:24:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def receive_image_attachment(self, length: int, path: str, base_dir: str,
|
2024-04-13 09:37:42 +00:00
|
|
|
domain: str, debug: bool,
|
|
|
|
|
outbox_authenticated: bool) -> None:
|
2024-03-04 11:24:29 +00:00
|
|
|
"""Receives an image via POST
|
|
|
|
|
"""
|
2024-04-13 09:37:42 +00:00
|
|
|
if not outbox_authenticated:
|
2024-03-04 11:24:29 +00:00
|
|
|
if debug:
|
|
|
|
|
print('DEBUG: unauthenticated attempt to ' +
|
|
|
|
|
'post image to outbox')
|
|
|
|
|
self.send_response(403)
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.server.postreq_busy = False
|
|
|
|
|
return
|
|
|
|
|
path_users_section = path.split('/users/')[1]
|
|
|
|
|
if '/' not in path_users_section:
|
|
|
|
|
http_404(self, 12)
|
|
|
|
|
self.server.postreq_busy = False
|
|
|
|
|
return
|
|
|
|
|
self.post_from_nickname = path_users_section.split('/')[0]
|
|
|
|
|
accounts_dir = acct_dir(base_dir, self.post_from_nickname, domain)
|
2026-05-02 11:59:08 +00:00
|
|
|
if not is_a_dir(accounts_dir):
|
2024-03-04 11:24:29 +00:00
|
|
|
http_404(self, 13)
|
|
|
|
|
self.server.postreq_busy = False
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
media_bytes = self.rfile.read(length)
|
|
|
|
|
except SocketError as ex:
|
|
|
|
|
if ex.errno == errno.ECONNRESET:
|
|
|
|
|
print('EX: POST media_bytes ' +
|
|
|
|
|
'connection reset by peer')
|
|
|
|
|
else:
|
|
|
|
|
print('EX: POST media_bytes socket error')
|
|
|
|
|
self.send_response(400)
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.server.postreq_busy = False
|
|
|
|
|
return
|
|
|
|
|
except ValueError as ex:
|
|
|
|
|
print('EX: POST media_bytes rfile.read failed, ' + str(ex))
|
|
|
|
|
self.send_response(400)
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.server.postreq_busy = False
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
media_filename_base = accounts_dir + '/upload'
|
|
|
|
|
media_filename = \
|
|
|
|
|
media_filename_base + '.' + \
|
|
|
|
|
get_image_extension_from_mime_type(self.headers['Content-type'])
|
|
|
|
|
if not binary_is_image(media_filename, media_bytes):
|
|
|
|
|
print('WARN: _receive_image image binary is not recognized ' +
|
|
|
|
|
media_filename)
|
2026-04-27 14:46:03 +00:00
|
|
|
save_binary(media_bytes, media_filename,
|
|
|
|
|
'EX: receive_image_attachment unable to write ' +
|
|
|
|
|
media_filename)
|
2024-03-04 11:24:29 +00:00
|
|
|
if debug:
|
2026-05-07 12:26:36 +00:00
|
|
|
if is_a_file(media_filename):
|
|
|
|
|
file_size: int = os.path.getsize(media_filename)
|
2026-05-07 14:01:25 +00:00
|
|
|
print('DEBUG: uploaded image saved to ' + media_filename + ' ' +
|
2026-05-07 12:00:48 +00:00
|
|
|
str(file_size) + ' bytes')
|
|
|
|
|
else:
|
2026-05-07 14:01:25 +00:00
|
|
|
print('WARN: uploaded image not saved ' + media_filename)
|
2024-03-04 11:24:29 +00:00
|
|
|
self.send_response(201)
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.server.postreq_busy = False
|