/clsStatMonger.cs
C# | 2441 lines | 2093 code | 209 blank | 139 comment | 315 complexity | 63a32ae9f00946f368d52ed21ced7ab7 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Google.GData.YouTube;
- using Google.GData.Extensions;
- using Google.YouTube;
- using System.Threading;
- using System.IO;
- using System.Xml;
- using System.Runtime.InteropServices;
- using System.Timers;
- using System.Net;
- using System.Net.Sockets;
- using System.Web;
- using mshtml;
- using System.Text.RegularExpressions;
- namespace TubeGuardian
- {
- // Hack-a-licious http 1.1 request using tcp sockets
- public class GetSocket
- {
- private static Socket ConnectSocket(string server, int port)
- {
- Socket s = null;
- IPHostEntry hostEntry = null;
- // Get host related information.
- hostEntry = Dns.GetHostEntry(server);
- // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
- // an exception that occurs when the host IP Address is not compatible with the address family
- // (typical in the IPv6 case).
- foreach (IPAddress address in hostEntry.AddressList)
- {
- IPEndPoint ipe = new IPEndPoint(address, port);
- Socket tempSocket =
- new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
- tempSocket.Connect(ipe);
- if (tempSocket.Connected)
- {
- s = tempSocket;
- break;
- }
- else
- {
- continue;
- }
- }
- return s;
- }
- // This method requests the home page content for the specified server.
- public static string SocketSendReceive(string server, int port, string headers, string data)
- {
- Byte[] bytesData = Encoding.ASCII.GetBytes(data);
- headers = headers + "\nContent-Length: " + bytesData.Length;
- string request = headers + "\n\n" + data;
- Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
- Byte[] bytesReceived = new Byte[256];
- // Create a socket connection with the specified server and port.
- Socket s = ConnectSocket(server, port);
- if (s == null)
- return ("Connection failed");
- // Send request to the server.
- s.Send(bytesSent, bytesSent.Length, 0);
- // Receive the server home page content.
- int bytes = 0;
- string page = "";
- bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
- page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
- return page;
- }
- }
- /* Bot-ish class that contantly maintains an updated dictionary of clsDataPoint objects */
- public class clsStatMonger
- {
- // private data members
- private List<clsCredentials> _accounts = new List<clsCredentials>();
- private List<clsVideoFeedReader> _feed_readers = new List<clsVideoFeedReader>();
- private List<clsVideoEntry> _initial_dataset = new List<clsVideoEntry>();
- private List<clsVideoEntry> _current_dataset = new List<clsVideoEntry>();
- private Dictionary<string, List<clsDataPoint>> _historical_data = new Dictionary<string, List<clsDataPoint>>();
- private System.Timers.Timer _update_timer;
- private clsFileLogger _file_logger = null;
- private string _dev_key = string.Empty;
- private string _app_name = string.Empty;
- private clsSettings _settings;
- // constructor
- public clsStatMonger(string DeveloperKey, string ApplicationName, List<clsCredentials> Credentials, clsSettings settings)
- {
- _file_logger = new clsFileLogger("CollectorData.log");
- _settings = settings;
- _settings.OnAccountAdded += new clsSettings.AccountAddedHandler(_settings_OnAccountAdded);
- _settings.OnAccountRemoved += new clsSettings.AccountRemovedHandler(_settings_OnAccountRemoved);
-
- _dev_key = DeveloperKey;
- _app_name = ApplicationName;
- this.Enabled = false;
- _update_timer = new System.Timers.Timer();
- _update_timer.Enabled = false;
- _update_timer.Interval = _settings.Collect_Interval * 1000 * 60;
- _update_timer.Elapsed += new ElapsedEventHandler(_update_timer_Elapsed);
- _accounts = Credentials;
- foreach (clsCredentials c in _accounts)
- {
- clsVideoFeedReader new_feed = new clsVideoFeedReader(DeveloperKey, ApplicationName, c.Username);
- if (c.Password != string.Empty && c.Password != "-")
- new_feed.SetCredentials(c.Username, c.Password);
- new_feed.OnEntryFetched += new clsVideoFeedReader.EntryFetchedHandler(new_feed_OnEntryFetched);
- new_feed.OnStatusChange += new clsVideoFeedReader.StatusChangeHandler(new_feed_OnStatusChange);
- _feed_readers.Add(new_feed);
- }
- }
- public clsStatMonger(string DataFile)
- {
- LoadDataFile(DataFile);
- }
- void _settings_OnAccountRemoved(object sender, clsCredentials Account)
- {
- RemoveAccount(Account);
- }
- void _settings_OnAccountAdded(object sender, clsCredentials Account)
- {
- AddAccount(Account);
- }
- // public methods
- public void Enable()
- {
- if (this.Enabled)
- return;
- this.Enabled = true;
- _update_videos();
- _update_timer.Interval = _settings.Collect_Interval;
- _update_timer.Enabled = true;
- }
- public void Disable()
- {
- this.Enabled = false;
- _update_timer.Enabled = false;
- }
- public void Update()
- {
- _update_videos();
- }
- public void AddAccount(clsCredentials Account)
- {
- foreach (clsVideoFeedReader r in _feed_readers)
- if (r.Username == Account.Username)
- return;
- clsVideoFeedReader new_feed = new clsVideoFeedReader(_dev_key, _app_name, Account.Username);
- if (Account.Password != "-")
- new_feed.SetCredentials(Account.Username, Account.Password);
- new_feed.OnEntryFetched += new clsVideoFeedReader.EntryFetchedHandler(new_feed_OnEntryFetched);
- new_feed.OnStatusChange += new clsVideoFeedReader.StatusChangeHandler(new_feed_OnStatusChange);
- new_feed.OnException += new clsVideoFeedReader.ExceptionHandler(new_feed_OnException);
- _feed_readers.Add(new_feed);
- }
- public void RemoveAccount(clsCredentials Account)
- {
- int i = 0;
- while (i < _feed_readers.Count)
- {
- if (_feed_readers[i].Username == Account.Username)
- {
- _feed_readers[i].Dispose();
- _feed_readers.RemoveAt(i);
- }
- else
- i++;
- }
- }
- public void AddDataset(List<clsVideoEntry> InitialDataset, Dictionary<string, List<clsDataPoint>> HistoricalData)
- {
- List<clsDataPoint> new_datapoints = new List<clsDataPoint>();
- int i = 0;
- while (i<InitialDataset.Count)
- {
- clsVideoEntry new_entry = InitialDataset[i];
- i++;
- if (new_entry == null)
- continue;
- clsVideoEntry old_entry = _GetEntryByIdFromList(_initial_dataset, new_entry.VideoID);
- if (old_entry == null)
- {
- _initial_dataset.Add(new_entry);
- try { _historical_data.Add(new_entry.VideoID, new List<clsDataPoint>()); }
- catch { }
- continue;
- }
- List<clsDataPoint> new_dps = _compare_entities(new_entry, old_entry);
- if (new_entry.Time < old_entry.Time)
- old_entry = new_entry;
- foreach (clsDataPoint dp in new_dps)
- _historical_data[new_entry.VideoID].Add(new clsDataPoint(dp));
-
- }
- foreach (KeyValuePair<string, List<clsDataPoint>> kvp in HistoricalDataPoints)
- {
- if (!_historical_data.ContainsKey(kvp.Key))
- {
- _historical_data.Add(kvp.Key, new List<clsDataPoint>(kvp.Value));
- continue;
- }
- _historical_data[kvp.Key].AddRange(new List<clsDataPoint>(kvp.Value));
- }
- _sort_historical_data();
- }
- public void LoadDataFile(string LogFileContents)
- {
- List<clsVideoEntry> init = new List<clsVideoEntry>();
- Dictionary<string, List<clsDataPoint>> hist = new Dictionary<string, List<clsDataPoint>>();
- string log = LogFileContents;
- Regex r = new Regex("init : .+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}.+?{(.+?)}");
- MatchCollection matches = r.Matches(log);
- foreach (Match m in matches)
- {
- Google.GData.YouTube.YouTubeEntry entry = new Google.GData.YouTube.YouTubeEntry();
- entry.VideoId = m.Groups[3].Value;
- Google.GData.Extensions.FeedLink feedlink = new Google.GData.Extensions.FeedLink();
- feedlink.CountHint = int.Parse(m.Groups[8].Value);
- entry.Comments = new Google.GData.Extensions.Comments();
- entry.Comments.FeedLink = feedlink;
- entry.Statistics = new Google.GData.YouTube.Statistics();
- entry.Statistics.ViewCount = m.Groups[7].Value;
- entry.Statistics.FavoriteCount = m.Groups[9].Value;
- entry.Rating = new Google.GData.Extensions.Rating();
- entry.Rating.NumRaters = int.Parse(m.Groups[5].Value);
- entry.Rating.Average = double.Parse(m.Groups[6].Value);
- entry.Title = new Google.GData.Client.AtomTextConstruct(Google.GData.Client.AtomTextConstructElementType.Title, m.Groups[4].Value);
- clsVideoEntry new_e = new clsVideoEntry(entry);
- new_e.Time = DateTime.Parse(m.Groups[1].Value + " " + m.Groups[2].Value);
- clsVideoEntry old_entry = _GetEntryByIdFromList(init, new_e.VideoID);
- if ( old_entry == null)
- init.Add(new_e);
- else
- {
- List<clsDataPoint> new_dps = _compare_entities(new_e, old_entry);
- if (new_e.Time < old_entry.Time)
- old_entry = new_e;
- foreach (clsDataPoint dp in new_dps)
- {
- if (!hist.ContainsKey(new_e.VideoID))
- hist.Add(new_e.VideoID, new List<clsDataPoint>());
- hist[new_e.VideoID].Add(dp);
- }
- }
- }
- r = new Regex("upd : d{(.*)},t{(.*)},vId{(.*),(.*)},old{(.*)},new{(.*)}");
- matches = r.Matches(log);
- foreach (Match m in matches)
- {
- string v = m.Groups[3].Value;
- string f = m.Groups[4].Value;
- double Iv = double.Parse(m.Groups[5].Value);
- double Nv = double.Parse(m.Groups[6].Value);
- if (!hist.ContainsKey(v))
- hist.Add(v, new List<clsDataPoint>());
- clsDataPointField field = new clsDataPointField();
- switch (f)
- {
- case "VIEWS":
- field.Field = clsDataPointField.VideoDataFields.VIEWS;
- break;
- case "RATERS":
- field.Field = clsDataPointField.VideoDataFields.RATERS;
- break;
- case "AVERAGE_RATING":
- field.Field = clsDataPointField.VideoDataFields.AVERAGE_RATING;
- break;
- case "COMMENT_COUNT":
- field.Field = clsDataPointField.VideoDataFields.COMMENT_COUNT;
- break;
- case "FAVORITED_COUNT":
- field.Field = clsDataPointField.VideoDataFields.FAVORITED_COUNT;
- break;
- }
- clsDataPoint new_dp = new clsDataPoint(Iv, Nv, field, v);
- new_dp.Time = DateTime.Parse(m.Groups[1].Value + " " + m.Groups[2].Value);
- hist[v].Add(new_dp);
- }
- _initial_dataset = init;
- _historical_data = hist;
- _sort_historical_data();
- }
- private void _sort_historical_data()
- {
- int i = 0;
- while (i < _historical_data.Count)
- {
- List<clsDataPoint> current_dps = _historical_data.ElementAt(i).Value;
- i++;
- current_dps.Sort(delegate(clsDataPoint d1, clsDataPoint d2)
- { return d1.Time.CompareTo(d2.Time); }
- );
- //current_dps = _remove_duplicates(current_dps);
- }
- }
- private static List<clsDataPoint> _remove_duplicates(List<clsDataPoint> input)
- {
- List<clsDataPoint> unique = new List<clsDataPoint>();
- foreach (clsDataPoint dp in input)
- if (unique.FindIndex(delegate(clsDataPoint d) { return ((dp.VideoID.Equals(d.VideoID)) && (dp.Time.Ticks.Equals(d.Time.Ticks)) && (dp.Field.Field.Equals(d.Field.Field)) && (dp.New.Equals(d.New)) && (dp.Old.Equals(d.Old))); }) == -1)
- unique.Add(dp);
- return unique;
- }
- private static List<clsDataPoint> _compare_entities(clsVideoEntry e_adding, clsVideoEntry e_init)
- {
- clsDataPoint new_dp = null;
- List<clsDataPoint> ret = new List<clsDataPoint>();
- if (e_adding.Time < e_init.Time)
- {
- if (e_adding.ViewsCount != e_adding.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_adding.ViewsCount, (double)e_init.ViewsCount, new clsDataPointField(clsDataPointField.VideoDataFields.VIEWS), e_init.VideoID);
- new_dp.Time = e_init.Time;
- ret.Add(new_dp);
- }
- if (e_adding.ViewsCount != e_adding.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_adding.Raters, (double)e_init.Raters, new clsDataPointField(clsDataPointField.VideoDataFields.RATERS), e_init.VideoID);
- new_dp.Time = e_init.Time;
- ret.Add(new_dp);
- }
- if (e_adding.ViewsCount != e_adding.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_adding.FavoritedCount, (double)e_init.FavoritedCount, new clsDataPointField(clsDataPointField.VideoDataFields.FAVORITED_COUNT), e_init.VideoID);
- new_dp.Time = e_init.Time;
- ret.Add(new_dp);
- }
- if (e_adding.ViewsCount != e_adding.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_adding.CommentCount, (double)e_init.CommentCount, new clsDataPointField(clsDataPointField.VideoDataFields.COMMENT_COUNT), e_init.VideoID);
- new_dp.Time = e_init.Time;
- ret.Add(new_dp);
- }
- if (e_adding.ViewsCount != e_adding.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_adding.AverageRating, (double)e_init.AverageRating, new clsDataPointField(clsDataPointField.VideoDataFields.AVERAGE_RATING), e_init.VideoID);
- new_dp.Time = e_init.Time;
- ret.Add(new_dp);
- }
- e_init = e_adding;
- }
- else
- {
- if (e_init.ViewsCount != e_init.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_init.ViewsCount, (double)e_adding.ViewsCount, new clsDataPointField(clsDataPointField.VideoDataFields.VIEWS), e_adding.VideoID);
- new_dp.Time = e_adding.Time;
- ret.Add(new_dp);
- }
- if (e_init.ViewsCount != e_init.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_init.Raters, (double)e_adding.Raters, new clsDataPointField(clsDataPointField.VideoDataFields.RATERS), e_adding.VideoID);
- new_dp.Time = e_adding.Time;
- ret.Add(new_dp);
- }
- if (e_init.ViewsCount != e_init.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_init.FavoritedCount, (double)e_adding.FavoritedCount, new clsDataPointField(clsDataPointField.VideoDataFields.FAVORITED_COUNT), e_adding.VideoID);
- new_dp.Time = e_adding.Time;
- ret.Add(new_dp);
- }
- if (e_init.ViewsCount != e_init.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_init.CommentCount, (double)e_adding.CommentCount, new clsDataPointField(clsDataPointField.VideoDataFields.COMMENT_COUNT), e_adding.VideoID);
- new_dp.Time = e_adding.Time;
- ret.Add(new_dp);
- }
- if (e_init.ViewsCount != e_init.ViewsCount)
- {
- new_dp = new clsDataPoint((double)e_init.AverageRating, (double)e_adding.AverageRating, new clsDataPointField(clsDataPointField.VideoDataFields.AVERAGE_RATING), e_adding.VideoID);
- new_dp.Time = e_adding.Time;
- ret.Add(new_dp);
- }
- }
- return ret;
- }
- private YouTubeEntry _new_youtube_entry(string title, double views, double raters, double favs, double avgR, double comments)
- {
- YouTubeEntry e = new YouTubeEntry();
- e.Rating = new Rating();
- e.Comments.FeedLink = new FeedLink();
- e.Statistics = new Statistics();
- e.Title = new Google.GData.Client.AtomTextConstruct();
- e.Statistics.FavoriteCount = favs.ToString();
- e.Statistics.ViewCount = views.ToString();
- e.Rating.Average = avgR;
- e.Rating.NumRaters = (int)raters;
- e.Comments.FeedLink.CountHint = (int)comments;
- e.Title.Text = title;
- return e;
- }
- // public events
- public delegate void EntryAddedEventHandler(object Sender, clsVideoEntry Entry);
- public event EntryAddedEventHandler OnEntryAdded;
- private void _entry_added(clsVideoEntry Entry)
- {
- if (_file_logger != null)
- _file_logger.appendFile(Entry.ToString());
- if (OnEntryAdded != null)
- OnEntryAdded(this, Entry);
- }
- public delegate void EntryUpdatedEventHandler(object Sender, clsDataPoint DataPoint, clsVideoEntry Entry);
- public event EntryUpdatedEventHandler OnEntryUpdated;
- private void _entry_updated(clsDataPoint DataPoint, clsVideoEntry Entry)
- {
- if (_file_logger != null)
- _file_logger.appendFile(DataPoint.ToString());
- if (OnEntryUpdated != null)
- OnEntryUpdated(this, DataPoint, Entry);
- }
- public delegate void FeedReaderUpdatedEventHandler(object Sender, clsVideoFeedReader.enumFeedReaderState status);
- public event FeedReaderUpdatedEventHandler OnFeedReaderUpdated;
- private void _feed_reader_updated(object sender, clsVideoFeedReader.enumFeedReaderState status)
- {
- if (OnFeedReaderUpdated != null)
- OnFeedReaderUpdated(sender, status);
- }
- public delegate void FeedReaderExceptionEventHandler(object Sender, string exception);
- public event FeedReaderExceptionEventHandler OnFeedReaderException;
- private void _feed_reader_exception(object sender, string exception)
- {
- if (OnFeedReaderException != null)
- OnFeedReaderException(sender, exception);
- }
- // private methods
- private void _update_timer_Elapsed(object sender, ElapsedEventArgs e)
- {
- if (this.Enabled == false)
- return;
- _update_timer.Enabled = false;
- _update_timer.Interval = _settings.Collect_Interval * 1000 * 60;
- _update_timer.Enabled = true;
- _update_videos();
- }
- private void new_feed_OnStatusChange(object Sender, clsVideoFeedReader.enumFeedReaderState NewState)
- {
- _feed_reader_updated(Sender, NewState);
- }
- private void new_feed_OnEntryFetched(object Sender, clsVideoEntry Entry)
- {
- clsVideoEntry initial_entry;
- if ((initial_entry = _GetEntryByIdFromList(_initial_dataset, Entry.VideoID)) == null)
- {
- _initial_dataset.Add(Entry);
- _current_dataset.Add(Entry);
- _entry_added(Entry);
- }
- else
- {
- clsVideoEntry CurrentEntry = _GetEntryByIdFromList(_current_dataset, Entry.VideoID);
- if (CurrentEntry == null)
- {
- _current_dataset.Add(Entry);
- _compare_entries(initial_entry, Entry);
- }
- else
- {
- _current_dataset.Remove(CurrentEntry);
- _current_dataset.Add(Entry);
- _compare_entries(CurrentEntry, Entry);
- }
- }
- }
- private void new_feed_OnException(object Sender, Exception e)
- {
- _feed_reader_exception(Sender, e.Message);
- }
- private void _compare_entries(clsVideoEntry OldEntry, clsVideoEntry NewEntry)
- {
- if (OldEntry.VideoID != NewEntry.VideoID)
- return;
- _compare_stat(OldEntry.AverageRating, NewEntry.AverageRating, clsDataPointField.VideoDataFields.AVERAGE_RATING, NewEntry);
- _compare_stat(OldEntry.CommentCount, NewEntry.CommentCount, clsDataPointField.VideoDataFields.COMMENT_COUNT, NewEntry);
- _compare_stat(OldEntry.FavoritedCount, NewEntry.FavoritedCount, clsDataPointField.VideoDataFields.FAVORITED_COUNT, NewEntry);
- _compare_stat(OldEntry.Raters, NewEntry.Raters, clsDataPointField.VideoDataFields.RATERS, NewEntry);
- _compare_stat(OldEntry.ViewsCount, NewEntry.ViewsCount, clsDataPointField.VideoDataFields.VIEWS, NewEntry);
- }
- private void _compare_stat(double Old, double New, clsDataPointField.VideoDataFields Field, clsVideoEntry Entry)
- {
- if (Old == New)
- return;
- else
- {
- clsDataPoint new_datapoint = new clsDataPoint(Old, New, new clsDataPointField(Field), Entry.VideoID);
- if (_historical_data.ContainsKey(Entry.VideoID))
- _historical_data[Entry.VideoID].Add(new_datapoint);
- else
- {
- List<clsDataPoint> new_dp_list = new List<clsDataPoint>();
- new_dp_list.Add(new_datapoint);
- _historical_data.Add(Entry.VideoID, new_dp_list);
- }
- _entry_updated(new_datapoint, Entry);
- }
- }
- private clsVideoEntry _GetEntryByIdFromList(List<clsVideoEntry> Entries, string VideoID)
- {
- int index = Entries.FindIndex(delegate(clsVideoEntry e) { return e.VideoID.Equals(VideoID); });
- return (index == -1) ? null : Entries[index];
- }
- private void _update_videos()
- {
- foreach (clsVideoFeedReader r in _feed_readers)
- if (!r.IsBusy)
- r.GetVideosModifiedSince(r.Updated);
- }
- // public properties
- public bool Enabled { get; private set; }
- public List<clsVideoEntry> CurrentDataSet
- {
- get { return new List<clsVideoEntry>(_current_dataset); }
- }
- public List<clsVideoEntry> InitialDataSet
- {
- get { return _initial_dataset; }
- }
- public Dictionary<string, List<clsDataPoint>> HistoricalDataPoints
- {
- get { return _historical_data; }
- }
- public clsFileLogger FileLogger
- {
- get { return _file_logger; }
- set { _file_logger = value; }
- }
- public List<clsVideoEntry> GetVideosByUsername(string username)
- {
- List<clsVideoEntry> ret = new List<clsVideoEntry>();
- foreach (clsVideoEntry e in _current_dataset)
- if (e.Account.Username == username)
- ret.Add(e);
- return ret;
- }
- public List<clsVideoFeedReader> FeedReaders { get { return _feed_readers; } }
- }
- /* Type-ish class to hold youtube usernames, and passwords */
- public class clsCredentials
- {
- public clsCredentials(string Username, string Password) { this.Username = Username; this.Password = Password; }
- public clsCredentials() { }
- public string Username
- {
- get;
- set;
- }
- public string Password
- {
- get;
- set;
- }
- }
-
- /* Type-ish class to hold data points (old/new value + data field) */
- public class clsDataPoint
- {
- public clsDataPoint()
- {
- this.Old = this.New = 0;
- this.Field = new clsDataPointField();
- this.Time = DateTime.Now;
- }
- public clsDataPoint(double OldValue, double NewValue, clsDataPointField DataField, string VideoID)
- {
- this.Old = OldValue;
- this.New = NewValue;
- this.Field = DataField;
- this.Time = DateTime.Now;
- this.VideoID = VideoID;
- }
- public clsDataPoint(clsDataPoint dp)
- {
- this.Old = dp.Old;
- this.New = dp.New;
- this.Field = dp.Field;
- this.Time = dp.Time;
- this.VideoID = dp.VideoID;
- }
- public override string ToString()
- {
- string[] values = {"upd : d{" + Time.ToShortDateString() + "}", "t{" + Time.ToShortTimeString() + "}", "vId{" + VideoID, Field.Field.ToString() + "}", "old{" + Old.ToString() + "}", "new{" + New.ToString() + "}" };
- return string.Join(",", values);
- }
-
- public clsDataPointField Field { get; set; }
- public double Old { get; set; }
- public double New { get; set; }
- public double Delta { get { return New - Old; } }
- public DateTime Time { get; set; }
- public string VideoID { get; set; }
- }
-
- /* Type-ish class to hold data field values and convert to string equivalents */
- public class clsDataPointField
- {
- public enum VideoDataFields
- {
- UNKNOWN = -1,
- VIEWS,
- RATERS,
- AVERAGE_RATING,
- COMMENT_COUNT,
- FAVORITED_COUNT
- }
- public clsDataPointField() { this.Field = VideoDataFields.UNKNOWN; }
- public clsDataPointField(VideoDataFields f) { this.Field = f; }
- public VideoDataFields Field { get; set; }
- public override string ToString()
- {
- switch (this.Field)
- {
- case VideoDataFields.AVERAGE_RATING:
- return "Average Rating";
- case VideoDataFields.COMMENT_COUNT:
- return "Comment Count";
- case VideoDataFields.FAVORITED_COUNT:
- return "Favorited Count";
- case VideoDataFields.RATERS:
- return "Raters";
- case VideoDataFields.UNKNOWN:
- return "Unknown";
- case VideoDataFields.VIEWS:
- return "Views";
- default:
- return "Error";
- }
- }
- }
-
- /* Wrapper class to access the information needed from YouTubeEntry objects */
- public class clsVideoEntry
- {
- private YouTubeEntry _yt_entry = null;
-
- // constructor
- public clsVideoEntry(YouTubeEntry e)
- {
- _yt_entry = e;
- }
- public override string ToString()
- {
- string[] values = { "init : t{" + Time.ToShortDateString() + "}", "d{" + Time.ToShortTimeString() + "}","vIf{" + VideoID + "}","ti{" + Title + "}", "r#{" + Raters.ToString() +"}", "ar{" + AverageRating.ToString() + "}", "v#{" + ViewsCount.ToString() + "}", "c#{" + CommentCount.ToString() + "}", "f#{" + FavoritedCount.ToString() + "}" };
- return string.Join(",", values);
- }
- public override bool Equals(object obj)
- {
- clsVideoEntry e = (clsVideoEntry)obj;
- return this.VideoID.Equals(e.VideoID);
- }
- public override int GetHashCode()
- {
- return this.Account.Username.GetHashCode();
- }
- // public properties
- public bool IsNull
- {
- get { return (_yt_entry == null); }
- }
- public int Raters
- {
- get { try { return _yt_entry.Rating.NumRaters; } catch { return 0; } }
- }
- public double AverageRating
- {
- get { try { return _yt_entry.Rating.Average; } catch { return 0; } }
- }
- public int ViewsCount
- {
- get { try { return int.Parse(_yt_entry.Statistics.ViewCount); } catch { return 0; } }
- }
- public int CommentCount
- {
- get { try { return _yt_entry.Comments.FeedLink.CountHint; } catch { return 0; } }
- }
- public int FavoritedCount
- {
- get { try { return int.Parse(_yt_entry.Statistics.FavoriteCount); } catch { return 0; } }
- }
- public string VideoID
- {
- get { try { return _yt_entry.VideoId; } catch { return string.Empty; } }
- }
- public string Title
- {
- get { try { return _yt_entry.Title.Text; } catch { return string.Empty; } }
- }
- public YouTubeEntry YouTubeEntry
- {
- get { return _yt_entry; }
- }
- public DateTime Time { get; set; }
- public clsCredentials Account { get; set; }
- }
- /* Utility class for reading video feeds asynchronously for a single account */
- public class clsVideoFeedReader
- {
- private class QueryArgs
- {
- public YouTubeService Service { get; set; }
- public YouTubeQuery Query { get; set; }
- }
- private class QueryReturn
- {
- public YouTubeFeed Feed { get; set; }
- public Exception Exception { get; set; }
- public YouTubeQuery NextQuery { get; set; }
- }
- public enum enumFeedReaderState
- {
- ERROR = -1,
- IDLE,
- GETTING_FIRST_CHUNK,
- GOT_FIRST_CHUNK,
- GETTING_ANOTHER_CHUNK,
- GOT_ANOTHER_CHUUNK
- }
- private enumFeedReaderState _state = enumFeedReaderState.IDLE;
- private YouTubeService _yt_service = null;
- private string _username = string.Empty;
- private string _password = string.Empty;
- private string _dev_key = string.Empty;
- private string _app_name = string.Empty;
- private int _retrieved = 0;
- private int _max_retry_query = 3;
- private int _current_retry_query = 1;
- private System.ComponentModel.BackgroundWorker _query_thread = new System.ComponentModel.BackgroundWorker();
- private DateTime _last_updated = DateTime.MinValue;
- public clsVideoFeedReader(string DevelopersKey, string ApplicationName, string Username)
- {
- _dev_key = DevelopersKey;
- _app_name = ApplicationName;
- _username = Username;
- _yt_service = new YouTubeService(ApplicationName, string.Empty, DevelopersKey);
- _query_thread.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(_query_thread_RunWorkerCompleted);
- _query_thread.DoWork += new System.ComponentModel.DoWorkEventHandler(_query_thread_DoWork);
- }
- public clsVideoFeedReader(string DevelopersKey, string ApplicationName, string Username, string Password)
- : this(DevelopersKey, ApplicationName, Username)
- {
- if (_password != "-")
- {
- _password = Password;
- SetCredentials(Username, Password);
- }
- }
- // public methods
- public void SetCredentials(string Username, string Password)
- {
- _username = Username;
- _password = Password;
- _yt_service.setUserCredentials(Username, Password);
- }
- public void GetVideos()
- {
- YouTubeQuery query = new YouTubeQuery(YouTubeQuery.CreateUserUri(_username));
- query.NumberToRetrieve = 50;
- _retrieved = 0;
- _current_retry_query = 1;
- _status_changed(enumFeedReaderState.GETTING_FIRST_CHUNK);
- _last_updated = DateTime.Now;
- _do_query(query);
- }
- public void GetVideosModifiedSince(DateTime When)
- {
- YouTubeQuery query = new YouTubeQuery(YouTubeQuery.CreateUserUri(_username));
- query.NumberToRetrieve = 50;
- query.ModifiedSince = When;
- _retrieved = 0;
- _current_retry_query = 1;
- _status_changed(enumFeedReaderState.GETTING_FIRST_CHUNK);
- _last_updated = DateTime.Now;
- _do_query(query);
- }
- public void Dispose()
- {
- _query_thread.Dispose();
- OnEntryFetched = null;
- OnException = null;
- OnProgress = null;
- OnQueryRetry = null;
- OnStatusChange = null;
- }
- // private methods
- private void _do_query(YouTubeQuery q)
- {
- if (_query_thread.IsBusy)
- return;
- QueryArgs qa = new QueryArgs();
- qa.Query = q;
- qa.Service = _yt_service;
- _query_thread.RunWorkerAsync(qa);
- }
- private void _query_thread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
- {
- QueryArgs qa = e.Argument as QueryArgs;
- QueryReturn qr = new QueryReturn();
- qr.Exception = null;
- qr.Feed = null;
- try
- {
- YouTubeFeed feed = qa.Service.Query(qa.Query);
- qr.Feed = feed;
- }
- catch (Exception exception)
- {
- qr.Exception = exception;
- qr.NextQuery = qa.Query;
- }
- e.Result = qr;
- }
- private void _query_thread_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
- {
- QueryReturn qr = e.Result as QueryReturn;
- YouTubeFeed feed = qr.Feed;
- if (feed != null)
- {
- _retrieved += feed.Entries.Count;
- foreach (YouTubeEntry entry in feed.Entries)
- _entry_fetched(entry);
- if (_state == enumFeedReaderState.GETTING_FIRST_CHUNK || _state == enumFeedReaderState.GETTING_ANOTHER_CHUNK)
- _status_changed(_state + 1);
- if (feed.NextChunk != null)
- {
- _progress(_retrieved, feed.TotalResults);
- _status_changed(enumFeedReaderState.GETTING_ANOTHER_CHUNK);
- _do_query(new YouTubeQuery(feed.NextChunk));
- }
- else
- {
- _progress(1, 1);
- _status_changed(enumFeedReaderState.IDLE);
- }
- }
- else
- {
- _exception(qr.Exception);
- if (_current_retry_query < _max_retry_query)
- {
- _current_retry_query++;
- if (qr.NextQuery != null)
- {
- _status_changed(_state);
- _do_query(new YouTubeQuery(qr.NextQuery.Uri.AbsoluteUri));
- }
- else
- {
- _progress(1, 1);
- _status_changed(enumFeedReaderState.ERROR);
- }
- }
- else
- {
- _progress(1, 1);
- _status_changed(enumFeedReaderState.ERROR);
- }
- }
- }
- // public events
- public delegate void StatusChangeHandler(object Sender, enumFeedReaderState NewState);
- public event StatusChangeHandler OnStatusChange;
- private void _status_changed(enumFeedReaderState state)
- {
- _state = state;
- if (OnStatusChange != null)
- OnStatusChange(this, state);
- }
- public delegate void EntryFetchedHandler(object Sender, clsVideoEntry Entry);
- public event EntryFetchedHandler OnEntryFetched;
- private void _entry_fetched(YouTubeEntry Entry)
- {
- if (OnEntryFetched != null)
- {
- clsVideoEntry nEntry = new clsVideoEntry(Entry);
- nEntry.Time = DateTime.Now;
- nEntry.Account = new clsCredentials(_username, _password);
- OnEntryFetched(this, nEntry);
- }
- }
- public delegate void ProgressHandler(object Sender, int Current, int Total);
- public event ProgressHandler OnProgress;
- private void _progress(int Current, int Total)
- {
- if (OnProgress != null)
- OnProgress(this, Current, Total);
- }
- public delegate void QueryRetryHandler(object Sender, Exception e);
- public event QueryRetryHandler OnQueryRetry;
- private void _query_retry(Exception e)
- {
- if (OnQueryRetry != null)
- OnQueryRetry(this, e);
- }
- public delegate void ExceptionHandler(object Sender, Exception e);
- public event ExceptionHandler OnException;
- private void _exception(Exception e)
- {
- if (OnException != null)
- OnException(this, e);
- }
- // public properties
- public string StateString
- {
- get
- {
- switch (_state)
- {
- case enumFeedReaderState.ERROR:
- return "Error";
- case enumFeedReaderState.GETTING_ANOTHER_CHUNK:
- return "Getting another chunk";
- case enumFeedReaderState.GETTING_FIRST_CHUNK:
- return "Getting first chunk";
- case enumFeedReaderState.GOT_ANOTHER_CHUUNK:
- return "Got another chunk";
- case enumFeedReaderState.GOT_FIRST_CHUNK:
- return "Got first chunk";
- case enumFeedReaderState.IDLE:
- return "Idle";
- default:
- return "Error";
- }
- }
- }
- public enumFeedReaderState State
- {
- get { return _state; }
- }
- public int MaxRetries
- {
- get { return _max_retry_query; }
- set { _max_retry_query = value; }
- }
- public bool IsBusy
- {
- get { return _query_thread.IsBusy; }
- }
- public DateTime Updated
- {
- get { return _last_updated; }
- }
- public string Username
- {
- get { return _username; }
- }
- }
-
- /* Math class for crunching all of the numbers in any given data set */
- public class clsStatMasher
- {
- private List<clsVideoEntry> _initial_dataset = null;
- private Dictionary<string, List<clsDataPoint>> _historical_data = null;
- public clsStatMasher() {}
- public clsStatMasher(List<clsVideoEntry> InitialDataSet, Dictionary<string, List<clsDataPoint>> HistoricalData)
- {
- _initial_dataset = InitialDataSet;
- _historical_data = HistoricalData;
- }
-
- // public methods
- public List<clsDataPoint> GetDataPointsByID(string VideoID)
- {
- if (_historical_data.ContainsKey(VideoID))
- return _historical_data[VideoID];
- else
- return null;
- }
- public clsVideoEntry GetInitialDataByID(string VideoID)
- {
- if (_initial_dataset == null)
- return null;
- int index = _initial_dataset.FindIndex(delegate(clsVideoEntry e) { return e.VideoID.Equals(VideoID); });
- if (index >= 0)
- return _initial_dataset[index];
- else
- return null;
- }
- public double AverageNewRatingByID(string VideoID)
- {
- clsVideoEntry InitialData = GetInitialDataByID(VideoID);
- List<clsDataPoint> HistoricalData = GetDataPointsByID(VideoID);
- if (InitialData == null || HistoricalData == null || HistoricalData.Count == 0)
- return 0;
- double[] A = { InitialData.AverageRating, -1 };
- double[] N = { InitialData.Raters, -1 };
- int counted = 0;
- for (int i = HistoricalData.Count - 1; i >= 0; i--)
- {
- if (A[1] != -1 && N[1] != -1)
- break;
- if (HistoricalData[i].Field.Field == clsDataPointField.VideoDataFields.RATERS)
- {
- if (N[1] == -1)
- N[1] = HistoricalData[i].New;
- counted += (int)HistoricalData[i].Delta;
- }
- if (HistoricalData[i].Field.Field == clsDataPointField.VideoDataFields.AVERAGE_RATING && A[1] == -1)
- A[1] = HistoricalData[i].New;
-
- }
- if (counted == 0)
- return 0;
- if (A[1] == -1)
- return 0;
- return _calc_average_new_rating(A[0], A[1], N[0], N[1]);
- }
- public KeyValuePair<int,double> AverageNewRatingByID(string VideoID, int numMostRecentVotes)
- {
- clsVideoEntry InitialData = GetInitialDataByID(VideoID);
- List<clsDataPoint> HistoricalData = GetDataPointsByID(VideoID);
- if (InitialData == null || HistoricalData == null || HistoricalData.Count == 0)
- return new KeyValuePair<int,double>(0,0);
- double[] A = { 0, -1 };
- double[] N = { 0, -1 };
- int counted = 0;
- for (int i = HistoricalData.Count - 1; i >= 0; i--)
- {
- if ((counted >= numMostRecentVotes) && A[1] != -1 && N[1] != 1)
- break;
- if (HistoricalData[i].Field.Field == clsDataPointField.VideoDataFields.RATERS)
- {
- if( N[1] == -1)
- N[1] = HistoricalData[i].New;
- N[0] = HistoricalData[i].Old;
- counted += (int)HistoricalData[i].Delta;
- }
- if (HistoricalData[i].Field.Field == clsDataPointField.VideoDataFields.AVERAGE_RATING)
- {
- if (A[1] == -1)
- A[1] = HistoricalData[i].New;
- A[0] = HistoricalData[i].Old;
- }
- }
- if (counted == 0)
- return new KeyValuePair<int, double>(0, 0);
- if (A[1] == -1)
- return new KeyValuePair<int, double>(0, 0);
- return new KeyValuePair<int,double>(counted, _calc_average_new_rating(A[0], A[1], N[0], N[1]));
- }
- public void CleanUp()
- {
- _initial_dataset = null;
- _historical_data = null;
- }
- public double GetMovedStatByField(string VideoID, clsDataPointField.VideoDataFields field)
- {
- clsVideoEntry InitialData = GetInitialDataByID(VideoID);
- List<clsDataPoint> HistoricalData = GetDataPointsByID(VideoID);
- if (InitialData == null || HistoricalData == null || HistoricalData.Count == 0)
- return 0;
- double ret = 0;
- int num = 0;
- foreach (clsDataPoint d in HistoricalData)
- {
- if (d.Field.Field == field)
- {
- if (d.Field.Field == clsDataPointField.VideoDataFields.AVERAGE_RATING)
- num++;
- else
- ret += d.Delta;
- }
- }
- if (field == clsDataPointField.VideoDataFields.AVERAGE_RATING)
- return num;
- else
- return ret;
- }
- // private methods
- private double _calc_average_new_rating(double old_average, double new_average, double old_raters, double new_raters)
- {
- System.Diagnostics.Debug.Print((((new_average * new_raters) - (old_average * old_raters)) / (new_raters - old_raters)).ToString());
- return ((new_average * new_raters) - (old_average * old_raters)) / (new_raters - old_raters);
- }
-
- // public properties
- public List<clsVideoEntry> InitialDataSet
- {
- get { return _initial_dataset; }
- set { _initial_dataset = value; }
- }
- public Dictionary<string, List<clsDataPoint>> HistoricalDataPoints
- {
- get { return _historical_data; }
- set { _historical_data = value; }
- }
- }
- /* Utility class to check video settings */
- public class clsSettingsManager
- {
- [DllImport("urlmon.dll")]
- [PreserveSig]
- [return: MarshalAs(UnmanagedType.Error)]
- static extern int CoInternetSetFeatureEnabled(
- int FeatureEntry,
- [MarshalAs(UnmanagedType.U4)] int dwFlags,
- bool fEnable);
- private const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
- private const int SET_FEATURE_ON_PROCESS = 0x00000002;
- // private enums
- public enum InternalState
- {
- unknown = -1,
- idle,
- login_step_1,
- login_step_2,
- login_step_3,
- login_check,
- get_settings,
- save_settings
- }
- public enum FailureCodes
- {
- FAILURE_LOGGING_IN,
- FAILURE_CHANGING_SETTINGS
- }
- private class Action
- {
- public string VideoID { get; set; }
- public bool Enable { get; set; }
- public Action(string ID, bool act)
- {
- this.VideoID = ID;
- this.Enable = act;
- }
- }
- // private member variable
- private InternalState _state = InternalState.idle;
- private HttpWebRequest _last_request = null;
- private CookieContainer _cookie_jar = null;
- private Cookie _login_info = null;
- private int _request_timeout = 20 * 1000; // 20 seconds default
- private System.ComponentModel.BackgroundWorker _response_fetcher = new System.ComponentModel.BackgroundWorker();
- private System.ComponentModel.BackgroundWorker _post_response_fetcher = new System.ComponentModel.BackgroundWorker();
- private bool _enable = false;
- private string _video_id = string.Empty;
- private System.Timers.Timer _activity_timer = new System.Timers.Timer();
- private List<Action> _action_list = new List<Action>();
- private Action _current_action;
- private int _current_action_fail_count = 0;
- public void Dispose()
- {
- _cookie_jar = null;
- OnException = null;
- OnFailure = null;
- OnStatusChange = null;
- OnSuccess = null;
- _activity_timer.Enabled = false;
- _response_fetcher.Dispose();
- _post_response_fetcher.Dispose();
- _activity_timer.Dispose();
- _action_list.Clear();
- }
- // public events
- public delegate void ExceptionEventHandler(object sender, Exception e);
- public event ExceptionEventHandler OnException;
- private void _raise_exception(Exception e)
- {
- if (OnException != null)
- OnException(this, e);
- }
- public delegate void StatusEventHandler(object sender, InternalState s);
- public event StatusEventHandler OnStatusChange;
- private void _raise_status_change(InternalState s)
- {
- _state = s;
- if (OnStatusChange != null)
- OnStatusChange(this, s);
- if (s == InternalState.idle)
- if (_action_list.Count > 0)
- _do_next_action();
- else
- _activity_timer.Enabled = true;
- }
- public delegate void FailureEventHandler(object sender, FailureCodes f);
- public event FailureEventHandler OnFailure;
- private void _raise_failure(FailureCodes f)
- {
- _current_action_fail_count++;
- if (_current_action_fail_count < …
Large files files are truncated, but you can click here to view the full file