I am using JohnnyCrazy/SpotifyAPI-NET for this application in Visual Studio.
The code creates a playlist just fine, but I can't modify it in any way(adding tracks, making the playlist private/public).
I am using the right scope (Scope.PlaylistModifyPrivate | Scope.PlaylistModifyPublic)
private FullPlaylist currentPlaylist;
public void DoThisStuff()
{
_profile = _spotify.GetPrivateProfile();
currentPlaylist = _spotify.CreatePlaylist(_profile.Id, Convert.ToString(DateTime.Now), false);
_spotify.AddPlaylistTrack(_profile.Id, currentPlaylist.Uri, "41VtJHghmomTfNrbTSF2Uj");
}
ok I found the solution:
currentPlaylist.Uri
That code gives me this: spotify:user:myname:playlist:02DfsHuBWwi1aCp8kxwVrs
but what I need is just the id at the end, so I cut it with
currentPlaylist.Uri.Substring(30)
An imperfect solution, as it will cause errors when the username has a different length than 7, but it works for now.
This solution is slightly less imperfect than the one you came up with.
currentPlaylist.Uri.Split(new[] {":playlist:"}, StringSplitOptions.None)[1]);
string playListUri = playlist.Uri.Substring(playlist.Uri.LastIndexOf(":") + 1);
Clean way to get URI from the string.
spotify:user:myname:playlist:02DfsHuBWwi1aCp8kxwVrs is separated by : so that you can split the string in multiple sub-strings. You then select the string you are interested in like so:
currentPlaylist.Uri.Split(':')[4] // Returns 02DfsHuBWwi1aCp8kxwVrs
Related
I'm writing a visual studio extension based on the Concord Samples Hello World project. The goal is to let the user filter out stack frames by setting a list of search strings. If any of the search strings are in a stack frame, it is omitted.
I've got the filter working for a hardcoded list. That needs to be in a non-package-based dll project in order for the debugger to pick it up. And I have a vsix project that references that dll with an OptionPageGrid to accept the list of strings. But I can't for the life of me find a way to connect them.
On the debugger side, my code looks something like this:
DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
{
if (input == null) // null input frame indicates the end of the call stack. This sample does nothing on end-of-stack.
return null;
if (input.InstructionAddress == null) // error case
return new[] { input };
DkmWorkList workList = DkmWorkList.Create(null);
DkmLanguage language = input.Process.EngineSettings.GetLanguage(new DkmCompilerId());
DkmInspectionContext inspection = DkmInspectionContext.Create(stackContext.InspectionSession, input.RuntimeInstance, input.Thread, 1000,
DkmEvaluationFlags.None, DkmFuncEvalFlags.None, 10, language, null);
string frameName = "";
inspection.GetFrameName(workList, input, DkmVariableInfoFlags.None, result => GotFrameName(result, out frameName));
workList.Execute();
CallstackCollapserDataItem dataItem = CallstackCollapserDataItem.GetInstance(stackContext);
bool omitFrame = false;
foreach (string filterString in dataItem.FilterStrings)
{
if (frameName.Contains(filterString))
{
omitFrame = true;
}
}
The CallstackCollapserDataItem is where I theoretically need to retrieve the strings from user settings. But I don't have access to any services/packages in order to e.g. ask for WritableSettingsStore, like in You've Been Haacked's Example. Nor can I get my OptionPageGrid, like in the MSDN Options Example.
The other thing I tried was based on this StackOverflow question. I overrode the LoadSettingsFromStorage function of my OptionPageGrid and attempted to set a static variable on a public class in the dll project. But if that code existed in the LoadSettingsFromStorage function at all, the settings failed to load without even entering the function. Which felt like voodoo to me. Comment out the line that sets the variable, the breakpoint hits normally, the settings load normally. Restore it, and the function isn't even entered.
I'm at a loss. I really just want to pass a string into my Concord extension, and I really don't care how.
Ok, apparently all I needed to do was post the question here for me to figure out the last little pieces. In my CallstackCollapserDataItem : DkmDataItem class, I added the following code:
private CallstackCollapserDataItem()
{
string registryRoot = DkmGlobalSettings.RegistryRoot;
string propertyPath = "vsix\\CallstackCollapserOptionPageGrid";
string fullKey = "HKEY_CURRENT_USER\\" + registryRoot + "\\ApplicationPrivateSettings\\" + propertyPath;
string savedStringSetting = (string)Registry.GetValue(fullKey, "SearchStrings", "");
string semicolonSeparatedStrings = "";
// The setting resembles "1*System String*Foo;Bar"
if (savedStringSetting != null && savedStringSetting.Length > 0 && savedStringSetting.Split('*').Length == 3)
{
semicolonSeparatedStrings = savedStringSetting.Split('*')[2];
}
}
vsix is the assembly in which CallstackCollapserOptionPageGrid is a DialogPage, and SearchStrings is its public property that's saved out of the options menu.
In addin for Sparx EA I use this code to get pictures and assign to entity. Then I use images from entities, to, as example, save at some folders or insert in word report etc (from this answer)
/// <summary>
/// Access to diagram image without using clipboard
/// </summary>
/// <param name="projectInterface">Ea Sparx interface</param>
/// <param name="eaDiagramGuid">Guid of the diagramm</param>
/// <returns></returns>
public static Image GetDiagramImage(this Project projectInterface, Guid eaDiagramGuid, ApplicationLogger _logger)
{
Image diagramImage;
try
{
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid.ToString("B"));
string tempFilename = string.Format("{0}{1}{2}", Path.GetTempPath(), Guid.NewGuid().ToString(), ".png");
bool imageToFileSuccess = projectInterface.PutDiagramImageToFile(diagramByGuid, tempFilename, FileExtensionByName);
if (imageToFileSuccess)
{
using (var imageStream = new MemoryStream(File.ReadAllBytes(tempFilename)))
{
diagramImage = Image.FromStream(imageStream);
}
File.Delete(tempFilename);
}
else
{
throw new Exception(string.Format("Image to file exprot fail {0}", projectInterface.GetLastError()));
}
}
catch (Exception e)
{
throw;
}
return diagramImage;
}
The problem is - it works if project I work with saved as .eap file.
If it's .feap file, which, as I believe means that it works with Firebird database (instead of Access), all saved/exproted to report images are blank, like this down below
Why does it happens and is there workaround?
UPD
It works if I use projectInterface.PutDiagramImageOnClipboard instead but I don't wont to use clipboard at all
UPD 2
After some experiments today at the morning (at my timezone, gmt+3, it's still morning) I found out that the problem was with GUIDs register!
After I decided to apply .toUpper() here
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid.ToString("B").ToUpper());
it started work fine!
Strange thing thou that if project is *.EAP type everything works even when guid is not in upper register!
UPD3
Well, unfortunately, I was wrong. Some pictures are still blank. But somehow that changes got impact on diagrams, I keep testing this stuff.
And some of the pictures are appeared twice or in wrong place.
But it's kinda interesting (if I could say so) behaviour.
UPD 4
I was wrong in my UPD2 part! GUID can contain down register symbols as well as upper ones.
So, first I removed that part.
What I done next - I started to pass GUID directly from diagram, so signature changed like that
public static Image GetDiagramImage(this Project projectInterface, string eaDiagramGuid, ApplicationLogger _logger)
and eaDiagramGuid should be passed right from EA.Diagram object.
When we parse it as Guid by Guid.Parse(eaDiagramGuid) it convert everything in lowercase like here
so, thats why I got the problem.
But for some reason it was not appeared in *.EAP type of projects!
Also it strange that register matters in that case, really. Seems like GUID in common and GUID in sparx ea are different things!
Okay, as I founded out here, the thing is, in case of *.FEAP all items GUIDs are surprisingly case sensetive.
So, my mistake was to store item GUID as Guid type - when we use Guid.Parse(myGuidString) function and then we converting it back to string - all symbols are appers to be in lowercase.
Also, I got my answer from support (they were surprisingly fast, I really like that)
Hello Danil,
Running over the Stack Overflow - it sounds like it's effectively
answered. The core point is that the Feap files are case sensitive.
To be technical, the collation used for our Firebird databases is case
sensitive.
So, in the Automation script you do need to adhere to the case.
So, I just change things to work directly with GUID string from project item like
Image diagramImage = _eaProjectInterface.GetDiagramImage(diagram.DiagramGUID, _logger);
and function now look like this
public static Image GetDiagramImage(this Project projectInterface, string eaDiagramGuid, ApplicationLogger _logger)
{
Image diagramImage;
try
{
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid);
string tempFilename = string.Format("{0}{1}{2}", Path.GetTempPath(), Guid.NewGuid().ToString(), ".png");
bool imageToFileSuccess = projectInterface.PutDiagramImageToFile(diagramByGuid, tempFilename, FileExtensionByName);
if (imageToFileSuccess)
{
using (var imageStream = new MemoryStream(File.ReadAllBytes(tempFilename)))
{
diagramImage = Image.FromStream(imageStream);
}
File.Delete(tempFilename);
}
else
{
throw new Exception(string.Format("Image to file exprot fail {0}", projectInterface.GetLastError()));
}
}
catch (Exception e)
{
throw;
}
return diagramImage;
}
So, this means that Sparx EA *.FEAP project GUIDs are NOT really GUIDs but just string-keys (as I assume).
Be careful when your work with them :-)
I'm trying to make C# program that gets a line on a website and use it.
Unfortunately, I don't know the full line on the site. I only know "steam://joinlobby/730/". Although, what comes after "/730/" is always different.
So i need help getting the full line that comes after it.
What I've got:
public void Main()
{
WebClient web = new WebClient();
// here is the site that i want to download and read text from it.
string result = web.DownloadString("http://steamcommunity.com/id/peppahtank");
if (result.Contains("steam://joinlobby/730/"))
{
//get the part after /730/
}
}
I can tell you that it always ends with "xxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxx"
so: steam://joinlobby/730/xxxxxxxxx/xxxxxxxx.
What's to prevent you from just splitting the string on '/730/'?
result.Split(#"/730/")[1]
https://msdn.microsoft.com/en-us/library/system.string.split(v=vs.110).aspx
The easiest method for this particular case would be to take the first part, and then just skip that many characters
const string Prefix = #"steam://joinlobby/730/";
//...
if(result.StartsWith(Prefix))
{
var otherPart = result.SubString(Prefix.Length);
// TODO: Process other part
}
Make sure your result is not null and begins with steam://joinlobby/730/
if(string.IsNullOrWhiteSpaces(result) && result.StartsWith("steam://joinlobby/730/"))
{
string rest = result.SubString(("steam://joinlobby/730/").Length);
}
So I am starting to learn how to use XML data within a app and decided to use some free data to do this however I cannot for the life of me get it working this is my code so far. (I have done a few apps with static data before but hey apps are designed to use the web right? :p)
public partial class MainPage : PhoneApplicationPage
{
List<XmlItem> xmlItems = new List<XmlItem>();
// Constructor
public MainPage()
{
InitializeComponent();
LoadXmlItems("http://hatrafficinfo.dft.gov.uk/feeds/datex/England/CurrentRoadworks/content.xml");
test();
}
public void test()
{
foreach (XmlItem item in xmlItems)
{
testing.Text = item.Title;
}
}
public void LoadXmlItems(string xmlUrl)
{
WebClient client = new WebClient();
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
return;
Stream str = e.Result;
XDocument xdoc = XDocument.Load(str);
***xmlItems = (from item in xdoc.Descendants("situation id")
select new XmlItem()
{
Title = item.Element("impactOnTraffic").Value,
Description = item.Element("trafficRestrictionType").Value
}).ToList();***
// close
str.Close();
// add results to the list
xmlItems.Clear();
foreach (XmlItem item in xmlItems)
{
xmlItems.Add(item);
}
};
client.OpenReadAsync(new Uri(xmlUrl, UriKind.Absolute));
}
}
I am basically trying to learn how to do this at the moment as I am intrigued how to actually do it (I know there are many ways but ATM this way seems the easiest) I just don't get what the error is ATM. (The bit in * is where it says the error is)
I also know the display function ATM is not great (As it will only show the last item) but for testing this will do for now.
To some this may seem easy, as a learner its not so easy for me just yet.
The error in picture form:
(It seems I cant post images :/)
Thanks in advance for the help
Edit:
Answer below fixed the error :D
However still nothing is coming up. I "think" it's because of the XML layout and the amount of descendants it has (Cant work out what I need to do being a noob at XML and pulling it from the web as a data source)
Maybe I am starting too complicated :/
Still any help/tips on how to pull some elements from the feed (As there all in Descendants) correctly and store them would be great :D
Edit2:
I have it working (In a crude way) but still :D
Thanks Adam Maras!
The last issue was the double listing. (Adding it to a list, to then add it to another list was causing a null exception) Just using the 1 list within the method solved this issue, (Probably not the best way of doing it but it works for now) and allowed for me to add the results to a listbox until I spend some time working out how to use ListBox.ItemTemplate & DataTemplate to make it look more appealing. (Seems easy enough I say now...)
Thanks Again!!!
from item in xdoc.Descendants("situation id")
// ^
XML tag names can't contain spaces. Looking at the XML, you probably just want "situation" to match the <situation> elements.
After looking at your edit and further reviewing the XML, I figured out what the problem is. If you look at the root element of the document:
<d2LogicalModel xmlns="http://datex2.eu/schema/1_0/1_0" modelBaseVersion="1.0">
You'll see that it has a default namespace applied. The easiest solution to your problem will be to first get the namespsace from the root element:
var ns = xdoc.Root.Name.Namespace;
And then apply it wherever you're using a string to identify an element or attribute name:
from item in xdoc.Descendants(ns + "situation")
// ...
item.Element(ns + "impactOnTraffic").Value
item.Element(ns + "trafficRestrictionType").Value
One more thing: <impactOnTraffic> and <trafficRestrictionType> aren't direct children of the <situation> element, so you'll need to change that code as well:
Title = items.Descendants(ns + "impactOnTraffic").Single().Value,
Description = item.Descendants(ns + "trafficRestrictionType").Single().Value
I need to validate a folder name in c#.
I have tried the following regex :
^(.*?/|.*?\\)?([^\./|^\.\\]+)(?:\.([^\\]*)|)$
but it fails and I also tried using GetInvalidPathChars().
It fails when i try using P:\abc as a folder name i.e Driveletter:\foldername
Can anyone suggest why?
You could do that in this way (using System.IO.Path.InvalidPathChars constant):
bool IsValidFilename(string testName)
{
Regex containsABadCharacter = new Regex("[" + Regex.Escape(System.IO.Path.InvalidPathChars) + "]");
if (containsABadCharacter.IsMatch(testName) { return false; };
// other checks for UNC, drive-path format, etc
return true;
}
[edit]
If you want a regular expression that validates a folder path, then you could use this one:
Regex regex = new Regex("^([a-zA-Z]:)?(\\\\[^<>:\"/\\\\|?*]+)+\\\\?$");
[edit 2]
I've remembered one tricky thing that lets you check if the path is correct:
var invalidPathChars = Path.GetInvalidPathChars(path)
or (for files):
var invalidFileNameChars = Path.GetInvalidFileNameChars(fileName)
Validating a folder name correctly can be quite a mission. See my blog post Taking data binding, validation and MVVM to the next level - part 2.
Don't be fooled by the title, it's about validating file system paths, and it illustrates some of the complexities involved in using the methods provided in the .Net framework. While you may want to use a regex, it isn't the most reliable way to do the job.
this is regex you should use :
Regex regex = new Regex("^([a-zA-Z0-9][^*/><?\"|:]*)$");
if (!regex.IsMatch(txtFolderName.Text))
{
MessageBox.Show(this, "Folder fail", "info", MessageBoxButtons.OK, MessageBoxIcon.Information);
metrotxtFolderName.Focus();
}