Skip to content

Commit

Permalink
Merge pull request #12 from smudge/thumbnail-path
Browse files Browse the repository at this point in the history
Obey relative path when downloading thumbnail.
  • Loading branch information
sundevista authored May 7, 2024
2 parents 42a7724 + a684832 commit c964558
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 54 deletions.
53 changes: 23 additions & 30 deletions src/apis/youtube.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { App, TFolder, requestUrl } from 'obsidian';
import { filterStringData, getAttachmentFolder, parseChapters, parseISODuration, parseVideoId } from 'src/utils/parser';
import { filterStringData, parseChapters, parseISODuration, parseVideoId } from 'src/utils/parser';
import { YouTubeTemplatePluginSettings } from '../settings';
import { VideoData } from '../types/video-data';
import { ChannelListResponse, Thumbnail, VideoListResponse } from '../types/youtube-response';
Expand All @@ -17,10 +17,7 @@ const baseUrlForChannels = 'https://www.googleapis.com/youtube/v3/channels?';
export async function getVideoData(
videoUrl: string,
settings: YouTubeTemplatePluginSettings,
downloadThumbnail: boolean,
): Promise<VideoData> {
let thumbnailFileLink = '';

try {
const videoResponse: VideoListResponse = await requestUrl(
baseUrlForVideos + `part=snippet,contentDetails&id=${parseVideoId(videoUrl)}&key=${settings.googleCloudApiKey}`,
Expand All @@ -40,15 +37,6 @@ export async function getVideoData(

const thumbnailUrl = getBestThumbnailUrl(Object.values(videoResponse.items[0].snippet.thumbnails));

if (downloadThumbnail) {
thumbnailFileLink =
(await downloadVideoThumbnail(
this.app,
settings.createPaths,
Object.values(videoResponse.items[0].snippet.thumbnails),
)) ?? '';
}

return {
id: videoResponse.items[0].id,
title: filterStringData(videoResponse.items[0].snippet.title),
Expand All @@ -57,7 +45,7 @@ export async function getVideoData(
length: parseISODuration(videoResponse.items[0].contentDetails.duration),
//@ts-ignore
publishDate: moment(videoResponse.items[0].snippet.publishedAt).format('YYYY-MM-DD'),
thumbnail: thumbnailFileLink ?? '',
thumbnail: '',
thumbnailUrl,
chapters: parseChapters(videoResponse.items[0].snippet.description).map(
(chapter) => `${chapter.timestamp} ${filterStringData(chapter.title)}`,
Expand Down Expand Up @@ -94,26 +82,31 @@ function getBestThumbnailUrl(availableThumbnails: Thumbnail[]): string {
export async function downloadVideoThumbnail(
app: App,
createFolders: boolean,
availableThumbnails: Thumbnail[],
imageUrl: string,
title: string,
path: string,
): Promise<string | undefined> {
const imageUrl = getBestThumbnailUrl(availableThumbnails);
const response = await requestUrl(imageUrl);

const filename = `${new Date().getTime()}.${imageUrl.split('.').pop()}`;
const attachmentFolderPath = getAttachmentFolder(app);
const abstractFile = this.app.vault.getAbstractFileByPath(attachmentFolderPath);

if (!(abstractFile instanceof TFolder)) {
if (createFolders) {
await app.vault.createFolder(attachmentFolderPath);
} else {
throw new Error(
`Attachment folder '${attachmentFolderPath}' does not exist. Check if the folder path is correct in your Settings → Files and links → Default location for new attachments. Or you can turn on option 'Create folders' in the plugin settings.`,
);
const attachmentFolderPath = app.vault.getConfig('attachmentFolderPath');
const filename = `${title}.${imageUrl.split('.').pop()}`;
let fullpath;
if (attachmentFolderPath.startsWith('./') && attachmentFolderPath.length === 2) {
fullpath = `${path}/${filename}`;
} else {
const abstractFile = this.app.vault.getAbstractFileByPath(attachmentFolderPath);
if (!(abstractFile instanceof TFolder)) {
if (createFolders) {
await app.vault.createFolder(attachmentFolderPath);
} else {
throw new Error(
`Attachment folder '${attachmentFolderPath}' does not exist. Check if the folder path is correct in your Settings → Files and links → Default location for new attachments. Or you can turn on option 'Create folders' in the plugin settings.`,
);
}
}
fullpath = `${app.vault.getConfig('attachmentFolderPath')}/${filename}`;
}

await app.vault.createBinary(`${app.vault.getConfig('attachmentFolderPath')}/${filename}`, response.arrayBuffer);
const response = await requestUrl(imageUrl);
await app.vault.createBinary(fullpath, response.arrayBuffer);

return filename;
}
23 changes: 17 additions & 6 deletions src/modals/insert-template.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { App, Modal, Notice, Setting, TextComponent, normalizePath } from 'obsidian';
import { findTFile } from 'src/utils/file';
import { checkPathTemplate, filterFilename } from 'src/utils/parser';
import { getVideoData } from '../apis/youtube';
import { getVideoData, downloadVideoThumbnail } from '../apis/youtube';
import YoutubeTemplatePlugin from '../main';
import { NO_CHANNEL_ERROR, NO_INTERNET_ERROR, NO_VIDEO_ERROR, WRONG_API_KEY_ERROR } from '../utils/constants';
import { processPathTemplate, processTemplate } from '../utils/templater';
Expand All @@ -25,16 +25,14 @@ export class InsertTemplateModal extends Modal {

// Get the video data from youtube APIs
try {
const downloadVideoThumbnail = this.plugin.settings.template.contains('{{thumbnail}}');

const data = await getVideoData(this.videoUrl, this.plugin.settings, downloadVideoThumbnail);
const data = await getVideoData(this.videoUrl, this.plugin.settings);

if (!this.app.vault.getAbstractFileByPath(this.plugin.settings.folder)) {
if (this.plugin.settings.createPaths) {
await this.app.vault.createFolder(this.plugin.settings.folder);
} else {
throw new Error(`Folder '${this.plugin.settings.folder}' does not exist`);
}

throw new Error(`Folder '${this.plugin.settings.folder}' does not exist`);
}

// Create a new file with the title of the video
Expand All @@ -57,6 +55,19 @@ export class InsertTemplateModal extends Modal {
await this.app.vault.createFolder(filepath.substring(0, filepath.lastIndexOf('/')));
}

let thumbnailFileLink = '';
if (this.plugin.settings.template.contains('{{thumbnail}}')) {
thumbnailFileLink =
(await downloadVideoThumbnail(
this.app,
this.plugin.settings.createPaths,
data.thumbnailUrl,
filterFilename(data.title),
filepath.substring(0, filepath.lastIndexOf('/')),
)) ?? '';
}
data.thumbnail = thumbnailFileLink;

const dataToWrite = await processTemplate(data, this.plugin.settings, this.app);

await this.app.vault.create(filepath, dataToWrite);
Expand Down
18 changes: 0 additions & 18 deletions src/utils/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,3 @@ export function filterFilename(text: string): string {
export function filterStringData(text: string): string {
return text.replace(/"(.*?)"/g, '«$1»').replace(/["]/g, '');
}

export function getAttachmentFolder(app: App): string {
const attachentPath = app.vault.getConfig('attachmentFolderPath');

if (attachentPath.startsWith('./')) {
if (attachentPath.length === 2) return '/';

const activeFile = app.workspace.getActiveFile();
if (!activeFile) throw new Error("No active file. Can't parse the path for the attachment folder.");

let parentFolder = activeFile?.parent?.path;
if (parentFolder?.startsWith('/')) parentFolder = parentFolder.substring(1);

return parentFolder + attachentPath.substring(2);
}

return attachentPath;
}

0 comments on commit c964558

Please sign in to comment.