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
*/
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 {
$actor = $this->accountService->getActorFromUserId($this->userId);
$post = new Post($actor);
$post->setContent($this->get('content', $data, ''));
$post->setReplyTo($this->get('replyTo', $data, ''));
$post->setTo($this->getArray('to', $data, []));
$post->addTo($this->get('to', $data, ''));
$post->setType($this->get('type', $data, Stream::TYPE_PUBLIC));
$post->setHashtags($this->getArray('hashtags', $data, []));
$post->setAttachments($this->getArray('attachments', $data, []));
$post->setContent($content);
$post->setReplyTo($replyTo);
$post->setTo($to);
$post->setType($type);
$post->setHashtags($hashtags);
$post->setAttachments($attachments);
$token = '';
$activity = $this->postService->createPost($post, $token);
@ -151,7 +160,6 @@ class LocalController extends Controller {
}
}
/**
* Get info about a post (limited to viewer rights).
*

Wyświetl plik

@ -137,6 +137,24 @@ class CacheDocumentService {
$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

Wyświetl plik

@ -53,34 +53,20 @@ use OCA\Social\Model\ActivityPub\Object\Note;
use OCA\Social\Model\Post;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use Psr\Log\LoggerInterface;
class PostService {
private StreamService $streamService;
private AccountService $accountService;
private ActivityService $activityService;
private CacheDocumentService $cacheDocumentService;
private ConfigService $configService;
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(
StreamService $streamService, AccountService $accountService, ActivityService $activityService,
CacheDocumentService $cacheDocumentService, ConfigService $configService, MiscService $miscService
CacheDocumentService $cacheDocumentService, ConfigService $configService, MiscService $miscService, LoggerInterface $logger
) {
$this->streamService = $streamService;
$this->accountService = $accountService;
@ -88,6 +74,7 @@ class PostService {
$this->cacheDocumentService = $cacheDocumentService;
$this->configService = $configService;
$this->miscService = $miscService;
$this->logger = $logger;
}
@ -142,15 +129,45 @@ class PostService {
*/
private function generateDocumentsFromAttachments(Note $note, Post $post) {
$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 {
$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->save($document);
$documents[] = $document;
} catch (Exception $e) {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);
}
}
$post->setDocuments($documents);
@ -168,21 +185,21 @@ class PostService {
* @throws SocialAppConfigException
* @throws UrlCloudException
*/
private function generateDocumentFromAttachment(Note $note, string $attachment): Document {
list(, $data) = explode(';', $attachment);
list(, $data) = explode(',', $data);
$content = base64_decode($data);
private function generateDocumentFromAttachment(Note $note, int $key): Document {
$tmp_name = $_FILES["attachments"]["tmp_name"][$key];
$name = basename($_FILES["attachments"]["name"][$key]);
$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();
$document->setUrlCloud($this->configService->getCloudUrl());
$document->generateUniqueId('/documents/local');
$document->setParentId($note->getId());
$document->setPublic(true);
$this->cacheDocumentService->saveFromTempToCache($document, $tmpPath);
}
$mime = '';
$this->cacheDocumentService->saveLocalUploadToCache($document, $content, $mime);
$document->setMediaType($mime);
$document->setMimeType($mime);
return $document;
}

Wyświetl plik

@ -458,19 +458,20 @@ export default {
let content = contentHtml.replace(/<(?!\/div)[^>]+>/gi, '').replace(/<\/div>/gi, '\n').trim()
content = he.decode(content)
let data = {
content: content,
to: to,
hashtags: hashtags,
type: this.type,
attachments: this.previewUrls.map(preview => preview.result), // TODO send the summary and other props too
let formData = new FormData()
formData.append('content', content)
formData.append('to', to)
formData.append('hashtags', hashtags)
formData.append('type', this.type)
for (const preview of this.previewUrls) {
// TODO send the summary and other props too
formData.append('attachments', preview.result)
}
if (this.replyTo) {
data.replyTo = this.replyTo.id
formData.append('replyTo', this.replyTo.id)
}
return data
return formData
},
keyup(event) {
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.
let regex = /@([-\w]+)$/
let lastMention = postData.content.match(regex)
let lastMention = postData.get('content').match(regex)
if (lastMention) {
// 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
if (result.data.result.accounts.length === 1) {
postData.content = postData.content.replace(regex, '@' + result.data.result.accounts[0].account)
postData.to.push(result.data.result.accounts[0].account)
postData.set('content', postData.get('content').replace(regex, '@' + 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
// 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' })
// return
// }

Wyświetl plik

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