diff options
Diffstat (limited to 'MediaBrowser.Api')
| -rw-r--r-- | MediaBrowser.Api/Javascript/ApiClient.js | 1360 | ||||
| -rw-r--r-- | MediaBrowser.Api/Javascript/JavascriptApiClientService.cs | 58 | ||||
| -rw-r--r-- | MediaBrowser.Api/LibraryService.cs | 25 | ||||
| -rw-r--r-- | MediaBrowser.Api/MediaBrowser.Api.csproj | 2 | ||||
| -rw-r--r-- | MediaBrowser.Api/PluginService.cs | 29 | ||||
| -rw-r--r-- | MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs | 33 | ||||
| -rw-r--r-- | MediaBrowser.Api/SystemService.cs | 35 | ||||
| -rw-r--r-- | MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 65 | ||||
| -rw-r--r-- | MediaBrowser.Api/UserService.cs | 45 |
9 files changed, 1619 insertions, 33 deletions
diff --git a/MediaBrowser.Api/Javascript/ApiClient.js b/MediaBrowser.Api/Javascript/ApiClient.js new file mode 100644 index 000000000..df1c8f2c0 --- /dev/null +++ b/MediaBrowser.Api/Javascript/ApiClient.js @@ -0,0 +1,1360 @@ +/** + * Represents a javascript version of ApiClient. + * This should be kept up to date with all possible api methods and parameters + */ +var ApiClient = { + + serverProtocol: "http", + + /** + * Gets or sets the host name of the server + */ + serverHostName: "localhost", + + serverPortNumber: 8096, + + /** + * Detects the hostname and port of MB server based on the current url + */ + inferServerFromUrl: function () { + + var loc = window.location; + + ApiClient.serverProtocol = loc.protocol; + ApiClient.serverHostName = loc.hostname; + ApiClient.serverPortNumber = loc.port; + }, + + /** + * Creates an api url based on a handler name and query string parameters + * @param {String} name + * @param {Object} params + */ + getUrl: function (name, params) { + + if (!name) { + throw new Error("Url name cannot be empty"); + } + + params = params || {}; + + var url = ApiClient.serverProtocol + "//" + ApiClient.serverHostName + ":" + ApiClient.serverPortNumber + "/mediabrowser/" + name; + + if (params) { + url += "?" + $.param(params); + + } + return url; + }, + + /** + * Returns the name of the current browser + */ + getDeviceName: function () { + + /*if ($.browser.chrome) { + return "Chrome"; + } + if ($.browser.safari) { + return "Safari"; + } + if ($.browser.webkit) { + return "WebKit"; + } + if ($.browser.msie) { + return "Internet Explorer"; + } + if ($.browser.firefox) { + return "Firefox"; + } + if ($.browser.mozilla) { + return "Firefox"; + } + if ($.browser.opera) { + return "Opera"; + }*/ + + return "Web Browser"; + }, + + /** + * Creates a custom api url based on a handler name and query string parameters + * @param {String} name + * @param {Object} params + */ + getCustomUrl: function (name, params) { + + if (!name) { + throw new Error("Url name cannot be empty"); + } + + params = params || {}; + params.client = "Dashboard"; + params.device = ApiClient.getDeviceName(); + params.format = "json"; + + var url = ApiClient.serverProtocol + "//" + ApiClient.serverHostName + ":" + ApiClient.serverPortNumber + "/mediabrowser/" + name; + + if (params) { + url += "?" + $.param(params); + + } + return url; + }, + + /** + * Gets an item from the server + * Omit itemId to get the root folder. + */ + getItem: function (userId, itemId) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Items/" + itemId); + + return $.getJSON(url); + }, + + /** + * Gets the root folder from the server + */ + getRootFolder: function (userId) { + + return ApiClient.getItem(userId); + }, + + /** + * Gets the current server status + */ + getSystemInfo: function () { + + var url = ApiClient.getUrl("System/Info"); + + return $.getJSON(url); + }, + + /** + * Gets all cultures known to the server + */ + getCultures: function () { + + var url = ApiClient.getUrl("Localization/cultures"); + + return $.getJSON(url); + }, + + /** + * Gets all countries known to the server + */ + getCountries: function () { + + var url = ApiClient.getUrl("Localization/countries"); + + return $.getJSON(url); + }, + + /** + * Gets plugin security info + */ + getPluginSecurityInfo: function () { + + var url = ApiClient.getUrl("Plugins/SecurityInfo"); + + return $.getJSON(url); + }, + + /** + * Gets the directory contents of a path on the server + */ + getDirectoryContents: function (path, options) { + + if (!path) { + throw new Error("null path"); + } + + options = options || {}; + + options.path = path; + + var url = ApiClient.getUrl("Environment/DirectoryContents", options); + + return $.getJSON(url); + }, + + /** + * Gets a list of physical drives from the server + */ + getDrives: function () { + + var url = ApiClient.getUrl("Environment/Drives"); + + return $.getJSON(url); + }, + + /** + * Gets a list of network computers from the server + */ + getNetworkComputers: function () { + + var url = ApiClient.getUrl("Environment/NetworkComputers"); + + return $.getJSON(url); + }, + + /** + * Cancels a package installation + */ + cancelPackageInstallation: function (installationId) { + + if (!installationId) { + throw new Error("null installationId"); + } + + var url = ApiClient.getUrl("Packages/Installing/" + id); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + }, + + /** + * Installs or updates a new plugin + */ + installPlugin: function (name, updateClass, version) { + + if (!name) { + throw new Error("null name"); + } + + if (!updateClass) { + throw new Error("null updateClass"); + } + + var options = { + updateClass: updateClass + }; + + if (version) { + options.version = version; + } + + var url = ApiClient.getUrl("Packages/Installed/" + name, options); + + return $.post(url); + }, + + /** + * Instructs the server to perform a pending kernel reload or app restart. + * If a restart is not currently required, nothing will happen. + */ + performPendingRestart: function () { + + var url = ApiClient.getUrl("System/Restart"); + + return $.post(url); + }, + + /** + * Gets information about an installable package + */ + getPackageInfo: function (name) { + + if (!name) { + throw new Error("null name"); + } + + var url = ApiClient.getUrl("Packages/" + name); + + return $.getJSON(url); + }, + + /** + * Gets the latest available application update (if any) + */ + getAvailableApplicationUpdate: function () { + + var url = ApiClient.getUrl("Packages/Updates", { PackageType: "System" }); + + return $.getJSON(url); + }, + + /** + * Gets the latest available plugin updates (if any) + */ + getAvailablePluginUpdates: function () { + + var url = ApiClient.getUrl("Packages/Updates", { PackageType: "UserInstalled" }); + + return $.getJSON(url); + }, + + /** + * Gets the virtual folder for a view. Specify a userId to get a user view, or omit for the default view. + */ + getVirtualFolders: function (userId) { + + var url = userId ? "Users/" + userId + "/VirtualFolders" : "Library/DefaultVirtualFolders"; + + url = ApiClient.getUrl(url); + + return $.getJSON(url); + }, + + /** + * Gets all the paths of the locations in the physical root. + */ + getPhysicalPaths: function () { + + var url = ApiClient.getUrl("Library/PhysicalPaths"); + + return $.getJSON(url); + }, + + /** + * Gets the current server configuration + */ + getServerConfiguration: function () { + + var url = ApiClient.getUrl("System/Configuration"); + + return $.getJSON(url); + }, + + /** + * Gets the server's scheduled tasks + */ + getScheduledTasks: function () { + + var url = ApiClient.getUrl("ScheduledTasks"); + + return $.getJSON(url); + }, + + /** + * Starts a scheduled task + */ + startScheduledTask: function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = ApiClient.getUrl("ScheduledTasks/Running/" + id); + + return $.post(url); + }, + + /** + * Gets a scheduled task + */ + getScheduledTask: function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = ApiClient.getUrl("ScheduledTasks/" + id); + + return $.getJSON(url); + }, + + /** + * Stops a scheduled task + */ + stopScheduledTask: function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = ApiClient.getUrl("ScheduledTasks/Running/" + id); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + }, + + /** + * Gets the configuration of a plugin + * @param {String} Id + */ + getPluginConfiguration: function (id) { + + if (!id) { + throw new Error("null Id"); + } + + var url = ApiClient.getUrl("Plugins/" + id + "/Configuration"); + + return $.getJSON(url); + }, + + /** + * Gets a list of plugins that are available to be installed + */ + getAvailablePlugins: function () { + + var url = ApiClient.getUrl("Packages", { PackageType: "UserInstalled" }); + + return $.getJSON(url); + }, + + /** + * Uninstalls a plugin + * @param {String} Id + */ + uninstallPlugin: function (id) { + + if (!id) { + throw new Error("null Id"); + } + + var url = ApiClient.getUrl("Plugins/" + id); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + }, + + /** + * Removes a virtual folder from either the default view or a user view + * @param {String} name + */ + removeVirtualFolder: function (name, userId) { + + if (!name) { + throw new Error("null name"); + } + + var params = { + name: name, + action: "RemoveVirtualFolder" + }; + + if (userId) { + params.userId = userId; + } + + var url = ApiClient.getUrl("UpdateMediaLibrary", params); + + return $.post(url); + }, + + /** + * Adds a virtual folder to either the default view or a user view + * @param {String} name + */ + addVirtualFolder: function (name, userId) { + + if (!name) { + throw new Error("null name"); + } + + var params = { + name: name, + action: "addVirtualFolder" + }; + + if (userId) { + params.userId = userId; + } + + var url = ApiClient.getUrl("UpdateMediaLibrary", params); + + return $.post(url); + }, + + /** + * Renames a virtual folder, within either the default view or a user view + * @param {String} name + */ + renameVirtualFolder: function (name, newName, userId) { + + if (!name) { + throw new Error("null name"); + } + + if (!newName) { + throw new Error("null newName"); + } + + var params = { + name: name, + newName: newName, + action: "RenameVirtualFolder" + }; + + if (userId) { + params.userId = userId; + } + + var url = ApiClient.getUrl("UpdateMediaLibrary", params); + + return $.post(url); + }, + + /** + * Adds an additional mediaPath to an existing virtual folder, within either the default view or a user view + * @param {String} name + */ + addMediaPath: function (virtualFolderName, mediaPath, userId) { + + if (!virtualFolderName) { + throw new Error("null virtualFolderName"); + } + + if (!mediaPath) { + throw new Error("null mediaPath"); + } + + var params = { + virtualFolderName: virtualFolderName, + mediaPath: mediaPath, + action: "addMediaPath" + }; + + if (userId) { + params.userId = userId; + } + + var url = ApiClient.getUrl("UpdateMediaLibrary", params); + + return $.post(url); + }, + + /** + * Removes a media path from a virtual folder, within either the default view or a user view + * @param {String} name + */ + removeMediaPath: function (virtualFolderName, mediaPath, userId) { + + if (!virtualFolderName) { + throw new Error("null virtualFolderName"); + } + + if (!mediaPath) { + throw new Error("null mediaPath"); + } + + var params = { + virtualFolderName: virtualFolderName, + mediaPath: mediaPath, + action: "RemoveMediaPath" + }; + + if (userId) { + params.userId = userId; + } + + var url = ApiClient.getUrl("UpdateMediaLibrary", params); + + return $.post(url); + }, + + /** + * Deletes a user + * @param {String} id + */ + deleteUser: function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = ApiClient.getUrl("Users/" + id); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + }, + + /** + * Deletes a user image + * @param {String} userId + * @param {String} imageType The type of image to delete, based on the server-side ImageType enum. + */ + deleteUserImage: function (userId, imageType) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Images/" + imageType); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + }, + + /** + * Uploads a user image + * @param {String} userId + * @param {String} imageType The type of image to delete, based on the server-side ImageType enum. + * @param {Object} file The file from the input element + */ + uploadUserImage: function (userId, imageType, file) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + if (!file || !file.type.match('image.*')) { + throw new Error("File must be an image."); + } + + var deferred = $.Deferred(); + + var reader = new FileReader(); + + reader.onerror = function () { + deferred.reject(); + }; + + reader.onabort = function () { + deferred.reject(); + }; + + // Closure to capture the file information. + reader.onload = function (e) { + + var data = window.btoa(e.target.result); + + var params = { + userId: userId, + type: imageType, + filename: file.name + }; + + var url = ApiClient.getUrl("UploadImage", params); + + $.post(url, data).done(function (result) { + + deferred.resolveWith(null, [result]); + + }).fail(function () { + deferred.reject(); + }); + }; + + // Read in the image file as a data URL. + reader.readAsBinaryString(file); + + return deferred.promise(); + }, + + /** + * Gets the list of installed plugins on the server + */ + getInstalledPlugins: function () { + + var url = ApiClient.getUrl("Plugins"); + + return $.getJSON(url); + }, + + /** + * Gets a user by id + * @param {String} id + */ + getUser: function (id) { + + if (!id) { + throw new Error("Must supply a userId"); + } + + var url = ApiClient.getUrl("Users/" + id); + + return $.getJSON(url); + }, + + /** + * Gets a studio + */ + getStudio: function (name) { + + if (!name) { + throw new Error("null name"); + } + + var url = ApiClient.getUrl("Library/Studios/" + name); + + return $.getJSON(url); + }, + + /** + * Gets a genre + */ + getGenre: function (name) { + + if (!name) { + throw new Error("null name"); + } + + var url = ApiClient.getUrl("Library/Genres/" + name); + + return $.getJSON(url); + }, + + /** + * Gets a year + */ + getYear: function (year) { + + if (!year) { + throw new Error("null year"); + } + + var url = ApiClient.getUrl("Library/Years/" + year); + + return $.getJSON(url); + }, + + /** + * Gets a Person + */ + getPerson: function (name) { + + if (!name) { + throw new Error("null name"); + } + + var url = ApiClient.getUrl("Library/Persons/" + name); + + return $.getJSON(url); + }, + + /** + * Gets weather info + * @param {String} location - us zip code / city, state, country / city, country + * Omit location to get weather info using stored server configuration value + */ + getWeatherInfo: function (location) { + + var url = ApiClient.getUrl("weather", { + location: location + }); + + return $.getJSON(url); + }, + + /** + * Gets all users from the server + */ + getAllUsers: function () { + + var url = ApiClient.getUrl("users"); + + return $.getJSON(url); + }, + + /** + * Gets all available parental ratings from the server + */ + getParentalRatings: function () { + + var url = ApiClient.getUrl("Localization/ParentalRatings"); + + return $.getJSON(url); + }, + + /** + * Gets a list of all available conrete BaseItem types from the server + */ + getItemTypes: function (options) { + + var url = ApiClient.getUrl("Library/ItemTypes", options); + + return $.getJSON(url); + }, + + /** + * Constructs a url for a user image + * @param {String} userId + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getUserImageUrl: function (userId, options) { + + if (!userId) { + throw new Error("null userId"); + } + + options = options || { + }; + + var url = "Users/" + userId + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for a person image + * @param {String} name + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getPersonImageUrl: function (name, options) { + + if (!name) { + throw new Error("null name"); + } + + options = options || { + }; + + var url = "Persons/" + name + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for a year image + * @param {String} year + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getYearImageUrl: function (year, options) { + + if (!year) { + throw new Error("null year"); + } + + options = options || { + }; + + var url = "Years/" + year + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for a genre image + * @param {String} name + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getGenreImageUrl: function (name, options) { + + if (!name) { + throw new Error("null name"); + } + + options = options || { + }; + + var url = "Genres/" + name + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for a genre image + * @param {String} name + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getStudioImageUrl: function (name, options) { + + if (!name) { + throw new Error("null name"); + } + + options = options || { + }; + + var url = "Studios/" + name + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for an item image + * @param {String} itemId + * @param {Object} options + * Options supports the following properties: + * type - Primary, logo, backdrop, etc. See the server-side enum ImageType + * index - When downloading a backdrop, use this to specify which one (omitting is equivalent to zero) + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getImageUrl: function (itemId, options) { + + if (!itemId) { + throw new Error("itemId cannot be empty"); + } + + options = options || { + }; + + var url = "Items/" + itemId + "/Images/" + options.type; + + if (options.index != null) { + url += "/" + options.index; + } + + // Don't put these on the query string + delete options.type; + delete options.index; + + return ApiClient.getUrl(url, options); + }, + + /** + * Constructs a url for an item logo image + * If the item doesn't have a logo, it will inherit a logo from a parent + * @param {Object} item A BaseItem + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getLogoImageUrl: function (item, options) { + + if (!item) { + throw new Error("null item"); + } + + options = options || { + }; + + options.imageType = "logo"; + + var logoItemId = item.HasLogo ? item.Id : item.ParentLogoItemId; + + return logoItemId ? ApiClient.getImageUrl(logoItemId, options) : null; + }, + + /** + * Constructs an array of backdrop image url's for an item + * If the item doesn't have any backdrops, it will inherit them from a parent + * @param {Object} item A BaseItem + * @param {Object} options + * Options supports the following properties: + * width - download the image at a fixed width + * height - download the image at a fixed height + * maxWidth - download the image at a maxWidth + * maxHeight - download the image at a maxHeight + * quality - A scale of 0-100. This should almost always be omitted as the default will suffice. + * For best results do not specify both width and height together, as aspect ratio might be altered. + */ + getBackdropImageUrl: function (item, options) { + + if (!item) { + throw new Error("null item"); + } + + options = options || { + }; + + options.imageType = "backdrop"; + + var backdropItemId; + var backdropCount; + + if (!item.BackdropCount) { + backdropItemId = item.ParentBackdropItemId; + backdropCount = item.ParentBackdropCount || 0; + } else { + backdropItemId = item.Id; + backdropCount = item.BackdropCount; + } + + if (!backdropItemId) { + return []; + } + + var files = []; + + for (var i = 0; i < backdropCount; i++) { + + options.imageIndex = i; + + files[i] = ApiClient.getImageUrl(backdropItemId, options); + } + + return files; + }, + + /** + * Authenticates a user + * @param {String} userId + * @param {String} password + */ + authenticateUser: function (userId, password) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/authenticate"); + + var postData = { + }; + + if (password) { + postData.password = password; + } + return $.post(url, postData); + }, + + /** + * Updates a user's password + * @param {String} userId + * @param {String} currentPassword + * @param {String} newPassword + */ + updateUserPassword: function (userId, currentPassword, newPassword) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Password"); + + var postData = { + }; + + if (currentPassword) { + postData.currentPassword = currentPassword; + } + if (newPassword) { + postData.newPassword = newPassword; + } + return $.post(url, postData); + }, + + /** + * Resets a user's password + * @param {String} userId + */ + resetUserPassword: function (userId) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Password"); + + var postData = { + }; + + postData.resetPassword = 1; + return $.post(url, postData); + }, + + /** + * Updates the server's configuration + * @param {Object} configuration + */ + updateServerConfiguration: function (configuration) { + + if (!configuration) { + throw new Error("null configuration"); + } + + var url = ApiClient.getUrl("System/Configuration"); + + return $.post(url, JSON.stringify(configuration)); + }, + + /** + * Creates a user + * @param {Object} user + */ + createUser: function (user) { + + if (!user) { + throw new Error("null user"); + } + + var url = ApiClient.getUrl("Users"); + + return $.post(url, JSON.stringify(user)); + }, + + /** + * Updates a user + * @param {Object} user + */ + updateUser: function (user) { + + if (!user) { + throw new Error("null user"); + } + + var url = ApiClient.getUrl("Users/" + user.Id); + + return $.post(url, JSON.stringify(user)); + }, + + /** + * Updates the Triggers for a ScheduledTask + * @param {String} id + * @param {Object} triggers + */ + updateScheduledTaskTriggers: function (id, triggers) { + + if (!id) { + throw new Error("null id"); + } + + if (!triggers) { + throw new Error("null triggers"); + } + + var url = ApiClient.getUrl("ScheduledTasks/" + id + "/Triggers"); + + return $.post(url, JSON.stringify(triggers)); + }, + + /** + * Updates a plugin's configuration + * @param {String} Id + * @param {Object} configuration + */ + updatePluginConfiguration: function (id, configuration) { + + if (!id) { + throw new Error("null Id"); + } + + if (!configuration) { + throw new Error("null configuration"); + } + + var url = ApiClient.getUrl("Plugins/" + id + "/Configuration"); + + return $.post(url, JSON.stringify(configuration)); + }, + + /** + * Gets items based on a query, typicall for children of a folder + * @param {String} userId + * @param {Object} options + * Options accepts the following properties: + * itemId - Localize the search to a specific folder (root if omitted) + * startIndex - Use for paging + * limit - Use to limit results to a certain number of items + * filter - Specify one or more ItemFilters, comma delimeted (see server-side enum) + * sortBy - Specify an ItemSortBy (comma-delimeted list see server-side enum) + * sortOrder - ascending/descending + * fields - additional fields to include aside from basic info. This is a comma delimited list. See server-side enum ItemFields. + * index - the name of the dynamic, localized index function + * dynamicSortBy - the name of the dynamic localized sort function + * recursive - Whether or not the query should be recursive + * searchTerm - search term to use as a filter + */ + getItems: function (userId, options) { + + if (!userId) { + throw new Error("null userId"); + } + + return $.getJSON(ApiClient.getUrl("Users/" + userId + "/Items", options)); + }, + + /** + * Marks an item as played or unplayed + * This should not be used to update playstate following playback. + * There are separate playstate check-in methods for that. This should be used for a + * separate option to reset playstate. + * @param {String} userId + * @param {String} itemId + * @param {Boolean} wasPlayed + */ + updatePlayedStatus: function (userId, itemId, wasPlayed) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = "Users/" + userId + "/PlayedItems/" + itemId; + + var method = wasPlayed ? "POST" : "DELETE"; + + return $.ajax({ + type: method, + url: url, + dataType: "json" + }); + }, + + /** + * Updates a user's favorite status for an item and returns the updated UserItemData object. + * @param {String} userId + * @param {String} itemId + * @param {Boolean} isFavorite + */ + updateFavoriteStatus: function (userId, itemId, isFavorite) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = "Users/" + userId + "/FavoriteItems/" + itemId; + + var method = isFavorite ? "POST" : "DELETE"; + + return $.ajax({ + type: method, + url: url, + dataType: "json" + }); + }, + + /** + * Updates a user's personal rating for an item + * @param {String} userId + * @param {String} itemId + * @param {Boolean} likes + */ + updateUserItemRating: function (userId, itemId, likes) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Items/" + itemId + "/Rating", { + likes: likes + }); + + return $.post(url); + }, + + /** + * Clears a user's personal rating for an item + * @param {String} userId + * @param {String} itemId + */ + clearUserItemRating: function (userId, itemId) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = ApiClient.getUrl("Users/" + userId + "/Items/" + itemId + "/Rating"); + + return $.ajax({ + type: "DELETE", + url: url, + dataType: "json" + }); + } +}; + +// Do this initially. The consumer can always override later +ApiClient.inferServerFromUrl(); diff --git a/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs new file mode 100644 index 000000000..8c7499a7c --- /dev/null +++ b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs @@ -0,0 +1,58 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using ServiceStack.ServiceHost; +using System; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Api.Javascript +{ + /// <summary> + /// Class GetJavascriptApiClient + /// </summary> + [Route("/JsApiClient.js", "GET")] + [ServiceStack.ServiceHost.Api(("Gets an api wrapper in Javascript"))] + public class GetJavascriptApiClient + { + /// <summary> + /// Version identifier for caching + /// </summary> + /// <value>The v.</value> + public string V { get; set; } + } + + /// <summary> + /// Class JavascriptApiClientService + /// </summary> + public class JavascriptApiClientService : BaseRestService + { + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetJavascriptApiClient request) + { + TimeSpan? cacheDuration = null; + + // If there's a version number in the query string we can cache this unconditionally + if (!string.IsNullOrEmpty(request.V)) + { + cacheDuration = TimeSpan.FromDays(365); + } + + var assembly = GetType().Assembly.GetName(); + + return ToStaticResult(assembly.Version.ToString().GetMD5(), null, cacheDuration, MimeTypes.GetMimeType("script.js"), GetStream); + } + + /// <summary> + /// Gets the stream. + /// </summary> + /// <returns>Stream.</returns> + private Task<Stream> GetStream() + { + return Task.FromResult(GetType().Assembly.GetManifestResourceStream("MediaBrowser.Api.Javascript.ApiClient.js")); + } + } +} diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs index 4ca073c10..434b04eff 100644 --- a/MediaBrowser.Api/LibraryService.cs +++ b/MediaBrowser.Api/LibraryService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -98,6 +99,26 @@ namespace MediaBrowser.Api public class LibraryService : BaseRestService { /// <summary> + /// The _app host + /// </summary> + private readonly IApplicationHost _appHost; + + /// <summary> + /// Initializes a new instance of the <see cref="LibraryService" /> class. + /// </summary> + /// <param name="appHost">The app host.</param> + /// <exception cref="System.ArgumentNullException">appHost</exception> + public LibraryService(IApplicationHost appHost) + { + if (appHost == null) + { + throw new ArgumentNullException("appHost"); + } + + _appHost = appHost; + } + + /// <summary> /// Gets the specified request. /// </summary> /// <param name="request">The request.</param> @@ -210,7 +231,7 @@ namespace MediaBrowser.Api { var kernel = (Kernel)Kernel; - var allTypes = kernel.AllTypes.Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(BaseItem))); + var allTypes = _appHost.AllConcreteTypes.Where(t => t.IsSubclassOf(typeof(BaseItem))); if (request.HasInternetProvider) { diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 9bdcdb650..c6c822624 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -80,6 +80,7 @@ <Compile Include="Images\ImageService.cs" /> <Compile Include="Images\ImageWriter.cs" /> <Compile Include="Images\UploadImageHandler.cs" /> + <Compile Include="Javascript\JavascriptApiClientService.cs" /> <Compile Include="LibraryService.cs" /> <Compile Include="LocalizationService.cs" /> <Compile Include="PackageService.cs" /> @@ -128,6 +129,7 @@ <None Include="packages.config" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="Javascript\ApiClient.js" /> <Content Include="options.xml" /> </ItemGroup> <ItemGroup /> diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index f982602bf..1f906f814 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -1,15 +1,15 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Serialization; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Serialization; using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using ServiceStack.Text.Controller; namespace MediaBrowser.Api { @@ -120,6 +120,27 @@ namespace MediaBrowser.Api public class PluginService : BaseRestService { /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="PluginService" /> class. + /// </summary> + /// <param name="jsonSerializer">The json serializer.</param> + /// <exception cref="System.ArgumentNullException">jsonSerializer</exception> + public PluginService(IJsonSerializer jsonSerializer) + : base() + { + if (jsonSerializer == null) + { + throw new ArgumentNullException("jsonSerializer"); + } + + _jsonSerializer = jsonSerializer; + } + + /// <summary> /// Gets the specified request. /// </summary> /// <param name="request">The request.</param> @@ -198,7 +219,7 @@ namespace MediaBrowser.Api { var kernel = (Kernel)Kernel; - var info = JsonSerializer.DeserializeFromStream<PluginSecurityInfo>(request.RequestStream); + var info = _jsonSerializer.DeserializeFromStream<PluginSecurityInfo>(request.RequestStream); kernel.PluginSecurityManager.SupporterKey = info.SupporterKey; kernel.PluginSecurityManager.LegacyKey = info.LegacyKey; @@ -217,7 +238,7 @@ namespace MediaBrowser.Api var plugin = Kernel.Plugins.First(p => p.Id == id); - var configuration = JsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration; + var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration; plugin.UpdateConfiguration(configuration); } diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index 1ca744542..e79ab90da 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -1,7 +1,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Common.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using ServiceStack.ServiceHost; using System; @@ -90,11 +90,32 @@ namespace MediaBrowser.Api.ScheduledTasks /// <value>The task manager.</value> private ITaskManager TaskManager { get; set; } - public ScheduledTaskService(ITaskManager taskManager) + /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="ScheduledTaskService" /> class. + /// </summary> + /// <param name="taskManager">The task manager.</param> + /// <param name="jsonSerializer">The json serializer.</param> + /// <exception cref="System.ArgumentNullException">taskManager</exception> + public ScheduledTaskService(ITaskManager taskManager, IJsonSerializer jsonSerializer) { + if (taskManager == null) + { + throw new ArgumentNullException("taskManager"); + } + if (jsonSerializer == null) + { + throw new ArgumentNullException("jsonSerializer"); + } + TaskManager = taskManager; + _jsonSerializer = jsonSerializer; } - + /// <summary> /// Gets the specified request. /// </summary> @@ -113,6 +134,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// </summary> /// <param name="request">The request.</param> /// <returns>IEnumerable{TaskInfo}.</returns> + /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception> public object Get(GetScheduledTask request) { var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id); @@ -131,6 +153,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// Posts the specified request. /// </summary> /// <param name="request">The request.</param> + /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception> public void Post(StartScheduledTask request) { var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id); @@ -147,6 +170,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// Posts the specified request. /// </summary> /// <param name="request">The request.</param> + /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception> public void Delete(StopScheduledTask request) { var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id); @@ -163,6 +187,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// Posts the specified request. /// </summary> /// <param name="request">The request.</param> + /// <exception cref="MediaBrowser.Common.Extensions.ResourceNotFoundException">Task not found</exception> public void Post(UpdateScheduledTaskTriggers request) { // We need to parse this manually because we told service stack not to with IRequiresRequestStream @@ -177,7 +202,7 @@ namespace MediaBrowser.Api.ScheduledTasks throw new ResourceNotFoundException("Task not found"); } - var triggerInfos = JsonSerializer.DeserializeFromStream<TaskTriggerInfo[]>(request.RequestStream); + var triggerInfos = _jsonSerializer.DeserializeFromStream<TaskTriggerInfo[]>(request.RequestStream); task.Triggers = triggerInfos.Select(ScheduledTaskHelpers.GetTrigger); } diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs index 04632aa8e..7921d024a 100644 --- a/MediaBrowser.Api/SystemService.cs +++ b/MediaBrowser.Api/SystemService.cs @@ -1,15 +1,19 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Serialization; using MediaBrowser.Controller; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using ServiceStack.ServiceHost; +using System; using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Api { + /// <summary> + /// Class GetSystemInfo + /// </summary> [Route("/System/Info", "GET")] public class GetSystemInfo : IReturn<SystemInfo> { @@ -40,6 +44,10 @@ namespace MediaBrowser.Api [Route("/System/Configuration", "POST")] public class UpdateConfiguration : IRequiresRequestStream { + /// <summary> + /// The raw Http Request Input Stream + /// </summary> + /// <value>The request stream.</value> public Stream RequestStream { get; set; } } @@ -49,6 +57,27 @@ namespace MediaBrowser.Api public class SystemService : BaseRestService { /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="SystemService" /> class. + /// </summary> + /// <param name="jsonSerializer">The json serializer.</param> + /// <exception cref="System.ArgumentNullException">jsonSerializer</exception> + public SystemService(IJsonSerializer jsonSerializer) + : base() + { + if (jsonSerializer == null) + { + throw new ArgumentNullException("jsonSerializer"); + } + + _jsonSerializer = jsonSerializer; + } + + /// <summary> /// Gets the specified request. /// </summary> /// <param name="request">The request.</param> @@ -95,8 +124,8 @@ namespace MediaBrowser.Api /// <param name="request">The request.</param> public void Post(UpdateConfiguration request) { - var serverConfig = JsonSerializer.DeserializeFromStream<ServerConfiguration>(request.RequestStream); - + var serverConfig = _jsonSerializer.DeserializeFromStream<ServerConfiguration>(request.RequestStream); + var kernel = (Kernel)Kernel; kernel.UpdateConfiguration(serverConfig); diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 576ff8892..4267947ad 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -1,11 +1,11 @@ using MediaBrowser.Common.Net; -using MediaBrowser.Common.Serialization; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Serialization; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; @@ -28,7 +28,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -48,7 +48,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the item id. /// </summary> @@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -106,7 +106,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -125,7 +125,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -144,7 +144,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -163,7 +163,7 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <value>The user id.</value> public Guid UserId { get; set; } - + /// <summary> /// Gets or sets the id. /// </summary> @@ -215,6 +215,9 @@ namespace MediaBrowser.Api.UserLibrary public string Id { get; set; } } + /// <summary> + /// Class GetLocalTrailers + /// </summary> [Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET")] public class GetLocalTrailers : IReturn<List<BaseItemDto>> { @@ -231,6 +234,9 @@ namespace MediaBrowser.Api.UserLibrary public string Id { get; set; } } + /// <summary> + /// Class GetSpecialFeatures + /// </summary> [Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")] public class GetSpecialFeatures : IReturn<List<BaseItemDto>> { @@ -253,6 +259,32 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> public class UserLibraryService : BaseRestService { + /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="UserLibraryService" /> class. + /// </summary> + /// <param name="jsonSerializer">The json serializer.</param> + /// <exception cref="System.ArgumentNullException">jsonSerializer</exception> + public UserLibraryService(IJsonSerializer jsonSerializer) + : base() + { + if (jsonSerializer == null) + { + throw new ArgumentNullException("jsonSerializer"); + } + + _jsonSerializer = jsonSerializer; + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> public object Get(GetSpecialFeatures request) { var kernel = (Kernel)Kernel; @@ -260,7 +292,7 @@ namespace MediaBrowser.Api.UserLibrary var user = kernel.GetUserById(request.UserId); var item = DtoBuilder.GetItemByClientId(request.Id, user.Id); - + // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -272,7 +304,12 @@ namespace MediaBrowser.Api.UserLibrary return ToOptimizedResult(items); } - + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> public object Get(GetLocalTrailers request) { var kernel = (Kernel)Kernel; @@ -280,7 +317,7 @@ namespace MediaBrowser.Api.UserLibrary var user = kernel.GetUserById(request.UserId); var item = DtoBuilder.GetItemByClientId(request.Id, user.Id); - + // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -290,7 +327,7 @@ namespace MediaBrowser.Api.UserLibrary return ToOptimizedResult(items); } - + /// <summary> /// Gets the specified request. /// </summary> @@ -303,7 +340,7 @@ namespace MediaBrowser.Api.UserLibrary var user = kernel.GetUserById(request.UserId); var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, user.Id); - + // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -366,7 +403,7 @@ namespace MediaBrowser.Api.UserLibrary var item = (Folder)DtoBuilder.GetItemByClientId(itemId, user.Id); - var displayPreferences = JsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream); + var displayPreferences = _jsonSerializer.DeserializeFromStream<DisplayPreferences>(request.RequestStream); var task = kernel.LibraryManager.SaveDisplayPreferencesForFolder(user, item, displayPreferences); diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index c76479d19..d4490d856 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -1,16 +1,16 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Serialization; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Serialization; using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using ServiceStack.Text.Controller; namespace MediaBrowser.Api { @@ -136,6 +136,39 @@ namespace MediaBrowser.Api public class UserService : BaseRestService { /// <summary> + /// The _XML serializer + /// </summary> + private readonly IXmlSerializer _xmlSerializer; + + /// <summary> + /// The _json serializer + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// Initializes a new instance of the <see cref="UserService" /> class. + /// </summary> + /// <param name="xmlSerializer">The XML serializer.</param> + /// <param name="jsonSerializer">The json serializer.</param> + /// <exception cref="System.ArgumentNullException">xmlSerializer</exception> + public UserService(IXmlSerializer xmlSerializer, IJsonSerializer jsonSerializer) + : base() + { + if (jsonSerializer == null) + { + throw new ArgumentNullException("jsonSerializer"); + } + + if (xmlSerializer == null) + { + throw new ArgumentNullException("xmlSerializer"); + } + + _jsonSerializer = jsonSerializer; + _xmlSerializer = xmlSerializer; + } + + /// <summary> /// Gets the specified request. /// </summary> /// <param name="request">The request.</param> @@ -262,10 +295,10 @@ namespace MediaBrowser.Api // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs var pathInfo = PathInfo.Parse(Request.PathInfo); var id = new Guid(pathInfo.GetArgumentValue<string>(1)); - + var kernel = (Kernel)Kernel; - var dtoUser = JsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream); + var dtoUser = _jsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream); var user = kernel.GetUserById(id); @@ -273,7 +306,7 @@ namespace MediaBrowser.Api Task.WaitAll(task); - user.UpdateConfiguration(dtoUser.Configuration); + user.UpdateConfiguration(dtoUser.Configuration, _xmlSerializer); } /// <summary> @@ -285,7 +318,7 @@ namespace MediaBrowser.Api { var kernel = (Kernel)Kernel; - var dtoUser = JsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream); + var dtoUser = _jsonSerializer.DeserializeFromStream<UserDto>(request.RequestStream); var newUser = kernel.UserManager.CreateUser(dtoUser.Name).Result; |
