Introduction
This article presents the CodeProject.dll project which may be used to extract information from The Code Project. In the first of a short series of articles, ArticlesSummary is presented which allows extraction of article information by member number. The following information may be extracted;
- Title
- Description
- Web link
- Last update date
- Number of page views
- Rating
- Number of votes
- Popularity
By extension it is then possible also to calculate the following information (and others);
- Number of articles per user
- Average rating / popularity
Finally an application for monitoring user article changes is presented.
PLEASE DO NOT ABUSE THIS LIBRARY. This library allows automatic updates of information polled from the Code Project website, please do not set the update interval too low or you will effective be performing a denial of service attack. If this happens too often this article will be removed! You have been warned.
Background
This article is based upon the http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=### page, where ### is the member id. Contained within the source of the page is the following;
<span id="ctl00_MC_AR_ctl03_MAS">
<b><a id="ctl00_MC_AR_ctl03_AT" href="http://www.codeproject.com/KB/WPF/roundbutton.aspx">A
###LINE BREAK INSERTED TO REDUCE ARTICLE WIDTH###
Microsoft Office Style WPF Application Button</a></b>
<div id="ctl00_MC_AR_ctl03_SbD" class="subdue SmallText">
Last Updated: 22 Mar 2008
Page Views: 8,278
Rating: 3.31 / 5
Votes: 6
Popularity: 2.57
</div>
<div style="margin-top:3;font-size:8pt;">An article presenting ApplicationButton used in
###LINE BREAK INSERTED TO REDUCE ARTICLE WIDTH###
creating round buttons as per Microsoft Office Style application buttons</div>
</span>
To summarise;
<span id="ctl00_MC_AR_ctl03_MAS">
<b><a id="ctl00_MC_AR_ctl03_AT" href="###relative web address###">###article title###</a></b>
<div id="ctl00_MC_AR_ctl03_SbD" class="subdue SmallText">
Last Updated: ###date###
Page Views: ###page views###
Rating: ###rating### / 5
Votes: ###number of votes###
Popularity: ###popularity###
</div>
<div style="margin-top:3;font-size:8pt;">###article description###</div>
</span>
The key elements for parsing are ctl00_MC_AR_ctl03_MAS, ctl00_MC_AR_ctl03_AT and ctl00_MC_AR_ctl03_SbD; where 103 can be any number (usually 100 onwards).
Using the code
The library is based around two classes Article
and ArticleSummary
, as presented herein.
ArticleSummary
performs the actual data requests and has the following events, methods, and properties;
event ArticleAddedEventDelegate ArticleAdded
* - Fires when a new article is detected. ArticlesSummary(String userID)
- Constructor accepts the member number of the user to monitor. String UserID {get;}
- Returns the user being monitored. TimeSpan UpdateInterval {get;set;}
- Used when AutoUpdate
is true, the time between data retrieval. bool AutoUpdate {get;set;}
- Enables or disables automatic updates (essentially calls update()
at UpdateInterval
intervals. List<Article> Articles {get;}
- Returns a list of articles for the specified member name (or empty list if update has not yet been called). void update()
and void update(WebProxy proxy)
- Updates the articles list; all event firing generation happens within the timescale of this function.
Article
encapsulates all information about an article, and has the following properties and events;
event TitleChangedEventDelegate TitleChanged
* - Fired when the title of the article changes (typically only fired when a new article is added). event DescriptionChangedEventDelegate DescriptionChanged
* - Fired when the article description changes. event LinkChangedEventDelegate LinkChanged
* - Fired when the web address of the article changes. event LastUpdatedChangedEventDelegate LastUpdatedChanged
* - Fires when the article is updates. event PageViewsChangedEventDelegate PageViewsChanged
* - Fires when the number of page views changes. event RatingChangedEventDelegate RatingChanged
* - Fires when the page rating changes. event VotesChangedEventDelegate VotesChanged
* - Fires when the number of votes changes. event PopularityChangedEventDelegate PopularityChanged
* - Fires when the popularity of the article changes. String Title {get;}
- Returns the article title. String Description {get;}
- Returns a description of the article. String Link {get;}
- Returns the relative web address of the article. DateTime LastUpdated {get;}
- Returns the date of the last update. int PageViews {get;}
- Returns the number of article views. double Rating {get;}
- Returns the article rating (out of 5). int Votes {get;}
- Returns the number of votes for the article. double Popularity {get;}
- Returns the popularity of the article. string ToString()
- Returns a debug string.
* Fired in response to update being called upon a ArticleSummary
.
About the Article Monitor
The article monitor is a utility that can be left running and displays a popup message indicating a new article, number of votes changed, popularity changed, and rating changed. It is a very basic utility and is primarily released as a demonstration of the CodeProject.dll library.
The monitor comprises of several parts, the top row allows setting of the member number. The centre section displays information are the known articles for the user (once connect has been clicked); the information is updated once a minute. The bottom row allows disabling of the popup alerts and a manual update button.
All the article data is stored in a DataTable
which is displayed on a WPF control (not described in this article). The data view is updated via the updateTable()
method.
When the connect button is clicked a new ArticlesSummary
object is created and the ArticleAdded
event is attached. Finally the AutoUpdate
property is set before a call to update()
is made (forces instant initial synchronisation).
summary = new ArticlesSummary(memberIDTextBox.Text);
summary.ArticleAdded += new ArticlesSummary.ArticleAddedEventDelegate(summary_ArticleAdded);
summary.AutoUpdate = true;
summary.update();
The ArticleAdded
event is handled, and the sent article has the various event handlers attached. A new DataRow
is added to the DataTable
which corresponds to the article added. Finally the table view is updated.
DataRow dr = dataTable.NewRow();
dataRows.Add(article, dr);
dataTable.Rows.Add(dr);
article.TitleChanged += new Article.TitleChangedEventDelegate(article_TitleChanged);
article.LastUpdatedChanged += new Article.LastUpdatedChangedEventDelegate(article_LastUpdatedChanged);
article.PageViewsChanged += new Article.PageViewsChangedEventDelegate(article_PageViewsChanged);
article.RatingChanged += new Article.RatingChangedEventDelegate(article_RatingChanged);
article.VotesChanged += new Article.VotesChangedEventDelegate(article_VotesChanged);
article.PopularityChanged += new Article.PopularityChangedEventDelegate(article_PopularityChanged);
dr["Title"] = article.Title;
dr["Last Updated"] = article.LastUpdated;
dr["Page Views"] = article.PageViews;
dr["Rating"] = article.Rating;
dr["Votes"] = article.Votes;
dr["Popularity"] = article.Popularity;
The article event handlers update the corresponding data row and specified attribute before updating the table. If the event is not fired during the initial update()
call on the ArticleSummary
then a popup is displayed showing the new information (assuming the popups are not disabled). For example, the VotesChange
event handler is as follows;
private void article_VotesChanged(object sender, int value)
{
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new RefreshDelegate(delegate()
{
dataRows[(Article)sender]["Votes"] = ((Article)sender).Votes;
if (!initialSync)
{
updateTable();
if ((bool)soundAlertCheckBox.IsChecked)
{
SimplePopup.ShowPopup(((Article)sender).Title
+ " votes changed to " + value);
}
}
}));
}
Note that the event handler forces processing onto the event dispatch thread as the events are fired from the thread calling ArticleSummary.update()
, which in the case of auto updating is not the event dispatch thread.
History
Version 1.0.0.0 - Initial build.
Version 1.0.0.1 - Added User class (see part 2)
Useful Links
codeprojectarticle.aspx (Part 1, Articles)
codeprojectuser.aspx (Part 2, Users)
codeprojectkevinbacon.aspx (Part 3, Kevin Bacon)
Additional Licensing Notes
Please feel free to use this in your work, however please be aware that a modified The Code Project Open License (CPOL) is in use; basically it is the same as the standard license except that this code must not be used for commercial or not-for-profit commercial use without prior authorisation. Please see license.txt or license.pdf in the included source and demo files.