Transfer Android ordinary attachment caches to the shared media worker
This commit is contained in:
1 parent
ce80fbcd10
commit
2dbc45e63d
2 files changed
+29
-81
No files matched your search
@@ -1,93 +1,40 @@
|
||||
/* Обычный picker-файл: общий worker владеет cache и подтверждает публикацию. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "attachment_sender.h"
|
||||
#include "instance_lite.h"
|
||||
#include "../../../lib/debug_config.h"
|
||||
#include "../../../lib/mem.h"
|
||||
#include "../../../lib/u_async.h"
|
||||
#include "../../../src/chat/chat_core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include "../../../src/media_async/attachment_send.h"
|
||||
|
||||
int attachment_send(const char* channel_id, const char* src_file_path, const char* db_path,
|
||||
const uint8_t reply_to[32], uint64_t request_id) {
|
||||
if (!channel_id || !src_file_path || !db_path) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "attachment_send: invalid args");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)db_path;
|
||||
struct UASYNC* ua = instance_lite_get_uasync();
|
||||
if (!uasync_is_running(ua)) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "attachment_send: core stopped"); return -1; }
|
||||
|
||||
/* get original basename for display, then make unique filename for storage */
|
||||
char path_copy[1024];
|
||||
snprintf(path_copy, sizeof(path_copy), "%s", src_file_path);
|
||||
char* fname = basename(path_copy);
|
||||
char original_basename[256];
|
||||
snprintf(original_basename, sizeof(original_basename), "%s", fname);
|
||||
char* dot = strrchr(fname, '.');
|
||||
char ext[32] = "";
|
||||
if (dot) { snprintf(ext, sizeof(ext), "%s", dot + 1); *dot = '\0'; }
|
||||
|
||||
struct stat st; memset(&st, 0, sizeof(st));
|
||||
stat(src_file_path, &st);
|
||||
|
||||
/* generate dt/suffix for unique filename */
|
||||
time_t t = time(NULL);
|
||||
struct tm tm_buf; localtime_r(&t, &tm_buf);
|
||||
char dt[32]; snprintf(dt, sizeof(dt), "%04d%02d%02d-%02d%02d%02d",
|
||||
tm_buf.tm_year + 1900, tm_buf.tm_mon + 1, tm_buf.tm_mday,
|
||||
tm_buf.tm_hour, tm_buf.tm_min, tm_buf.tm_sec);
|
||||
int rnd = rand() & 0xFFFF;
|
||||
char suffix[8]; snprintf(suffix, sizeof(suffix), "%04x", rnd);
|
||||
|
||||
/* ensure media dir exists */
|
||||
char media_dir[1024];
|
||||
snprintf(media_dir, sizeof(media_dir), "%s/media/%s", db_path, channel_id);
|
||||
{
|
||||
char tmp[1024]; size_t off = 0;
|
||||
for (size_t i = 0; media_dir[i] && off < sizeof(tmp) - 1; i++) {
|
||||
tmp[off++] = media_dir[i];
|
||||
if (media_dir[i] == '/' && off > 1) { tmp[off] = '\0'; mkdir(tmp, 0755); }
|
||||
}
|
||||
tmp[off] = '\0';
|
||||
mkdir(tmp, 0755);
|
||||
if (!channel_id || !src_file_path || !reply_to || strlen(channel_id) >= 64 || strlen(src_file_path) >= 1024 ||
|
||||
!uasync_is_running(ua)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment_send: invalid arguments/stopped core"); return -1;
|
||||
}
|
||||
|
||||
/* single file path — no splitting */
|
||||
char media_file[1280];
|
||||
snprintf(media_file, sizeof(media_file), "%s/%s_%s_%s.%s",
|
||||
media_dir, dt, fname, suffix, ext[0] ? ext : "bin");
|
||||
|
||||
/* post chat_msg_submit — media_copy=1 so media_index copies src to dest
|
||||
data = original_basename — becomes first part of message "d" field: "name.ext|size|..." */
|
||||
size_t datalen = strlen(original_basename);
|
||||
struct chat_msg_submit* req = u_calloc(1, sizeof(struct chat_msg_submit) + datalen + 1);
|
||||
const char* name = strrchr(src_file_path, '/'); name = name ? name + 1 : src_file_path;
|
||||
struct attachment_send_req* req = u_calloc(1, sizeof(*req));
|
||||
struct posted_task* post = u_calloc(1, sizeof(*post));
|
||||
if (!req || !post) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment_send: allocation failed"); u_free(req); u_free(post); return -1;
|
||||
}
|
||||
|
||||
req->inst = instance_lite_get_instance();
|
||||
memcpy(req->reply_to, reply_to, sizeof(req->reply_to));
|
||||
req->request_id = request_id;
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s", channel_id);
|
||||
snprintf(req->content_type, sizeof(req->content_type), "application/octet-stream");
|
||||
snprintf(req->media_src, sizeof(req->media_src), "%s", src_file_path);
|
||||
snprintf(req->media_dest, sizeof(req->media_dest), "%s", media_file);
|
||||
req->media_copy = 1;
|
||||
req->data = (uint8_t*)(req + 1);
|
||||
memcpy(req->data, original_basename, datalen);
|
||||
req->data_len = (uint32_t)datalen;
|
||||
req->timestamp = 0;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "attachment_send: ch=%s src=%s dst=%s name=%s size=%lld",
|
||||
channel_id, src_file_path, media_file, original_basename, (long long)st.st_size);
|
||||
|
||||
post->callback = chat_core_submit_trampoline; post->arg = req;
|
||||
if (strlen(name) >= sizeof(req->info.name)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment_send: filename too long"); u_free(req); u_free(post); return -1;
|
||||
}
|
||||
req->inst = instance_lite_get_instance(); req->info.kind = ATTACHMENT_FILE;
|
||||
snprintf(req->info.name, sizeof(req->info.name), "%s", name);
|
||||
if (attachment_validate(&req->info)) { u_free(req); u_free(post); return -1; }
|
||||
snprintf(req->target, sizeof(req->target), "%s", channel_id);
|
||||
snprintf(req->source, sizeof(req->source), "%s", src_file_path);
|
||||
memcpy(req->reply_to, reply_to, sizeof(req->reply_to)); req->request_id = request_id;
|
||||
req->temporary_source = 1;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "attachment_send: accepted channel=%s source=%s request=%llu",
|
||||
channel_id, src_file_path, (unsigned long long)request_id);
|
||||
post->callback = attachment_send_trampoline; post->arg = req;
|
||||
uasync_post_reserved(ua, post);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
/* Android-обёртка отправки обычного файла в канал через chat_core_submit_trampoline.
|
||||
* Строит имя назначения в db_path/media/channel_id, копирование/индексацию выполняет media_index.
|
||||
/* Android-обёртка отправки обычного cache-файла в канал через общий attachment_send worker.
|
||||
* Назначение выбирает ядро, копирование/индексация выполняются вне UI.
|
||||
* 0 = запрос поставлен в uasync, -1 = отказ подготовки, результат публикации — CHAT_EVT_MSG_SUBMITTED.
|
||||
* Вызовы сериализовать со stop/restart ядра; строки копируются, исходный файл нужен неизменным до завершения media-задачи. */
|
||||
* При 0 worker забирает собственный временный файл caller и удаляет также при ошибке/отмене.
|
||||
* При -1 файл остаётся caller. Вызовы сериализовать со stop/restart ядра; строки копируются. */
|
||||
#ifndef ATTACHMENT_SENDER_H
|
||||
#define ATTACHMENT_SENDER_H
|
||||
#include <stdint.h>
|
||||
@@ -10,9 +11,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* channel_id — десятичный ID канала, db_path — каталог БД; пути/строки NUL-терминированы.
|
||||
/* channel_id — десятичный ID канала, db_path не используется; пути/строки NUL-терминированы.
|
||||
* reply_to обязательно указывает на 32 байта (нули = без ответа), request_id коррелирует результат с UI.
|
||||
* Источник остаётся у caller и здесь не удаляется; MIME application/octet-stream, имя — basename источника. */
|
||||
* MIME application/octet-stream, имя — UTF-8 basename источника. Пользовательский исходник сначала копировать в cache. */
|
||||
int attachment_send(const char* channel_id, const char* src_file_path, const char* db_path,
|
||||
const uint8_t reply_to[32], uint64_t request_id);
|
||||
|
||||
|
||||
Reference in new issue
Block a user