using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.IO;
using System.Web.UI;
using Nuclex.Networking.Gallery3.Requests;
namespace Nuclex.Networking.Gallery3 {
/// Connects to a gallery installation using the gallery REST API
public class Gallery : ConnectionUser {
/// Connects to a Gallery 3 installation
/// URL of the Gallery 3 installation
/// API key for the user to connect as
///
/// A new gallery connector through which the gallery can be accessed
///
public static Gallery Connect(string galleryUrl, string apiKey) {
return Connect(new RequestFactory(galleryUrl), apiKey);
}
/// Connects to a Gallery 3 installation
///
/// Interface through which requests to the Gallery 3 installation are created
///
/// API key for the user to connect as
///
/// A new gallery connector through which the gallery can be accessed
///
public static Gallery Connect(IRequestFactory requestFactory, string apiKey) {
if (apiKey == null) {
throw new ArgumentNullException("apiKey", "The API key must not be null");
}
return connectInternal(requestFactory, apiKey);
}
/// Connects to a Gallery 3 installation as a guest user
/// URL of the Gallery 3 installation
///
/// A new gallery connector through which the gallery can be accessed
///
///
/// This method is named differently instead of as an overload to Connect() to
/// ensure it is not accidentally used. Without special preparations, Gallery3's
/// REST API does not allow guest access.
///
public static Gallery ConnectAsGuest(string galleryUrl) {
return ConnectAsGuest(CreateRequestFactory(galleryUrl));
}
/// Connects to a Gallery 3 installation as a guest user
///
/// Interface through which requests to the Gallery 3 installation are created
///
///
/// A new gallery connector through which the gallery can be accessed
///
///
/// This method is named differently instead of as an overload to Connect() to
/// ensure it is not accidentally used. Without special preparations, Gallery3's
/// REST API does not allow guest access.
///
public static Gallery ConnectAsGuest(IRequestFactory requestFactory) {
return connectInternal(requestFactory, null);
}
/// Queries gallery for the REST API key of the specified user
///
/// URL of the gallery base installation
/// (for example, 'http://www.mydomain.com/gallery3/index.php')
///
/// Name of the user whose REST API key will be retrieved
/// Password for the user
/// The REST API key for the specified user
public static string QueryApiKey(string galleryUrl, string user, string password) {
return QueryApiKey(CreateRequestFactory(galleryUrl), user, password);
}
/// Queries gallery for the REST API key of the specified user
///
/// Interface through which requests to the Gallery 3 installation are created
///
/// URL of the gallery base installation
/// (for example, 'http://www.mydomain.com/gallery3/index.php')
///
/// Name of the user whose REST API key will be retrieved
/// Password for the user
/// The REST API key for the specified user
public static string QueryApiKey(
IRequestFactory requestFactory, string user, string password
) {
IRequest request = requestFactory.CreateRequest("rest");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.AddHeader("X-Gallery-Request-Method", "post");
// Attach the url-encoded credentials we'll use to log in
{
StringBuilder builder = new StringBuilder();
builder.Append("user=");
builder.Append(HttpUtility.UrlEncode(user));
builder.Append("&password=");
builder.Append(HttpUtility.UrlEncode(password));
byte[] credentials = Encoding.UTF8.GetBytes(builder.ToString());
request.AttachContent(credentials);
}
// Execute the request and read its JSON response
return request.GetJsonResponse();
}
/// The root album in the gallery
public Album RootAlbum {
get { return this.rootAlbum; }
}
/// Creates the default request factory used for gallery requests
/// Base URL of the gallery installation
/// The newly created request factory
internal static IRequestFactory CreateRequestFactory(string url) {
return new RequestFactory(url);
}
/// Initializes a new gallery 3 connector
///
/// Factory used to issue new requests to the gallery installation
///
///
/// API key for the user the requests will run as
///
/// JSON data for the gallery's root album
private Gallery(
IRequestFactory requestFactory, string apiKey, ref Responses.JsonItem rootAlbum
) :
base(new GalleryConnection(requestFactory, apiKey)) {
this.rootAlbum = new Album(Connection, ref rootAlbum);
}
/// Establishes a connection to a gallery installation
///
/// Request factory that will be used to contact the gallery REST API
///
///
/// API key of the user to access the gallery as. If this is null,
/// a connection will be made as the guest user.
///
/// A new gallery connector of the connection was successful
private static Gallery connectInternal(IRequestFactory requestFactory, string apiKey) {
IRequest request = requestFactory.CreateRequest("rest/item/1");
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.AddHeader("X-Gallery-Request-Method", "get");
if (apiKey != null) {
request.AddHeader("X-Gallery-Request-Key", apiKey);
}
// Read the response to our request. Because the java script serializer mapping
// is non-strict, if this connector is used to connect to something else (or
// the server implementation is changed), we only notice this by our fields not
// being assigned.
var item = request.GetJsonResponse();
if (item.Entity.Id != 1) {
throw new WebException("Could not understand reply from remote host");
}
return new Gallery(requestFactory, apiKey, ref item);
}
/// The root album in the gallery
private Album rootAlbum;
}
} // namespace Nuclex.Networking.Gallery3