Skip to content

Commit 463dc50

Browse files
committed
fix: migrate media location and thumbnails to agnostic space provider
1 parent dae86c9 commit 463dc50

File tree

19 files changed

+100
-34
lines changed

19 files changed

+100
-34
lines changed

packages/@liexp/backend/src/flows/tg/parseVideo.flow.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const parseVideo =
7373
TE.mapLeft(ServerError.fromUnknown),
7474
);
7575
}),
76-
TE.map((r) => ensureHTTPS(r.Location)),
76+
TE.map((r) => ensureHTTPS(ctx.env.SPACE_ENDPOINT, r.Location)),
7777
),
7878
),
7979
);

packages/@liexp/backend/src/io/media.io.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ const encodeMedia = (
3030
return pipe(
3131
Schema.encodeEither(io.http.Media.AdminMedia)({
3232
...media,
33+
location: ensureHTTPS(spaceEndpoint, media.location),
3334
label: media.label ?? media.location,
3435
description: media.description ?? undefined,
35-
thumbnail: media.thumbnail ? ensureHTTPS(media.thumbnail) : undefined,
36+
thumbnail: media.thumbnail
37+
? ensureHTTPS(spaceEndpoint, media.thumbnail)
38+
: undefined,
3639
transferable: !media.location.includes(spaceEndpoint),
3740
creator: Schema.is(UUID)(media.creator)
3841
? media.creator
@@ -65,7 +68,7 @@ const decodeMedia = (
6568
...media,
6669
label: media.label ?? media.location,
6770
description: media.description ?? undefined,
68-
location: ensureHTTPS(media.location),
71+
location: ensureHTTPS(spaceEndpoint, media.location),
6972
creator: Schema.is(UUID)(media.creator)
7073
? media.creator
7174
: media.creator?.id,
@@ -76,8 +79,10 @@ const decodeMedia = (
7679
areas: (media.areas ?? []).map((a) => (Schema.is(UUID)(a) ? a : a.id)),
7780
featuredInStories: media.featuredInStories ?? [],
7881
socialPosts: media.socialPosts ?? [],
79-
thumbnail: media.thumbnail ? ensureHTTPS(media.thumbnail) : undefined,
80-
transferable: !media.location.includes(spaceEndpoint),
82+
thumbnail: media.thumbnail
83+
? ensureHTTPS(spaceEndpoint, media.thumbnail)
84+
: undefined,
85+
transferable: !media.location.startsWith("/"),
8186
createdAt: media.createdAt.toISOString(),
8287
updatedAt: media.updatedAt.toISOString(),
8388
deletedAt: media.deletedAt?.toISOString() ?? undefined,

packages/@liexp/backend/src/providers/puppeteer.provider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,11 @@ export const GetPuppeteerProvider = (
172172
});
173173
b.on("disconnected", (e) => {
174174
puppeteerLogger.debug.log(
175-
"browser disconnected %ds",
175+
"browser disconnected %ds: %O",
176176
differenceInSeconds(new Date(), connectedAt, {
177177
roundingMethod: "ceil",
178178
}),
179+
e,
179180
);
180181
});
181182
return b;

packages/@liexp/backend/src/providers/wikipedia/wikipedia.provider.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ interface WikipediaProviderOpts {
5252
logger: Logger;
5353
client: Bot;
5454
restClient: AxiosInstance;
55+
spaceEndpoint: string;
5556
}
5657

5758
const toMWError = (e: unknown): Error => {
@@ -62,6 +63,7 @@ export const WikipediaProvider = ({
6263
logger,
6364
client,
6465
restClient,
66+
spaceEndpoint,
6567
}: WikipediaProviderOpts): WikipediaProvider => {
6668
logger.debug.log("Wikipedia provider created");
6769

@@ -127,7 +129,7 @@ export const WikipediaProvider = ({
127129
items.filter((i) => i.type === "image"),
128130
fp.A.head,
129131
fp.O.chainNullableK((r) => r.srcset?.[0]?.src),
130-
fp.O.map((url) => ensureHTTPS(url)),
132+
fp.O.map((url) => ensureHTTPS(spaceEndpoint, url)),
131133
fp.O.toUndefined,
132134
);
133135
}),
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { Schema } from "effect/index";
12
import * as R from "fp-ts/lib/Record.js";
23
import { pipe } from "fp-ts/lib/function.js";
34
import qs from "query-string";
4-
import { type URL } from "../io/http/Common/URL.js";
5+
import { URL } from "../io/http/Common/URL.js";
56

67
export const sanitizeURL = (url: URL): URL => {
78
const [cleanURL, query] = url.split("?");
@@ -14,20 +15,28 @@ export const sanitizeURL = (url: URL): URL => {
1415
);
1516

1617
if (!R.isEmpty(cleanQuery)) {
17-
return `${cleanURL}?${qs.stringify(cleanQuery)}` as URL;
18+
return Schema.decodeSync(URL)(`${cleanURL}?${qs.stringify(cleanQuery)}`);
1819
}
1920

20-
return cleanURL as URL;
21+
return Schema.decodeSync(URL)(cleanURL);
2122
};
2223

23-
export const ensureHTTPS = (url: string): URL => {
24-
if (url.startsWith("https://") || url.startsWith("http://")) {
25-
return url as URL;
24+
const encodeWithSpaceEndpoint = (spaceHost: string, url: string): string => {
25+
if (url.startsWith("//")) {
26+
return `https:${url}`;
2627
}
2728

28-
if (url.startsWith("//")) {
29-
return `https:${url}` as URL;
29+
if (url.startsWith("/")) {
30+
return `https://${spaceHost}${url}`;
31+
}
32+
33+
if (url.startsWith("https://") || url.startsWith("http://")) {
34+
return url;
3035
}
3136

32-
return `https://${url}` as URL;
37+
return `https://${url}`;
38+
};
39+
40+
export const ensureHTTPS = (spaceHost: string, url: string): URL => {
41+
return pipe(encodeWithSpaceEndpoint(spaceHost, url), Schema.decodeSync(URL));
3342
};

packages/@liexp/ui/src/components/Cards/Events/EventCard.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ const EventCard = <E extends SearchEvent.SearchEvent>({
8787
height: props.style?.maxHeight ?? 150,
8888
width: isVertical ? "100%" : 150,
8989
}}
90+
onError={(e) => {
91+
if (defaultImage && e.currentTarget.src !== defaultImage) {
92+
e.currentTarget.src = defaultImage;
93+
}
94+
}}
9095
/>
9196
</Stack>
9297
) : null}

packages/@liexp/ui/src/components/Media/ExpandableImageElement.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ interface ExpandableImageElementProps {
6464
onLoad?: (rect: DOMRect) => void;
6565
onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
6666
disableZoom?: boolean;
67+
fallbackImage?: string;
6768
}
6869

6970
const ExpandableImageElement: React.FC<ExpandableImageElementProps> = ({
@@ -73,6 +74,7 @@ const ExpandableImageElement: React.FC<ExpandableImageElementProps> = ({
7374
onLoad,
7475
onClick,
7576
disableZoom = false,
77+
fallbackImage,
7678
}) => {
7779
const [modal, showModal] = useModal({ disablePortal: false });
7880

@@ -135,6 +137,11 @@ const ExpandableImageElement: React.FC<ExpandableImageElementProps> = ({
135137
const rect = e.currentTarget.getBoundingClientRect();
136138
onLoad?.(rect);
137139
}}
140+
onError={(e) => {
141+
if (fallbackImage) {
142+
e.currentTarget.src = fallbackImage;
143+
}
144+
}}
138145
loading="lazy"
139146
/>
140147
{!disableZoom ? (

packages/@liexp/ui/src/components/Media/MediaElement.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Media } from "@liexp/shared/lib/io/http/index.js";
22
import { clsx } from "clsx";
33
import * as React from "react";
4+
import { useConfiguration } from "../../context/ConfigurationContext.js";
45
import { styled } from "../../theme/index.js";
56
import { Video } from "../Video/Video.js";
67
import { Box, Typography } from "../mui/index.js";
@@ -44,6 +45,7 @@ export interface MediaElementProps {
4445
onLoad?: (rect: DOMRect) => void;
4546
enableDescription?: boolean;
4647
disableZoom?: boolean;
48+
fallbackImage?: string;
4749
onClick?: (e: any) => void;
4850
options?: {
4951
iframe: {
@@ -64,8 +66,12 @@ const MediaElement: React.FC<MediaElementProps> = ({
6466
enableDescription = false,
6567
options,
6668
disableZoom = false,
69+
fallbackImage: _fallbackImage,
6770
...props
6871
}) => {
72+
const { platforms } = useConfiguration();
73+
const fallbackImage = _fallbackImage ?? platforms.web.defaultImage;
74+
6975
const mediaElement = React.useMemo(() => {
7076
switch (media.type) {
7177
case Media.IframeVideoType.literals[0]:
@@ -129,6 +135,7 @@ const MediaElement: React.FC<MediaElementProps> = ({
129135
className={clsx(classes.item, itemClassName)}
130136
media={{ ...media, type: media.type }}
131137
disableZoom={disableZoom}
138+
fallbackImage={fallbackImage}
132139
/>
133140
);
134141
}

services/api/.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ DB_DATABASE=liexp
1616
DB_SSL_MODE=off
1717
WEB_URL=http://liexp.dev
1818

19-
SPACE_BUCKET=local
20-
SPACE_ENDPOINT=space.liexp.dev:9000
19+
SPACE_BUCKET=public
20+
SPACE_ENDPOINT=space.liexp.dev
2121
SPACE_REGION=fra1
2222
SPACE_ACCESS_KEY_ID=space-access-key-id
2323
SPACE_ACCESS_KEY_SECRET=space-access-key-secret-id

services/api/.env.test

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ DB_HOST=127.0.0.1
1818
DB_PORT=8432
1919
DB_DATABASE=liexp_test
2020
DB_SSL_MODE=off
21-
WEB_URL=http://localhost:4020
21+
WEB_URL=http://liexp.dev
2222

2323
SPACE_BUCKET=media
2424
SPACE_ENDPOINT=localhost:9000
@@ -35,14 +35,6 @@ DEFAULT_PAGE_SIZE=20
3535

3636
JWT_SECRET=my-secret
3737

38-
# Cron jobs
39-
DOWNLOAD_VACCINE_DATA_CRON="0 * * * * *"
40-
SOCIAL_POSTING_CRON="0 * * * * *"
41-
TEMP_FOLDER_CLEAN_UP_CRON="* * 0 * *"
42-
GENERATE_MISSING_THUMBNAILS_CRON="* * 0 * *"
43-
PROCESS_DONE_JOB_CRON="* * 0 * *"
44-
REGENERATE_MEDIA_THUMBNAILS_CRON="* * 0 * *"
45-
4638
TG_BOT_TOKEN=invalid
4739
TG_BOT_CHAT=invalid
4840
TG_BOT_USERNAME=invalid

0 commit comments

Comments
 (0)