Make uploading files work

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
pull/1469/head
Carl Schwan 2022-09-14 12:37:18 +02:00
rodzic b423ac536c
commit e037394a50
5 zmienionych plików z 110 dodań i 64 usunięć

Wyświetl plik

@ -124,18 +124,27 @@ class LocalController extends Controller {
* *
* @NoAdminRequired * @NoAdminRequired
*/ */
public function postCreate(array $data): DataResponse { public function postCreate(string $content = '', $to = null, string $type = null, ?string $replyTo = null, $attachments = null, ?string $hashtags = null): DataResponse {
$content = $content ?? '';
$to = is_string($to) ? [$to] : $to;
$to = $to ?? [];
$replyTo = $replyTo ?? '';
$type = $type ?? Stream::TYPE_PUBLIC;
$hashtags = $hashtags === '' ? [] : $hashtags;
$hashtags = $hashtags ?? [];
$attachments = $attachments ?? [];
try { try {
$actor = $this->accountService->getActorFromUserId($this->userId); $actor = $this->accountService->getActorFromUserId($this->userId);
$post = new Post($actor); $post = new Post($actor);
$post->setContent($this->get('content', $data, '')); $post->setContent($content);
$post->setReplyTo($this->get('replyTo', $data, '')); $post->setReplyTo($replyTo);
$post->setTo($this->getArray('to', $data, [])); $post->setTo($to);
$post->addTo($this->get('to', $data, '')); $post->setType($type);
$post->setType($this->get('type', $data, Stream::TYPE_PUBLIC)); $post->setHashtags($hashtags);
$post->setHashtags($this->getArray('hashtags', $data, [])); $post->setAttachments($attachments);
$post->setAttachments($this->getArray('attachments', $data, []));
$token = ''; $token = '';
$activity = $this->postService->createPost($post, $token); $activity = $this->postService->createPost($post, $token);
@ -151,7 +160,6 @@ class LocalController extends Controller {
} }
} }
/** /**
* Get info about a post (limited to viewer rights). * Get info about a post (limited to viewer rights).
* *

Wyświetl plik

@ -137,6 +137,24 @@ class CacheDocumentService {
$document->setResizedCopy($resized); $document->setResizedCopy($resized);
} }
public function saveFromTempToCache(Document $document, string $tmpPath) {
$mime = mime_content_type($tmpPath);
$this->filterMimeTypes($mime);
$document->setMediaType($mime);
$document->setMimeType($mime);
$file = fopen($tmpPath, 'r');
$content = fread($file, filesize($tmpPath));
$filename = $this->generateFileFromContent($content);
$document->setLocalCopy($filename);
$this->resizeImage($content);
$resized = $this->generateFileFromContent($content);
$document->setResizedCopy($resized);
}
/** /**
* @param string $content * @param string $content

Wyświetl plik

@ -53,34 +53,20 @@ use OCA\Social\Model\ActivityPub\Object\Note;
use OCA\Social\Model\Post; use OCA\Social\Model\Post;
use OCP\Files\NotFoundException; use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException; use OCP\Files\NotPermittedException;
use Psr\Log\LoggerInterface;
class PostService { class PostService {
private StreamService $streamService; private StreamService $streamService;
private AccountService $accountService; private AccountService $accountService;
private ActivityService $activityService; private ActivityService $activityService;
private CacheDocumentService $cacheDocumentService; private CacheDocumentService $cacheDocumentService;
private ConfigService $configService; private ConfigService $configService;
private MiscService $miscService; private MiscService $miscService;
private LoggerInterface $logger;
/**
* PostService constructor.
*
* @param StreamService $streamService
* @param AccountService $accountService
* @param ActivityService $activityService
* @param CacheDocumentService $cacheDocumentService
* @param ConfigService $configService
* @param MiscService $miscService
*/
public function __construct( public function __construct(
StreamService $streamService, AccountService $accountService, ActivityService $activityService, StreamService $streamService, AccountService $accountService, ActivityService $activityService,
CacheDocumentService $cacheDocumentService, ConfigService $configService, MiscService $miscService CacheDocumentService $cacheDocumentService, ConfigService $configService, MiscService $miscService, LoggerInterface $logger
) { ) {
$this->streamService = $streamService; $this->streamService = $streamService;
$this->accountService = $accountService; $this->accountService = $accountService;
@ -88,6 +74,7 @@ class PostService {
$this->cacheDocumentService = $cacheDocumentService; $this->cacheDocumentService = $cacheDocumentService;
$this->configService = $configService; $this->configService = $configService;
$this->miscService = $miscService; $this->miscService = $miscService;
$this->logger = $logger;
} }
@ -142,15 +129,45 @@ class PostService {
*/ */
private function generateDocumentsFromAttachments(Note $note, Post $post) { private function generateDocumentsFromAttachments(Note $note, Post $post) {
$documents = []; $documents = [];
foreach ($post->getAttachments() as $attachment) { \OC::$server->getLogger()->error(var_export($_FILES["attachments"], true));
if (is_array($_FILES["attachments"]["error"])) {
foreach ($_FILES["attachments"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
try {
$document = $this->generateDocumentFromAttachment($note, $key);
$service = AP::$activityPub->getInterfaceForItem($document);
$service->save($document);
$documents[] = $document;
} catch (Exception $e) {
}
}
}
} else {
try { try {
$document = $this->generateDocumentFromAttachment($note, $attachment); $tmp_name = $_FILES["attachments"]["tmp_name"];
$name = basename($_FILES["attachments"]["name"]);
$tmpFile = tmpfile();
$tmpPath = stream_get_meta_data($tmpFile)['uri'];
if (move_uploaded_file($tmp_name, $tmpPath)) {
$document = new Document();
$document->setUrlCloud($this->configService->getCloudUrl());
$document->generateUniqueId('/documents/local');
$document->setParentId($note->getId());
$document->setPublic(true);
$this->cacheDocumentService->saveFromTempToCache($document, $tmpPath);
}
$service = AP::$activityPub->getInterfaceForItem($document); $service = AP::$activityPub->getInterfaceForItem($document);
$service->save($document); $service->save($document);
$documents[] = $document; $documents[] = $document;
} catch (Exception $e) { } catch (Exception $e) {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);
} }
} }
$post->setDocuments($documents); $post->setDocuments($documents);
@ -168,21 +185,21 @@ class PostService {
* @throws SocialAppConfigException * @throws SocialAppConfigException
* @throws UrlCloudException * @throws UrlCloudException
*/ */
private function generateDocumentFromAttachment(Note $note, string $attachment): Document { private function generateDocumentFromAttachment(Note $note, int $key): Document {
list(, $data) = explode(';', $attachment); $tmp_name = $_FILES["attachments"]["tmp_name"][$key];
list(, $data) = explode(',', $data); $name = basename($_FILES["attachments"]["name"][$key]);
$content = base64_decode($data); $tmpFile = tmpfile();
$tmpPath = stream_get_meta_data($tmpFile)['uri'];
if (move_uploaded_file($tmp_name, $tmpPath)) {
$document = new Document();
$document->setUrlCloud($this->configService->getCloudUrl());
$document->generateUniqueId('/documents/local');
$document->setParentId($note->getId());
$document->setPublic(true);
$document = new Document(); $this->cacheDocumentService->saveFromTempToCache($document, $tmpPath);
$document->setUrlCloud($this->configService->getCloudUrl()); }
$document->generateUniqueId('/documents/local');
$document->setParentId($note->getId());
$document->setPublic(true);
$mime = '';
$this->cacheDocumentService->saveLocalUploadToCache($document, $content, $mime);
$document->setMediaType($mime);
$document->setMimeType($mime);
return $document; return $document;
} }

Wyświetl plik

@ -458,19 +458,20 @@ export default {
let content = contentHtml.replace(/<(?!\/div)[^>]+>/gi, '').replace(/<\/div>/gi, '\n').trim() let content = contentHtml.replace(/<(?!\/div)[^>]+>/gi, '').replace(/<\/div>/gi, '\n').trim()
content = he.decode(content) content = he.decode(content)
let data = { let formData = new FormData()
content: content, formData.append('content', content)
to: to, formData.append('to', to)
hashtags: hashtags, formData.append('hashtags', hashtags)
type: this.type, formData.append('type', this.type)
attachments: this.previewUrls.map(preview => preview.result), // TODO send the summary and other props too for (const preview of this.previewUrls) {
// TODO send the summary and other props too
formData.append('attachments', preview.result)
} }
if (this.replyTo) { if (this.replyTo) {
data.replyTo = this.replyTo.id formData.append('replyTo', this.replyTo.id)
} }
return data return formData
}, },
keyup(event) { keyup(event) {
if (event.shiftKey || event.ctrlKey) { if (event.shiftKey || event.ctrlKey) {
@ -487,7 +488,7 @@ export default {
// Trick to validate last mention when the user directly clicks on the "post" button without validating it. // Trick to validate last mention when the user directly clicks on the "post" button without validating it.
let regex = /@([-\w]+)$/ let regex = /@([-\w]+)$/
let lastMention = postData.content.match(regex) let lastMention = postData.get('content').match(regex)
if (lastMention) { if (lastMention) {
// Ask the server for matching accounts, and wait for the results // Ask the server for matching accounts, and wait for the results
@ -495,13 +496,13 @@ export default {
// Validate the last mention only when it matches a single account // Validate the last mention only when it matches a single account
if (result.data.result.accounts.length === 1) { if (result.data.result.accounts.length === 1) {
postData.content = postData.content.replace(regex, '@' + result.data.result.accounts[0].account) postData.set('content', postData.get('content').replace(regex, '@' + result.data.result.accounts[0].account))
postData.to.push(result.data.result.accounts[0].account) postData.set('to', postData.get('to').push(result.data.result.accounts[0].account))
} }
} }
// Abort if the post is a direct message and no valid mentions were found // Abort if the post is a direct message and no valid mentions were found
// if (this.type === 'direct' && postData.to.length === 0) { // if (this.type === 'direct' && postData.get('to').length === 0) {
// OC.Notification.showTemporary(t('social', 'Error while trying to post your message: Could not find any valid recipients.'), { type: 'error' }) // OC.Notification.showTemporary(t('social', 'Error while trying to post your message: Could not find any valid recipients.'), { type: 'error' })
// return // return
// } // }

Wyświetl plik

@ -144,17 +144,19 @@ const actions = {
context.commit('setTimelineType', 'account') context.commit('setTimelineType', 'account')
context.commit('setAccount', account) context.commit('setAccount', account)
}, },
post(context, post) { async post(context, post) {
return new Promise((resolve, reject) => { try {
axios.post(generateUrl('apps/social/api/v1/post'), { data: post }).then((response) => { const { data } = axios.post(generateUrl('apps/social/api/v1/post'), post, {
Logger.info('Post created with token ' + response.data.result.token) headers: {
resolve(response) 'Content-Type': 'multipart/form-data'
}).catch((error) => { }
OC.Notification.showTemporary('Failed to create a post')
Logger.error('Failed to create a post', { 'error': error.response })
reject(error)
}) })
}) Logger.info('Post created with token ' + data.result.token)
} catch (error) {
OC.Notification.showTemporary('Failed to create a post')
console.error(error)
Logger.error('Failed to create a post', { 'error': error.response })
}
}, },
postDelete(context, post) { postDelete(context, post) {
return axios.delete(generateUrl(`apps/social/api/v1/post?id=${post.id}`)).then((response) => { return axios.delete(generateUrl(`apps/social/api/v1/post?id=${post.id}`)).then((response) => {