Source Code:
The primary purpose of Soapi.FindUser is to serve as a simple sample application for the Soapi.CS library.
In this spirit, the complete source code for the application is provided here:
//
// Project: SOAPI
// http://soapics.codeplex.com
// http://stackapps.com/questions/386
//
// Copyright 2010, Sky Sanders
// Licensed under the GPL Version 2 license.
// http://soapics.codeplex.com/license
//
// Date: Aug 08 2010
// API ver 1.0 rev 2010.0709.04
//
#region
using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using Soapi.Domain;
using Soapi.Parameters;
using SortOrder = System.Windows.Forms.SortOrder;
#endregion
namespace Soapi.Samples
{
public partial class FindUser : Form
{
private const string ApiKey = "qgAq_KfDu0KYzlNG-qaTuw";
private const string GravatarFormat = "http://www.gravatar.com/avatar/{0}?s=128&d=identicon&r=PG";
private const string AboutMeFormat =
"<html><head><link rel='stylesheet' href='http://stackapps.com/content/sa/all.css'></head><body style='background:#eaefef;'>{0}</body></html>";
private const string HelpPageUrl = "http://stackapps.com/questions/386";
private static ApiContext _context;
private readonly UserListViewColumnSorter _sorter;
private bool _fetchStopFlag;
private Thread _fetchThread;
public FindUser()
{
InitializeComponent();
_sorter = new UserListViewColumnSorter();
UserListView.ListViewItemSorter = _sorter;
SearchTermTextBox.Enabled = false;
SearchTermTextBox.Text = "initializing";
_context = new ApiContext(ApiKey);
_context.Initialized += (x, y) => BeginInvoke(new MethodInvoker(() =>
{
SearchTermTextBox.Enabled = true;
SearchTermTextBox.Text = "";
SearchTermTextBox.Focus();
}));
_context.Initialize();
}
/// <summary>
/// You can use this form as a selector in your app.
/// </summary>
public User User { get; private set; }
private void SearchButtonClick(object sender, EventArgs e)
{
SearchButton.Enabled = false;
SearchTermTextBox.Enabled = false;
if (_fetchThread != null)
{
if (_fetchThread.IsAlive)
{
_fetchStopFlag = true;
_fetchThread.Join();
_fetchStopFlag = false;
}
}
UserListView.BeginUpdate();
UserListView.Items.Clear();
UserListView.Groups.Clear();
UserListView.EndUpdate();
string searchTerm = SearchTermTextBox.Text;
_fetchThread = new Thread(() =>
{
var sites = _context.Sites.Where(s => s.ApiEndpoint.IndexOf("stackauth") < 0).ToList();
foreach (var site in sites)
{
if (_fetchStopFlag) continue;
var group = new ListViewGroup(site.ApiEndpoint, site.Name);
BeginInvoke(new MethodInvoker(() =>
UserListView.Groups.Add(group)));
ThreadPool.QueueUserWorkItem(s =>
{
var lSite = (Site) s;
if (!_fetchStopFlag)
{
var possibleMatches = lSite
.Users
.Filter(searchTerm)
.PageCount(-1)
.Sort(UserSort.Name);
foreach (var user in possibleMatches.ToList())
{
if (_fetchStopFlag) continue;
var item = new ListViewItem(new[]
{
user.DisplayName,
user.Reputation.ToString()
}, group) {Tag = user};
BeginInvoke(new MethodInvoker(() =>
UserListView.Items.Add(item)));
}
}
}, site);
}
});
_fetchThread.Start();
SearchButton.Enabled = SearchTermTextBox.Text.Length > 3;
SearchTermTextBox.Enabled = true;
}
private void UserListViewColumnClick(object sender, ColumnClickEventArgs e)
{
if (e.Column == _sorter.SortColumn)
{
_sorter.Order = _sorter.Order == SortOrder.Ascending
? SortOrder.Descending
: SortOrder.Ascending;
}
else
{
_sorter.SortColumn = e.Column;
_sorter.Order = SortOrder.Ascending;
}
UserListView.Sort();
}
private void SearchTermTextBoxChanged(object sender, EventArgs e)
{
SearchButton.Enabled = SearchTermTextBox.Text.Length > 3;
}
private void UserListViewSelectedIndexChanged(object sender, EventArgs e)
{
if (UserListView.SelectedItems.Count > 0)
{
var user = UserListView.SelectedItems[0].Tag as User;
if (user != null)
{
User = user;
userBindingSource.DataSource = User;
}
}
}
private void FindUserLoad(object sender, EventArgs e)
{
HelpButtonClicked += (x, y) => Process.Start(HelpPageUrl);
}
private void UserBindingSourceCurrentChanged(object sender, EventArgs e)
{
var current = (User) userBindingSource.Current;
LoadGravatar(current.EmailHash);
RenderAboutMe(string.Format(AboutMeFormat, current.AboutMe ?? ""));
}
private void RenderAboutMe(string html)
{
AboutMeHtmlControl.LoadDocument(html);
}
private void LoadGravatar(string emailHash)
{
try
{
WebRequest r = WebRequest.Create(string.Format(GravatarFormat, emailHash));
using (WebResponse response = r.GetResponse())
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())
{
if (stream != null)
{
GravatarPictureBox.Image = Image.FromStream(stream);
}
}
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
}
}
private void WebSiteLinkClick(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start(websiteUrlLinkLabel.Text);
}
private void UserListDoubleClick(object sender, EventArgs e)
{
Process.Start(string.Format("{0}/users/{1}", User.Site.SiteUrl, User.UserId));
}
#region Nested type: UserListViewColumnSorter
private class UserListViewColumnSorter : IComparer
{
#region Fields
private readonly CaseInsensitiveComparer _objectCompare;
private int _columnToSort;
private SortOrder _orderOfSort;
#endregion
#region Constructors
public UserListViewColumnSorter()
{
_columnToSort = 0;
_orderOfSort = SortOrder.None;
_objectCompare = new CaseInsensitiveComparer();
}
#endregion
#region Properties
public SortOrder Order
{
set { _orderOfSort = value; }
get { return _orderOfSort; }
}
public int SortColumn
{
set { _columnToSort = value; }
get { return _columnToSort; }
}
#endregion
#region Public Methods
public int Compare(object x, object y)
{
int compareResult;
var listviewX = (ListViewItem) x;
var listviewY = (ListViewItem) y;
if (_columnToSort == 0)
{
compareResult = _objectCompare.Compare(listviewX.SubItems[_columnToSort].Text,
listviewY.SubItems[_columnToSort].Text);
}
else
{
compareResult = _objectCompare.Compare(Convert.ToInt32(listviewX.SubItems[_columnToSort].Text),
Convert.ToInt32(listviewY.SubItems[_columnToSort].Text));
}
if (_orderOfSort == SortOrder.Ascending)
{
return compareResult;
}
if (_orderOfSort == SortOrder.Descending)
{
return (-compareResult);
}
return 0;
}
#endregion
}
#endregion
}
}