Differentiate iTunes internal playlists and user playlist - c#

Following my previous question
When I fetch Playlists in iTunes library I get some entries which seems to be default playlists for iTunes
Here is my code:
App = new iTunesAppClass();
IITSourceCollection sources = App.Sources;
foreach (IITSource src in sources)
{
if (src.Name == "Library")
{
IITPlaylistCollection pls = src.Playlists;
foreach (IITPlaylist pl in pls)
{
// add pl.Name to a List<string> and them show them on TreeView
}
}
}
This is the result:
You see that I have created a playlist named "Music". There is also a default entry named "Music". How can I differentiate these two playlist ? Is there any property in iTunesLib which says which one is the default one and which is the one I have created?

Using Kind and SpecialKind properties, I was able to implement a solution:
App = new iTunesAppClass();
IITSourceCollection sources = App.Sources;
foreach (IITSource src in sources)
{
if (src.Name == "Library")
{
IITPlaylistCollection pls = src.Playlists;
foreach (IITPlaylist pl in pls)
{
/* here is the trick */
if (p is IITUserPlaylist)
{
var upl = (IITUserPlaylist)p;
if (upl.SpecialKind != ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindNone)
continue;
}
/* and this one */
if (p.Kind == ITPlaylistKind.ITPlaylistKindLibrary)
continue;
// add pl.Name to a List<string> and them show them on TreeView
}
}
}

Related

UWP: MediaPlaybackItem get ViewModel

My MediaPlaybackList.ShuffledItems has 10 items in it. But when I was trying to convert the items back to a list of ViewModel (in my case it is Music) using the uri, I got null.
Why is that? Is it because I load the file from my local drive?
This is how I get the uri:
public static async Task<List<Music>> GetRealPlayList()
{
if (PlayList.ShuffleEnabled)
{
if (ShuffledPlayList.Count == 0)
{
foreach (var music in PlayList.ShuffledItems)
{
ShuffledPlayList.Add(await Music.GetMusic(music.Source.Uri.AbsolutePath));
}
}
return ShuffledPlayList;
}
else
return CurrentPlayList;
}
This is how I set the items:
public static async Task SetPlayList(IEnumerable<Music> playlist)
{
if (Helper.SamePlayList(playlist, CurrentPlayList)) return;
PlayList.Items.Clear();
CurrentPlayList.Clear();
foreach (var music in playlist)
{
var item = new MediaPlaybackItem(MediaSource.CreateFromStorageFile(await Helper.CurrentFolder.GetFileAsync(music.GetShortPath())));
PlayList.Items.Add(item);
CurrentPlayList.Add(music);
}
}
What ways else can I convert the MediaPlackBackItem back to the ViewModel? The GetDisplayProperties().MusicProperties doesn't have the some properties that I want and the properties in it are also empty.
When you create MediaSource,you can set CustomProperties to save the file path in it.And when you loop through the PlayList.ShuffledItems,get file path from the CustomProperties.
Set the items:
MediaSource source = MediaSource.CreateFromStorageFile(await Helper.CurrentFolder.GetFileAsync(music.GetShortPath()));
source.CustomProperties.Add("Path", file.Path);
var item = new MediaPlaybackItem(source);
Get Music class:
foreach (var music in PlayList.ShuffledItems)
{​
MediaSource source = music.Source;​
String path = sour.CustomProperties["Path"].ToString();​
ShuffledPlayList.Add(await Music.GetMusic(path));​
}

How to Parse Json to obtains values

This is the Json Format from the Imgur API using gallery search (heavily simplified, what matters is still there)
{
"data":[
{
"id":"q33FYFh",
"is_album":true,
"images":[
{
"id":"ObcYQRc",
"link":"https:\/\/i.imgur.com\/ObcYQRc.jpg",
"is_album":false
},
{
"id":"ifB0uac",
"link":"https:\/\/i.imgur.com\/ifB0uac.jpg",
"is_album":false
}
]
},
{
"id":"jYInL3c",
"is_album":true,
"images":[
{
"id":"bq2L5C4",
"link":"https:\/\/i.imgur.com\/bq2L5C4.jpg",
"is_album":false
},
{
"id":"Z0OPngk",
"link":"https:\/\/i.imgur.com\/Z0OPngk.jpg",
"is_album":false
}
]
},
{
"id":"8xxM5TO",
"link":"https:\/\/i.imgur.com\/8xxM5TO.jpg",
"is_album":false
}
],
"success":true,
"status":200
}
I need a way to get all image ID, not album ID, you can tell if an item is an album or a image by looking at the "is_album" tag
So first I tried to at least access the "id" subfield in the "images" field :
using Newtonsoft.Json;
string response = "Change this with the json file above"
dynamic dynJson = JsonConvert.DeserializeObject(response);
foreach (var data in dynJson)
{
string id = data["images"]["id"].ToString();
Debug.WriteLine(id);
}
This gave me this error : (By the way, I need to use Debug.WriteLine because Console doesn't work in PCL code in Xamarin.Forms)
System.InvalidOperationException: Cannot access child value on Newtonsoft.Json.Linq.JProperty.
But even if it worked, it would not get the id's for the images that are not part of an album.
using pseudo code this is what I would want (I think) :
for each (item in myjson)
{
if (item.is_album == "false")
{
Console.write(item.id);
}
else
{
for each (image in element)
{
Console.write(image.id);
}
}
}
You are not accessing your data correctly based on your JSON data.
data is your top level array, so your foreach would look like this:
foreach (var data in dynJson["data"])
Inside your foreach you would access your images like this:
string id = data["images"][0]["id"].ToString();
Where 0 is the index of the images array.
So combining this with another loop to get all the images for that data:
foreach (var data in dynJson["data"])
{
if (data["is_album"] == false)
{
// continue or do something
continue;
}
foreach(var image in data["images"])
{
string id = image["id"].ToString();
Debug.WriteLine(id);
}
}
You are accessing the dynamic object incorrectly. Here is the code you need:
public static List<string> GetImageIds(string jsonData)
{
List<string> imageIds = new List<string> ();
dynamic temp = JsonConvert.DeserializeObject (jsonData);
dynamic dynJson = temp.data;
foreach (dynamic data in dynJson)
{
int j = 0;
if (data.is_album == false)
{
imageIds.Add (data.id.ToString ());
}
else
{
dynamic images = data.images;
foreach (var image in images)
{
imageIds.Add (image.id.ToString ());
}
}
}
return imageIds;
}
Note: This is a simple example of how to traverse dynamic object. You will need to add validations and business logic to it as needed per your need.
Hope this helps!

Find subsolution items

I am trying to find subsolution and add items into that solution programmatically. But code that i use is not searching for subfolders.
I use code on github: See code here please
Method that i search for solution is:
public static IEnumerable<EnvDTE.Project> GetAllProjects(EnvDTE.DTE dte)
{
List<EnvDTE.Project> projectList = new List<EnvDTE.Project>();
var folders = dte.Solution.Projects.Cast<EnvDTE.Project>().Where(p=>p.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder);
foreach (EnvDTE.Project folder in folders)
{
if (folder.ProjectItems == null) continue;
foreach (EnvDTE.ProjectItem item in folder.ProjectItems)
{
if (item.Object is EnvDTE.Project)
projectList.Add(item.Object as EnvDTE.Project);
}
}
var projects = dte.Solution.Projects.Cast<EnvDTE.Project>().Where(p=>p.Kind != EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder);
if (projects.Count() > 0)
projectList.AddRange(projects);
return projectList;
}
But this is searching only main solution and sub solution. But solution that i want to find has a longer path like "MainFolder\SubFolder1\SubFolder2\SubFolder3\SubSolution"

copy list items from one list to another in sharepoint

In Sharepoint how can you copy a list item from one list to another list
eg copy from "List A" to "List B" (both are at the root of the site)
I want this copying to occur when a new list item is added to "List A"
I tried using the CopyTo() method of an SPListItem inside the ItemAdded event receiver but couldnt figure out the url to copy to.
Here is the code I use. Pass it a SPlistItem and the name of the destination list as seen in Sharepoint(Not the URL). The only restriction is that both list must be in the same site:
private SPListItem CopyItem(SPListItem sourceItem, string destinationListName) {
//Copy sourceItem to destinationList
SPList destinationList = sourceItem.Web.Lists[destinationListName];
SPListItem targetItem = destinationList.Items.Add();
foreach (SPField f in sourceItem.Fields) {
//Copy all except attachments.
if (!f.ReadOnlyField && f.InternalName != "Attachments"
&& null != sourceItem[f.InternalName])
{
targetItem[f.InternalName] = sourceItem[f.InternalName];
}
}
//Copy attachments
foreach (string fileName in sourceItem.Attachments) {
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
byte[] imageData = file.OpenBinary();
targetItem.Attachments.Add(fileName, imageData);
}
return targetItem;
}
Indeed as Lars said, it can be tricky to move items and retain versions and correct userinfo. I have done similar things with that before so if you need some code examples, let me know through a comment and can supply you with some guidance.
The CopyTo method (if you decide to go with that) need an absolute Uri like:
http://host/site/web/list/filename.doc
So, if you are performing this in an event receiver you need to concatinate a string containing the elements needed. Something like (note that this can be done in other ways to):
string dest=
siteCollection.Url + "/" + site.Name + list.Name + item.File.Name;
Copying and moving files, items and folders in SharePoint can be tricky if you want to retain all metadata, timestamps, author info and version history. Take a look a CopyMove for SharePoint - it also has a Web Service API.
There's many tools on the market for copying a list item to another list (avepoint, metavis, etc.) but they are pretty expensive if you're planning to do this on only one list.
If you can do this manually once a week for example, look at the following tool : http://en.share-gate.com/sharepoint-tools/copy-move-sharepoint-list-items-with-metadata-and-version-history
Here is a powershell equivalent of Sylvian's that does allow for cross-site copy. His code could be modified similarly as well...
param([string]$sourceWebUrl, [string]$sourceListName, [string]$destWebUrl, [string]$destListName)
$sourceWeb = get-spweb $sourceWebUrl;
$sourceList = $sourceWeb.Lists[$sourceListName];
$destWeb = get-spweb $destWebUrl;
$destList = $destWeb.Lists[$destListName];
$sourceList.Items |%{
$destItem = $destList.Items.Add();
$sourceItem = $_;
$sourceItem.Fields |%{
$f = $_;
if($f.ReadOnlyField -eq $false -and $f.InternalName -ne "Attachments" -and $sourceItem[$f.InternalName] -ne $null){
$destItem[$f.InternalName] = $sourceItem[$f.InternalName];
}
}
$destItem.Update();
}
To use, copy and past to a file copy-listitems.ps1 and run using Sharpoint powerhsell commandline...
Make sure you call CopyTo(url) method on SPFile, not on SPListItem.
for example:
ItemUpdated(SPItemEventProperties properties)
{
//...
string url = properties.Web.Site.Url + "/" + properties.Web.Name + "Lists/ListName/" + properties.ListItem.File.Name;
//properties.ListItem.File.MoveTo(url);
properties.ListItem.File.CopyTo(url);
//...
}
private void CopyAttachmentsToList(SPListItem srcItem, SPListItem tgtItem)
{
try
{
//get source item attachments from the folder
SPFolder srcAttachmentsFolder =
srcItem.Web.Folders["Lists"].SubFolders[srcItem.ParentList.Title].SubFolders["Attachments"].SubFolders[srcItem.ID.ToString()];
//Add items to the target item
foreach (SPFile file in srcAttachmentsFolder.Files)
{
byte[] binFile = file.OpenBinary();
tgtItem.Update();
tgtItem.Attachments.AddNow(file.Name, binFile);
tgtItem.Update();
}
}
catch
{
//exception message goes here
}
finally
{
srcItem.Web.Dispose();
}
}
Don't forget to add this line, tgtItem.Update();, else you will get an err.
So, the lists have the exact same or similar columns? Either way, you could create a simple workflow that runs automatically when an item is created in "List A". Since the workflow in question is relatively simple, I'd recommend using SharePoint Designer (which is free) to create it, since you can easily match up the columns from the two lists. The walk through below should be able to help you get started.
Create a Workflow - SharePoint Designer
I had the same problem.
After experimenting a bit instead of
targetItem[f.InternalName] = sourceItem[f.InternalName];
I used:
targetItem[childField.Title] = sourceItem[parentField.Title];
How to copy field and save versions:
public static SPListItem CopyItem(SPListItem sourceItem, SPList destinationList)
{
SPListItem targetItem = destinationList.AddItem();
//loop over the soureitem, restore it
for (int i = sourceItem.Versions.Count - 1; i >= 0; i--)
{
//set the values into the archive
foreach (SPField sourceField in sourceItem.Fields)
{
SPListItemVersion version = sourceItem.Versions[i];
if ((!sourceField.ReadOnlyField) && (sourceField.InternalName != "Attachments"))
{
SetFields(targetItem, sourceField, version);
}
}
//update the archive item and
//loop over the the next version
targetItem.Update();
}
foreach (string fileName in sourceItem.Attachments)
{
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
targetItem.Attachments.Add(fileName, file.OpenBinary());
}
targetItem.SystemUpdate();
return targetItem;
}
private static bool SetFields(SPListItem targetItem, SPField sourceField, SPListItemVersion version)
{
try
{
targetItem[sourceField.InternalName] = version.ListItem[sourceField.InternalName];
return true;
}
catch (System.ArgumentException)//field not filled
{
return false;
}
catch (SPException)//field not filled
{
return false;
}
}
Copy List Items from one SharePoint List or library to Another SharePoint list or library using c# server side code
//Itecollection is a collection of data from source list
public void CopyItemsFromOneListToAnotherList(SPListItemCollection itemCollection)
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
//Get destination list/library
//destListName - Destination list/library name
SPList destList = web.Lists.TryGetList(destListName);
foreach (SPListItem sourceItem in itemCollection)
{
//Add new Item to list
SPListItem destItem = destList.Items.Add();
foreach (SPField field in sourceItem.Fields)
{
if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
{
if (destItem.Fields.ContainsField(field.InternalName))
{
//Copy item to destination library
destItem[field.InternalName] = sourceItem[field.InternalName];
}
}
}
//Update item in destination library or list
destItem.Update();
Console.WriteLine("Copied " + sourceItem["ID"] + "to destination list/library");
}
}
}
}

Retrieve all items from a SharePoint Field Choice Column

I am playing around with a SharePoint server and I am trying to programmatically add a service request to microsoft's call center application template. So far, I have had pretty good success. I can add a call for a specified customer and assign a specific support tech:
private enum FieldNames
{
[EnumExtension.Value("Service Request")]
ServiceRequest,
[EnumExtension.Value("Customer")]
Customer,
[EnumExtension.Value("Service Representative")]
ServiceRepresentative,
[EnumExtension.Value("Assigned To")]
AssignedTo,
[EnumExtension.Value("Software")]
Software,
[EnumExtension.Value("Category")]
Category
}
private void CreateServiceCall(string serviceCallTitle, string customerName, string serviceRep)
{
SPSite allSites = new SPSite(siteURL);
SPWeb site = allSites.AllWebs[siteName];
SPListItemCollection requestsList = site.Lists[serviceRequests].Items;
SPListItem item = requestsList.Add();
SPFieldLookup customerLookup = item.Fields[FieldNames.Customer.Value()] as SPFieldLookup;
item[FieldNames.ServiceRequest.Value()] = serviceCallTitle;
if (customerLookup != null)
{
using (SPWeb lookupWeb = allSites.OpenWeb(customerLookup.LookupWebId))
{
SPList lookupList = lookupWeb.Lists.GetList(new Guid(customerLookup.LookupList), false);
foreach (SPListItem listItem in lookupList.Items)
{
if (listItem[customerLookup.LookupField].ToString() != customerName) continue;
item[FieldNames.Customer.Value()] = new SPFieldLookupValue(listItem.ID, customerName);
break;
}
}
}
SPUserCollection userCollection = site.SiteUsers;
if (userCollection != null)
{
foreach (SPUser user in userCollection)
{
if (user.Name != serviceRep) continue;
item[FieldNames.AssignedTo.Value()] = user;
break;
}
}
item.Update();
site.Close();
allSites.Close();
}
I added two custom columns (category, software) to the default list:
I populated both of these columns inside of SharePoint, now I want to retrieve that data so I can use it in the code snippet I posted to assign the proper category/software etc to the call. I have not been able to get the list in the code, I have tried using a item["Software"], site.Lists["Software"] and a couple of others, but so far all I have come up is null.
Can anyone point me in the right direction for this? Thanks!
SPFieldMultiChoice and related fields have a Choices property:
SPFieldMultiChoice software = item.Fields[FieldNames.Software.Value()] as SPFieldMultiChoice;
StringCollection softwareChoices = software.Choices;
If you need to set a value on the field, use the SPFieldMultiChoiceValue type:
SPFieldMultiChoiceValue values = new SPFieldMultiChoiceValue();
values.Add("Choice 1");
values.Add("Choice 2");
item[FieldNames.Software.Value()] = values;

Categories

Resources