4

OBSOLETE: soapi.info has been down since at least 2012.

Soapi.FindUser

alt text

About

Soapi.FindUser is a tiny .NET 3.5 application that searches all Stack Exchange sites for users by name with the provided search term.

The results are grouped by site and are sortable by Name or Reputation.

Hover or click an item to view the profile, double click an item to open your default browser to the users profile page.

License

Soapi.FindUser is free to use and is licensed under GPL V2.

Download

You can install Soapi.FindUser via Click-Once here:

http://soapi.info/Code/CSSL/Stable/ScoobySnacks/FindUser/publish.htm
(down since at least 2012)

Platform

This application will run on any .NET 3.5sp1 compatible platform.

Contact

Soapi.FindUser was created by code poet.

Code

Soapi.FindUser was written, in 30 minutes, to serve as a sample app for Soapi.CS.

The source for Soapi.FindUser can be found in the answers and is included in the Soapi.CS source code.

4
  • 1
    If this works on Mono, I'll give it a go. Aug 9, 2010 at 22:32
  • @geo - I may have to whip up a GTK+ version. This version uses System.Windows.Forms. Not sure if that is going to work on linux. Aug 9, 2010 at 22:37
  • I really don't know... but a GTK+ version would be awesome. Are you thinking .net, C++, or PyGTK? Aug 10, 2010 at 1:49
  • @geo - mono. in any case - the silverlight version is up at stackapps.com/questions/1344/… - you should be able to use that. Aug 10, 2010 at 13:02

1 Answer 1

2

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
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .