1 line
No EOL
17 KiB
JavaScript
1 line
No EOL
17 KiB
JavaScript
import ApiClient from"./apiclient.js";import LocalAssetManager from"./../localdatabase/localassetmanager.js";import{itemRepository,userActionRepository}from"./../common/servicelocator.js";let localPrefix="local:",localViewPrefix="localview:";function isLocalId(str){return str&&str.startsWith("local")}function mapToId(i){return i.Id}function isLocalViewId(str){return str&&str.startsWith(localViewPrefix)}function isTopLevelLocalViewId(str){return"localview"===str}function stripLocalPrefix(str){str=stripStart(str,localPrefix);return stripStart(str,localViewPrefix)}function stripStart(str,find){return str&&find&&str.startsWith(find)?str.substr(find.length):str}function normalizeId(id){return id?(id=stripStart(id,"localview:"),stripStart(id,"local:")):null}function convertIdToLocal(guid){return guid?isLocalId(guid)?guid:localPrefix+guid:null}function syncNow(){require(["localsync"],function(localSync){localSync.sync()})}function getLocalUrl({MediaSources}){return MediaSources&&MediaSources.length?(MediaSources=MediaSources[0]).StreamUrl||MediaSources.Path:""}function getMusicFolders(serverId){var list=[];return list.push({Name:"Albums",ServerId:serverId,Id:"localview:MusicAlbumsView",Type:"MusicAlbumsView",IsFolder:!0}),list.push({Name:"Songs",ServerId:serverId,Id:"localview:MusicSongsView",Type:"MusicSongsView",IsFolder:!0}),list}function getTopLevelViews(serverId,types,forceIncludeAll){var list=[];return(types.includes("Audio")||forceIncludeAll)&&list.push({Name:"Music",ServerId:serverId,Id:"localview:MusicView",Type:"MusicView",CollectionType:"music",IsFolder:!0}),(types.includes("Photo")||forceIncludeAll)&&list.push({Name:"Photos",ServerId:serverId,Id:"localview:PhotosView",Type:"PhotosView",CollectionType:"photos",IsFolder:!0}),(types.includes("Episode")||forceIncludeAll)&&list.push({Name:"TV",ServerId:serverId,Id:"localview:TVView",Type:"TVView",CollectionType:"tvshows",IsFolder:!0}),(types.includes("Movie")||forceIncludeAll)&&list.push({Name:"Movies",ServerId:serverId,Id:"localview:MoviesView",Type:"MoviesView",CollectionType:"movies",IsFolder:!0}),(types.includes("Video")||forceIncludeAll)&&list.push({Name:"Videos",ServerId:serverId,Id:"localview:VideosView",Type:"VideosView",IsFolder:!0}),(types.includes("MusicVideo")||forceIncludeAll)&&list.push({Name:"Music Videos",ServerId:serverId,Id:"localview:MusicVideosView",Type:"MusicVideosView",CollectionType:"musicvideos",IsFolder:!0}),(types.includes("Trailer")||forceIncludeAll)&&list.push({Name:"Trailers",ServerId:serverId,Id:"localview:TrailersView",Type:"TrailersView",IsFolder:!0}),list}function getAllPossibleLocalViews(serverId){let list=getTopLevelViews(serverId,[],!0);return list=list.concat(getMusicFolders(serverId)),Promise.resolve(list)}function toQueryResult(items){return{Items:items,TotalRecordCount:items.length}}function getDownloadedItems(serverId,options){switch(normalizeId(options.ParentId)){case"MusicView":if(options.Recursive)break;return Promise.resolve(toQueryResult(getMusicFolders(serverId)))}return itemRepository.getLibraryItems(serverId,options)}function getViews(serverId){return itemRepository.getLibarytemTypes(serverId).then(types=>getTopLevelViews(serverId,types))}function createGuid(){let d=Date.now();return window.performance&&"function"==typeof window.performance.now&&(d+=performance.now()),"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,c=>{var r=(d+16*Math.random())%16|0;return d=Math.floor(d/16),("x"===c?r:3&r|8).toString(16)})}function adjustIdProperties(downloadedItem){downloadedItem.Id=convertIdToLocal(downloadedItem.Id),downloadedItem.SeriesId=convertIdToLocal(downloadedItem.SeriesId),downloadedItem.SeasonId=convertIdToLocal(downloadedItem.SeasonId),downloadedItem.AlbumId=convertIdToLocal(downloadedItem.AlbumId),downloadedItem.ParentId=convertIdToLocal(downloadedItem.ParentId),downloadedItem.ParentThumbItemId=convertIdToLocal(downloadedItem.ParentThumbItemId),downloadedItem.ParentPrimaryImageItemId=convertIdToLocal(downloadedItem.ParentPrimaryImageItemId),downloadedItem.PrimaryImageItemId=convertIdToLocal(downloadedItem.PrimaryImageItemId),downloadedItem.ParentLogoItemId=convertIdToLocal(downloadedItem.ParentLogoItemId),downloadedItem.ParentBackdropItemId=convertIdToLocal(downloadedItem.ParentBackdropItemId),downloadedItem.ParentBackdropImageTags=null}function getLocalView(instance,serverId,userId){return instance.getLocalFolders(serverId,userId).then(function(views){let localView=null;return 0<views.length&&(localView={Name:instance.downloadsTitleText||"Downloads",ServerId:serverId,Id:"localview",Type:"localview",IsFolder:!0}),Promise.resolve(localView)})}function updateFavoriteStatus(instance,serverId,itemId,isFavorite){return itemRepository.getLibraryItem(serverId,stripLocalPrefix(itemId)).then(item=>{var libraryItem=item.Item;return libraryItem.UserData=libraryItem.UserData||{},libraryItem.UserData.IsFavorite=isFavorite,itemRepository.updateLibraryItem(item.ServerId,item.Id,item).then(function(){return Promise.resolve()})})}function markPlayed(instance,serverId,itemId,date){return itemRepository.getLibraryItem(serverId,stripLocalPrefix(itemId)).then(item=>{var libraryItem=item.Item;return libraryItem.UserData=libraryItem.UserData||{},libraryItem.UserData.Played=!0,itemRepository.updateLibraryItem(item.ServerId,item.Id,item).then(function(){return Promise.resolve()})})}function markUnplayed(instance,serverId,itemId){return itemRepository.getLibraryItem(serverId,stripLocalPrefix(itemId)).then(item=>{var libraryItem=item.Item;return libraryItem.UserData=libraryItem.UserData||{},libraryItem.UserData.Played=!1,itemRepository.updateLibraryItem(item.ServerId,item.Id,item).then(function(){return Promise.resolve()})})}function getRandomInt(min,max){min=Math.ceil(min),max=Math.floor(max);return Math.floor(Math.random()*(max-min)+min)}let PlaySessionIdPrefix=Date.now()+"_"+getRandomInt(1,1e5);function nextPlaySessionId(){return PlaySessionIdPrefix+"_"+Date.now()}class ApiClientEx extends ApiClient{constructor(serverAddress,appName,appVersion,deviceName,deviceId,devicePixelRatio){super(serverAddress,appName,appVersion,deviceName,deviceId,devicePixelRatio)}getPlaybackInfo(itemId,options,deviceProfile,signal){var promises=[];return isLocalId(itemId)||options&&isLocalId(options.MediaSourceId)?promises.push(Promise.resolve({MediaSources:[],PlaySessionId:nextPlaySessionId()})):promises.push(super.getPlaybackInfo.apply(this,arguments)),options&&options.MediaSourceId&&!isLocalId(options.MediaSourceId)?promises.push(Promise.resolve({MediaSources:[],PlaySessionId:nextPlaySessionId()})):promises.push(itemRepository.getLibraryItem(this.serverId(),stripLocalPrefix(itemId)).then(item=>!item||item.SyncStatus&&"synced"!==item.SyncStatus?{MediaSources:[],PlaySessionId:nextPlaySessionId()}:{MediaSources:item.Item.MediaSources.map(m=>(null!=options.AudioStreamIndex&&(m.DefaultAudioStreamIndex=parseInt(options.AudioStreamIndex)),null!=options.SubtitleStreamIndex&&(m.DefaultSubtitleStreamIndex=parseInt(options.SubtitleStreamIndex)),m.SupportsDirectPlay=!0,m.SupportsDirectStream=!1,m.SupportsTranscoding=!1,m.IsLocal=!0,m.Name="Downloaded version",m.Id=localPrefix+item.Item.Id,m)),PlaySessionId:nextPlaySessionId()})),Promise.all(promises).then(results=>{var result=results[0],localResult=results[1];for(let i=0,length=localResult.MediaSources.length;i<length;i++)result.MediaSources.unshift(localResult.MediaSources[i]);return result})}getAudioStreamUrl(item,transcodingProfile,directPlayContainers,maxBitrate,maxAudioSampleRate,maxAudioBitDepth,startPosition,enableRemoteMedia){if(isLocalId(item.Id)&&(item.MediaSources&&item.MediaSources.length))return(item=item.MediaSources[0]).StreamUrl||item.Path;return super.getAudioStreamUrl.apply(this,arguments)}getAudioStreamUrls(items,transcodingProfile,directPlayContainers,maxBitrate,maxAudioSampleRate,maxAudioBitDepth,startPosition,enableRemoteMedia){if(!items.length)return Promise.resolve([]);if(isLocalId(items[0].Id))return Promise.resolve(items.map(getLocalUrl));let self=this;var ids=items.map(({Id})=>Id);return itemRepository.getLibraryItemPathsByIds(items[0].ServerId,ids).then(localItems=>{let localItemMap={};var localUrls=localItems.map(libraryItem=>(localItemMap[libraryItem.ItemId]=libraryItem).LocalPath);if(localUrls.length===items.length)return localUrls;if(localItems.length){var streamUrls=[];for(let i=0;i<items.length;i++){var item=items[i];let streamUrl;streamUrl=localItemMap[item.Id]?localItemMap[item.Id].LocalPath:super.getAudioStreamUrl.call(self,item,transcodingProfile,directPlayContainers,maxBitrate,maxAudioSampleRate,maxAudioBitDepth,startPosition,enableRemoteMedia),streamUrls.push(streamUrl||"")}return streamUrls}return super.getAudioStreamUrls.call(self,items,transcodingProfile,directPlayContainers,maxBitrate,maxAudioSampleRate,maxAudioBitDepth,startPosition,enableRemoteMedia)})}getItems(userId,options){var serverInfo=this.serverInfo();let i;if(serverInfo&&"localview"===options.ParentId)return this.getLocalFolders(serverInfo.Id,userId).then(items=>{items={Items:items,TotalRecordCount:items.length};return Promise.resolve(items)});if(serverInfo&&options&&(isLocalId(options.ParentId)||isLocalId(options.SeriesId)||isLocalId(options.SeasonId)||isLocalId(options.AlbumIds)))return getDownloadedItems(serverInfo.Id,options).then(result=>(result.Items.forEach(item=>{adjustIdProperties(item)}),Promise.resolve(result)));if(options&&options.ExcludeItemIds&&options.ExcludeItemIds.length){var exItems=options.ExcludeItemIds.split(",");for(i=0;i<exItems.length;i++)if(isLocalId(exItems[i]))return Promise.resolve({Items:[],TotalRecordCount:0})}else if(options&&options.Ids&&options.Ids.length){var ids=options.Ids.split(",");let hasLocal=!1;for(i=0;i<ids.length;i++)if(isLocalId(ids[i])){hasLocal=!0;break}if(hasLocal)return userId=ids.map(stripLocalPrefix),itemRepository.getLibraryItemsByIds(serverInfo.Id,userId).then(items=>{items.forEach(({Item})=>{adjustIdProperties(Item)});items=items.map(({Item})=>Item),items={Items:items,TotalRecordCount:items.length};return Promise.resolve(items)})}return super.getItems.apply(this,arguments)}getItem(userId,itemId,options){if(!itemId)throw new Error("null itemId");let serverInfo;return isTopLevelLocalViewId(itemId=itemId&&itemId.toString())&&(serverInfo=this.serverInfo())?getLocalView(this,serverInfo.Id,userId):isLocalViewId(itemId)&&(serverInfo=this.serverInfo())?getAllPossibleLocalViews(serverInfo.Id).then(items=>{items=items.filter(({Id})=>Id===itemId);return 0<items.length?Promise.resolve(items[0]):Promise.reject()}):isLocalId(itemId)?(serverInfo=this.serverInfo())?itemRepository.getLibraryItem(serverInfo.Id,stripLocalPrefix(itemId)).then(item=>item?(adjustIdProperties(item.Item),Promise.resolve(item.Item)):Promise.reject()):Promise.reject():super.getItem.apply(this,arguments)}getLocalFolders(userId){var serverInfo=this.serverInfo();return userId=userId||serverInfo.UserId,getViews(serverInfo.Id,userId).catch(()=>[])}getSeasons(itemId,options){return isLocalId(itemId)?(options.SeriesId=itemId,options.IncludeItemTypes="Season",options.SortBy=options.Recursive?"ParentIndexNumber,IndexNumber":"IndexNumber",this.getItems(this.getCurrentUserId(),options)):super.getSeasons.apply(this,arguments)}getEpisodes(itemId,options){return isLocalId(options.SeasonId)||isLocalId(options.seasonId)||isLocalId(itemId)?(options.SeriesId=itemId,options.IncludeItemTypes="Episode",options.SortBy="ParentIndexNumber,IndexNumber,SortName",this.getItems(this.getCurrentUserId(),options)):super.getEpisodes.apply(this,arguments)}getLatestOfflineItems(options){options.SortBy="DateCreated",options.SortOrder="Descending",options.EnableTotalRecordCount=!1;var serverInfo=this.serverInfo();return serverInfo?itemRepository.getLibraryItems(serverInfo.Id,options).then(({Items})=>(Items.forEach(item=>{adjustIdProperties(item)}),Promise.resolve(Items))):Promise.resolve([])}getImageUrl(itemId,options){var serverInfo;return isLocalId(itemId)||options&&options.itemid&&isLocalId(options.itemid)?(serverInfo=this.serverInfo(),itemId=stripLocalPrefix(itemId),LocalAssetManager.getImageUrl(serverInfo.Id,itemId,options)):super.getImageUrl.apply(this,arguments)}updateFavoriteStatus(userId,itemIds,isFavorite){let instance=this;return super.updateFavoriteStatus.apply(this,arguments).then(function(response){let promise;if(0<(itemIds=itemIds.filter(isLocalId)).length){let serverInfo=this.serverInfo();var promises;serverInfo&&(promises=itemIds.map(function(itemId){return updateFavoriteStatus(instance,serverInfo.Id,itemId,isFavorite)}),promise=Promise.all(promises))}return(promise||Promise.resolve()).then(function(){return response})})}markPlayed(userId,itemIds,date){let instance=this;return super.markPlayed.apply(this,arguments).then(function(response){let promise;if(0<(itemIds=itemIds.filter(isLocalId)).length){let serverInfo=this.serverInfo();var promises;serverInfo&&(promises=itemIds.map(function(itemId){return markPlayed(instance,serverInfo.Id,itemId,date)}),promise=Promise.all(promises))}return(promise||Promise.resolve()).then(function(){return response})})}markUnplayed(userId,itemIds){let instance=this;return super.markUnplayed.apply(this,arguments).then(function(response){let promise;if(0<(itemIds=itemIds.filter(isLocalId)).length){let serverInfo=this.serverInfo();var promises;serverInfo&&(promises=itemIds.map(function(itemId){return markUnplayed(instance,serverInfo.Id,itemId)}),promise=Promise.all(promises))}return(promise||Promise.resolve()).then(function(){return response})})}reportPlaybackStart(options){if(options)return isLocalId(options.ItemId)?Promise.resolve():super.reportPlaybackStart.apply(this,arguments);throw new Error("null options")}reportPlaybackProgress(options){if(!options)throw new Error("null options");let localPromise,localId=isLocalId(options.ItemId)?options.ItemId:isLocalId(options.MediaSourceId)?options.MediaSourceId:null;localId&&(serverInfo=this.serverInfo())&&(localPromise=itemRepository.getLibraryItem(serverInfo.Id,stripLocalPrefix(localId)).then(item=>{var libraryItem;return item?"Video"===(libraryItem=item.Item).MediaType?(libraryItem.UserData=libraryItem.UserData||{},libraryItem.UserData.PlaybackPositionTicks=options.PositionTicks,libraryItem.UserData.PlayedPercentage=Math.min(libraryItem.RunTimeTicks?(options.PositionTicks||0)/libraryItem.RunTimeTicks*100:0,100),libraryItem.UserData.PlaybackPositionTicks&&libraryItem.RunTimeTicks&&libraryItem.UserData.PlaybackPositionTicks>=.9*libraryItem.RunTimeTicks&&(libraryItem.UserData.Played=!0,libraryItem.UserData.PlaybackPositionTicks=0,libraryItem.UserData.PlayedPercentage=0),itemRepository.updateLibraryItem(item.ServerId,item.Id,item)):void 0:(console.log("item not found in local database: "+stripLocalPrefix(localId)),Promise.resolve())}));var serverInfo=isLocalId(options.ItemId)?Promise.resolve():super.reportPlaybackProgress.apply(this,arguments);return Promise.all([localPromise||Promise.resolve(),serverInfo])}reportPlaybackStopped(options){if(!options)throw new Error("null options");let localPromise,localId=isLocalId(options.ItemId)?options.ItemId:isLocalId(options.MediaSourceId)?options.MediaSourceId:null;if(localId){let serverInfo=this.serverInfo();if(serverInfo){let instance=this;localPromise=itemRepository.getLibraryItem(serverInfo.Id,stripLocalPrefix(localId)).then(item=>{var libraryItem;return item?"Video"===(libraryItem=item.Item).MediaType?(libraryItem.UserData=libraryItem.UserData||{},libraryItem.UserData.PlaybackPositionTicks=options.PositionTicks,libraryItem.UserData.PlayedPercentage=Math.min(libraryItem.RunTimeTicks?(options.PositionTicks||0)/libraryItem.RunTimeTicks*100:0,100),libraryItem.UserData.PlaybackPositionTicks&&libraryItem.RunTimeTicks&&libraryItem.UserData.PlaybackPositionTicks>=.9*libraryItem.RunTimeTicks&&(libraryItem.UserData.Played=!0,libraryItem.UserData.PlaybackPositionTicks=0,libraryItem.UserData.PlayedPercentage=0),itemRepository.updateLibraryItem(item.ServerId,item.Id,item).then(function(){var action;return isLocalId(options.ItemId)?(action={Date:(new Date).toISOString(),ItemId:stripLocalPrefix(localId),PositionTicks:options.PositionTicks,ServerId:serverInfo.Id,Type:"PlayedItem",UserId:instance.getCurrentUserId(),Id:createGuid()},userActionRepository.addUserAction(action.Id,action)):Promise.resolve()})):void 0:(console.log("item not found in local database: "+stripLocalPrefix(localId)),Promise.resolve())})}}var serverPromise=isLocalId(options.ItemId)?Promise.resolve():super.reportPlaybackStopped.apply(this,arguments);return Promise.all([localPromise||Promise.resolve(),serverPromise])}getLiveTvPrograms(options={}){return options&&options.LibrarySeriesId&&isLocalId(options.LibrarySeriesId)?Promise.resolve({Items:[],TotalRecordCount:0}):super.getLiveTvPrograms.apply(this,arguments)}getItemDownloadUrl(itemId,mediaSourceId){itemId=isLocalId(itemId)?itemId:isLocalId(mediaSourceId)?mediaSourceId:null;return itemId?(mediaSourceId=this.serverInfo())?itemRepository.getLibraryItem(mediaSourceId.Id,stripLocalPrefix(itemId)).then(({LocalPath})=>Promise.resolve(LocalPath)):Promise.reject():super.getItemDownloadUrl.apply(this,arguments)}deleteItemsInternal(items){if(!items)throw new Error("null itemId");let itemIds=items.map(mapToId).filter(isLocalId),instance=this;return super.deleteItemsInternal.apply(instance,arguments).then(function(){return Promise.all(itemIds.map(function(itemId){return itemRepository.getLibraryItem(instance.serverId(),stripLocalPrefix(itemId)).then(item=>item?LocalAssetManager.removeLocalItem(item).then(syncNow):Promise.resolve())}))})}}export default ApiClientEx; |