@@ -2,6 +2,8 @@ import { Notice, TFile, requestUrl } from "obsidian";
22import { downloadedEpisodes } from "./store" ;
33import { DownloadPathTemplateEngine } from "./TemplateEngine" ;
44import type { Episode } from "./types/Episode" ;
5+ import type { LocalEpisode } from "./types/LocalEpisode" ;
6+ import { isLocalFile } from "./utility/isLocalFile" ;
57import getUrlExtension from "./utility/getUrlExtension" ;
68
79function getErrorMessage ( error : unknown ) : string {
@@ -179,10 +181,71 @@ async function createEpisodeFile({
179181 downloadedEpisodes . addEpisode ( episode , filePath , blob . size ) ;
180182}
181183
184+ function resolveLocalEpisodeFilePath ( episode : LocalEpisode ) : string | null {
185+ const downloadedEpisode = downloadedEpisodes . getEpisode ( episode ) ;
186+ const candidatePaths = [
187+ episode . filePath ,
188+ downloadedEpisode ?. filePath ,
189+ getLocalFilePathFromLink ( episode . url ) ,
190+ ] ;
191+
192+ for ( const possiblePath of candidatePaths ) {
193+ if ( ! possiblePath ) continue ;
194+
195+ const file = app . vault . getAbstractFileByPath ( possiblePath ) ;
196+ if ( file instanceof TFile ) {
197+ return file . path ;
198+ }
199+ }
200+
201+ return null ;
202+ }
203+
204+ function getLocalFilePathFromLink ( link : string ) : string | null {
205+ if ( ! link ) return null ;
206+
207+ const trimmedLink = link . trim ( ) ;
208+ if ( ! trimmedLink ) return null ;
209+
210+ const innerLink = trimmedLink . match ( / ^ \[ \[ ( .* ) \] \] $ / ) ?. [ 1 ] ?? trimmedLink ;
211+ const [ target ] = innerLink . split ( "|" ) ;
212+ const normalizedTarget = target ?. trim ( ) ;
213+
214+ if ( ! normalizedTarget ) {
215+ return null ;
216+ }
217+
218+ const directFile = app . vault . getAbstractFileByPath ( normalizedTarget ) ;
219+ if ( directFile instanceof TFile ) {
220+ return directFile . path ;
221+ }
222+
223+ const linkedFile = app . metadataCache ?. getFirstLinkpathDest (
224+ normalizedTarget ,
225+ "" ,
226+ ) ;
227+ if ( linkedFile instanceof TFile ) {
228+ return linkedFile . path ;
229+ }
230+
231+ return null ;
232+ }
233+
182234export async function downloadEpisode (
183235 episode : Episode ,
184236 downloadPathTemplate : string ,
185237) : Promise < string > {
238+ if ( isLocalFile ( episode ) ) {
239+ const localFilePath = resolveLocalEpisodeFilePath ( episode ) ;
240+ if ( ! localFilePath ) {
241+ throw new Error (
242+ `Unable to locate the local audio file for "${ episode . title } ". Try playing the file again.` ,
243+ ) ;
244+ }
245+
246+ return localFilePath ;
247+ }
248+
186249 const basename = DownloadPathTemplateEngine ( downloadPathTemplate , episode ) ;
187250 const fileExtension = await getFileExtension ( episode . streamUrl ) ;
188251 const filePath = `${ basename } .${ fileExtension } ` ;
0 commit comments