GitHub API update file - c#

I'm trying to update a file via the GitHub API.
I've got everything setup, and in the end the actual file is updated, which is a good thing.
However, let's say I've got these 2 files in my repo
FileToBeUpdated.txt
README.md
And then I run my program
The FileToBeUpdated.txt is updated, like it should, however the README.md is deleted.
This is the code with the 5 steps to update the file:
private static void Main()
{
string shaForLatestCommit = GetSHAForLatestCommit();
string shaBaseTree = GetShaBaseTree(shaForLatestCommit);
string shaNewTree = CreateTree(shaBaseTree);
string shaNewCommit = CreateCommit(shaForLatestCommit, shaNewTree);
SetHeadPointer(shaNewCommit);
}
private static void SetHeadPointer(string shaNewCommit)
{
WebClient webClient = GetMeAFreshWebClient();
string contents = "{" +
"\"sha\":" + "\"" + shaNewCommit + "\", " +
// "\"force\":" + "\"true\"" +
"}";
// TODO validate ?
string downloadString = webClient.UploadString(Constants.Start + Constants.PathToRepo + "refs/heads/master", "PATCH", contents);
}
private static string CreateCommit(string latestCommit, string shaNewTree)
{
WebClient webClient = GetMeAFreshWebClient();
string contents = "{" +
"\"parents\" :[ \"" + latestCommit + "\" ], " +
"\"tree\":" + "\"" + shaNewTree + "\", " +
"\"message\":" + "\"test\", " +
"\"author\": { \"name\": \""+ Constants.Username +"\", \"email\": \""+ Constants.Email+"\",\"date\": \"" + DateTime.UtcNow.ToString("s", CultureInfo.InvariantCulture) + "\"}" +
"}";
string downloadString = webClient.UploadString(Constants.Start + Constants.PathToRepo + "commits", contents);
var foo = JsonConvert.DeserializeObject<CommitRootObject>(downloadString);
return foo.sha;
}
private static string CreateTree(string shaBaseTree)
{
WebClient webClient = GetMeAFreshWebClient();
string contents = "{" +
"\"tree\" :" +
"[ {" +
"\"base_tree\": " + "\"" + shaBaseTree + "\"" + "," +
"\"path\": " + "\"" + Constants.FileToChange + "\"" + " ," +
"\"content\":" + "\"" + DateTime.Now.ToLongTimeString() + "\"" +
"} ]" +
"}";
string downloadString = webClient.UploadString(Constants.Start + Constants.PathToRepo + "trees", contents);
var foo = JsonConvert.DeserializeObject<TreeRootObject>(downloadString);
return foo.sha;
}
private static string GetShaBaseTree(string latestCommit)
{
WebClient webClient = GetMeAFreshWebClient();
string downloadString = webClient.DownloadString(Constants.Start + Constants.PathToRepo + "commits/" + latestCommit);
var foo = JsonConvert.DeserializeObject<CommitRootObject>(downloadString);
return foo.tree.sha;
}
private static string GetSHAForLatestCommit()
{
WebClient webClient = GetMeAFreshWebClient();
string downloadString = webClient.DownloadString(Constants.Start + Constants.PathToRepo + "refs/heads/master");
var foo = JsonConvert.DeserializeObject<HeadRootObject>(downloadString);
return foo.#object.sha;
}
private static WebClient GetMeAFreshWebClient()
{
var webClient = new WebClient();
webClient.Headers.Add(string.Format("Authorization: token {0}", Constants.OAuthToken));
return webClient;
}
Which part am I missing? Am I using the wrong tree to start from?

It seems that in the function CreateTree I should set the base_tree at the root level, not at the level of each tree I create.
So in the function CreateTree the contents become this:
string contents = "{" +
"\"base_tree\": " + "\"" + shaBaseTree + "\"" + "," + // IT'S THIS LINE!
"\"tree\" :" +
"[ {" +
"\"path\": " + "\"" + Constants.FileToChange + "\"" + " ," +
"\"content\":" + "\"" + DateTime.Now.ToLongTimeString() + "\"" +
"} ]" +
"}";
Updated GitHub documentation: https://github.com/Snakiej/developer.github.com/commit/2c4f93003703f68c4c8a436df8cf18e615e293c7

Related

Results in descending order

I've got a block of code which sums up time togged for various tasks in a project and returns the total hours logged per project (intMinutesLogged). How do I get my results n descending order?
static async void NotifyEntriesByWorkSpace(Dictionary<string, List<TimeEntry>> dicEntriesByWorkspace, string strChatURL)
{
string strMessage = "";
foreach (var kvpEntry in dicEntriesByWorkspace)
{
var lstTimeEntries = kvpEntry.Value;
string strTitle = "";
var intMinutesLogged = 0;
var intMinutesBillable = 0;
var intMinutesNonBillable = 0;
foreach (var objTimeEntry in lstTimeEntries)
{
if (objTimeEntry.Billable)
{
intMinutesBillable += objTimeEntry.TimeInMinutes;
}
else
{
intMinutesNonBillable += objTimeEntry.TimeInMinutes;
}
}
strTitle = Workspaces.getWorkspaceFromCache(kvpEntry.Key).Title;
//Console.WriteLine(intMinutesLogged + ": " + strTitle + "m");
intMinutesLogged = intMinutesBillable + intMinutesNonBillable;
Console.WriteLine(TimeLoggedMessage(intMinutesLogged) + ": " + strTitle + " " + "(Billable: " + TimeLoggedMessage(intMinutesBillable) + ";" + " " + "Non-Billable: " + TimeLoggedMessage(intMinutesNonBillable) + ")");
strMessage += TimeLoggedMessage(intMinutesLogged) + ": " + strTitle + " " + "(Billable: " + TimeLoggedMessage(intMinutesBillable) + ";" + " " + "Non-Billable: " + TimeLoggedMessage(intMinutesNonBillable) + ")" + "\n";
}
await SendMessage(strChatURL, strMessage);
}
static string TimeLoggedMessage(int intMinutesLogged)
{
return intMinutesLogged / 60 + "h" + " " + intMinutesLogged % 60 + "m";
}
You could use LINQ for this: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.orderbydescending?view=net-6.0
You could create a simple class or anonymous type to hold the integer values you're summing up (total minutes, billable minutes, non-billable minutes). Then you could populate a collection of this type within the code you shared and afterwards call OrderByDescending on it. You could order based on any of the three integer values.

OneNote UpdatePageContent

I am trying to update the page content in OneNote through my C# application. Here is the code I have for doing this:
private static void SetElementInPage(string pageId)
{
Microsoft.Office.Interop.OneNote.Application m_app = new Microsoft.Office.Interop.OneNote.Application();
string strPageContent = "<one:Page xmlns:one=\"http://schemas.microsoft.com/office/onenote/2010/onenote\" ID=\"{0}\" >" +
"<one:Outline>" +
"<one:Position x=\"36.0\" y=\"86.4000015258789\" z=\"0\" />" +
"<one:Size width=\"117.001953125\" height=\"40.28314971923828\" />" +
"<one:OEChildren>" +
"<one:OE>" +
"<one:T><![CDATA[This is a sample data added to test out OneNote API functionality. Following is a list item.]]></one:T>" +
"</one:OE>" +
"</one:OEChildren>" +
"<one:OEChildren indent=\"2\">" +
"<one:OE alignment=\"left\">" +
"<one:List>" +
"<one:Bullet bullet=\"2\" fontSize=\"11.0\" />" +
"</one:List>" +
"<one:T><![CDATA[A for Apple]]></one:T>" +
"</one:OE>" +
"<one:OE alignment=\"left\">" +
"<one:List>" +
"<one:Bullet bullet=\"2\" fontSize=\"11.0\" />" +
"</one:List>" +
"<one:T><![CDATA[B for Ball]]></one:T>" +
"</one:OE>" +
"<one:OE alignment=\"left\">" +
"<one:List>" +
"<one:Bullet bullet=\"2\" fontSize=\"11.0\" />" +
"</one:List>" +
"<one:T><![CDATA[C for Cat]]></one:T>" +
"</one:OE>" +
"</one:OEChildren>" +
"</one:Outline>" +
"</one:Page>";
strPageContent = string.Format(strPageContent, pageId);
m_app.UpdatePageContent(strPageContent);
}
On the final line m_app.UpdatePageContent(strPageContent); I am getting an error that reads:
An exception of type 'System.Runtime.InteropServices.COMException' occurred in Microsoft.Office.Interop.OneNote.dll but was not handled in user code
The method setElementInPage(string pageId) is also called in the code below:
private async void ThisAddIn_Startup(object sender, System.EventArgs e)
{
GetNamespace();
string notebookId = GetObjectId(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsNotebooks, "Aaron # Microsoft");
string sectionId = GetObjectId(notebookId, Microsoft.Office.Interop.OneNote.HierarchyScope.hsSections, "New Section 1");
string firstPageId = GetObjectId(sectionId, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, "My Page");
SetElementInPage(firstPageId);
Console.Read();
}
What could be causing this issue? Any help is appreciated, thanks.

Add pause to Alexa without using SSML

Is there a way to add a pause (preferably 1 second) in Amazon Alexa without using SSML? Perhaps there is a trick I can do with the Outputspeech.Text and I just don't know it.
Below, I am saying "Here are works of art by {artist name}" but the name and the start of the works of art become mixed together - in spite of the period - so I end up with things like "Here are the works of art by Pablo Picasso Harlequin..."
I am using C# and my own https endpoint, not AWS Lambda.
Any suggestions? Otherwise I will add it as SSML. Thanks.
var output = new StringBuilder();
var outputCard = new StringBuilder();
string m_location;
string m_current_location;
string m_artist = dt_artist.Rows[0]["DisplayName"].ToString();
output.Append("here are works of art for " + m_artist + ". ");
outputCard.Append("Here are works of art for " + m_artist + ".\n\n");
foreach (DataRow dr in dt_artist_objs.Rows)
{
m_current_location = dr["CurrentLocation"].ToString();
if (m_current_location == " ")
{
m_location = "The location is not available.";
}
else
{
m_location = "It is located on the " + m_current_location;
}
output.Append(dr["Title"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + m_location);
outputCard.Append(dr["Title"].ToString() + ", " + dr["Dated"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + dr["Creditline"].ToString() + ". " + m_location + ".\n"); // It is located on the " + dr["CurrentLocation"].ToString());
}
sql_conn_data.Close();
response.Response.OutputSpeech.Text = output.ToString();
response.Response.Card.Title = "Art";
response.Response.Card.Type = "Standard";
response.Response.Card.Text = outputCard.ToString();
response.Response.ShouldEndSession = true;
return response;
UPDATE
OK. Ended up going the SSML route which looks like this:
var output = new StringBuilder();
var outputCard = new StringBuilder();
string m_location;
string m_current_location;
string m_location_card;
string m_artist = dt_artist.Rows[0]["DisplayName"].ToString();
output.Append("<speak>");
output.Append("here are works of art for " + m_artist + ". <break time='1s'/> ");
outputCard.Append("Here are works of art for " + m_artist + ".\n\n");
foreach (DataRow dr in dt_artist_objs.Rows)
{
m_current_location = dr["CurrentLocation"].ToString();
if (m_current_location == " ")
{
m_location = "The location is not available. <break time='1s' />";
m_location_card = "The location is not available. ";
}
else
{
m_location = "It is located on the " + m_current_location + "<break time = '1s' />";
m_location_card = "It is located on the " + m_current_location;
}
output.Append(dr["Title"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + m_location);
outputCard.Append(dr["Title"].ToString() + ", " + dr["Dated"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + dr["Creditline"].ToString() + ". " + m_location_card + ". \n");
}
output.Append("</speak>");
sql_conn_data.Close();
response.Response.OutputSpeech.Ssml = output.ToString();
response.Response.OutputSpeech.Type = "SSML";
response.Response.Card.Title = "Art";
response.Response.Card.Type = "Standard";
response.Response.Card.Text = outputCard.ToString();
response.Response.ShouldEndSession = true;
return response;
}
There is not a way to introduce a pause in Alexa without SSML. You will need to build the ssml string and return it back to Alexa using the pause, or the cadence strings.

how to know whether compatibility is on or off using asp.net(c#)

I have to do if user's browser compatibility is on then need to show message to user that your browser's compatibility is on.
I have searched this a lot on google but yet not found a proper answer.
I have tried below code but HttpContext.Current.Request.UserAgent always contains MSIE 7.0
string isOn = string.Empty;
if (HttpContext.Current.Request.UserAgent.IndexOf("MSIE 7.0") > -1)
{
isOn = "IE8 Compatibility View";`
}
else
{
isOn = "IE8";
}
}
You may try like this
if (Request.Browser.Type.ToUpper().Contains("IE"))
{
if (Request.Browser.MajorVersion < 7)
{
//Show the message here
}
...
}
else if (Request.Browser.Type.Contains("Firefox"))
{
//code to show message
}
else if (Request.Browser.Type.Contains("Chrome"))
{
//code to show message
}
Also check this MSDN which has its own way of detecting the browser
Query the Browser property, which contains an HttpBrowserCapabilities
object. This object gets information from the browser or client device
during an HTTP request, telling your application the type and level of
support the browser or client device offers. The object in turn
exposes information about browser capabilities using strongly typed
properties and a generic name-value dictionary.
private void Button1_Click(object sender, System.EventArgs e)
{
System.Web.HttpBrowserCapabilities browser = Request.Browser;
string s = "Browser Capabilities\n"
+ "Type = " + browser.Type + "\n"
+ "Name = " + browser.Browser + "\n"
+ "Version = " + browser.Version + "\n"
+ "Major Version = " + browser.MajorVersion + "\n"
+ "Minor Version = " + browser.MinorVersion + "\n"
+ "Platform = " + browser.Platform + "\n"
+ "Is Beta = " + browser.Beta + "\n"
+ "Is Crawler = " + browser.Crawler + "\n"
+ "Is AOL = " + browser.AOL + "\n"
+ "Is Win16 = " + browser.Win16 + "\n"
+ "Is Win32 = " + browser.Win32 + "\n"
+ "Supports Frames = " + browser.Frames + "\n"
+ "Supports Tables = " + browser.Tables + "\n"
+ "Supports Cookies = " + browser.Cookies + "\n"
+ "Supports VBScript = " + browser.VBScript + "\n"
+ "Supports JavaScript = " +
browser.EcmaScriptVersion.ToString() + "\n"
+ "Supports Java Applets = " + browser.JavaApplets + "\n"
+ "Supports ActiveX Controls = " + browser.ActiveXControls
+ "\n"
+ "Supports JavaScript Version = " +
browser["JavaScriptVersion"] + "\n";
TextBox1.Text = s;
}

C# issue with a json string if value is null

I'm using the following code:
if (e.Data.MessageArray[0] == "!streams")
{
try
{
WebClient webclient = new WebClient();
var data = webclient.DownloadString("http://api.justin.tv/api/stream/list.json?channel=dotademon");
JArray ja = JArray.Parse(data);
WebClient webclient2 = new WebClient();
var data2 = webclient2.DownloadString("http://api.justin.tv/api/stream/list.json?channel=trixilulz");
JArray ja2 = JArray.Parse(data2);
WebClient webclient3 = new WebClient();
var data3 = webclient3.DownloadString("http://api.justin.tv/api/stream/list.json?channel=thepremierleague");
JArray ja3 = JArray.Parse(data3);
string streamingString = "Live right now: ";
streamingString += (char)3 + "03EG.Demon" + (char)15 + " - " + "Viewers: " + ja[0]["channel_count"] + " - " + "http://www.justin.tv/dotademon" + (char)3 + "03 Mouz.Trixi" + (char)15 + " - " + "Viewers: " + ja2[0]["channel_count"] + " - " + "http://www.justin.tv/trixilulz" + (char)3 + "03 The Premier League" + (char)15 + " - " + "Viewers: " + ja3[0]["channel_count"] + " - " + "http://www.justin.tv/thepremierleague";
irc.SendMessage(SendType.Message, e.Data.Channel, streamingString);
Console.WriteLine("EG.Demon is " + ja[0]["format"]);
Console.WriteLine("Mouz.Trixi is " + ja[2]["format"]);
Console.WriteLine("The Premier League is " + ja[3]["format"]);
}
catch (ArgumentOutOfRangeException)
{
//catch something
}
}
However, if one of the streams aren't online, then it doesn't output that string at all. Even if 2 are online and 1 is offline and vice versa. However, if they're all online, then it outputs it correctly like:
Live right now: EG.Demon - Viewers: 164 - http://www.justin.tv/dotademon Mouz.Trixi - Viewers: 49 - http://www.justin.tv/trixilulz The Premier League - Viewers: 2992 - http://www.justin.tv/thepremierleague
To demonstrate it with outputting to console, here is that code, it essentially does the same thing as the above code, but sends it to the console, same issue though obviously:
using System;
using System.Net;
using Newtonsoft.Json.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
try
{
WebClient webclient = new WebClient();
var data = webclient.DownloadString("http://api.justin.tv/api/stream/list.json?channel=dotademon");
JArray ja = JArray.Parse(data);
WebClient webclient2 = new WebClient();
var data2 = webclient2.DownloadString("http://api.justin.tv/api/stream/list.json?channel=trixilulz");
JArray ja2 = JArray.Parse(data2);
WebClient webclient3 = new WebClient();
var data3 = webclient3.DownloadString("http://api.justin.tv/api/stream/list.json?channel=thepremierleague");
JArray ja3 = JArray.Parse(data3);
string streamingString = "Live right now: ";
streamingString += (char)3 + "03EG.Demon" + (char)15 + " - " + "Viewers: " + ja[0]["channel_count"] + " - " + "http://www.justin.tv/dotademon" + (char)3 + "03 Mouz.Trixi" + (char)15 + " - " + "Viewers: " + ja2[0]["channel_count"] + " - " + "http://www.justin.tv/trixilulz" + (char)3 + "03 The Premier League" + (char)15 + " - " + "Viewers: " + ja3[0]["channel_count"] + " - " + "http://www.justin.tv/thepremierleague";
Console.WriteLine(streamingString);
}
catch (ArgumentOutOfRangeException)
{
//do something
}
}
}
}
Live right now: EG.Demon - Viewers: 164 - http://www.justin.tv/dotademon Mouz.Trixi - Viewers: 49 - http://www.justin.tv/trixilulz The Premier League - Viewers: 2992 - http://www.justin.tv/thepremierleague
My question is, how can I use this as a string but output it still if it's online and not output the rest if it's offline. When at least one of them are offline, then it doesn't output it at all. It checks if it's online if it finds channel_count in the json, because if it's offline, the json file contains nothing, just []. It's the only approach I know of to check if it's online/offline. I'm using JSON.Net by the way.
You can check ja.Count to see if you got a response.
var sb = new StringBuilder("Live right now: ");
if (ja.Count > 0)
sb.Append(string.Format("EG.Demon - Viewers: {0} - http://www.justin.tv/dotademon", ja[0]["channel_count"]));
if (ja2.Count > 0)
//...
if (ja3.Count > 0)
//...
irc.SendMessage(SendType.Message, e.Data.Channel, sb.ToString());

Categories