/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Tizen.Content.MediaContent
{
///
/// Provides the commands to manage playlists in the database.
///
///
/// 4
public class PlaylistCommand : MediaCommand
{
///
/// Initializes a new instance of the class with the specified .
///
/// A that the commands run on.
/// is null.
/// has already been disposed.
/// 4
public PlaylistCommand(MediaDatabase database) : base(database)
{
}
///
/// Retrieves the number of playlists.
///
/// The number of playlists.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// 4
public int Count()
{
return Count(null);
}
///
/// Retrieves the number of playlists with the .
///
/// The criteria to use to filter. This value can be null.
/// The number of playlists.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// 4
public int Count(CountArguments arguments)
{
ValidateDatabase();
return CommandHelper.Count(Interop.Playlist.GetPlaylistCount, arguments);
}
///
/// Retrieves the play order of the member.
///
/// The playlist ID.
/// The member ID of the playlist.
/// The order of the member in the playlist.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
///
/// is less than or equal to zero.
/// -or-
/// is less than or equal to zero.
///
/// 4
public int GetPlayOrder(int playlistId, int memberId)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (memberId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(memberId), memberId,
"Member id can't be less than or equal to zero.");
}
Interop.Playlist.GetPlayOrder(playlistId, memberId, out var order).ThrowIfError("Failed to query");
return order;
}
///
/// Deletes a playlist from the database.
///
/// http://tizen.org/privilege/content.write
/// The playlist ID to delete.
/// true if the matched record was found and deleted, otherwise false.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// The caller has no required privilege.
/// 4
public bool Delete(int playlistId)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (Select(playlistId) == null)
{
return false;
}
CommandHelper.Delete(Interop.Playlist.Delete, playlistId);
return true;
}
///
/// Inserts the playlist into the database from the specified M3U file.
///
///
/// If you want to access an internal storage, you should add privilege http://tizen.org/privilege/mediastorage.
/// If you want to access an external storage, you should add privilege http://tizen.org/privilege/externalstorage.
///
/// http://tizen.org/privilege/content.write
/// http://tizen.org/privilege/mediastorage
/// http://tizen.org/privilege/externalstorage
/// The name of the playlist.
/// The path to a M3U file to import.
/// The instance that contains the record information inserted.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
///
/// is null.
/// -or-
/// is null.
///
///
/// is a zero-length string.
/// -or-
/// is a zero-length string, contains only white space.
///
/// does not exists.
/// The caller has no required privilege.
/// 4
public Playlist InsertFromFile(string name, string path)
{
ValidateDatabase();
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
if (name.Length == 0)
{
throw new ArgumentException("Playlist name can't be an empty string.");
}
ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
if (File.Exists(path) == false)
{
throw new FileNotFoundException("The specified path does not exists.", path);
}
IntPtr handle = IntPtr.Zero;
Interop.Playlist.ImportFromFile(path, name, out handle).ThrowIfError("Failed to insert");
try
{
return new Playlist(handle);
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Exports the playlist to a M3U file.
///
///
/// If the file already exists in the file system, then it will be overwritten.
///
/// If you want to access an internal storage, you should add privilege http://tizen.org/privilege/mediastorage.
/// If you want to access an external storage, you should add privilege http://tizen.org/privilege/externalstorage.
///
/// http://tizen.org/privilege/mediastorage
/// http://tizen.org/privilege/externalstorage
/// The playlist ID to export.
/// The path to a M3U file.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is a zero-length string, contains only white space.
/// is less than or equal to zero.
/// No matching playlist exists.
/// The caller has no required privilege.
/// 4
public void ExportToFile(int playlistId, string path)
{
ValidateDatabase();
ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
IntPtr handle = IntPtr.Zero;
try
{
Interop.Playlist.GetPlaylistFromDb(playlistId, out handle).ThrowIfError("Failed to query");
Interop.Playlist.ExportToFile(handle, path).ThrowIfError("Failed to export");
}
catch (ArgumentException)
{
// Native FW returns ArgumentException when there's no matched record.
throw new RecordNotFoundException("No matching playlist exists.");
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Inserts the playlist into the database with the specified name.
///
/// http://tizen.org/privilege/content.write
/// The name of the playlist.
/// The instance that contains the record information inserted.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is a zero-length string.
/// The caller has no required privilege.
/// 4
public Playlist Insert(string name)
{
return Insert(name, null);
}
///
/// Inserts the playlist into the database with the specified name and the thumbnail path.
///
/// http://tizen.org/privilege/content.write
/// The name of the playlist.
/// The path of the thumbnail for the playlist. This value can be null.
/// The instance that contains the record information inserted.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is a zero-length string.
/// The caller has no required privilege.
/// 4
public Playlist Insert(string name, string thumbnailPath)
{
ValidateDatabase();
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
if (name.Length == 0)
{
throw new ArgumentException("Playlist name can't be an empty string.");
}
IntPtr handle = IntPtr.Zero;
Interop.Playlist.Create(out handle).ThrowIfError("Failed to insert");
try
{
Interop.Playlist.SetName(handle, name).ThrowIfError("Failed to insert");
if (thumbnailPath != null)
{
Interop.Playlist.SetThumbnailPath(handle, thumbnailPath).ThrowIfError("Failed to insert");
}
Interop.Playlist.Insert(handle).ThrowIfError("Failed to insert");
return new Playlist(handle);
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Retrieves the playlists.
///
/// The containing the results.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// 4
public MediaDataReader Select()
{
return Select(null);
}
///
/// Retrieves the playlists with the .
///
/// The criteria to use to filter. This value can be null.
/// The containing the results.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// 4
public MediaDataReader Select(SelectArguments filter)
{
ValidateDatabase();
return CommandHelper.Select(filter, Interop.Playlist.ForeachPlaylistFromDb,
Playlist.FromHandle);
}
///
/// Retrieves the playlist with the specified playlist ID.
///
/// The playlist ID to select.
/// The instance if the matched record was found in the database, otherwise null.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// 4
public Playlist Select(int playlistId)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
IntPtr handle = IntPtr.Zero;
try
{
Interop.Playlist.GetPlaylistFromDb(playlistId, out handle).ThrowIfError("Failed to query");
return new Playlist(handle);
}
catch (ArgumentException)
{
// Native FW returns ArgumentException when there's no matched record.
return null;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Retrieves the number of media information of the playlist.
///
/// The playlist ID to count media added to the playlist.
/// The number of media information.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// 4
public int CountMember(int playlistId)
{
return CountMember(playlistId, null);
}
///
/// Retrieves the number of media information of the playlist with the .
///
/// The playlist ID to count the media added to the playlist.
/// The criteria to use to filter. This value can be null.
/// The number of media information.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// 4
public int CountMember(int playlistId, CountArguments arguments)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
return CommandHelper.Count(Interop.Playlist.GetMediaCountFromDb, playlistId, arguments);
}
private static List GetMembers(int playlistId, SelectArguments arguments)
{
using (var filter = QueryArguments.ToNativeHandle(arguments))
{
Exception caught = null;
List list = new List();
Interop.Playlist.ForeachMediaFromDb(playlistId, filter, (memberId, mediaInfoHandle, _) =>
{
try
{
list.Add(new PlaylistMember(memberId, MediaInfo.FromHandle(mediaInfoHandle)));
return true;
}
catch (Exception e)
{
caught = e;
return false;
}
}).ThrowIfError("Failed to query");
if (caught != null)
{
throw caught;
}
return list;
}
}
///
/// Retrieves the member ID of the media in the playlist.
///
/// The playlist ID.
/// The media ID.
/// The member ID if the member was found in the playlist, otherwise -1.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// is null.
/// is a zero-length string, contains only white space.
/// 4
public int GetMemberId(int playlistId, string mediaId)
{
ValidateDatabase();
ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
var reader = SelectMember(playlistId, new SelectArguments()
{
FilterExpression = $"{MediaInfoColumns.Id}='{mediaId}'"
});
reader.Read();
return reader.Current?.MemberId ?? -1;
}
///
/// Retrieves the media information of the playlist.
///
/// The playlist ID to query with.
/// The containing the results.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// 4
public MediaDataReader SelectMember(int playlistId)
{
return SelectMember(playlistId, null);
}
///
/// Retrieves the media information of the playlist with the .
///
/// The playlist ID to query with.
/// The criteria to use to filter. This value can be null.
/// The containing the results.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is less than or equal to zero.
/// 4
public MediaDataReader SelectMember(int playlistId, SelectArguments filter)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
return new MediaDataReader(GetMembers(playlistId, filter));
}
///
/// Updates the playlist with the specified values.
///
/// http://tizen.org/privilege/content.write
/// The playlist ID to update.
/// The values for the update.
/// true if the matched record was found and updated, otherwise false.
/// Only values set in the are updated.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is less than or equal to zero.
/// The caller has no required privilege.
/// 4
public bool Update(int playlistId, PlaylistUpdateValues values)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (values == null)
{
throw new ArgumentNullException(nameof(values));
}
if (CommandHelper.Count(
Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
{
return false;
}
Interop.Playlist.Create(out var handle).ThrowIfError("Failed to update");
try
{
if (values.Name != null)
{
Interop.Playlist.SetName(handle, values.Name).ThrowIfError("Failed to update");
}
if (values.ThumbnailPath != null)
{
Interop.Playlist.SetThumbnailPath(handle, values.ThumbnailPath).ThrowIfError("Failed to update");
}
Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to update");
return true;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Adds the media to the playlist.
///
/// The playlist ID that the media will be added to.
/// The media ID to add to the playlist.
/// true if the matched record was found and updated, otherwise false.
/// The invalid media ID will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is a zero-length string, contains only white space.
/// is less than or equal to zero.
/// 4
public bool AddMember(int playlistId, string mediaId)
{
ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
return AddMembers(playlistId, new string[] { mediaId });
}
///
/// Adds the media set to the playlist.
///
/// The playlist ID that the media will be added to.
/// The collection of media ID to add to the playlist.
/// true if the matched record was found and updated, otherwise false.
/// The invalid media IDs will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
///
/// has no element.
/// -or-
/// contains null value.
/// -or-
/// contains a zero-length string or white space.
///
/// is less than or equal to zero.
/// 4
public bool AddMembers(int playlistId, IEnumerable mediaIds)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (mediaIds == null)
{
throw new ArgumentNullException(nameof(mediaIds));
}
if (mediaIds.Count() == 0)
{
throw new ArgumentException("mediaIds has no element.", nameof(mediaIds));
}
if (CommandHelper.Count(
Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
{
return false;
}
IntPtr handle = IntPtr.Zero;
Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
try
{
foreach (var mediaId in mediaIds)
{
if (mediaId == null)
{
throw new ArgumentException("Media id should not be null.", nameof(mediaIds));
}
if (string.IsNullOrWhiteSpace(mediaId))
{
throw new ArgumentException("Media id should not be empty.", nameof(mediaId));
}
Interop.Playlist.AddMedia(handle, mediaId).ThrowIfError("Failed to add member");
}
Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
return true;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Removes a member from the playlist.
///
/// The playlist ID.
/// The member ID to be removed.
/// true if the matched record was found and updated, otherwise false.
/// The invalid ID will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
///
/// is less than or equal to zero.
/// -or-
/// is less than or equal to zero.
///
/// 4
public bool RemoveMember(int playlistId, int memberId)
{
if (memberId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(memberId), memberId,
"Member id can't be less than or equal to zero.");
}
return RemoveMembers(playlistId, new int[] { memberId });
}
///
/// Removes a media set from the playlist.
///
/// The playlist ID.
/// The collection of member ID to remove from to the playlist.
/// true if the matched record was found and updated, otherwise false.
/// The invalid IDs will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
///
/// has no element.
/// -or-
/// contains a value which is less than or equal to zero.
///
/// is less than or equal to zero.
/// 4
public bool RemoveMembers(int playlistId, IEnumerable memberIds)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (memberIds == null)
{
throw new ArgumentNullException(nameof(memberIds));
}
if (memberIds.Count() == 0)
{
throw new ArgumentException("memberIds has no element.", nameof(memberIds));
}
if (CommandHelper.Count(
Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
{
return false;
}
IntPtr handle = IntPtr.Zero;
Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
try
{
foreach (var memberId in memberIds)
{
if (memberId <= 0)
{
throw new ArgumentException(nameof(memberIds),
"Member id can't be less than or equal to zero.");
}
Interop.Playlist.RemoveMedia(handle, memberId).ThrowIfError("Failed to add member");
}
Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
return true;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
///
/// Updates a play order of the playlist.
///
/// The playlist ID.
/// The to apply.
/// true if the matched record was found and updated, otherwise false.
/// The that is invalid will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
/// is less than or equal to zero.
/// 4
public bool UpdatePlayOrder(int playlistId, PlayOrder playOrder)
{
if (playOrder == null)
{
throw new ArgumentNullException(nameof(playOrder));
}
return UpdatePlayOrders(playlistId, new PlayOrder[] { playOrder });
}
///
/// Updates play orders of the playlist.
///
/// The playlist ID.
/// The collection of the to apply.
/// true if the matched record was found and updated, otherwise false.
/// The that is invalid will be ignored.
/// The is disconnected.
/// The has already been disposed.
/// An error occurred while executing the command.
/// is null.
///
/// has no element.
/// -or-
/// contains a null value.
///
/// is less than or equal to zero.
/// 4
public bool UpdatePlayOrders(int playlistId, IEnumerable orders)
{
ValidateDatabase();
if (playlistId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
"Playlist id can't be less than or equal to zero.");
}
if (orders == null)
{
throw new ArgumentNullException(nameof(orders));
}
if (orders.Count() == 0)
{
throw new ArgumentException("memberIds has no element.", nameof(orders));
}
if (CommandHelper.Count(
Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
{
return false;
}
IntPtr handle = IntPtr.Zero;
Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
try
{
foreach (var order in orders)
{
if (order == null)
{
throw new ArgumentException(nameof(orders),
"orders should not contain null value.");
}
Interop.Playlist.SetPlayOrder(handle, order.MemberId, order.Value).ThrowIfError("Failed to add member");
}
Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
return true;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.Playlist.Destroy(handle);
}
}
}
}
}