Skip to content

Commit

Permalink
chore: move netlify functions to ts
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomontalbano committed Jun 16, 2024
1 parent d8123a6 commit a71551b
Show file tree
Hide file tree
Showing 42 changed files with 528 additions and 304 deletions.
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"rules": {
"recommended": true,
"complexity": {
"noThisInStatic": "warn"
"noThisInStatic": "off"
}
}
}
Expand Down
62 changes: 0 additions & 62 deletions netlify/functions/cloudinary/index.js

This file was deleted.

60 changes: 60 additions & 0 deletions netlify/functions/cloudinary/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import crypto from 'node:crypto';
import { v2 as cloudinary } from 'cloudinary';
import type { Options } from '../types';
import type VideoProvider from '../videoWrapper/VideoProvider';

const { USE_HIGH_QUALITY = false } = process.env;

// const search = (providerName, videoId) =>
// cloudinary.search
// .expression(`resource_type:"image" AND folder="video_to_markdown/images" AND filename="${providerName}-${videoId}"`)
// .sort_by('uploaded_at', 'desc')
// .max_results(30)
// .execute();

const useHighQuality = () => USE_HIGH_QUALITY === 'true';

async function create(source: string, video: VideoProvider, options?: Options) {
const highQualitySize = 720;
const lowQualitySize = 500;

// https://cloudinary.com/documentation/image_transformations#adjusting_image_quality
const highQuality = [{ height: highQualitySize }];

const lowQuality = [
{ quality: 'auto:low' },
{ if: 'w_gt_h' },
{ height: lowQualitySize },
{ if: 'else' },
{ width: lowQualitySize },
{ if: 'end' },
];

const overlayHeight = useHighQuality() ? '1.0' : (lowQualitySize / highQualitySize).toFixed(2).toString();
const transformations = options?.showPlayIcon
? {
overlay: `video_to_markdown:icons:${video.providerName}`,
height: overlayHeight,
flag: 'relative',
gravity: 'center',
}
: {};
const hash = crypto.createHash('md5').update(JSON.stringify(options)).digest('hex');
const cloudinaryOptions = {
folder: 'video_to_markdown/images',
public_id: `${video.providerName}--${video.getId()}-${hash}`,
context: `url=${video.url}|provider=${video.providerName}`,
secure: true,
transformation: [...(useHighQuality() ? highQuality : lowQuality), { ...transformations }],
};

const cloudinaryResponse = await cloudinary.uploader.upload(source, cloudinaryOptions);

return cloudinaryResponse;
}

export default {
// search,
create,
useHighQuality,
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @ts-check

import cloudinary from './cloudinary/index.js';
import { create } from './videoWrapper/index.js';

Expand Down Expand Up @@ -30,7 +28,8 @@ export const handler = async (event, context, callback) => {
return throwException(422, 'param URL is mandatory.');
}

let video;
let video: Awaited<ReturnType<typeof create>>;

try {
video = await create(url, {
showPlayIcon: getParam(event, 'showPlayIcon') === 'true',
Expand Down
13 changes: 13 additions & 0 deletions netlify/functions/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type VideoProvider from './videoWrapper/VideoProvider';

export type ImageService = {
// search: (providerName: string, videoId: string) => Promise<unknown>;
create: (source: string, video: VideoProvider, options?: Options) => Promise<{ secure_url: string }>;
useHighQuality: () => boolean;
};

export type Options = {
showPlayIcon?: boolean;
image?: string;
ImageService?: ImageService;
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ export default class Asciinema extends VideoProvider {
}

getThumbnail_asVideoUrl() {
return new Promise((resolve) => resolve(`${this.url}.svg`));
return Promise.resolve(`${this.url}.svg`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ export default class CleanShotCloud extends VideoProvider {
return fetch(this.url)
.then((response) => response.text())
.then((html) => {
return parse(html).querySelector('[property="og:image"]').getAttribute('content');
return parse(html)?.querySelector('[property="og:image"]')?.getAttribute('content');
})
.then((image) => {
if (this.options.showPlayIcon) {
return image;
}

return image.replace(/\/draw\(image\(.*\),position:center\)/, '').replace(/&?play=1/, '');
});
return image?.replace(/\/draw\(image\(.*\),position:center\)/, '').replace(/&?play=1/, '');
})
.then((image) => image ?? null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export default class GoogleDrive extends VideoProvider {
}

getThumbnail_asVideoUrl() {
return new Promise((resolve) =>
resolve(`https://drive.google.com/thumbnail?authuser=0&sz=w1280&id=${this.getId()}`),
);
return Promise.resolve(`https://drive.google.com/thumbnail?authuser=0&sz=w1280&id=${this.getId()}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ export default class Imgur extends VideoProvider {
}

getThumbnail_asVideoUrl() {
return new Promise((resolve) => resolve(`${this.url}.jpg`));
return Promise.resolve(`${this.url}.jpg`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default class OneDrive extends VideoProvider {

if (redeem != null) {
this.log('auth', 'authentication required');
const [, appId] = text.match(/"clientId":"([\w-]+)"/);
const [, appId] = text.match(/"clientId":"([\w-]+)"/) ?? [];
this.log('appId', appId);
const auth = await fetch('https://api-badgerp.svc.ms/v1.0/token', {
headers: {
Expand Down Expand Up @@ -109,7 +109,13 @@ export default class OneDrive extends VideoProvider {
});
}
})
.then((res) => res.json())
.then((res) => {
if (res == null) {
throw new Error('Cannot elaborate the request.');
}

return res.json();
})
.then((json) => {
const [firstThumbnail] = json.value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class PeerTube extends VideoProvider {
return fetch(this.url)
.then((response) => response.text())
.then((html) => {
const platform = htmlMiner(html, (arg) => arg.$('[property="og:platform"]').attr('content'));
const platform = parse(html)?.querySelector('[property="og:platform"]')?.getAttribute('content');

if (platform !== 'PeerTube') {
throw new Error(`'og:platform' does not match PeerTube`);
Expand All @@ -28,7 +28,8 @@ export default class PeerTube extends VideoProvider {
return html;
})
.then((html) => {
return parse(html).querySelector('[property="og:image"]').getAttribute('content');
});
return parse(html)?.querySelector('[property="og:image"]')?.getAttribute('content');
})
.then((url) => url ?? null);
}
}
34 changes: 0 additions & 34 deletions netlify/functions/videoWrapper/Providers/Streamable.js

This file was deleted.

28 changes: 28 additions & 0 deletions netlify/functions/videoWrapper/Providers/Streamable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import VideoProvider from '../VideoProvider.js';

// https://support.streamable.com/api-documentation

export default class Streamable extends VideoProvider {
get providerName() {
return 'streamable';
}

static get regex() {
return [
// - //streamable.com/1nvj5i
/https?\:\/\/streamable\.com\/([a-z0-9]+)/,
];
}

needsCloudinary() {
return true;
}

getThumbnail_asVideoUrl() {
const endpoint = `https://api.streamable.com/oembed.json?url=${encodeURIComponent(`https://streamable.com/${this.getId()}`)}`;

return fetch(endpoint)
.then((response) => response.json())
.then((json) => json.thumbnail_url);
}
}
22 changes: 0 additions & 22 deletions netlify/functions/videoWrapper/Providers/Video.js

This file was deleted.

25 changes: 25 additions & 0 deletions netlify/functions/videoWrapper/Providers/Video.ts

Large diffs are not rendered by default.

Loading

0 comments on commit a71551b

Please sign in to comment.