Skip to content

Commit

Permalink
Merge pull request #237 from etkecc/purge-remote-media
Browse files Browse the repository at this point in the history
Add "Purge Remote Media" button
  • Loading branch information
aine-etke authored Dec 16, 2024
2 parents fd4bf7c + 7844987 commit db6594f
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ The following changes are already implemented:
* 🎞️ [Add "Media" tab for rooms](https://github.com/etkecc/synapse-admin/pull/196)
* 📞 [Support E.164-based Matrix IDs (MSC4009)](https://github.com/etkecc/synapse-admin/pull/214)
* 🛑 [Add support for Account Suspension (MSC3823)](https://github.com/etkecc/synapse-admin/pull/195)
* 🗑️ [Add "Purge Remote Media" button](https://github.com/etkecc/synapse-admin/pull/237)

#### exclusive for [etke.cc](https://etke.cc) customers

Expand Down
74 changes: 74 additions & 0 deletions src/components/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,80 @@ export const DeleteMediaButton = (props: ButtonProps) => {
);
};

const PurgeRemoteMediaDialog = ({ open, onClose, onSubmit }) => {
const translate = useTranslate();

const PurgeRemoteMediaToolbar = (props: ToolbarProps) => (
<Toolbar {...props}>
<SaveButton label="purge_remote_media.action.send" icon={<DeleteSweepIcon />} />
<Button label="ra.action.cancel" onClick={onClose}>
<IconCancel />
</Button>
</Toolbar>
);

return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>{translate("purge_remote_media.action.send")}</DialogTitle>
<DialogContent>
<DialogContentText>{translate("purge_remote_media.helper.send")}</DialogContentText>
<SimpleForm toolbar={<PurgeRemoteMediaToolbar />} onSubmit={onSubmit}>
<DateTimeInput
source="before_ts"
label="purge_remote_media.fields.before_ts"
defaultValue={0}
parse={dateParser}
/>
</SimpleForm>
</DialogContent>
</Dialog>
);
};

export const PurgeRemoteMediaButton = (props: ButtonProps) => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const notify = useNotify();
const dataProvider = useDataProvider<SynapseDataProvider>();
const { mutate: purgeRemoteMedia, isPending } = useMutation({
mutationFn: (values: DeleteMediaParams) => dataProvider.purgeRemoteMedia(values),
onSuccess: () => {
notify("purge_remote_media.action.send_success");
closeDialog();
},
onError: () => {
notify("purge_remote_media.action.send_failure", {
type: "error",
});
},
});

const openDialog = () => setOpen(true);
const closeDialog = () => setOpen(false);

return (
<>
<Button
{...props}
label="purge_remote_media.action.send"
onClick={openDialog}
disabled={isPending}
sx={{
"&:hover": {
// Reset on mouse devices
"@media (hover: none)": {
backgroundColor: "transparent",
},
},
}}
>
<DeleteSweepIcon />
</Button>
<PurgeRemoteMediaDialog open={open} onClose={closeDialog} onSubmit={purgeRemoteMedia} />
</>
);
};

export const ProtectMediaButton = (props: ButtonProps) => {
const record = useRecordContext();
const translate = useTranslate();
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ const de: SynapseTranslationMessages = {
send: "Diese API löscht die lokalen Medien von der Festplatte des eigenen Servers. Dies umfasst alle lokalen Miniaturbilder und Kopien von Medien. Diese API wirkt sich nicht auf Medien aus, die sich in externen Medien-Repositories befinden.",
},
},
purge_remote_media: {
name: "Externe Medien",
fields: {
before_ts: "letzter Zugriff vor",
},
action: {
send: "Externe Medien löschen",
send_success: "Die Anfrage zum Löschen externer Medien wurde gesendet.",
send_failure: "Bei der Anfrage zum Löschen externer Medien ist ein Fehler aufgetreten.",
},
helper: {
send: "Diese API löscht den externen Medien-Cache von der Festplatte Ihres eigenen Servers. Dazu gehören alle lokalen Thumbnails und Kopien heruntergeladener Medien. Diese API beeinflusst nicht die Medien, die in das eigene Medienarchiv des Servers hochgeladen wurden.",
},
},
resources: {
users: {
name: "Benutzer",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ const en: SynapseTranslationMessages = {
send: "This API deletes the local media from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to external media repositories.",
},
},
purge_remote_media: {
name: "Remote Media",
fields: {
before_ts: "last access before",
},
action: {
send: "Purge remote media",
send_success: "Purge remote media request has been sent.",
send_failure: "An error has occurred with the purge remote media request.",
},
helper: {
send: "This API purges the remote media cache from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to the server's own media repository.",
},
},
resources: {
users: {
name: "User |||| Users",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ const fa: SynapseTranslationMessages = {
send: "این API رسانه های محلی را از دیسک سرور خود حذف می کند. این شامل هر تصویر کوچک محلی و کپی از رسانه دانلود شده است. این API بر رسانه‌هایی که در مخازن رسانه خارجی آپلود شده‌اند تأثیری نخواهد گذاشت.",
},
},
purge_remote_media: {
name: "رسانه‌های از راه دور",
fields: {
before_ts: "آخرین دسترسی قبل از",
},
action: {
send: "پاک کردن رسانه‌های از راه دور",
send_success: "درخواست پاک کردن رسانه‌های از راه دور ارسال شد.",
send_failure: "درخواست برای پاک کردن رسانه‌های از راه دور با خطا مواجه شد.",
},
helper: {
send: "این API کش رسانه‌های از راه دور را از دیسک سرور شما پاک می‌کند. این شامل هر گونه بندانگشتی محلی و نسخه‌های رسانه‌های دانلود شده می‌شود. این API بر رسانه‌های آپلود شده به مخزن رسانه سرور تأثیری نخواهد داشت.",
},
},
resources: {
users: {
name: "کاربر |||| کاربران",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ const fr: SynapseTranslationMessages = {
send: "Cette API supprime les médias locaux du disque de votre propre serveur. Cela inclut toutes les vignettes locales et les copies des médias téléchargés. Cette API n'affectera pas les médias qui ont été téléversés dans des dépôts de médias externes.",
},
},
purge_remote_media: {
name: "Médias distants",
fields: {
before_ts: "dernier accès avant",
},
action: {
send: "Purger les médias distants",
send_success: "La demande de purge des médias distants a été envoyée.",
send_failure: "Une erreur est survenue lors de la demande de purge des médias distants.",
},
helper: {
send: "Cette API purge le cache des médias distants du disque de votre propre serveur. Cela inclut toutes les vignettes locales et les copies des médias téléchargés. Cette API n'affectera pas les médias qui ont été téléchargés dans le dépôt de médias du serveur.",
},
},
resources: {
users: {
name: "Utilisateur |||| Utilisateurs",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ interface SynapseTranslationMessages extends TranslationMessages {
send: string;
};
};
purge_remote_media: {
name: string;
fields: {
before_ts: string;
};
action: {
send: string;
send_success: string;
send_failure: string;
};
helper: {
send: string;
};
};
resources: {
users: {
name: string;
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ const it: SynapseTranslationMessages = {
send: "Questa API cancella i media locali dal disco del tuo server. Questo include anche ogni miniatura e copia del media scaricato. Questa API non inciderà sui media che sono stati caricati nei repository esterni.",
},
},
purge_remote_media: {
name: "Media Remoti",
fields: {
before_ts: "ultimo accesso prima di",
},
action: {
send: "Elimina media remoti",
send_success: "La richiesta per eliminare i media remoti è stata inviata.",
send_failure: "Si è verificato un errore con la richiesta di eliminazione dei media remoti.",
},
helper: {
send: "Questa API elimina la cache dei media remoti dal disco del tuo server. Questo include qualsiasi miniatura locale e copie di media scaricati. Questa API non influirà sui media che sono stati caricati nel repository multimediale del server.",
},
},
resources: {
users: {
name: "Utente |||| Utenti",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,20 @@ const ru: SynapseTranslationMessages = {
Данный API не затрагивает файлы, загруженные во внешние хранилища.",
},
},
purge_remote_media: {
name: "Внешние медиа",
fields: {
before_ts: "последний доступ до",
},
action: {
send: "Очистить внешние медиа",
send_success: "Запрос на очистку внешних медиа был отправлен.",
send_failure: "Произошла ошибка при запросе очистки внешних медиа.",
},
helper: {
send: "Этот API очищает кэш внешних медиа с диска вашего сервера. Это включает любые локальные миниатюры и копии загруженных медиа. Этот API не повлияет на медиа, которые были загружены в собственное медиа-хранилище сервера.",
},
},
resources: {
users: {
name: "Пользователь |||| Пользователи",
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ const zh: SynapseTranslationMessages = {
send: "这个API会删除您硬盘上的本地媒体。包含了任何的本地缓存和下载的媒体备份。这个API不会影响上传到外部媒体存储库上的媒体文件。",
},
},
purge_remote_media: {
name: "远程媒体",
fields: {
before_ts: "最后访问于之前",
},
action: {
send: "清除远程媒体",
send_success: "远程媒体清除请求已发送。",
send_failure: "发生错误,远程媒体清除请求未成功。",
},
helper: {
send: "此API清除您服务器磁盘上的远程媒体缓存。这包括任何本地缩略图和下载的媒体副本。此API不会影响已经上传到服务器媒体存储库的媒体。",
},
},
resources: {
users: {
name: "用户",
Expand Down
3 changes: 2 additions & 1 deletion src/resources/user_media_statistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import {
useListContext,
} from "react-admin";

import { DeleteMediaButton } from "../components/media";
import { DeleteMediaButton, PurgeRemoteMediaButton } from "../components/media";

const ListActions = () => {
const { isLoading, total } = useListContext();
return (
<TopToolbar>
<DeleteMediaButton />
<PurgeRemoteMediaButton />
<ExportButton disabled={isLoading || total === 0} />
</TopToolbar>
);
Expand Down
18 changes: 18 additions & 0 deletions src/synapse/dataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export interface ServerProcessResponse {

export interface SynapseDataProvider extends DataProvider {
deleteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
purgeRemoteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
uploadMedia: (params: UploadMediaParams) => Promise<UploadMediaResult>;
updateFeatures: (id: Identifier, features: ExperimentalFeaturesModel) => Promise<void>;
getRateLimits: (id: Identifier) => Promise<RateLimitsModel>;
Expand Down Expand Up @@ -849,6 +850,23 @@ const baseDataProvider: SynapseDataProvider = {
return json as DeleteMediaResult;
},

/**
* Purge remote media by date
*
* @link https://element-hq.github.io/synapse/latest/admin_api/media_admin_api.html#purge-remote-media-api
*
* @param before_ts Unix timestamp in milliseconds. Files that were last used before this timestamp will be deleted. It is the timestamp of last access, not the timestamp when the file was created.
* @returns
*/
purgeRemoteMedia: async ({ before_ts }) => {
const endpoint = `/_synapse/admin/v1/purge_media_cache?before_ts=${before_ts}`;

const base_url = localStorage.getItem("base_url");
const endpoint_url = base_url + endpoint;
const { json } = await jsonClient(endpoint_url, { method: "POST" });
return json as DeleteMediaResult;
},

uploadMedia: async ({ file, filename, content_type }: UploadMediaParams) => {
const base_url = localStorage.getItem("base_url");
const uploadMediaURL = `${base_url}/_matrix/media/v3/upload`;
Expand Down
6 changes: 5 additions & 1 deletion src/utils/mxid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export const isMXID = (id: string | Identifier): boolean => mxidPattern.test(id
* @returns Whether the user is managed by an application service
*/
export const isASManaged = (id: string | Identifier): boolean => {
return GetConfig().asManagedUsers.some(regex => regex.test(id as string));
const managedUsers = GetConfig().asManagedUsers;
if (!managedUsers) {
return false;
}
return managedUsers.some(regex => regex.test(id as string));
};

/**
Expand Down

0 comments on commit db6594f

Please sign in to comment.