Desktop client for Google Reader API, written in C# and WPF.
Switch branches/tags
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Nemira is a desktop client for Google Reader API. I've created it in order to
learn C# and WPF (Windows Presentation Foundation).

An executable may be downloaded from Download setup.exe
from the above address and follow the standard installation procedures.

The Nemira project is the one that handles all UI related stuff, like displaying
of windows and event handling. It delegates to classes in the GoogleReader.API
project when it has to read/create/update/delete (CRUD) subscriptions.

The GoogleReader.API.Tests project contains a few tests I wrote while exploring
Google's API. The Nemira.Tests project is, unfortunately, just a skeleton.

The ReaderAccount class
The ReaderAccount class is the heart of the Reader API wrapper. Basically, it
exposes a set of methods that are direct corespondents of the methods exposed
by Google's Reader API. ReaderAccount is open for extension by having a constructor
that receives an HttpClient and an instance of a config object representing
endpoint URLs to the Google service.

Because the HTTP client is pluggable, a lot of things are possible without even
touching the internals of the ReaderAccount class:

  - local caching of subscriptions
  - use of stub subscriptions instead of real ones (see StubHttpClient class
    inside the Nemira project)
  - different forms of authentication

For convenience, I've added a constructor that takes an user email and password
an uses them to instantiate some default dependencies.

Authentication took advantage of the above design and was implemented as a
decorator (AuthorizedHttpClient) over the SimpleHttpClient class. Basically,
each HTTP request is decorated to include an Authorization header and a Google
Reader token.

The Google Reader API provides two authentication and authorization methods:
  - using OAuth, which is the recommended option
  - using the so called Client Login, which makes use of custom HTTP headers and
    is deprecated in favor of OAuth.

I chose to use the second method because it's easier to implement. OAuth would
have required a proxy or an embedded server to be implemented. However, because
the authentication and authorization mechanism is pluggable it shoulnd't be so
hard to provide an HTTP client that would decorate requests with OAuth info.

Reading Google's Responses
The ReaderAccount class makes a pretty big assumptions when it comes to reading
Google's responses. It expects JSON, and this thing is hardcoded inside the
internals of the class. Swapping to XML, for example, would require changes in
the internals of the class. However, I thought that this kind of flexibility
isn't yet necessary. Construnction of domain objects is also hard coded inside
the ReaderAccount class, and maybe it would have been nice to have some factories
for this, but... those objects are generally value objects. Even if they have
behavior, this is usually delegated back to a ReaderAccount instance (for example,
the Subscription class uses delegation in its Items property).

Error Handling
It's almost totally missing at this time. I've concentrated more on getting
some functionality up and running, than on treating HTTP network erros or JSON
parsing errors. This is an item on the TODO list though.

This is a weak point too. The main subscription tree loads items for *all* the
subscriptions as soon as the app starts up. Deferred loading, using the Expanded
event of TreeViewItem should solve this problem and it's on the TODO list too.

Also, quickly navigating with the arrow keys through subscription items will
load cause that item's content to be loaded inside the content area without any
timeout at all. A timeout period of 4-5 milliseconds before loading the content
would be a nice thing to have.

Content Area
Each feed item that Google sends contains HTML markup. For this reason I had
too use an embedded Internet Explorer browser as a display.

User Interface
Main entry point is the App class, which will show a LoginWindow when the app
starts up, the then the MainWindow instance. The other UI classes should have
pretty descriptive names for what they do.