BitBucket API from Windows Phone 7 and C#

With my latest update of CodeTrack (1.2) I implemented BitBucket as a provider, so you can watch repositories from there now as well. On the app itself there are a few search functions using the BitBucket API, this post will provide some insight and example code for doing this.

So basically I wanted to go from having nothing at all (no BitBucket user, no username, no repo slug/id) to being able to search for repositories by either their name or their owners username.

Note: The BitBucket API has recently changed to allow you to do this by giving the repository responses the Onwer property.

As always, RestSharp was used in the making of this code sample.

The 2 requests share the same response class BitBucketRepoList, this class is pretty simple because we are calling the API anonymously where using a BitBucket username/password would return a more detailed response.

public class BitBucketRepoList
{
    public List<BitBucketRepo> Repositories { get; set; }
}

public class BitBucketRepo
{
    public string Website { get; set; }
    public string Slug { get; set; }
    public string Name { get; set; }
    public string Owner { get; set; }
    public int FollowersCount { get; set; }
    public string Description { get; set; }
}

Searching by Repo Name

This request is pretty straight forward, RestClient with the base url for the API, RestRequest with the Resource “repositories” then add a get parameter of "name” with the search term. (API Doco)

_client = new RestClient("https://api.bitbucket.org/1.0");
var request = new RestRequest("repositories/");

request.AddParameter("name", searchTerm);

_client.ExecuteAsync<BitBucketRepoList>(request, (response) =>
{
    //Do stuff here with response
});

Searching by Repo Owner

Now for this request, BitBucket API doesnt actually support searching on usernames so these must be exact matches on the username.

_client = new RestClient("https://api.bitbucket.org/1.0");
var request = new RestRequest("users/{username}");

request.AddParameter("username", username, ParameterType.UrlSegment);

_client.ExecuteAsync<BitBucketRepoList>(request, (response) =>
{
    //Do stuff here with response
});

 

And there you have it, BitBucket API from Windows Phone 7. (The above code will also work in Silverlight/WPF as well as Win forms or ASP.NET depending on the version of RestSharp used.)

Dropbox API, RestSharp and C# Part 2: The Revenge!

Following on from my previous post where I showed you how to Login and get the Account Info for a Dropbox account. Today we dive into the Box full of files. Uploading, Downloading and Deleting!

 

A lot has changed since my last post in the way of RestSharp with OAuth. OAuth is now available Out-of-the-box (this can be downloaded from Github). Ok, Time for some code…

Download File:

Update: Fixed a bug in the code that only allowed for text based files to be downloaded. Using restClient.DownloadData now instead of Execute to get the response’s raw Data.

public byte[] DownloadFile(string path)
{
    var restClient = new RestClient("http://api-content.dropbox.com");
    //load the JsonDeserializer for all types
    restClient.ClearHandlers();
    restClient.AddHandler("*", new JsonDeserializer());
    if (!path.StartsWith("/")) path = "/" + path;

    restClient.Authenticator = new OAuthAuthenticator(restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);

    var request = new RestRequest(Method.GET);
    request.Resource = "{version}/files/dropbox{path}";
    request.AddParameter("version", _version, ParameterType.UrlSegment);
    request.AddParameter("path", path, ParameterType.UrlSegment);

    var responseData = restClient.DownloadData(request);

    return responseData;
}

Note: This is assuming the user has already logged in and we have the token/secret (_userLogin).

Starting from the top, we create a new Instance of the RestSharp Client with the baseUrl then set the Json Deserializer for all requests. We then set the RestClient’s Authenticator to the OAuthAuthenticator and give it our baseUrl, all our secrets and that is all we need to do for OAuth (the rest is build into RestSharp, awesome?!). Now we create the Request up, its a GET method, set the version and path of the file to download call Execute and you have just downloaded your first Dropbox API file! I then converted this to a stream so save back to a local file.

Delete File:

public bool DeleteFile(string path)
{
    var restClient = new RestClient("http://api.dropbox.com");
    //load the JsonDeserializer for all types
    restClient.ClearHandlers();
    restClient.AddHandler("*", new JsonDeserializer());

    if (!path.StartsWith("/")) path = "/" + path;

    restClient.Authenticator = new OAuthAuthenticator(_restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);

    var request = new RestRequest(Method.GET);
    request.Resource = "{version}/fileops/delete";
    request.AddParameter("version", _version, ParameterType.UrlSegment);

    request.AddParameter("path", path);
    request.AddParameter("root", "dropbox");

    var response = restClient.Execute(request);

    return response.StatusCode == System.Net.HttpStatusCode.OK;
}

Delete is pretty similar to Download, only differences is the Url, the response and this time the path is sent as a parameter instead of part of the Url. The “root” parameter is for applications that only have sandbox access (they would set this to sandbox) who only get access to a “sandbox” folder on the users dropbox account.

Upload File:

Now this is where I had the most difficulties, many “Forbidden” messages later I finally came up with the solution!

public bool UploadFile(string path, FileInfo localFile)
{
    var restClient = new RestClient("http://api-content.dropbox.com");
    //load the JsonDeserializer for all types
    restClient.ClearHandlers();
    restClient.AddHandler("*", new JsonDeserializer());

    if (!path.StartsWith("/")) path = "/" + path;

    //Get the file stream
    byte[] bytes = null;
    FileStream fs = new FileStream(localFile.FullName, FileMode.Open, FileAccess.Read);
    BinaryReader br = new BinaryReader(fs);
    long numBytes = localFile.Length;
    bytes = br.ReadBytes((int)numBytes);

    restClient.Authenticator = new OAuthAuthenticator(_restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);

    var request = new RestRequest(Method.POST);
    request.Resource = "{version}/files/dropbox{path}";
    request.AddParameter("version", _version, ParameterType.UrlSegment);
    request.AddParameter("path", path, ParameterType.UrlSegment);
    //Need to add the "file" parameter with the file name
    request.AddParameter("file", localFile.Name);

    request.AddFile(new FileParameter { Data = bytes, FileName = localFile.Name, ParameterName = "file" });

    var response = restClient.Execute(request);

    return response.StatusCode == System.Net.HttpStatusCode.OK;
}

Ok to start with the “path” variable/parameter is the folder path (not the file).

Starts off the same with the RestClient, JsonDeserializer and the OAuthAuthenticator. We also need to read the file as a byte array. Now this request is a POST so we set that in the RestRequest object then add the version and path Url parameters. We also need to add the Filename as a “file” parameter for this request as well as adding the actual file to the Request. Execute that and: {\"result\": \"winner!\"} we just uploaded a file to dropbox!

 

This code was taken from my Dropbox open source .NET project called DropNet.

Dropbox API and RestSharp for a C# developer

The Dropbox API has foiled my development of “Droppedboxx” for some time now. Mainly because the on site documentation is average for anyone not planning on developing for the iphone (dropbox, you used to be cool). Being a C# developer this was bad news for me but I decided to give it a go anyway and after a few weeks of failed attempts and a few emails to support about my issues I realised the API documentation on the dropbox website is slightly wrong.

So now that I have it working I thought i’d share this with my fellow .NET developers (and anyone else who will care to listen).

What you will need (What i used):

  • RestSharp (What would i do without you…)
  • Oauth Library for C# (this one seems the easiest to use with RestSharp)
  • Access to the Dropbox API and an APIKey/Secret for your app

I guess I should start with the Setup of it, I started this as a Windows Mobile application but I switched to a .NET library so I could test it easier and also use RestSharp (might open source the library if I get around to it).

 

Login, this is possibly the easiest method if you have the right URL (the API documentation give you the wrong URL). We should be using “https://api.getdropbox.com/0/token” Code you say?

Update: Got some helpful advice about using the request.Resource property with parameters instead of a string.format.

public UserLogin Login(string email, string password)
{
    var restClient = new RestClient("https://api.getdropbox.com");
    var request = new RestRequest(Method.GET);
    request.Resource = "{version}/token";
    request.AddParameter("version", _version, ParameterType.UrlSegment);

    request.AddParameter("oauth_consumer_key", _apiKey);

    request.AddParameter("email", email);
    request.AddParameter("password", password);

    var response = restClient.Execute<UserLogin>(request);

    _userLogin = response.Data;

    return response.Data;
}

Seems pretty easy right? Most of thats RestSharp (with the JSONDeserializer), I then have the UserLogin class which is returned by this function.

public class UserLogin
{
    public string Token { get; set; }
    public string Secret { get; set; }
}

And now your user is logged in, you will then want to store the Users Token and Secret (storing UserLogin object would probably be better) as its used for the rest of the requests. I’ll just show you how to get the User Info as the other requests differ from the login (that is where we’ll need the Oauth stuff).

 

Account/Info, I’ll start with the Response classes this time…

public class AccountInfo
{
    public string Country { get; set; }
    public string Display_Name { get; set; }
    public QuotaInfo Quota_Info { get; set; }
    public string Uid { get; set; }
}

public class QuotaInfo
{
    public string Shared { get; set; }
    public string Quota { get; set; }
    public string Normal { get; set; }
}

These are the classes for RestSharp to Deserialize the JSON to. Pretty simple, this is straight off the API Documentation site. Now for the actual request…

public AccountInfo Account_Info()
{
    var restClient = new RestClient("http://api.dropbox.com");
    OAuthBase oAuth = new OAuthBase();
    string nonce = oAuth.GenerateNonce();
    string timeStamp = oAuth.GenerateTimeStamp();
    string normalizedUrl;
    string normalizedRequestParameters;
    string sig = oAuth.GenerateSignature(new Uri(string.Format("{0}/{1}/account/info", restClient.BaseUrl, _version)),
        _apiKey, _appsecret,
        _userLogin.Token, _userLogin.Secret,
        "GET", timeStamp, nonce, out normalizedUrl, out normalizedRequestParameters);
    sig = HttpUtility.UrlEncode(sig);

    var request = new RestRequest(Method.GET);
    request.Resource = string.Format("{0}/account/info", _version);
    request.AddParameter("oauth_consumer_key", _apiKey);
    request.AddParameter("oauth_token", _userLogin.Token);
    request.AddParameter("oauth_nonce", nonce);
    request.AddParameter("oauth_timestamp", timeStamp);
    request.AddParameter("oauth_signature_method", "HMAC-SHA1");
    request.AddParameter("oauth_version", "1.0");
    request.AddParameter("oauth_signature", sig);

    var response = restClient.Execute<AccountInfo>(request);

    return response.Data;
}

Now, this request has a different Base Url to the Login function and this uses OAuth. So firstly we create an instance of the RestSharp client and the OAutheBase classes. The OAuthBase class then handles all of the oauth parameters that we need to make the Request (nonce, timestamp, etc.). GenerateSignature is the main 1 that rolls up the request path and the tokens/secrets into a hash for extra security. As for the dropbox part of this, we dont need any extra parameters as we are just getting the logged in users Account Info. Then its just a matter of adding these parameters to the RestRequest object, notice the oauth_token is actually the UserLogin.Token that we got from our Login method?

 

Stay tuned for more, Tales of interest!

 

Update: I have added a Part 2 to this post.

Smack my BitSharp!

Its an open source .NET client for the BandsInTown API.

TBODA currently have a number of web projects that focus on Live music, such as Promote.fm, and through these projects I have worked very closely with a lot of gig guide APIs. So i thought I’d make some of my code reusable but not just by me, thus BitSharp was born.

Now I’m a big fan of RestSharp (The .NET Rest Client) so BitSharp uses it for all the API requests and Responses. BitSharp is still in early development but most of the event and artist functions are working.

 

Now for the code to us it:

var client = new BitClient("API_KEY_HERE");

Artist artist = null;
try
{
    artist = client.Artists_Get("de11b037-d880-40e0-8901-0397c768c457");
}
catch (BitException ex)
{
    Console.WriteLine("BandsInTown Error:" + ex.Message);
    return;
}

Console.WriteLine(artist.Name);
Console.WriteLine(artist.MusicBrainzID);
Console.WriteLine("Bytes received: " + client.DataCount);

 

Starting by creating an instance of the BitClient with the APIKey this object is then what we use to make all the requests to the API so its a good idea to keep this at the global level that way you only need 1 instance.

Then inside the Try/Catch is where we call the Artists_Get function (this function simply gets artist info given the MusicBrainz ID). All the API Functions throw a BitException if an error is returned from the API so this exception is then caught.

Now that we have called the Artists_Get function we get an Artist object returned and its as easy as that.

 

The other BitSharp functions currently implemented include: (Updated)

  • Events_Search (Search for events either by artist(s), location or date)
  • Events_Daily (Returns a list of events that have been created updated or deleted in the last day)
  • Events_Recommended (Gets recommended events either by artist(s), location or date)
  • Artists_Events (Returns an artists upcoming events)
  • Artists_Get (Gets information on a single Artist)
  • Venues_Search (Search for venues by name and/or location)
  • Venues_Events (Returns a venues upcoming events)

 

You can find the source for BitSharp @ Github.