jellyfin-web/dashboard-ui/bower_components/emby-apiclient/sync/mediasync.js

471 lines
15 KiB
JavaScript
Raw Normal View History

2016-08-06 19:56:32 -07:00
define(['localassetmanager'], function (LocalAssetManager) {
2016-10-01 23:13:04 -07:00
'use strict';
2015-09-09 20:22:52 -07:00
2016-08-06 19:56:32 -07:00
return function () {
2015-09-09 20:22:52 -07:00
var self = this;
2015-09-22 09:06:27 -07:00
self.sync = function (apiClient, serverInfo, options) {
2015-09-09 20:22:52 -07:00
2016-08-06 19:56:32 -07:00
return reportOfflineActions(apiClient, serverInfo).then(function () {
2015-09-14 05:50:37 -07:00
// Do the first data sync
2016-08-06 19:56:32 -07:00
return syncData(apiClient, serverInfo, false).then(function () {
2015-09-14 05:50:37 -07:00
// Download new content
2016-08-06 19:56:32 -07:00
return getNewMedia(apiClient, serverInfo, options).then(function () {
2015-09-14 05:50:37 -07:00
// Do the second data sync
2016-08-06 19:56:32 -07:00
return syncData(apiClient, serverInfo, false);
});
});
});
2015-09-09 20:22:52 -07:00
};
2015-09-14 05:50:37 -07:00
2015-09-14 12:47:03 -07:00
function reportOfflineActions(apiClient, serverInfo) {
2015-12-23 10:46:01 -07:00
console.log('Begin reportOfflineActions');
2015-09-14 05:50:37 -07:00
2016-08-06 19:56:32 -07:00
return LocalAssetManager.getOfflineActions(serverInfo.Id).then(function (actions) {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
if (!actions.length) {
return Promise.resolve();
}
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
return apiClient.reportOfflineActions(actions).then(function () {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
return LocalAssetManager.deleteOfflineActions(actions);
});
2015-09-14 12:47:03 -07:00
});
2015-09-14 05:50:37 -07:00
}
2015-09-14 12:47:03 -07:00
function syncData(apiClient, serverInfo, syncUserItemAccess) {
2015-12-23 10:46:01 -07:00
console.log('Begin syncData');
2015-09-14 05:50:37 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 05:50:37 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.getServerItemIds(serverInfo.Id).then(function (localIds) {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
var request = {
TargetId: apiClient.deviceId(),
LocalItemIds: localIds,
OfflineUserIds: (serverInfo.Users || []).map(function (u) { return u.Id; })
};
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
apiClient.syncData(request).then(function (result) {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
afterSyncData(apiClient, serverInfo, syncUserItemAccess, result, deferred);
2015-09-14 12:47:03 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 12:47:03 -07:00
return deferred.promise();
}
function afterSyncData(apiClient, serverInfo, enableSyncUserItemAccess, syncDataResult, deferred) {
2015-12-23 10:46:01 -07:00
console.log('Begin afterSyncData');
2015-09-14 12:47:03 -07:00
2015-12-14 08:43:03 -07:00
removeLocalItems(syncDataResult, serverInfo.Id).then(function (result) {
2015-09-14 12:47:03 -07:00
if (enableSyncUserItemAccess) {
2015-12-14 08:43:03 -07:00
syncUserItemAccess(syncDataResult, serverInfo.Id).then(function () {
2015-09-14 12:47:03 -07:00
deferred.resolve();
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 12:47:03 -07:00
}
else {
deferred.resolve();
}
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 12:47:03 -07:00
2015-09-14 05:50:37 -07:00
deferred.resolve();
2015-09-14 12:47:03 -07:00
}
function removeLocalItems(syncDataResult, serverId) {
2015-12-23 10:46:01 -07:00
console.log('Begin removeLocalItems');
2015-09-14 12:47:03 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 12:47:03 -07:00
removeNextLocalItem(syncDataResult.ItemIdsToRemove, 0, serverId, deferred);
return deferred.promise();
}
function removeNextLocalItem(itemIdsToRemove, index, serverId, deferred) {
var length = itemIdsToRemove.length;
if (index >= length) {
deferred.resolve();
return;
}
2015-12-14 08:43:03 -07:00
removeLocalItem(itemIdsToRemove[index], serverId).then(function () {
2015-09-14 12:47:03 -07:00
removeNextLocalItem(itemIdsToRemove, index + 1, serverId, deferred);
2015-12-14 08:43:03 -07:00
}, function () {
2015-09-14 12:47:03 -07:00
removeNextLocalItem(itemIdsToRemove, index + 1, serverId, deferred);
});
}
function removeLocalItem(itemId, serverId) {
2015-12-23 10:46:01 -07:00
console.log('Begin removeLocalItem');
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
return LocalAssetManager.removeLocalItem(itemId, serverId);
2015-09-14 05:50:37 -07:00
}
2015-09-22 09:06:27 -07:00
function getNewMedia(apiClient, serverInfo, options) {
2015-09-14 05:50:37 -07:00
2015-12-23 10:46:01 -07:00
console.log('Begin getNewMedia');
2015-09-14 12:47:03 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 05:50:37 -07:00
2015-12-14 08:43:03 -07:00
apiClient.getReadySyncItems(apiClient.deviceId()).then(function (jobItems) {
2015-09-14 12:47:03 -07:00
2015-09-22 09:06:27 -07:00
getNextNewItem(jobItems, 0, apiClient, serverInfo, options, deferred);
2015-09-14 12:47:03 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 12:47:03 -07:00
return deferred.promise();
}
2015-09-22 09:06:27 -07:00
function getNextNewItem(jobItems, index, apiClient, serverInfo, options, deferred) {
2015-09-14 12:47:03 -07:00
var length = jobItems.length;
if (index >= length) {
deferred.resolve();
return;
}
2015-09-22 09:06:27 -07:00
var hasGoneNext = false;
var goNext = function () {
2015-09-14 12:47:03 -07:00
2015-09-22 09:06:27 -07:00
if (!hasGoneNext) {
hasGoneNext = true;
getNextNewItem(jobItems, index + 1, apiClient, serverInfo, options, deferred);
}
};
2015-12-14 08:43:03 -07:00
getNewItem(jobItems[index], apiClient, serverInfo, options).then(goNext, goNext);
2015-09-14 12:47:03 -07:00
}
2015-09-24 10:08:10 -07:00
function getNewItem(jobItem, apiClient, serverInfo, options) {
2015-09-14 14:24:54 -07:00
2015-12-23 10:46:01 -07:00
console.log('Begin getNewItem');
2015-09-14 14:24:54 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
var libraryItem = jobItem.Item;
LocalAssetManager.createLocalItem(libraryItem, serverInfo, jobItem.OriginalFileName).then(function (localItem) {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
downloadMedia(apiClient, jobItem, localItem, options).then(function (isQueued) {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
if (isQueued) {
deferred.resolve();
return;
}
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
getImages(apiClient, jobItem, localItem).then(function () {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
getSubtitles(apiClient, jobItem, localItem).then(function () {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
apiClient.reportSyncJobItemTransferred(jobItem.SyncJobItemId).then(function () {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
deferred.resolve();
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
return deferred.promise();
}
2015-09-24 10:08:10 -07:00
function downloadMedia(apiClient, jobItem, localItem, options) {
2015-09-14 14:24:54 -07:00
2015-12-23 10:46:01 -07:00
console.log('Begin downloadMedia');
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
var url = apiClient.getUrl("Sync/JobItems/" + jobItem.SyncJobItemId + "/File", {
api_key: apiClient.accessToken()
});
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
var localPath = localItem.LocalPath;
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
console.log('Downloading media. Url: ' + url + '. Local path: ' + localPath);
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
options = options || {};
2015-09-24 10:08:10 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.downloadFile(url, localPath, options.enableBackgroundTransfer, options.enableNewDownloads).then(function (path, isQueued) {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
if (isQueued) {
deferred.resolveWith(null, [true]);
return;
}
LocalAssetManager.addOrUpdateLocalItem(localItem).then(function () {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
deferred.resolveWith(null, [false]);
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
return deferred.promise();
}
function getImages(apiClient, jobItem, localItem) {
2015-12-23 10:46:01 -07:00
console.log('Begin getImages');
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 14:24:54 -07:00
getNextImage(0, apiClient, localItem, deferred);
return deferred.promise();
}
function getNextImage(index, apiClient, localItem, deferred) {
2015-12-23 10:46:01 -07:00
console.log('Begin getNextImage');
2015-09-14 14:24:54 -07:00
if (index >= 4) {
deferred.resolve();
return;
}
2015-09-22 10:09:29 -07:00
// Just for now while media syncing gets worked out
deferred.resolve();
2015-09-14 14:24:54 -07:00
2016-10-01 23:13:04 -07:00
//var libraryItem = localItem.Item;
//var serverId = libraryItem.ServerId;
//var itemId = null;
//var imageTag = null;
//var imageType = "Primary";
//switch (index) {
// case 0:
// itemId = libraryItem.Id;
// imageType = "Primary";
// imageTag = (libraryItem.ImageTags || {})["Primary"];
// break;
// case 1:
// itemId = libraryItem.SeriesId;
// imageType = "Primary";
// imageTag = libraryItem.SeriesPrimaryImageTag;
// break;
// case 2:
// itemId = libraryItem.SeriesId;
// imageType = "Thumb";
// imageTag = libraryItem.SeriesPrimaryImageTag;
// break;
// case 3:
// itemId = libraryItem.AlbumId;
// imageType = "Primary";
// imageTag = libraryItem.AlbumPrimaryImageTag;
// break;
// default:
// break;
//}
//if (!itemId || !imageTag) {
// getNextImage(index + 1, apiClient, localItem, deferred);
// return;
//}
//downloadImage(apiClient, serverId, itemId, imageTag, imageType).then(function () {
// // For the sake of simplicity, limit to one image
// deferred.resolve();
// return;
// getNextImage(index + 1, apiClient, localItem, deferred);
//}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
}
function downloadImage(apiClient, serverId, itemId, imageTag, imageType) {
2015-09-14 18:16:31 -07:00
2015-12-23 10:46:01 -07:00
console.log('Begin downloadImage');
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.hasImage(serverId, itemId, imageTag).then(function (hasImage) {
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
if (hasImage) {
deferred.resolve();
return;
}
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
var imageUrl = apiClient.getImageUrl(itemId, {
tag: imageTag,
type: imageType,
api_key: apiClient.accessToken()
});
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.downloadImage(imageUrl, serverId, itemId, imageTag).then(function () {
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
deferred.resolve();
2015-09-14 18:16:31 -07:00
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 18:16:31 -07:00
});
2015-09-14 12:47:03 -07:00
return deferred.promise();
}
2015-09-14 14:24:54 -07:00
function getSubtitles(apiClient, jobItem, localItem) {
2015-12-23 10:46:01 -07:00
console.log('Begin getSubtitles');
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
if (!jobItem.Item.MediaSources.length) {
console.log("Cannot download subtitles because video has no media source info.");
deferred.resolve();
return;
}
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
var files = jobItem.AdditionalFiles.filter(function (f) {
2016-10-01 23:13:04 -07:00
return f.Type === 'Subtitles';
2016-08-06 19:56:32 -07:00
});
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
var mediaSource = jobItem.Item.MediaSources[0];
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
getNextSubtitle(files, 0, apiClient, jobItem, localItem, mediaSource, deferred);
2015-09-14 14:24:54 -07:00
return deferred.promise();
}
function getNextSubtitle(files, index, apiClient, jobItem, localItem, mediaSource, deferred) {
2015-09-14 14:24:54 -07:00
var length = files.length;
if (index >= length) {
deferred.resolve();
return;
}
2015-12-14 08:43:03 -07:00
getItemSubtitle(file, apiClient, jobItem, localItem, mediaSource).then(function () {
2015-09-14 14:24:54 -07:00
getNextSubtitle(files, index + 1, apiClient, jobItem, localItem, mediaSource, deferred);
2015-09-14 14:24:54 -07:00
2015-12-14 08:43:03 -07:00
}, function () {
getNextSubtitle(files, index + 1, apiClient, jobItem, localItem, mediaSource, deferred);
2015-09-14 14:24:54 -07:00
});
}
function getItemSubtitle(file, apiClient, jobItem, localItem, mediaSource) {
2015-12-23 10:46:01 -07:00
console.log('Begin getItemSubtitle');
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 14:24:54 -07:00
var subtitleStream = mediaSource.MediaStreams.filter(function (m) {
2016-10-01 23:13:04 -07:00
return m.Type === 'Subtitle' && m.Index === file.Index;
2015-09-14 14:24:54 -07:00
})[0];
if (!subtitleStream) {
// We shouldn't get in here, but let's just be safe anyway
2015-12-23 10:46:01 -07:00
console.log("Cannot download subtitles because matching stream info wasn't found.");
2015-09-14 14:24:54 -07:00
deferred.reject();
return;
}
var url = apiClient.getUrl("Sync/JobItems/" + jobItem.SyncJobItemId + "/AdditionalFiles", {
2015-09-17 14:26:06 -07:00
Name: file.Name,
api_key: apiClient.accessToken()
2015-09-14 14:24:54 -07:00
});
2016-08-06 19:56:32 -07:00
LocalAssetManager.downloadSubtitles(url, localItem, subtitleStream).then(function (subtitlePath) {
2015-09-14 14:24:54 -07:00
2016-08-06 19:56:32 -07:00
subtitleStream.Path = subtitlePath;
LocalAssetManager.addOrUpdateLocalItem(localItem).then(function () {
deferred.resolve();
2015-12-14 08:43:03 -07:00
}, getOnFail(deferred));
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 14:24:54 -07:00
return deferred.promise();
}
2015-09-14 12:47:03 -07:00
function syncUserItemAccess(syncDataResult, serverId) {
2015-12-23 10:46:01 -07:00
console.log('Begin syncUserItemAccess');
2015-09-14 12:47:03 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 12:47:03 -07:00
var itemIds = [];
for (var id in syncDataResult.ItemUserAccess) {
itemIds.push(id);
}
syncNextUserAccessForItem(itemIds, 0, syncDataResult, serverId, deferred);
return deferred.promise();
}
function syncNextUserAccessForItem(itemIds, index, syncDataResult, serverId, deferred) {
var length = itemIds.length;
if (index >= length) {
deferred.resolve();
return;
}
2015-12-14 08:43:03 -07:00
syncUserAccessForItem(itemIds[index], syncDataResult).then(function () {
2015-09-14 12:47:03 -07:00
syncNextUserAccessForItem(itemIds, index + 1, syncDataResult, serverId, deferred);
2015-12-14 08:43:03 -07:00
}, function () {
2015-09-14 12:47:03 -07:00
syncNextUserAccessForItem(itemIds, index + 1, syncDataResult, serverId, deferred);
});
}
function syncUserAccessForItem(itemId, syncDataResult) {
2015-12-23 10:46:01 -07:00
console.log('Begin syncUserAccessForItem');
2015-09-14 12:47:03 -07:00
2016-02-21 10:22:41 -07:00
var deferred = DeferredBuilder.Deferred();
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.getUserIdsWithAccess(itemId, serverId).then(function (savedUserIdsWithAccess) {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
var userIdsWithAccess = syncDataResult.ItemUserAccess[itemId];
2015-09-14 12:47:03 -07:00
2016-10-01 23:13:04 -07:00
if (userIdsWithAccess.join(',') === savedUserIdsWithAccess.join(',')) {
2016-08-06 19:56:32 -07:00
// Hasn't changed, nothing to do
deferred.resolve();
}
else {
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
LocalAssetManager.saveUserIdsWithAccess(itemId, serverId, userIdsWithAccess).then(function () {
2015-09-14 12:47:03 -07:00
deferred.resolve();
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
}
2015-09-14 12:47:03 -07:00
2016-08-06 19:56:32 -07:00
}, getOnFail(deferred));
2015-09-14 05:50:37 -07:00
return deferred.promise();
}
function getOnFail(deferred) {
return function () {
deferred.reject();
};
}
2016-08-06 19:56:32 -07:00
};
});