Skip to content

Instantly share code, notes, and snippets.

@praeclarum
Created June 19, 2011 17:56
Show Gist options
  • Save praeclarum/1034521 to your computer and use it in GitHub Desktop.
Save praeclarum/1034521 to your computer and use it in GitHub Desktop.
Initial implementation of the Dropbox API
public class DropboxCredentials {
public string Email { get; set; }
public string Token { get; set; }
public string TokenSecret { get; set; }
public string DisplayName { get; set; }
public string Uid { get; set; }
public string LastDirectory { get; set; }
public DropboxCredentials() {
Email = "";
Token = "";
TokenSecret = "";
DisplayName = "";
Uid = "";
LastDirectory = "";
}
}
public class DropboxFile {
public bool ThumbExists { get; set; }
public long Bytes { get; set; }
public string Path { get; set; }
public bool IsDir { get; set; }
public string Icon { get; set; }
public List<DropboxFile> Contents { get; private set; }
public DropboxFile () {
Path = "";
Icon = "";
Contents = new List<DropboxFile>();
}
}
public class Dropbox {
public DropboxCredentials Credentials { get; private set; }
public string ConsumerKey = "";
public string ConsumerSecret = "";
readonly Random _rand = new Random();
public Dropbox(DropboxCredentials creds){
Credentials = creds;
}
public void Login (string password, Action k, Action<string> error) {
Begin(delegate {
try {
if (string.IsNullOrEmpty(Credentials.Token)) {
var resp = Request("token",
"email", Credentials.Email,
"password", password);
Credentials.Token = resp["token"];
Credentials.TokenSecret = resp["secret"];
}
k ();
}
catch (Exception ex) {
error(ex.Message);
}
});
}
public void Metadata (string path, Action<DropboxFile> k) {
var p = (path ?? "").Trim();
if (p.Length == 0) {
p = "/";
}
Begin(delegate {
var resp = Request("metadata/dropbox" + p);
k (ReadFile (resp));
});
}
DropboxFile ReadFile (JsonObject obj) {
var f = new DropboxFile() {
ThumbExists = obj["thumb_exists"],
Bytes = (long)obj["bytes"],
Path = obj["path"],
IsDir = obj["is_dir"],
Icon = obj["icon"] ?? "",
};
var cs = obj.ContainsKey("contents") ? (obj["contents"] as JsonArray) : null;
if (cs != null) {
for (var i = 0; i < cs.Count; i++) {
f.Contents.Add (ReadFile ((JsonObject)cs[i]));
}
}
return f;
}
JsonObject Request (string op, params string[] args) {
var baseUrl = "https://api.dropbox.com/0/" + Uri.EscapeUriString(op);
var url = baseUrl;
var qargs = new SortedDictionary<string,string>();
for (var i = 0; (i+1) < args.Length; i += 2) {
qargs[Uri.EscapeDataString(args[i]??"")] = Uri.EscapeDataString(args[i+1]??"");
}
qargs["oauth_consumer_key"] = Uri.EscapeDataString(ConsumerKey);
if (!string.IsNullOrEmpty(Credentials.Token)) {
qargs["oauth_nonce"] = _rand.Next().ToString();
qargs["oauth_signature_method"] = "HMAC-SHA1";
qargs["oauth_timestamp"] = ((long)((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds)).ToString();
qargs["oauth_token"] = Uri.EscapeDataString(Credentials.Token);
var addUrl = string.Join("&", from kv in qargs
select kv.Key + "=" + kv.Value);
var sigBase = "GET&" +
Uri.EscapeDataString(baseUrl) + "&" +
Uri.EscapeDataString(addUrl);
HMACSHA1 sh = new HMACSHA1();
sh.Key = Encoding.UTF8.GetBytes (Uri.EscapeDataString(ConsumerSecret) + "&" +
Uri.EscapeDataString(Credentials.TokenSecret));
var hash = sh.ComputeHash (Encoding.UTF8.GetBytes(sigBase));
var sigHash = Convert.ToBase64String (hash);
url += "?" + addUrl + "&oauth_signature=" + Uri.EscapeDataString(sigHash);
}
else {
var addUrl = string.Join("&", from kv in qargs
select kv.Key + "=" + kv.Value);
url += "?" + addUrl;
}
var req = (HttpWebRequest)WebRequest.Create(url);
try {
using (var resp = req.GetResponse ()) {
using (var s = resp.GetResponseStream()) {
using (var r = new StreamReader (s)) {
return (JsonObject)JsonValue.Parse (r.ReadToEnd());
}
}
}
}
catch (WebException ex) {
var msg = "";
if (ex.Status == WebExceptionStatus.ProtocolError) {
try {
using (var s = ex.Response.GetResponseStream()) {
using (var r = new StreamReader (s)) {
var str = r.ReadToEnd ();
if (str.IndexOf("\"error\":") > 0) {
msg = JsonValue.Parse(str)["error"];
}
}
}
}
catch (Exception) {}
}
if (msg.Length > 0) {
throw new Exception (msg, ex);
}
else {
throw;
}
}
}
static void Begin (Action a) {
ThreadPool.QueueUserWorkItem(delegate {
try {
a ();
}
catch (Exception err) {
Log.Error (err);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment