2
using System.Collections.Generic;
3
using System.ComponentModel;
7
using System.Windows.Forms;
10
using Microsoft.Win32;
11
using Google.GData.YouTube;
12
using Google.GData.Client;
14
using NotifierForYT.Properties;
17
namespace NotifierForYT
19
public partial class YouTubeNotifier : Form
21
private NotifyIcon nIcon;
22
private string authToken;
23
private YouTubeRequest ytRequest;
25
private int initialPullinHours;
26
private int updateFrequency;
27
private int notificationDuration;
28
private bool closeThis=false;
29
private DateTime lastUpdate;
30
private const string AppKey = "NotifierYT";
32
private const string YTNOTIFIERKEY = "Software\\GoogleYouTubeNotifier";
33
private const string YTCLIENTID = "ytapi-FrankMantek-TestaccountforGD-sjgv537n-0";
34
private const string YTDEVKEY = "AI39si4v3E6oIYiI60ndCNDqnPP5lCqO28DSvvDPnQt-Mqia5uPz2e4E-gMSBVwHXwyn_LF1tWox4LyM-0YQd2o4i_3GcXxa2Q";
36
private List<Activity> allActivities = new List<Activity>();
37
private List<Video> allVideos = new List<Video>();
39
public YouTubeNotifier()
41
InitializeComponent();
43
this.Icon = this.nIcon.Icon;
45
if (CheckForFirstStartup() == true)
51
if (this.authToken != null)
53
this.isAuthenticated.Checked = true;
58
this.refreshTimer.Interval = 10000;
59
this.refreshTimer.Enabled = true;
62
private void ShowSettings()
64
ShowMe(this.tabPageSettings);
67
private void CreateNotifyIcon()
69
this.ShowInTaskbar = false;
70
this.nIcon = new NotifyIcon(this.components);
72
// Bitmap b = Resources.gdata_youtube;
73
// this.nIcon.Icon = Icon.FromHandle(b.GetHicon());
74
Bitmap b = Resources.ytfavicon;
75
IntPtr Hicon = b.GetHicon();
77
this.nIcon.Icon = Icon.FromHandle(Hicon);
79
this.nIcon.Text = AppTitle + " - double click to restore it";
80
this.nIcon.Visible = true;
81
this.nIcon.ContextMenuStrip = this.defaultMenu;
82
this.nIcon.DoubleClick += new EventHandler(nIcon_DoubleClick);
86
private void nIcon_DoubleClick(Object sender, EventArgs e)
91
private bool CheckForFirstStartup()
93
RegistryKey ytNotifier = Registry.CurrentUser.OpenSubKey(YTNOTIFIERKEY);
95
if (ytNotifier == null)
98
this.user = this.userName.Text = ytNotifier.GetValue("userName") as string;
99
this.authToken = ytNotifier.GetValue("token") as string;
100
this.InitialDataPullTime.Value = this.initialPullinHours = (int)ytNotifier.GetValue("initialDataPullTime", 24);
101
this.UpdateFrequency.Value = this.updateFrequency = (int)ytNotifier.GetValue("updateFrequency", 15);
102
this.notifcationBalloons.Value = this.notificationDuration = (int)ytNotifier.GetValue("notificationDuration", 10);
104
string s = ytNotifier.GetValue("userList") as string;
107
string[] users = s.Split(',');
108
foreach (string u in users)
110
this.usernameGrid.Rows.Add(u);
115
YouTubeRequestSettings settings = new YouTubeRequestSettings(AppKey,
121
this.ytRequest = new YouTubeRequest(settings);
122
OnAuthenticationModified(this.authToken);
127
private void OnAuthenticationModified(string token)
129
this.authToken = token;
130
this.isAuthenticated.Checked = token != null;
131
if (this.ytRequest != null && this.ytRequest.Service != null)
132
this.ytRequest.Service.SetAuthenticationToken(token);
135
private void ButtonSaveSettings_Click(object sender, EventArgs e)
138
if (this.isAuthenticated.Checked == false && this.userName.Text.Length > 0)
140
// let's see if we get a valid authtoken back for the passed in credentials....
141
YouTubeRequestSettings settings = new YouTubeRequestSettings(AppKey,
146
// settings.PageSize = 15;
147
this.ytRequest = new YouTubeRequest(settings);
150
this.authToken = this.ytRequest.Service.QueryAuthenticationToken();
151
this.passWord.Text = "";
155
MessageBox.Show("There was a problem with your credentials");
156
this.authToken = null;
159
OnAuthenticationModified(this.authToken);
162
// let's save the username to the registry, but not the password
163
RegistryKey ytNotifier = Registry.CurrentUser.OpenSubKey(YTNOTIFIERKEY, true);
165
if (ytNotifier == null)
167
ytNotifier = Registry.CurrentUser.CreateSubKey(YTNOTIFIERKEY);
171
ytNotifier.SetValue("initialDataPullTime", this.InitialDataPullTime.Value, RegistryValueKind.DWord);
172
ytNotifier.SetValue("updateFrequency", this.UpdateFrequency.Value, RegistryValueKind.DWord);
173
ytNotifier.SetValue("notificationDuration", this.notifcationBalloons.Value, RegistryValueKind.DWord);
174
ytNotifier.SetValue("userList", GetUserNamesToSave());
176
this.initialPullinHours = (int)this.InitialDataPullTime.Value;
177
this.updateFrequency = (int)this.UpdateFrequency.Value;
178
this.notificationDuration = (int)this.notifcationBalloons.Value;
180
if (this.authToken != null)
182
ytNotifier.SetValue("userName", this.userName.Text);
183
ytNotifier.SetValue("token", this.authToken);
185
this.user = this.userName.Text;
197
private void userName_TextChanged(object sender, EventArgs e)
199
this.isAuthenticated.Checked = false;
202
private void passWord_TextChanged(object sender, EventArgs e)
204
this.isAuthenticated.Checked = false;
207
private void ButtonIgnore_Click(object sender, EventArgs e)
210
this.userName.Text = this.user;
211
this.passWord.Text = null;
212
this.UpdateFrequency.Value = this.updateFrequency;
213
this.InitialDataPullTime.Value = this.initialPullinHours;
214
this.notifcationBalloons.Value = this.notificationDuration;
217
private void refreshTimer_Tick(object sender, EventArgs e)
219
CheckForUpdateActivities();
222
private void CheckForUpdateActivities()
224
DateTime d = this.lastUpdate.AddMinutes(this.updateFrequency);
225
if (d < DateTime.Now)
232
private List<string> GetUserNames()
234
// first update the not authenticated case.
235
List<string> users = new List<string>();
237
foreach (DataGridViewRow r in this.usernameGrid.Rows)
239
if (r.Cells[0].Value != null)
240
users.Add(r.Cells[0].Value as string);
245
private string GetUserNamesToSave()
248
List<string> users = GetUserNames();
249
foreach (string s in users)
251
if (String.IsNullOrEmpty(s) != true)
264
private void UpdateActivities()
267
this.refreshTimer.Enabled = false;
269
DateTime since = DateTime.MinValue;
271
if (this.allActivities.Count == 0)
273
// first call, do a modified-since query
274
since = DateTime.Now.AddHours(-1 * this.initialPullinHours);
280
this.nIcon.BalloonTipText = "";
282
List<string> users = GetUserNames();
284
if (users.Count > 0 && String.IsNullOrEmpty(users[0]) != true)
287
// let's see if we get a valid authtoken back for the passed in credentials....
288
YouTubeRequestSettings settings = new YouTubeRequestSettings("YouTubeNotifier",
291
// settings.PageSize = 15;
292
YouTubeRequest r = new YouTubeRequest(settings);
293
Feed<Activity> pf = r.GetActivities(users, since);
294
iCounter += ProcessFeed(pf, since);
299
if (this.authToken != null)
301
Feed<Activity> f = this.ytRequest.GetActivities(since);
303
iCounter += ProcessFeed(f, since);
307
// now redo the layout in the right order of controls:
308
this.linkList.SuspendLayout();
309
this.linkList.Controls.Clear();
310
foreach (Activity act in this.allActivities)
312
LinkLabel l = new LinkLabel();
313
string when = act.Updated.ToShortDateString();
315
if (act.Updated.Date == DateTime.Now.Date)
318
when = act.Updated.ToShortTimeString();
321
if (act.Updated.Date == DateTime.Now.AddDays(-1).Date)
323
when = "yesterday, at " + act.Updated.ToShortTimeString();
326
l.Text = act.Author + " has ";
332
case ActivityType.Commented:
333
l.Text += "commented on ";
334
len = AddVideoText(l, act.VideoId);
336
case ActivityType.Favorited:
337
l.Text += "favorited ";
338
len = AddVideoText(l, act.VideoId);
341
case ActivityType.FriendAdded:
342
l.Text += "added a friend - " + act.Username ;
345
case ActivityType.Rated:
347
len = AddVideoText(l, act.VideoId);
349
case ActivityType.Shared:
351
len = AddVideoText(l, act.VideoId);
353
case ActivityType.SubscriptionAdded:
354
l.Text += "subscriped to " + act.Username;
357
case ActivityType.Uploaded:
358
l.Text += "uploaded ";
359
len = AddVideoText(l, act.VideoId);
366
l.Links[0].Start = l.Text.Length - len;
367
l.Links[0].Length = len;
368
l.Links[0].LinkData = YouTubeQuery.CreateVideoWatchUri(act.VideoId);
369
l.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.Label_LinkClicked);
373
// create a link for the user
374
l.Links[0].Start = l.Text.Length - act.Username.Length;
375
l.Links[0].Length = act.Username.Length;
376
l.Links[0].LinkData = "http://www.youtube.com/user/" + act.Username;
377
l.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.Label_LinkClicked);
380
l.Text += " (" + when + ")";
382
this.linkList.Controls.Add(l);
385
this.linkList.ResumeLayout();
389
this.nIcon.BalloonTipTitle = "YouTube activities for " + this.userName.Text + " friends";
390
this.nIcon.ShowBalloonTip(this.notificationDuration * 1000);
393
this.refreshTimer.Enabled = true;
394
this.lastUpdate = DateTime.Now;
398
private int AddVideoText(LinkLabel l, string videoId)
401
Video v = FindVideo(videoId);
405
len = v.Title.Length;
409
l.Text += " a video";
415
private void UpdateTitle()
417
this.nIcon.Text = AppTitle + " " + this.UnreadCount + " unread activities";
421
private int ProcessFeed(Feed<Activity> feed, DateTime since)
423
List<Activity> newGuys = new List<Activity>();
427
foreach (Activity a in feed.Entries)
429
// first check if the activity is inside our maximum timeframe
430
// substract the max number of hours to pull
431
DateTime oldest = DateTime.Now.AddHours(-1 * this.initialPullinHours);
433
if (a.Updated > oldest)
435
// so it's part of the timeline. Let's see if we already have it
437
if (IsContained(a) == false)
439
AddBallonText(newGuys.Count, a.ToString());
440
if (since == DateTime.MinValue)
442
this.allActivities.Insert(0, a);
446
this.allActivities.Add(a);
453
catch (GDataForbiddenException e)
455
MessageBox.Show("Your accesstoken has expired.", "Please reauthenticate by providing your password again");
456
OnAuthenticationModified(null);
459
catch (InvalidCredentialsException e)
461
MessageBox.Show("Your accesstoken has expired.", "Please reauthenticate by providing your password again");
462
OnAuthenticationModified(null);
465
catch (GDataRequestException e)
467
HttpWebResponse r = e.Response as HttpWebResponse;
468
if (r != null && r.StatusCode == HttpStatusCode.Unauthorized)
470
MessageBox.Show("Your accesstoken has expired.", "Please reauthenticate by providing your password again");
471
OnAuthenticationModified(null);
474
else if (r != null && r.StatusCode == HttpStatusCode.NotModified)
476
// nothing new there, so ignore the exception.
479
MessageBox.Show(e.ResponseString, "There was a problem getting the data from YouTube");
481
// now get the metadata for the new guys
483
GetMetaData(newGuys);
486
return newGuys.Count;
491
private void GetMetaData(List<Activity> list)
493
Feed<Video> meta = this.ytRequest.GetVideoMetaData(list);
495
foreach (Video v in meta.Entries)
497
if (IsContained(v) == false)
499
this.allVideos.Add(v);
506
private int UnreadCount
511
foreach (LinkLabel l in linkList.Controls)
513
if (l.Links[0].Visited == false)
520
private void AddBallonText(int iCounter, string text)
523
this.nIcon.BalloonTipText = text;
524
else if (iCounter < 4)
525
this.nIcon.BalloonTipText += "\r" + text;
526
else if (iCounter == 4)
527
this.nIcon.BalloonTipText += "\r" + "and more...";
530
private bool IsContained(Activity a)
532
foreach (Activity act in this.allActivities)
540
private bool IsContained(Video v)
542
foreach (Video video in this.allVideos)
544
if (video.Id == v.Id)
550
private Video FindVideo(string videoId)
552
foreach (Video video in this.allVideos)
554
if (video.VideoId == videoId)
561
private void HideMe()
564
this.WindowState = FormWindowState.Minimized;
568
private void ToggleVisibility()
570
if (this.WindowState == FormWindowState.Minimized)
580
private void ShowMe(TabPage page)
583
this.WindowState = FormWindowState.Normal;
586
this.tabControl.SelectedTab = this.tabPageActivities;
588
this.tabControl.SelectedTab = page;
591
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
596
private void activitiesToolStripMenuItem_Click(object sender, EventArgs e)
598
ShowMe(this.tabPageActivities);
602
private void YouTubeNotifier_FormClosing(object sender, FormClosingEventArgs e)
605
if (e.CloseReason == CloseReason.UserClosing && this.closeThis == false)
609
this.nIcon.BalloonTipText = "Use the context menu to exit or restore particular parts of the application";
610
this.nIcon.BalloonTipTitle = AppTitle + " is still running !";
611
this.nIcon.ShowBalloonTip(this.notificationDuration * 1000);
615
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
617
this.closeThis = true;
621
private void clearActivitiesToolStripMenuItem_Click(object sender, EventArgs e)
623
this.linkList.Controls.Clear();
630
private void YouTubeNotifier_Resize(object sender, EventArgs e)
632
if (this.WindowState == FormWindowState.Minimized)
637
private void Label_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
639
string u = e.Link.LinkData as string;
645
System.Diagnostics.Process.Start(u);
649
MessageBox.Show("There was a problem navigating to: " + u);
651
e.Link.Visited = true;
656
private void button1_Click(object sender, EventArgs e)
658
// let's save the username to the registry, but not the password
659
RegistryKey ytNotifier = Registry.CurrentUser.OpenSubKey(YTNOTIFIERKEY, true);
660
if (ytNotifier == null)
662
ytNotifier = Registry.CurrentUser.CreateSubKey(YTNOTIFIERKEY);
665
ytNotifier.SetValue("userList", GetUserNamesToSave());
670
private void usersToolStripMenuItem_Click(object sender, EventArgs e)
672
ShowMe(this.tabPageUsers);
675
private void usernameGrid_UserAddedRow(object sender, DataGridViewRowEventArgs e)
677
this.usernameGrid.AllowUserToAddRows = true;
678
if (this.usernameGrid.Rows.Count >= 20)
680
this.usernameGrid.AllowUserToAddRows = false;
b'\\ No newline at end of file'