406 lines
No EOL
18 KiB
JavaScript
406 lines
No EOL
18 KiB
JavaScript
define(["filerepository", "itemrepository", "useractionrepository", "transfermanager"], function(filerepository, itemrepository, useractionrepository, transfermanager) {
|
|
"use strict";
|
|
|
|
function getLocalItem(serverId, itemId) {
|
|
return console.log("[lcoalassetmanager] Begin getLocalItem"), itemrepository.get(serverId, itemId)
|
|
}
|
|
|
|
function recordUserAction(action) {
|
|
return action.Id = createGuid(), useractionrepository.set(action.Id, action)
|
|
}
|
|
|
|
function getUserActions(serverId) {
|
|
return useractionrepository.getByServerId(serverId)
|
|
}
|
|
|
|
function deleteUserAction(action) {
|
|
return useractionrepository.remove(action.Id)
|
|
}
|
|
|
|
function deleteUserActions(actions) {
|
|
var results = [];
|
|
return actions.forEach(function(action) {
|
|
results.push(deleteUserAction(action))
|
|
}), Promise.all(results)
|
|
}
|
|
|
|
function getServerItems(serverId) {
|
|
return console.log("[localassetmanager] Begin getServerItems"), itemrepository.getAll(serverId)
|
|
}
|
|
|
|
function getItemsFromIds(serverId, ids) {
|
|
var actions = ids.map(function(id) {
|
|
var strippedId = stripStart(id, "local:");
|
|
return getLocalItem(serverId, strippedId)
|
|
});
|
|
return Promise.all(actions).then(function(items) {
|
|
var libItems = items.map(function(locItem) {
|
|
return locItem.Item
|
|
});
|
|
return Promise.resolve(libItems)
|
|
})
|
|
}
|
|
|
|
function getViews(serverId, userId) {
|
|
return itemrepository.getServerItemTypes(serverId, userId).then(function(types) {
|
|
var item, list = [];
|
|
return types.indexOf("Audio") > -1 && (item = {
|
|
Name: "Music",
|
|
ServerId: serverId,
|
|
Id: "localview:MusicView",
|
|
Type: "MusicView",
|
|
CollectionType: "music",
|
|
IsFolder: !0
|
|
}, list.push(item)), types.indexOf("Photo") > -1 && (item = {
|
|
Name: "Photos",
|
|
ServerId: serverId,
|
|
Id: "localview:PhotosView",
|
|
Type: "PhotosView",
|
|
CollectionType: "photos",
|
|
IsFolder: !0
|
|
}, list.push(item)), types.indexOf("Episode") > -1 && (item = {
|
|
Name: "TV",
|
|
ServerId: serverId,
|
|
Id: "localview:TVView",
|
|
Type: "TVView",
|
|
CollectionType: "tvshows",
|
|
IsFolder: !0
|
|
}, list.push(item)), types.indexOf("Movie") > -1 && (item = {
|
|
Name: "Movies",
|
|
ServerId: serverId,
|
|
Id: "localview:MoviesView",
|
|
Type: "MoviesView",
|
|
CollectionType: "movies",
|
|
IsFolder: !0
|
|
}, list.push(item)), types.indexOf("Video") > -1 && (item = {
|
|
Name: "Videos",
|
|
ServerId: serverId,
|
|
Id: "localview:VideosView",
|
|
Type: "VideosView",
|
|
CollectionType: "videos",
|
|
IsFolder: !0
|
|
}, list.push(item)), types.indexOf("MusicVideo") > -1 && (item = {
|
|
Name: "Music Videos",
|
|
ServerId: serverId,
|
|
Id: "localview:MusicVideosView",
|
|
Type: "MusicVideosView",
|
|
CollectionType: "videos",
|
|
IsFolder: !0
|
|
}, list.push(item)), Promise.resolve(list)
|
|
})
|
|
}
|
|
|
|
function updateFiltersForTopLevelView(parentId, mediaTypes, includeItemTypes, query) {
|
|
switch (parentId) {
|
|
case "MusicView":
|
|
return query.Recursive ? includeItemTypes.push("Audio") : includeItemTypes.push("MusicAlbum"), !0;
|
|
case "PhotosView":
|
|
return query.Recursive ? includeItemTypes.push("Photo") : includeItemTypes.push("PhotoAlbum"), !0;
|
|
case "TVView":
|
|
return query.Recursive ? includeItemTypes.push("Episode") : includeItemTypes.push("Series"), !0;
|
|
case "VideosView":
|
|
return query.Recursive, includeItemTypes.push("Video"), !0;
|
|
case "MoviesView":
|
|
return query.Recursive, includeItemTypes.push("Movie"), !0;
|
|
case "MusicVideosView":
|
|
return query.Recursive, includeItemTypes.push("MusicVideo"), !0
|
|
}
|
|
return !1
|
|
}
|
|
|
|
function normalizeId(id) {
|
|
return id ? (id = stripStart(id, "localview:"), id = stripStart(id, "local:")) : null
|
|
}
|
|
|
|
function normalizeIdList(val) {
|
|
return val ? val.split(",").map(normalizeId) : []
|
|
}
|
|
|
|
function shuffle(array) {
|
|
for (var temporaryValue, randomIndex, currentIndex = array.length; 0 !== currentIndex;) randomIndex = Math.floor(Math.random() * currentIndex), currentIndex -= 1, temporaryValue = array[currentIndex], array[currentIndex] = array[randomIndex], array[randomIndex] = temporaryValue;
|
|
return array
|
|
}
|
|
|
|
function sortItems(items, query) {
|
|
if (!query.SortBy || 0 === query.SortBy.length) return items;
|
|
if ("Random" === query.SortBy) return shuffle(items);
|
|
var sortSpec = getSortSpec(query);
|
|
return items.sort(function(a, b) {
|
|
for (var i = 0; i < sortSpec.length; i++) {
|
|
var result = compareValues(a, b, sortSpec[i].Field, sortSpec[i].OrderDescending);
|
|
if (0 !== result) return result
|
|
}
|
|
return 0
|
|
}), items
|
|
}
|
|
|
|
function compareValues(a, b, field, orderDesc) {
|
|
if (!a.hasOwnProperty(field) || !b.hasOwnProperty(field)) return 0;
|
|
var valA = a[field],
|
|
valB = b[field],
|
|
result = 0;
|
|
return "string" == typeof valA || "string" == typeof valB ? (valA = valA || "", valB = valB || "", result = valA.toLowerCase().localeCompare(valB.toLowerCase())) : valA > valB ? result = 1 : valA < valB && (result = -1), orderDesc && (result *= -1), result
|
|
}
|
|
|
|
function getSortSpec(query) {
|
|
for (var sortFields = (query.SortBy || "").split(","), sortOrders = (query.SortOrder || "").split(","), sortSpec = [], i = 0; i < sortFields.length; i++) {
|
|
var orderDesc = !1;
|
|
i < sortOrders.length && -1 !== sortOrders[i].toLowerCase().indexOf("desc") && (orderDesc = !0), sortSpec.push({
|
|
Field: sortFields[i],
|
|
OrderDescending: orderDesc
|
|
})
|
|
}
|
|
return sortSpec
|
|
}
|
|
|
|
function getViewItems(serverId, userId, options) {
|
|
var searchParentId = options.ParentId;
|
|
searchParentId = normalizeId(searchParentId);
|
|
var seasonId = normalizeId(options.SeasonId || options.seasonId),
|
|
seriesId = normalizeId(options.SeriesId || options.seriesId),
|
|
albumIds = normalizeIdList(options.AlbumIds || options.albumIds),
|
|
includeItemTypes = options.IncludeItemTypes ? options.IncludeItemTypes.split(",") : [],
|
|
filters = options.Filters ? options.Filters.split(",") : [],
|
|
mediaTypes = options.MediaTypes ? options.MediaTypes.split(",") : [];
|
|
return updateFiltersForTopLevelView(searchParentId, mediaTypes, includeItemTypes, options) && (searchParentId = null), getServerItems(serverId).then(function(items) {
|
|
var itemsMap = new Map,
|
|
subtreeIdSet = new Set;
|
|
if (items.forEach(function(item) {
|
|
item.Item.LocalChildren = [], itemsMap.set(item.Item.Id, item.Item)
|
|
}), itemsMap.forEach(function(item, ignored, ignored2) {
|
|
if (item.ParentId && itemsMap.has(item.ParentId)) {
|
|
itemsMap.get(item.ParentId).LocalChildren.push(item)
|
|
}
|
|
}), options.Recursive && searchParentId && itemsMap.has(searchParentId)) {
|
|
var addSubtreeIds = function(recurseItem) {
|
|
subtreeIdSet.has(recurseItem.Id) || subtreeIdSet.add(recurseItem.Id), recurseItem.LocalChildren.forEach(function(childItem) {
|
|
addSubtreeIds(childItem)
|
|
})
|
|
},
|
|
searchParentItem = itemsMap.get(searchParentId);
|
|
addSubtreeIds(searchParentItem)
|
|
}
|
|
var resultItems = items.filter(function(item) {
|
|
return (!item.SyncStatus || "synced" === item.SyncStatus) && ((!mediaTypes.length || -1 !== mediaTypes.indexOf(item.Item.MediaType || "")) && ((!seriesId || item.Item.SeriesId === seriesId) && ((!seasonId || item.Item.SeasonId === seasonId) && ((!albumIds.length || -1 !== albumIds.indexOf(item.Item.AlbumId || "")) && ((!item.Item.IsFolder || -1 === filters.indexOf("IsNotFolder")) && (!(!item.Item.IsFolder && -1 !== filters.indexOf("IsFolder")) && ((!includeItemTypes.length || -1 !== includeItemTypes.indexOf(item.Item.Type || "")) && (!searchParentId || (options.Recursive ? subtreeIdSet.has(item.Item.Id) : item.Item.ParentId === searchParentId)))))))))
|
|
}).map(function(item2) {
|
|
return item2.Item
|
|
});
|
|
return resultItems = sortItems(resultItems, options), options.Limit && (resultItems = resultItems.slice(0, options.Limit)), Promise.resolve(resultItems)
|
|
})
|
|
}
|
|
|
|
function removeObsoleteContainerItems(serverId) {
|
|
return getServerItems(serverId).then(function(items) {
|
|
var seriesItems = items.filter(function(item) {
|
|
return "series" === (item.Item.Type || "").toLowerCase()
|
|
}),
|
|
seasonItems = items.filter(function(item) {
|
|
return "season" === (item.Item.Type || "").toLowerCase()
|
|
}),
|
|
albumItems = items.filter(function(item) {
|
|
var type = (item.Item.Type || "").toLowerCase();
|
|
return "musicalbum" === type || "photoalbum" === type
|
|
}),
|
|
requiredSeriesIds = items.filter(function(item) {
|
|
return "episode" === (item.Item.Type || "").toLowerCase()
|
|
}).map(function(item2) {
|
|
return item2.Item.SeriesId
|
|
}).filter(filterDistinct),
|
|
requiredSeasonIds = items.filter(function(item) {
|
|
return "episode" === (item.Item.Type || "").toLowerCase()
|
|
}).map(function(item2) {
|
|
return item2.Item.SeasonId
|
|
}).filter(filterDistinct),
|
|
requiredAlbumIds = items.filter(function(item) {
|
|
var type = (item.Item.Type || "").toLowerCase();
|
|
return "audio" === type || "photo" === type
|
|
}).map(function(item2) {
|
|
return item2.Item.AlbumId
|
|
}).filter(filterDistinct),
|
|
obsoleteItems = [];
|
|
seriesItems.forEach(function(item) {
|
|
requiredSeriesIds.indexOf(item.Item.Id) < 0 && obsoleteItems.push(item)
|
|
}), seasonItems.forEach(function(item) {
|
|
requiredSeasonIds.indexOf(item.Item.Id) < 0 && obsoleteItems.push(item)
|
|
}), albumItems.forEach(function(item) {
|
|
requiredAlbumIds.indexOf(item.Item.Id) < 0 && obsoleteItems.push(item)
|
|
});
|
|
var p = Promise.resolve();
|
|
return obsoleteItems.forEach(function(item) {
|
|
p = p.then(function() {
|
|
return itemrepository.remove(item.ServerId, item.Id)
|
|
})
|
|
}), p
|
|
})
|
|
}
|
|
|
|
function removeLocalItem(localItem) {
|
|
return itemrepository.get(localItem.ServerId, localItem.Id).then(function(item) {
|
|
var onFileDeletedSuccessOrFail = function() {
|
|
return itemrepository.remove(localItem.ServerId, localItem.Id)
|
|
},
|
|
p = Promise.resolve();
|
|
return item.LocalPath && (p = p.then(function() {
|
|
return filerepository.deleteFile(item.LocalPath)
|
|
})), item && item.Item && item.Item.MediaSources && item.Item.MediaSources.forEach(function(mediaSource) {
|
|
mediaSource.MediaStreams && mediaSource.MediaStreams.length > 0 && mediaSource.MediaStreams.forEach(function(mediaStream) {
|
|
mediaStream.Path && (p = p.then(function() {
|
|
return filerepository.deleteFile(mediaStream.Path)
|
|
}))
|
|
})
|
|
}), p.then(onFileDeletedSuccessOrFail, onFileDeletedSuccessOrFail)
|
|
}, function(item) {
|
|
return Promise.resolve()
|
|
})
|
|
}
|
|
|
|
function addOrUpdateLocalItem(localItem) {
|
|
return itemrepository.set(localItem.ServerId, localItem.Id, localItem)
|
|
}
|
|
|
|
function getSubtitleSaveFileName(localItem, mediaPath, language, isForced, format) {
|
|
var name = getNameWithoutExtension(mediaPath);
|
|
name = filerepository.getValidFileName(name), language && (name += "." + language.toLowerCase()), isForced && (name += ".foreign"), name = name + "." + format.toLowerCase();
|
|
var mediaFolder = filerepository.getParentPath(localItem.LocalPath);
|
|
return filerepository.combinePath(mediaFolder, name)
|
|
}
|
|
|
|
function getItemFileSize(path) {
|
|
return filerepository.getItemFileSize(path)
|
|
}
|
|
|
|
function getNameWithoutExtension(path) {
|
|
var fileName = path,
|
|
pos = fileName.lastIndexOf(".");
|
|
return pos > 0 && (fileName = fileName.substring(0, pos)), fileName
|
|
}
|
|
|
|
function downloadFile(url, localItem) {
|
|
var imageUrl = getImageUrl(localItem.Item.ServerId, localItem.Item.Id, {
|
|
type: "Primary",
|
|
index: 0
|
|
});
|
|
return transfermanager.downloadFile(url, localItem, imageUrl)
|
|
}
|
|
|
|
function downloadSubtitles(url, fileName) {
|
|
return transfermanager.downloadSubtitles(url, fileName)
|
|
}
|
|
|
|
function getImageUrl(serverId, itemId, imageOptions) {
|
|
var imageType = imageOptions.type,
|
|
index = imageOptions.index,
|
|
pathArray = getImagePath(serverId, itemId, imageType, index);
|
|
return filerepository.getImageUrl(pathArray)
|
|
}
|
|
|
|
function hasImage(serverId, itemId, imageType, index) {
|
|
var pathArray = getImagePath(serverId, itemId, imageType, index),
|
|
localFilePath = filerepository.getFullMetadataPath(pathArray);
|
|
return filerepository.fileExists(localFilePath).then(function(exists) {
|
|
return Promise.resolve(exists)
|
|
}, function(err) {
|
|
return Promise.resolve(!1)
|
|
})
|
|
}
|
|
|
|
function fileExists(localFilePath) {
|
|
return filerepository.fileExists(localFilePath)
|
|
}
|
|
|
|
function downloadImage(localItem, url, serverId, itemId, imageType, index) {
|
|
var localPathParts = getImagePath(serverId, itemId, imageType, index);
|
|
return transfermanager.downloadImage(url, localPathParts)
|
|
}
|
|
|
|
function isDownloadFileInQueue(path) {
|
|
return transfermanager.isDownloadFileInQueue(path)
|
|
}
|
|
|
|
function getDownloadItemCount() {
|
|
return transfermanager.getDownloadItemCount()
|
|
}
|
|
|
|
function getDirectoryPath(item) {
|
|
var parts = [],
|
|
itemtype = item.Type.toLowerCase(),
|
|
mediaType = (item.MediaType || "").toLowerCase();
|
|
"episode" === itemtype || "series" === itemtype || "season" === itemtype ? parts.push("TV") : "video" === mediaType ? parts.push("Videos") : "audio" === itemtype || "musicalbum" === itemtype || "musicartist" === itemtype ? parts.push("Music") : "photo" === itemtype || "photoalbum" === itemtype ? parts.push("Photos") : "game" !== itemtype && "gamesystem" !== itemtype || parts.push("Games");
|
|
var albumArtist = item.AlbumArtist;
|
|
albumArtist && parts.push(albumArtist);
|
|
var seriesName = item.SeriesName;
|
|
seriesName && parts.push(seriesName);
|
|
var seasonName = item.SeasonName;
|
|
seasonName && parts.push(seasonName), item.Album && parts.push(item.Album), ("video" === mediaType && "episode" !== itemtype || "game" === itemtype || item.IsFolder) && parts.push(item.Name);
|
|
for (var finalParts = [], i = 0; i < parts.length; i++) finalParts.push(filerepository.getValidFileName(parts[i]));
|
|
return finalParts
|
|
}
|
|
|
|
function getImagePath(serverId, itemId, imageType, index) {
|
|
var parts = [];
|
|
parts.push("images"), index = index || 0, parts.push(itemId + "_" + imageType + "_" + index.toString());
|
|
for (var finalParts = [], i = 0; i < parts.length; i++) finalParts.push(parts[i]);
|
|
return finalParts
|
|
}
|
|
|
|
function getLocalFileName(item, originalFileName) {
|
|
var filename = originalFileName || item.Name;
|
|
return filerepository.getValidFileName(filename)
|
|
}
|
|
|
|
function resyncTransfers() {
|
|
return transfermanager.resyncTransfers()
|
|
}
|
|
|
|
function createGuid() {
|
|
var d = (new Date).getTime();
|
|
return window.performance && "function" == typeof window.performance.now && (d += performance.now()), "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
var r = (d + 16 * Math.random()) % 16 | 0;
|
|
return d = Math.floor(d / 16), ("x" === c ? r : 3 & r | 8).toString(16)
|
|
})
|
|
}
|
|
|
|
function startsWith(str, find) {
|
|
return !!(str && find && str.length > find.length && 0 === str.indexOf(find))
|
|
}
|
|
|
|
function stripStart(str, find) {
|
|
return startsWith(str, find) ? str.substr(find.length) : str
|
|
}
|
|
|
|
function filterDistinct(value, index, self) {
|
|
return self.indexOf(value) === index
|
|
}
|
|
|
|
function enableBackgroundCompletion() {
|
|
return transfermanager.enableBackgroundCompletion
|
|
}
|
|
return {
|
|
getLocalItem: getLocalItem,
|
|
getDirectoryPath: getDirectoryPath,
|
|
getLocalFileName: getLocalFileName,
|
|
recordUserAction: recordUserAction,
|
|
getUserActions: getUserActions,
|
|
deleteUserAction: deleteUserAction,
|
|
deleteUserActions: deleteUserActions,
|
|
removeLocalItem: removeLocalItem,
|
|
addOrUpdateLocalItem: addOrUpdateLocalItem,
|
|
downloadFile: downloadFile,
|
|
downloadSubtitles: downloadSubtitles,
|
|
hasImage: hasImage,
|
|
downloadImage: downloadImage,
|
|
getImageUrl: getImageUrl,
|
|
getSubtitleSaveFileName: getSubtitleSaveFileName,
|
|
getServerItems: getServerItems,
|
|
getItemFileSize: getItemFileSize,
|
|
isDownloadFileInQueue: isDownloadFileInQueue,
|
|
getDownloadItemCount: getDownloadItemCount,
|
|
getViews: getViews,
|
|
getViewItems: getViewItems,
|
|
resyncTransfers: resyncTransfers,
|
|
getItemsFromIds: getItemsFromIds,
|
|
removeObsoleteContainerItems: removeObsoleteContainerItems,
|
|
fileExists: fileExists,
|
|
enableBackgroundCompletion: enableBackgroundCompletion
|
|
}
|
|
}); |