Searching an uploaded youtube video from my youtube video channel using c# - c#

In Youtube,Please help me in searching the video which I uploaded in my youtube channel..
Here is the code I am trying..
namespace Google.Apis.YouTube.Samples
{
that you have enabled the YouTube Data API for your project.
/// </summary>
internal class Search
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("YouTube Data API: Search");
Console.WriteLine("========================");
try
{
new Search().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "API KEY ",
ApplicationName = "YouTubeUpload"
});
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = "T52cSiV4vV8"; // Replace with your search term.
searchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var searchListResponse = await searchListRequest.ExecuteAsync();
List<string> videos = new List<string>();
List<string> channels = new List<string>();
List<string> playlists = new List<string>();
foreach (var searchResult in searchListResponse.Items)
{
switch (searchResult.Id.Kind)
{
case "youtube#video":
videos.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.VideoId));
break;
case "youtube#channel":
channels.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.ChannelId));
break;
case "youtube#playlist":
playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.PlaylistId));
break;
}
}
Console.WriteLine(String.Format("Videos:\n{0}\n", string.Join("\n", videos)));
Console.WriteLine(String.Format("Channels:\n{0}\n", string.Join("\n", channels)));
Console.WriteLine(String.Format("Playlists:\n{0}\n", string.Join("\n", playlists)));
}
}
}
On running the above code I am getting a 'Bad Request 400' exceptionException screenshot
Am i missing something??

You need set a field "ApiKey" with your APIkey, in Google Console Developer
First, enable the Youtube Data API to your project and then create credentials to get your APIKey.

Related

How to get parallel access to the method for multiple users

My telegram bot is necessary so that the user can answer questions in order and save these answers in the same order for a specific user in parallel.
static readonly ConcurrentDictionary<int, string[]> Answers = new ConcurrentDictionary<int, string[]>();
static void Main(string[] args)
{
try
{
Task t1 = CreateHostBuilder(args).Build().RunAsync();
Task t2 = BotOnMessage();
await Task.WhenAll(t1, t2);
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex);
}
}
here is my BotOnMessage() method to receive and process messages from users
async static Task BotOnMessage()
{
int offset = 0;
int timeout = 0;
try
{
await bot.SetWebhookAsync("");
while (true)
{
var updates = await bot.GetUpdatesAsync(offset, timeout);
foreach (var update in updates)
{
var message = update.Message;
if (message.Text == "/start")
{
Registration(message.Chat.Id.ToString(), message.Chat.FirstName.ToString(), createdDateNoTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
var replyKeyboard = new ReplyKeyboardMarkup
{
Keyboard = new[]
{
new[]
{
new KeyboardButton("eng"),
new KeyboardButton("ger")
},
}
};
replyKeyboard.OneTimeKeyboard = true;
await bot.SendTextMessageAsync(message.Chat.Id, "choose language", replyMarkup: replyKeyboard);
}
switch (message.Text)
{
case "eng":
var replyKeyboardEN = new ReplyKeyboardMarkup
{
Keyboard = new[]
{
new[]
{
new KeyboardButton("choice1"),
new KeyboardButton("choice2")
},
}
};
replyKeyboardEN.OneTimeKeyboard = true;
await bot.SendTextMessageAsync(message.Chat.Id, "Enter choice", replyMarkup: replyKeyboardEN);
await AnonymEN();
break;
case "ger":
var replyKeyboardGR = new ReplyKeyboardMarkup
{
Keyboard = new[]
{
new[]
{
new KeyboardButton("choice1.1"),
new KeyboardButton("choice2.2")
},
}
};
replyKeyboardGR.OneTimeKeyboard = true;
await bot.SendTextMessageAsync(message.Chat.Id, "Enter choice", replyMarkup: replyKeyboardGR);
await AnonymGR();
break;
}
offset = update.Id + 1;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex);
}
}
and AnonymEN() method for eng case in switch. The problem appears here when I call this method from switch case in BotOnMessage(). Until switch (message.Text) multiple users can asynchronously send messages and get response. When first user enters AnonymEN() second user can't get response from this method until first user will finish it till the end. Also I call BotOnMessage() in the end of AnonymEN() to get back for initial point with possibility to start bot again. For the ordered structure of questions and answers I used ConcurrentDictionary way from here Save user messages sent to bot and send finished form to other user. Any suggestion and solution how to edit code to make this bot available for multiple users at one time?
async static Task AnonymEN()
{
int offset = 0;
int timeout = 0;
try
{
await bot.SetWebhookAsync("");
while (true)
{
var updates = await bot.GetUpdatesAsync(offset, timeout);
foreach (var update in updates)
{
var message = update.Message;
int userId = (int)message.From.Id;
if (message.Type == MessageType.Text)
{
if (Answers.TryGetValue(userId, out string[] answers))
{
var title = message.Text;
if (answers[0] == null)
{
answers[0] = message.Text;
await bot.SendTextMessageAsync(message.Chat, "Enter age");
}
else
{
SaveMessage(message.Chat.Id.ToString(), "anonym", "anonym", "anonym", answers[0].ToString(), title.ToString(), createdDateNoTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
Answers.TryRemove(userId, out string[] _);
await bot.SendTextMessageAsync(message.Chat.Id, "ty for request click /start");
await BotOnMessage();
}
}
else if (message.Text == "choice1")
{
Answers.TryAdd(userId, new string[1]);
await bot.SendTextMessageAsync(message.Chat.Id, "Enter name");
}
}
offset = update.Id + 1;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex);
}
}
I can see multiple issues with your code:
It is hard to read. While this is a personal preference I strongly advise to write short concise methods that have 1 responsibility. This will make it easier to understand and maintain your code. https://en.wikipedia.org/wiki/Single-responsibility_principle
Everything is static. This makes it very hard to keep track of any state such as language that should be tracked per user.
Using infinite loops and recursion with no escape. I highly doubt this was intended but you could get an infinite chain of calls like this BotOnMessage -> AnonymEN -> BotOnMessage -> AnonymEN. I think you want to exit the AnonymEN function using either a return, break or while(someVar) approach instead of calling the BotOnMessage function.
If two users are sending messages you get mixed responses. Example message flow user1: /start, user1: eng, user2: hello. The bot will now give an english response to user2. I'm sure this is not intended
The code below is a minimal example that addresses the issues I mentioned. It is not perfect code but should help you get started.
private Dictionaty<string, UserSession> userSessions = new ();
async Task BotOnMessage()
{
try
{
while(true)
{
var message = await GetMessage(timeout);
var userSession = GetUserSession(message.user);
userSession.ProcessMessage(message);
}
}
catch(){}
}
async void GetUserSession(string user)
{
if(!userSessions.HasKey(user))
{
userSessions[user](new Session());
}
return userSessions[user];
}
public class UserSession
{
public async Task ProcessMessage(message)
{
// Existing message processing code goes here.
// Do not use a loop or recursion.
// Instead track the state (e.g. languge) using fields.
}
}

Youtube Data API C# - use without requesting user credentials

I would like to use the YouTubeData API in C# - .Net Core - without requesting user credentials.
The only thing I need from this API is to retrieve the information of a playlist, but always when I use it on localhost it is requesting the user's credential.
How can I use this API without any request for credential or using my own token?
If you want to retrieve information (title, thumbnail) of a public playlist, you only need an API key. You only need to authenticate the user if you want to create or edit playlists.
This sample program retrieves the title and the thumbnail of a playlist by id.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
namespace YtbExample
{
internal class PlayList
{
[STAThread]
static void Main(string[] args)
{
try
{
new PlayList().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "YOUR_API_KEY",
ApplicationName = this.GetType().ToString()
});
var listRequest = youtubeService.Playlists.List("snippet");
listRequest.Id = "PLdo4fOcmZ0oXzJ3FC-ApBes-0klFN9kr9";
//Get playlists by channel id
//listRequest.ChannelId = "";
listRequest.MaxResults = 50;
var listResponse = await listRequest.ExecuteAsync();
List<string> playlists = new List<string>();
// Add each result to the list, and then display the lists of
// matching playlists.
foreach (var result in listResponse.Items)
{
playlists.Add(String.Format("Title: {0}, Id: {1}, Thumbnail: {2}", result.Snippet.Title, result.Id, result.Snippet.Thumbnails.Medium.Url));
}
Console.WriteLine(String.Format("{0}\n", string.Join("\n", playlists)));
}
}
}
I hope I could help you!

How to update/edit SharePoint classic pages content/aspx using CSOM

We did successfully migrate the content from MediaWiki into the SharePoint classic page. However, some of the content that came from the MediaWiki has extra information that we don't need
Is there a way through CSOM to update all the ASPX pages we generated when migrated content from MediaWiki to SharePoint?
All we need is to remove some footers from all the pages that we generated.
Thank you in advance for everyone's help
Here is the code that worked for me
static void Main(string[] args)
{
try
{
ClientContext ctx = GetClientContext("https://tenant.sharepoint.com/sites/sitename",
"usernaname#tenant.onmicrosoft.com", "password");
var listTitle = "Site Pages";
var list = ctx.Web.Lists.GetByTitle(listTitle);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, icol => icol.Include(i => i["WikiField"], i => i["CanvasContent1"], i => i["FileRef"], i => i.ContentType));
ctx.ExecuteQuery();
foreach (var item in items)
{
switch (item.ContentType.Name)
{
case "Site Page":
if (item["CanvasContent1"] != null)
{
if (item["CanvasContent1"].ToString().Contains("certain pattern"))
{
ProcessSiteHTML(item["CanvasContent1"].ToString(), item["FileRef"].ToString(), item, ctx, "CanvasContent1");
}
}
break;
case "Wiki Page":
if (item["WikiField"] != null)
{
if (item["WikiField"].ToString().Contains("certain pattern"))
{
ProcessSiteHTML(item["WikiField"].ToString(), item["FileRef"].ToString(), item, ctx, "WikiField");
}
}
break;
}
}
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Main " + e.Message);
WriteLog(fileName, "Main " + e.Message);
}
finally
{
Console.ForegroundColor = ConsoleColor.White;
}
}
private static void ProcessSiteHTML(string page, string pageName, ListItem item, ClientContext ctx, string pageType)
{
string pattern = "Regular expression pattern";
System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex(pattern, System.Text.RegularExpressions.RegexOptions.Multiline);
System.Text.RegularExpressions.MatchCollection matched = rg.Matches(page.ToLower());
if (matched.Count > 0)
{
System.Text.RegularExpressions.Match m =
System.Text.RegularExpressions.Regex.Match(page, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string updatedField = System.Text.RegularExpressions.Regex.Replace(page,
m.Value, string.Empty, System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
item[pageType] = updatedField;
item.Update();
ctx.ExecuteQuery();
Console.WriteLine(pageName + " has been updated");
}
}

C# how to capture async results?

I am a newbie to C# & am trying to use the Lync SDK to search for a Lync user programmatically to get their status. I am not sure how to pass the results to the webservice response when the async callback gets executed.
This is the code:
Webservice Controller GET endpoint:
// GET: api/Lync/5
public String Get(int id)
{
log.Info("[GET] Search for Lync User: " + id);
Lync lync = new Lync();
////lync.signIn();
Boolean isSignedIn = lync.isUserSignedIn();
if (isSignedIn)
{
log.Info("User is Signed In");
Console.Write("Enter search key : ");
lync.Search("medina");
//lync.Search("medina",
//(lyncContacts) =>
//{
// log.Debug("Search Results Callback fired!");
// log.Info("Results found: " + lyncContacts.Count);
// return lyncContacts.ToString();
//});
//Console.WriteLine(name);
//Console.ReadLine();
return "testUser";
}
else
{
log.Info("User is not Signed In!");
// TODO: Return status 500
return "testUser";
}
//Console.ReadLine();
//return "testUser";
}
The above method calls the business service lync.search(..) which is as follows:
public void Search(string searchKey)
{
List<LyncContact> contactList = new List<LyncContact>();
//List<ContactInformationType> ContactInformationList = new List<ContactInformationType>();
//ContactInformationList.Add(ContactInformationType.Activity);
//ContactInformationList.Add(ContactInformationType.Availability);
// ContactInformationList.Add(ContactInformationType.CapabilityString);
//ContactSubscription contactSubscription = LyncClient.GetClient().ContactManager.CreateSubscription();
Console.WriteLine("Searching for contacts on " + searchKey);
LyncClient.GetClient().ContactManager.BeginSearch(
searchKey,
(ar) =>
{
SearchResults searchResults = LyncClient.GetClient().ContactManager.EndSearch(ar);
if (searchResults.Contacts.Count > 0)
{
log.Info("Search results found: " + searchResults.Contacts.Count);
Console.WriteLine(searchResults.Contacts.Count.ToString() + " found");
foreach (Contact contact in searchResults.Contacts)
{
String displayName = contact.GetContactInformation(ContactInformationType.DisplayName).ToString();
ContactAvailability currentAvailability = (ContactAvailability)contact.GetContactInformation(ContactInformationType.Availability);
Console.WriteLine(
contact.GetContactInformation(ContactInformationType.DisplayName).ToString() + " " + contact.GetContactInformation(ContactInformationType.Availability).ToString());
log.Debug("Display Name: " + displayName);
log.Debug("Availability: " + currentAvailability);
LyncContact lyncContact = new LyncContact.Builder().DisplayName("Snehil").Availability("Busy").build();
contactList.Add(lyncContact);
//done(contactList);
}
return;
}
else
{
log.Info("No Results found!");
//done(contactList);
return;
}
},
null);
} else
{
log.Info("No Results found!");
//done(contactList);
return;
}
},
null);
}
I tried to use Task+await but I am having a hard time trying to figure out how can i return the results from the callback funtion as results from the search method. How do i capture this in the controller class?
If you would like to use the async/await pattern for this use Task.FromAsync https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.fromasync(v=vs.110).aspx
Google for examples. Like this:
public async Task<List<LyncContact>> SearchAsync(string searchKey)
{
List<LyncContact> contactList = new List<LyncContact>();
Console.WriteLine("Searching for contacts on " + searchKey);
var cm = LyncClient.GetClient().ContactManager;
var searchResults = await Task<SearchResults>.Factory.FromAsync<String>(
cm.BeginSearch,
cm.EndSearch, searchKey, null);
if (searchResults.Contacts.Count > 0)
{
Console.WriteLine(searchResults.Contacts.Count.ToString() + " found");
foreach (Contact contact in searchResults.Contacts)
{
String displayName = contact.GetContactInformation(ContactInformationType.DisplayName).ToString();
ContactAvailability currentAvailability = (ContactAvailability)contact.GetContactInformation(ContactInformationType.Availability);
Console.WriteLine(
contact.GetContactInformation(ContactInformationType.DisplayName).ToString() + " " + contact.GetContactInformation(ContactInformationType.Availability).ToString());
LyncContact lyncContact = new LyncContact.Builder().DisplayName("Snehil").Availability("Busy").build();
contactList.Add(lyncContact);
}
}
return contactList
}
In the controller you then can do:
public async Task<String> Get(int id)
{
log.Info("[GET] Search for Lync User: " + id);
Lync lync = new Lync();
////lync.signIn();
Boolean isSignedIn = lync.isUserSignedIn();
if (isSignedIn)
{
log.Info("User is Signed In");
Console.Write("Enter search key : ");
var lyncContacts = await SearchAsync("medina");
log.Info("Results found: " + lyncContacts.Count);
return lyncContacts.ToString();
}
else
{
log.Info("User is not Signed In!");
// TODO: Return status 500
return "testUser";
}
//Console.ReadLine();
//return "testUser";
}
Or you can use a TaskCompletionSource, see http://blog.stephencleary.com/2012/07/async-interop-with-iasyncresult.html (older post but principle is still valid.
Warning
I cannot compile this since I do not have access to the libraries you use. It should work but there might be some compile errors
What does it do
Callbacks are not a nice model to work with, as you have found out. using Tasks and the async/await model are far easier to work with. Luckily for you and me they have created several methods that can act as a bridge between the old and the new model. Using Task.FromAsync you can transform IAsyncResult methods to an easier to use Task based methodology. Stephen Cleary has written some nice blogs about them. See the post I mentioned earlier.
It looks like, by looking at your commented out code, that you tried to provide some sort of callback to your Search function. That would work, it should be of type Action<Microsoft.Lync.Model.SearchResults>
public void Search(string searchKey, Action<SearchResults> callback)
{
....
LyncClient.GetClient().ContactManager.BeginSearch(
searchKey,
(ar) =>
{
SearchResults searchResults = LyncClient.GetClient().ContactManager.EndSearch(ar);
callback(searchResults);
});
....
}
Then just uncomment the code in your controller:
lync.Search("medina",
(lyncContacts) =>
{
log.Debug("Search Results Callback fired!");
log.Info("Results found: " + lyncContacts.AllResults.Count);
});

Google Analytics API BatchRequest - Filtering/Callback

I am trying to submit a BatchRequest and unsure of how to apply a filter or how to handle the callback.
class Program
{
static void Main(string[] args)
{
try
{
new Program().Run().Wait();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.Read();
}
private async Task Run()
{
var privatekey = "private key";
var accountEmailAddress = "email address";
var credentials = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(accountEmailAddress) {
Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
}.FromPrivateKey(privatekey));
var service = new AnalyticsService(new BaseClientService.Initializer() {
HttpClientInitializer = credentials,
ApplicationName = "Test"
});
var request = new BatchRequest(service);
request.Queue<DataResource.GaResource.GetRequest>(service.Data.Ga.Get("ga:XXXXXX", "30daysAgo", "yesterday", "ga:sessions"),
(content, error, i, message) =>
{
//callback code
});
await request.ExecuteAsync();
}
}
Two Questions:
How do I apply the following filter to the request?
ga:pagePath==/page1.html
How do I handle the callback and view the data returned?
Update
I believe I have solved the filter issue with the following code:
var req = service.Data.Ga.Get("ga:XXXXXX", "30daysAgo", "yesterday", "ga:sessions");
req.Filters = "ga:pagePath==/page1.html";
request.Queue<DataResource.GaResource.GetRequest>(req,
(content, error, i, message) =>
{
//callback code
});
I am still unsure of how to handle the callback. The "content" parameter is returned as the class: Google.Apis.Analytics.v3.DataResource.GaResource.GetRequest
I was finally able to get this working.
For future reference for anyone, here is a working .Net example of submitting a BatchRequest to the Analytics API.
class Program
{
static void Main(string[] args)
{
try
{
new Program().Run().Wait();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.Read();
}
private async Task Run()
{
var privatekey = "private key";
var accountEmailAddress = "email address";
var credentials = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(accountEmailAddress)
{
Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
}.FromPrivateKey(privatekey));
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials,
ApplicationName = "Test"
});
var request = new BatchRequest(service);
BatchRequest.OnResponse<GaData> callback = (content, error, i, message) =>
{
if (error != null)
{
Console.WriteLine("Error: {0}", error.Message);
}
else
{
if (content.Rows != null)
{
foreach (var item in content.Rows)
{
foreach (var item1 in item)
{
Console.WriteLine(item1);
}
}
}
else
{
Console.WriteLine("Not Found");
}
}
};
int counter = 0;
while (counter < 5)
{
var req = service.Data.Ga.Get("ga:XXXXX", "30daysAgo", "yesterday", "ga:sessions");
req.Filters = "ga:pagePath==/page" + counter + ".html";
request.Queue<GaData>(req, callback);
counter++;
}
await request.ExecuteAsync();
}
}
So I am not familiar with C# but I did look at the source code for the get method. And the GetRequest object has a filters property which you can set.
var request = service.Data.Ga.Get("ga:XXXXXX",
"30daysAgo", "yesterday", "ga:sessions");
request.dimensions("ga:pagePath");
request.filters("ga:pagePath==/page1.html");
I would encourage you to also look at the Core Reporting API reference for the full set of parameters.
I would imagine that the content object in the callback method would correspond to the GaData response object
I hope that helps some.

Categories

Resources