Here is the github repo for it.
Now for some documentation.
As with the YouTube API the first step in getting this sucker setup is getting a developer key by visiting https://www.dropbox.com/developers/apps. There you will setup your new application and they will give you an 'App Key' and 'App Secret'. Put these values into a config file so that we can reference them later. Now download the API files from my github repository and place them into your application folder.
- My trusty oauth_helper.php file belongs in the helpers directory
- dropbox.php is the API file and belongs in the libraries directory
Once they are in place we need to authenticate the API with your dropbox account. We do this using OAuth so you will need to create a controller and add the following methods.
public function request_dropbox() { $params['key'] = $this->config->item('dropbox_key'); $params['secret'] = $this->config->item('dropbox_secret'); $this->load->library('dropbox', $params); $data = $this->dropbox->get_request_token(site_url("welcome/access_dropbox")); $this->session->set_userdata('token_secret', $data['token_secret']); redirect($data['redirect']); } public function access_dropbox() { $params['key'] = $this->config->item('dropbox_key'); $params['secret'] = $this->config->item('dropbox_secret'); $this->load->library('dropbox', $params); $oauth = $this->dropbox->get_access_token($this->session->userdata('token_secret')); $this->_store_in_db($oauth['oauth_token']); $this->_store_in_db($oauth['oauth_token_secret']); }
Now a few lines there need some explanation. In request_dropbox my get_request_token call should have a URL to the access_dropbox method right below. Basically we want the dropbox site to redirect there once the request step is finished. On the next line we store the token secret because we will need that in the access_dropbox method later. Finally we redirect to the provided redirect (this will take the user to the dropbox site).
In the access_dropbox method not too much is different. Make the get_access_token call and pass in the token secret. You should get back an array with an 'oauth_token' value and an 'oauth_token_secret' value. You should store those with your user as they are what you will use to make authenticated request on that users behalf.
Provided those went well we can begin actually fiddling with the API (it should be noted that most calls from the API will return PHP objects as a response). Here is an example of how to load the API with all of the data we have generated.
$params['key'] = $this->config->item('dropbox_key'); $params['secret'] = $this->config->item('dropbox_secret'); $params['access'] = array('oauth_token'=>urlencode($this->_get_from_db()), 'oauth_token_secret'=>urlencode($this->_get_from_db())); $this->load->library('dropbox', $params);
Note that the access parameter is an array with keys 'oauth_token' and 'oauth_token_secret' and that the value of each of these keys is urlencoded. Make sure you mimic this same layout otherwise you risk running into issues with your authenication. Finally load the library with the parameters.
Once the library is successfully loaded you can now make some calls. There are several to choose from the simplest is 'account', so calling:
$this->dropbox->account();
Should return a php object with various account data in it. Most of the methods return a php object there are only two that do not.
$this->dropbox->thumbnail($destination, $path, $size='small', $format='JPEG', $root='dropbox') $this->dropbox->get($destination, $path, $root='dropbox')
The reason these don't return an object is because they actually write a file to the $destination path. The only time these will return anything useful is if an error has occurred.
Another useful method is the add method which will add a file to your dropbox.
$this->dropbox->add($dbpath, $filepath, $root='dropbox');
Here $dbpath is the path within your dropbox (including file name) where the file will go, and $filepath is the path to the file on your server. Unless you know what the $root parameter is for I would just leave it alone.
To finish things off here is the list of the remaining methods. Most are simply for manipulating files in your dropbox folder a few are for getting information on files in your dropbox.
$this->dropbox->metadata($path, $root='dropbox'); $this->dropbox->link($path) $this->dropbox->copy($from, $to, $root='dropbox'); $this->dropbox->create_folder($path, $root='dropbox'); $this->dropbox->delete($path, $root='dropbox'); $this->dropbox->move($from, $to, $root='dropbox');
That's it every one of those should be decently documented in the code. I should point out that I am not doing anything specatular with CodeIgniter so the library should work with 2.0 and the old 1.7.2. I hope you guys enjoy, it was a lot of fun writing it. Let me know in the comments or post on the github repo if you have any problems.
[EDIT] Here is the link to the Dropbox web api: https://www.dropbox.com/developers/web_docs
Hi Jim
ReplyDeleteGreat library and thank you for posting this documentation.
I cant seem to get an oauth_verifier sent back to me in the get_access_token function. I can see the token coming back in the URL, but not the verifier. I could show you the code, but my implementation is exactly as you documented.
Any suggestions?
It is my understanding that Dropbox doesn't currently use an oauth_verifier so it shouldn't prevent you from getting an access token and access token secret.
ReplyDeleteHey Jim, this library is great! I'm finding it super useful. I'm stuck on the get() function, though. What is $destination? Why/where are files being written? I'm trying to get information about a specific file - I have the full, relative Dropbox path to the file - but instead the code seems like it's trying to write a file somewhere. What is supposed to go in the first parameter?
ReplyDeleteThanks!!
If you simply want info on a file in your dropbox then use the metadata call.
ReplyDeleteThe get method is for actually pulling a file from dropbox to your server. The $destination parameter of get is where, on your server, you want the file retrieved from dropbox to be placed.
everytime I try to upload a file i get the following error
ReplyDeleteInvalid signature. Expected signature base string
any ideas?
Tough to say without seeing some code, but if I had to guess I would say you aren't providing access token data.
ReplyDeleteI think that error is an oauth error which would happen because your request isn't being signed with authentication credentials.
Hello,
ReplyDeleteI am using a similar API for CakePHP and the API call for the /links method seems to be broken.
Is it working in your library?
I mean, can you get back a proper link to a file located in a private folder?
Thank you!
Yeah mine work, but I had to make some changes that deviated from the documentation. I would imagine that the creators of your library followed the docs and never tested it. That method is pretty simple so you should be able to duplicate it into Cake easily.
ReplyDeleteThank you for the quick reply ;)
ReplyDeleteI will try to work on it but it's difficult cause the documentation of the /links method is not online anymore on Dropbox..
I had to copy mine from their python library. I don't really know why they don't have it in the docs.
ReplyDeleteHi,
ReplyDeleteI try to use 'add' to upload a db backup, but nothing happens, I get back 'null'.
Are my paths correct? My dropbox dir is backups, and server dir is temp where the backup file successfully generated. I'm on localhost. I have the api keys.
$dbpath = 'backups/dbbackup'.$result['date'].'.zip';
$filepath = './temp/dbbackup'.$result['date'].'.zip';
thanks
The add method will add a file to your dropbox folder. Is ./temp/ a dropbox folder on your server?
ReplyDeleteAlso the dropbox path does not need the file name only the directories. The file name get's copied from the file path.
Here is an example call from my tests.
$dbobj = $this->dropbox->add('Photos', 'assets/Boston City Flow.jpg');
I am adding that 'Boston City Flow.jpg' in assets directory to my dropbox Photos folder which is in the root of my dropbox. Note that assets is relative to my CI root directory.
So what you need to make sure is that 'temp' is a folder in dropbox, looks like you want it in the root as well. Also make sure that backups/dbbackup.xxxxx.zip is relative to the CI root.
Hi Jim,
ReplyDeleteI think I have more complex problem (understanding). Temp should be THE dropbox folder on my maschine, and now it is c:/*user*/Dropbox. After changing it to my CI folder, it works. Now two questions:
- why I need to log-in in the browser, as I know OAuth doesn't need to login. Because I have to log in after running the script, if I'm not logged in..
I want a CRON controlled backup but won't be there always to log in :/
- As I guess I need Dropbox application on my server, so I need a VPS at least to buy and install? Simple website host package doesn't allow install anything.
Yes these are rather Dropbox related questions, but I appreciate if you can answer it in short.
Anyway, your lib is awesome, thank you for the Spark too!
Hi
DeleteCan you please explain what is the exact $dbpath and $filepath such that i am worked for you.
I am also facing the same problem and couldn't find what is going wrong.
Glad you figured it out.
ReplyDeleteTo answer your first question, you should only have to login to dropbox once. The OAuth access token the library generates should be used after the initial login. You just need to store the access token and the token secret. Then any time you load the library pass those values in.
The second issue you are having I really can't give much advice on. That seems like a hosting issue. Try contacting your host and asking them if you can get that setup.
Message: Missing argument 3 for dropbox::_ ..../application/libraries/dropbox.php on line 110 and defined
ReplyDeletei got this error when i have running your dropbox api in my site... do you have any idea?
I need your help...
and by the way, i was set my API key and secret in example.php controller
ReplyDeleteThanks for the heads up that was an issue with the API. I fixed it. Get the latest version and it should work properly.
ReplyDeleteHi i recive a 500 internal error server, and i don't undertand, i'm using your example method.
ReplyDeleteWhich method are you trying to use?
ReplyDeleteHi Jim,
ReplyDeleteThanks for a great lib. Unfortunately I am unable to upload files to db . I am able to use the get, info and meta data functions .
add function gives me a null object(similar to 'subdesign's problem) . I checked the http_code and it returns '0'.
Usage
$this->dropbox->add($dbpath, $file);
$dbpath = path to directory on dropbox
$file = path to file on server
Interstingly I can get a file from $dbpath and write to local folder where $file resides.
any suggestions?
Can you post the code using the library?
ReplyDeleteI tested it out and the latest version does work in my tests.
One thing to try: Make sure debug mode is on (set the DEBUG flag to true). Then monitor the php error log. All of the request and response data the library sends and receives will be put in the log in debug mode.
If the answer isn't obvious by looking at the logs post the response here.
Thx for the prompt response. Given below is the complete log for a single call to this code . I have removed the authorization bit with the keys
ReplyDeleteMy setup -> Xampp + CI on localhost(WinXP)
Thanks
Smit
Code :
--------------------
$params['access'] = array('oauth_token'=>urlencode($this->session->userdata('oauth_token')),
'oauth_token_secret'=>urlencode($this->session->userdata('oauth_token_secret')));
$params['key'] = self::app_key;
$params['secret'] = self::app_secret;
$this->load->library('dropbox', $params);
$dbpath='test';
$path='uploads/local.txt';
$return =$this->dropbox->get($path, $dbpath."/db.txt");
$return =$this->dropbox->add($dbpath, '/'.$path);
--------------------
Error-Log
--------------------
[26-Nov-2011 23:15:55] GET /1/files/dropbox/test/db.txt HTTP/1.1
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
[26-Nov-2011 23:15:55]
[26-Nov-2011 23:15:57] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/test/db.txt
[content_type] => text/plain; charset=ascii
[http_code] => 200
[header_size] => 228
[request_size] => 439
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 1.762
[namelookup_time] => 0.3
[connect_time] => 0.59
[pretransfer_time] => 1.271
[size_upload] => 0
[size_download] => 113
[speed_download] => 64
[speed_upload] => 0
[download_content_length] => 113
[upload_content_length] => 0
[starttransfer_time] => 1.762
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
[request_header] => GET /1/files/dropbox/test/db.txt HTTP/1.1
Accept: */*
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
)
[26-Nov-2011 23:15:57] This file will be copied to local(server) folder and renamed local.txt. Then it should be copied back to dropbox.
[26-Nov-2011 23:15:57] POST /files/dropbox/test?file=%2Fuploads%2Flocal.txt HTTP/1.1
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
[26-Nov-2011 23:15:57] Array
(
[file] => @/uploads/local.txt
)
[26-Nov-2011 23:15:58] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/test?file=%2Fuploads%2Flocal.txt
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 0.942
[namelookup_time] => 0
[connect_time] => 0.301
[pretransfer_time] => 0.942
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
)
[26-Nov-2011 23:15:58]
--------------------
When I run $pics = $this->dropbox->metadata("file.zip", array(), $root="sandbox");
ReplyDeleteI get an error: The provided token does not allow this operation
If I change "dropbox" to "sandbox" I get Path '/file.zip' not found
Any idea what I'm doing wrong?
First just for a sanity check make sure that you have file.zip in the root of your dropbox folder. I have never used the "sandbox" root before and am not sure what the difference is.
ReplyDeleteAlso just to check, your call should be:
$this->dropbox->metadata("file.zip", array(), "sandbox");
Hello Jim,
DeleteI am doing as per your guide lines but still i got error not found.
Actually i am not understand about the path like the below function calling:
$this->dropbox->metadata("/Public/", array(), "sandbox");
Is i am wrong on the above code because it gives not found error.
I had posted the code and log, but seems to have vanished , did you happen to look at it ? should I post it again ?
ReplyDelete-Smit
I got the email but when I didn't see it on here I figured you had deleted it. Yes please post again, if you are still having difficulties.
ReplyDeleteI have removed the authorization bit from the headers log.
ReplyDeleteMy setup -> Xampp + CI on local host(WinXp)
Thanks
Smit
Code :
-------------------------------------
$params['access'] = array('oauth_token'=>urlencode($this->session->userdata('oauth_token')),
'oauth_token_secret'=>urlencode($this->session->userdata('oauth_token_secret')));
$params['key'] = self::app_key;
$params['secret'] = self::app_secret;
$this->load->library('dropbox', $params);
$dbpath='test';
$path='uploads/local.txt';
$return =$this->dropbox->get($path, $dbpath."/db.txt");
$return =$this->dropbox->add($dbpath, '/'.$path);
-------------------------------------
Log
-------------------------------------
[26-Nov-2011 23:15:55] GET /1/files/dropbox/test/db.txt HTTP/1.1
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
[26-Nov-2011 23:15:55]
[26-Nov-2011 23:15:57] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/test/db.txt
[content_type] => text/plain; charset=ascii
[http_code] => 200
[header_size] => 228
[request_size] => 439
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 1.762
[namelookup_time] => 0.3
[connect_time] => 0.59
[pretransfer_time] => 1.271
[size_upload] => 0
[size_download] => 113
[speed_download] => 64
[speed_upload] => 0
[download_content_length] => 113
[upload_content_length] => 0
[starttransfer_time] => 1.762
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
[request_header] => GET /1/files/dropbox/test/db.txt HTTP/1.1
Accept: */*
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
)
[26-Nov-2011 23:15:57] This file will be copied to local(server) folder and renamed local.txt. Then it should be copied back to dropbox.
[26-Nov-2011 23:15:57] POST /files/dropbox/test?file=%2Fuploads%2Flocal.txt HTTP/1.1
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
[26-Nov-2011 23:15:57] Array
(
[file] => @/uploads/local.txt
)
[26-Nov-2011 23:15:58] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/test?file=%2Fuploads%2Flocal.txt
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 0.942
[namelookup_time] => 0
[connect_time] => 0.301
[pretransfer_time] => 0.942
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
)
[26-Nov-2011 23:15:58]
-------------------------------------
Smit,
ReplyDeleteYour post must be getting filtered out for some reason. I got the email though, and looking through the code have you tried using the path "uploads/local.txt" instead of "/uploads/local.txt"?
If the path to the file to upload isn't exact then cURL will fail. So make sure that the path to that file is correct.
Jim,
ReplyDeleteSorry for the delayed reply. I have tried both the paths, but no luck.
Smit
Can you confirm that your "uploads" folder is in the root of your CI instance? It should be on the same level as your application and system folders.
ReplyDeleteSorry if this seems like a stupid question I just want to make sure all the bases are covered before I dig into any serious debugging.
The only reason you wouldn't be getting a response from dropbox is if cURL was failing, and since you have already demonstrated that you can make some calls successfully, we know that cURL is working to some degree.
If your uploads folder is in the proper place, try using the "restore" method of the api library. That sends a similar request to dropbox. If that fails then we will know that the code that is doing the POSTs is the issue. If it succeeds then we will know it has something to do with sending the file.
If you do make the "restore" call please send the log output that is generated.
I could not integrate with my Dropbox account. I did exactly the same as your example and did not work, can you help me?
ReplyDeleteI tested the CI 2.0 and also in CI 1.7.
Thanked.
Can you post the code you are using to instantiate and use the library. That will help me identify what the issue might be.
ReplyDeleteI created a controller with your code: http://pastebin.com/PjGXmYMP
ReplyDeleteAdded the oauth_helper.php, dropbox.php in the correct directories, but did not generate any results.
Where specifically are you having problems? What is the error output? Looking at your controller methods everything seems to be in order.
ReplyDeleteThere is no error message displayed. =/
ReplyDeleteI'm not clear as to where you are having problems. Can you go over the steps of what you are doing and where the problem occurs?
ReplyDeleteOnly one Controller created with this code you posted in the tutorial and added the helper and Librarie available for you.
ReplyDeleteI called the function in the URL and do not return anything.
Have to install something?
Which controller method are you calling? That is the part I am unsure of. Are you calling the request_dropbox controller method? If so and you aren't getting redirected, then you should be getting some kind or error message. If you aren't seeing any error messages you should check you PHP logging level and your PHP error log.
ReplyDeleteI activated the error log and got the following error:
ReplyDeleteFatal error: Call to undefined function site_url () in / home/anderson/Projetos/testeCI202/application/controllers/welcome.php on line 23 Call Stack: 0.0007 347788 1. {main} () / home/anderson/Projetos/testeCI202/index.php: 0 2 0.0023 406824. require_once ('/ home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php') / home/anderson/Projetos/testeCI202/index.php: 0.0252 201 1635960 3. call_user_func_array () / home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php: 339 4 0.0252 1636032. Welcome-> request_dropbox () / home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php: 0
Can you help me?
Ignore the above error. Consider the following error:
ReplyDeleteFatal error: Call to undefined function curl_init () in / home/anderson/Projetos/testeCI202/application/libraries/dropbox.php on line 441 Call Stack: 0.0007 347788 1. {main} () / home/anderson/Projetos/testeCI202/index.php: 0 2 0.0023 406824. require_once ('/ home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php') / home/anderson/Projetos/testeCI202/index.php: 0.0234 201 1730836 3. call_user_func_array () / home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php: 339 4 0.0234 1730908. Welcome-> request_dropbox () / home/anderson/Projetos/testeCI202/system/core/CodeIgniter.php: 0 0.0262 1,909,560 5. dropbox-> get_request_token () / home/anderson/Projetos/testeCI202/application/controllers/welcome.php: 0.0264 1,911,072 6 23. dropbox-> _Connect () / home/anderson/Projetos/testeCI202/application/libraries/dropbox.php: 110
The site_url error is because you didn't include the URL helper on your site.
ReplyDeleteThe next error sounds like you may not have the cURL PHP module installed on your server. You should contact your server administrator to resolve that issue.
I'm testing on localhost(so the administrator myself =P).
ReplyDeleteI will install this PHP cURL module.
OPAA, PHP cURL module installed and everything went right!
ReplyDeleteThank you! =D
Glad to hear it, enjoy!
ReplyDeleteJim,
ReplyDeleteI'm trying to upload a file with the add function like this:
$dbpath = "Apps/acensapp';
$filepath = 'assets/test.pdf';
$dbobj = $this->dropbox->add($dbpath, $filepath);
There is no error, but the file is not sent.
Thank you for your attention.
You need to enable the DEBUG flag of the library and check what it puts in your log.
ReplyDeleteHow to enable OPAA in php ?
ReplyDeleteI don't know what OPAA means.
ReplyDelete@JimDoesCode : Hello,I am using ur library and it works till basic installation and displays account info of dropbox user but when i try any other api calls like get,search or metadata i get a weird error saying : Invalid signature. Expected signature base string: GET&https%3A%2F%2Fapi.dropbox.com%2F1%2Fsearch%2Fdropbox%2FApps%2Ftest2385%2F&access%255Boauth_token%255D%3Dx4trxajxi5isbrq%26access%255Boauth_token_secret%255D%3D3yrvinhg4opqyn0%26key%3D1pcx3fzppi9whwy%26oauth_consumer_key%3D1pcx3fzppi9whwy%26oauth_nonce%3D22666d4ca7ee5d5804e6424df8d9cb56%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1324100802%26oauth_token%3Dx4trxajxi5isbrq%26oauth_version%3D1.0%26query%3Dtes%26secret%3Dungptdqwukcivbw .Can you tell me what am doing wrong?
ReplyDeleteA message like that indicates that your oauth authentication failed. It seems weird that it would succeed when first run and fail other times.
ReplyDeleteEnable debugging on the library and see if you can spot anything suspicious.
Debugging is already on my friend :) and if the oauth authentication failed how come i got the dropbox users info via account function?
ReplyDeleteWhat is being logged?
ReplyDeleteHi Jim,
ReplyDeleteYour api works great. Thanks for your effort.
I was trying to upload a file. After lots of effort i made it work. Problem was incorrect file path.
But debugging was quite difficult, so i wanted to suggest a change, so that debugging becomes more easy.
After line no. 458 in "libraries/Dropbox.php", add the following line:
if($response === false && self::DEBUG)
{
die("Curl Error : ".curl_error($ch));
}
This will help in getting curl errors.
Hi Jim,
ReplyDeleteI installed the latest version of CI and your API pack, however I just can not get the example running.
First I run http://localhost/index.php/example/request_dropbox, it takes me to an authentication page (which I assume is correct). I click "allow" and it then redirects to my dropbox main folder. However, when I run http://localhost/index.php/example/test_dropbox, it prompts me which an error that "stdClass Object ( [error] => Access token not found. )".
Do you know what is the reason causing this error? Thanks.
The library should redirect back to your site after you accept the request. If it doesnt redirect to the accept method the access token never gets set.
DeleteMake sure your ci instance is configured properly also that the base_url property is set correctly.
DeleteHi Jim,
DeleteIt works! Thanks for the tip. Still I have one more question in mind. Do I have to go through request->access->test(or other app) all over again every time?
No, after the access call you should store the token data in your database instead of in the session. Then anytime you make an API call you would pass in the token data.
DeleteMeaning you should only have to do the request and access calls once per user.
Finally I have my app running (tons of bugs though :D) thanks a lot! Now I face another problem: a way to logout the dropbox app. Since the dropbox API does not provide an API to logout, I used the redirect in my codes. Basically I wrote:
Deleteredirect('https://www.dropbox.com/logout');
redirect('start_page');
But the page stuck at dropbox homepage after logout. Any suggestions on that? Thanks a lot!
To "logout" all you need to do is delete the oauth access token. Then when they run you app again a user will have to go through the access step again.
Delete@Jim, your lib works great but could it provide unicode support? I have some folders named by Chinese characters and when it comes to those folders, the api does not work. Otherwise it goes quite smoothly. Thanks!
ReplyDeleteThere shouldn't be any code changes necessary to the library. I believe all you need to do is call utf8_encode() on the folder path you are using prior to passing it into the library.
DeleteHi Jim, I tried several encoding functions but still no luck. The server prompts me the following error message:
DeletestdClass Object
(
[error] => Invalid signature. Expected signature base string: GET&https%3A%2F%2Fapi.dropbox.com%2F1%2Fmetadata%2Fdropbox%2F%25C3%25A7%25C2%2594%25C2%259F%25C3%25A6%25C2%25B4%25C2%25BB&oauth_consumer_key%3Dgkpd49saqugiiy0%26oauth_nonce%3D050600a15076d46f961076bfb334e877%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1333274774%26oauth_token%3Dy85hq1g9ay60bgn%26oauth_version%3D1.0
)
Any ideas what could be the problem? Thanks a lot!
Set your DEBUG flag in the library to true. That will write out everything that the library is doing to your error log. Then compare the signature base string the library is generating to the one that is being suggested in the error string.
DeleteIf you wouldn't mind please provide the folder name you are trying to access. I will use it for testing purposes and see if I can figure out a solution.
The folder name I am use is 生活, which is the Chinese word of "life". I set the DEBUG flag and the following is (part of) the error message when I try to get the metadata of the folder:
Delete[request_header] => GET /1/metadata/dropbox/生活 HTTP/1.1
Authorization: OAuth oauth_consumer_key="gkpd49saqugiiy0", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1333335098", oauth_nonce="83a6ebef37a23bb9265d0c5c527167d5", oauth_version="1.0", oauth_token="lcbjhkjvlf79btt", oauth_signature="bVwhfg46lie%2F0J0j5UBtYKM2iv0%3D"
{"error": "Invalid signature. Expected signature base string: GET&https%3A%2F%2Fapi.dropbox.com%2F1%2Fmetadata%2Fdropbox%2F%25E7%2594%259F%25E6%25B4%25BB&oauth_consumer_key%3Dgkpd49saqugiiy0%26oauth_nonce%3D83a6ebef37a23bb9265d0c5c527167d5%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1333335098%26oauth_token%3Dlcbjhkjvlf79btt%26oauth_version%3D1.0"}
thx a lot!
Wen, I figured it out. You will need to call url_encode on the Chinese characters only. For example if you have a path called:
DeletePhotos/生活/Boston City Flow.jpg
You would specify it as:
'Photos/'.url_encode('生活').'/Boston City Flow.jpg'
I have tested it and it works. I also moved the characters to the root of my dropbox. In that case all I had to do was call:
url_encode('生活')
Be careful that you DO NOT url_encode slashes. If you have multiple folders you must handle them like this:
urlencode('生活').'/'.urlencode('生活')
That should solve your problem.
Great, it works, many thanks Jim!
DeleteFYI:
ReplyDelete@Jim, it would be great if you include the unicode support in your SDK. :)
Hi Jim,
ReplyDeleteFirst of all, thank you so much, your CI dropbox api is really a great help to me.
As Wen mentioned,the api seems Haven't handled special characters.
For example, if my file name to upload is "Larry Gaga (Born this way).mp3"
The brackets are not rawurlencode
So my fix to it is replacing all your
$path = str_replace(' ', '%20', $path);
to
$path = rawurlencode($path)
in the function media.
I have been thinking about a solution. Calling rawurlencode on all input wont work as there are some special characters like slashes that should not be encoded. I will explore some other options and see what i can come up with.
DeleteWhat i did to solve it:
DeleteThere are only white spaces in filenames or foldernames url encoded like this:
$path = str_replace(' ', '%20', $path);
so folders or filenames with umlauts, or other special characters won't work
better do it this way the other way around:
$path = str_replace('%2F', '/', urlencode($path));
What it does it, that everything get's urlencoded and after it the slashes get back to real slashes.
I had big issues with german umlauts in filenames.
Just so it'll help others... here's what i did on a similar matter that (not with this library using CI, but with another 3rd party (non-framework attached) one...
DeleteBut! +100 for this page for setting me on the right path.
Here it is:
https://gist.github.com/4150896
Hope this helps...
(shameless plug... donate to wortell-at-comcast.net via paypal to show thanks?) :)
This is what worked for me (Ortell, based on your solution):
Deletefunction _correct_filepath($fp=null){
if ( empty($fp) ) {
return false;
}
$fpe = explode("/",trim($fp));
$fpe_new = array_map('utf8_encode',$fpe);
$fpe_encoded = array();
foreach($fpe_new as $f){
$f = rawurlencode($f);
$fpe_encoded[] = str_replace('+', '%20', $f);
}
$fpe_new_str = implode("/",$fpe_encoded);
return $fpe_new_str;
}
Jim very big thanks for the library!!!, so helpful, unfortunately it seems that dropbox made some kind of change and now my created app is asking for permissions everytime someone enters, did you or anyone else had this problem? if so, did you find a solution?
ReplyDeleteLast time I tested the library, which was a few weeks ago I didn't have this problem. I will test again and see if I can track down what the problem might be. Until then try turning on the DEBUG flag in the library and see if that gives you some more detailed information.
DeleteYeah, this probably started last week or this last few days, 2 weeks ago it was still running like clockwork, even now it works, it's just the permission asking that's off, thanks in advace!
DeleteP.S. The DEBUG flag does't show more info, or maybe i'm not checking in the right place
The DEBUG flag will write everything to the PHP error log.
DeleteDEBUG doesn't show anything weird :(
ReplyDeleteI ran some tests and wasn't able to reproduce what you are seeing. Are you storing the access token in your database?
DeleteQuite strangely, I experienced the same problem as luchito..
DeleteMake sure you are storing the access token and secret in your database and reusing it instead of generating a new one each time.
DeleteCan you give me a time frame on when you are seeing the token expire? The tests I ran involved getting a new access token then running through several different library commands. I only needed to authenticate the first time after that the same token was used for each request.
Hello Jim!
ReplyDeleteFirst of all, thanks for the library! Great work!
I am trying to save a file to my dropbox folder, but it isn't really working. I am working on localhost.
As you can see, the image (accept.png) I'm trying to save to my dropbox is a folder 'img' which is in my CI-root.
http://dl.dropbox.com/u/17130137/imagefolder.PNG
I am trying to save it to my app folder which was created on granted access to my app, request_dropbox()) on dropbox.
http://dl.dropbox.com/u/17130137/dropboxfolder.PNG
This is the code I've been testing.
http://dl.dropbox.com/u/17130137/code.png
This is the result I'm getting:
http://dl.dropbox.com/u/17130137/results.png
No file has been uploaded. DEBUG flag is set on TRUE. No erros have been logged.
Can you see what I'm doing wrong?
Thanks
Looking at your examples nothing obvious jumps out to me.
DeleteWhat kind of response are you getting from dropbox? That should be logged if you have the DEBUG flag set.
Oh, now I see in my log following:
Delete[25-Apr-2012 14:20:41]
[25-Apr-2012 14:20:41] POST /files/dropbox/Apps/TestCZ?file=img%2Faccept.png HTTP/1.1
Host: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization: OAuth oauth_consumer_key="c3swcjtpphnbtx1", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1335356441", oauth_nonce="31fa2e30a6bf36dbbb69e1090915a750", oauth_version="1.0", oauth_token="fnhbjts1wilskig", oauth_signature="LjjIOIZDlJE%2BdXH7bJccBptuElA%3D"
[25-Apr-2012 14:20:41] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/Apps/TestCZ?file=img%2Faccept.png
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 0.343
[namelookup_time] => 0
[connect_time] => 0.109
[pretransfer_time] => 0.343
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
)
So it's not getting any response back from dropbox. Which means you are sending some kind of malformed request. Let me do some research. Will you upload the image you are trying to send to dropbox so that I can test with it?
Deletehttp://dl.dropbox.com/u/17130137/accept.png
ReplyDeleteI only used this image for testing. In the future it will be PDF-files I need to send to dropbox.
Hi jim. Do you have a solution for this error?
ReplyDeletestdClass Object ( [error] => Invalid OAuth request. ) 1
test: Array ( [oauth_token] => genhdognnc4q16h [oauth_token_secret] => nva0sun9362m83a ) 1
That's tough to diagnose without seeing your code. Make sure that you are providing your oauth data using the access key of the params array:
Delete$params['access'] = array('oauth_token'=>'...', 'oauth_token_secret'=>'...');
hi jim. it seems like i've resolved my first problem but still i got another error. I just followed exactly what was written in this tutorial.Please help me with this one. Thanks!
DeleteMessage: Undefined index: oauth_verifier
Filename: libraries/Dropbox.php
Line Number: 148
[11:51:52 AM] Reine: Message: Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/myvirtualcampus/system/core/Exceptions.php:185)
Filename: helpers/url_helper.php
Line Number: 546
That indicates to me that your oauth verification is failing. Have you turned on the DEBUG flag on the library? Make sure you are passing the correct oauth data into the library with the correct keys.
Deletewhat function will i use to display all the dropbox folder into my site?
ReplyDeleteThere isn't a specific function to do that available in the API. If you read though the docs on Dropbox probably the best way would be to use the metadata call. https://www.dropbox.com/developers/reference/api#metadata
DeleteIs there a way to download the file directly from dropbox without moving it first?
ReplyDeleteI figure this out :)
DeleteThanks for this library
Could you please let us know. How you did this?
DeleteThanks
I am trying tu add the file to dropbox but with different filename. Can that be done?
ReplyDeleteYou can do it by using the add method then the move method.
DeleteHi Jim,
ReplyDeleteI am having the ff errors:
Severity: Notice
Message: Undefined index: oauth_token
Filename: libraries/Dropbox.php
Line Number: 95
Severity: Notice
Message: Undefined index: oauth_token_secret
Filename: libraries/Dropbox.php
Line Number: 97
Message: Cannot modify header information - headers already sent by (output started at /home/mediamas/public_html/dev/application/libraries/Dropbox.php:1)
Message: Cannot modify header information - headers already sent by (output started at /home/mediamas/public_html/dev/application/libraries/Dropbox.php:1)
You need to include the oauth token data for a user.
DeleteThanks for the answer Jim, Where will I obtain the oAuth token data?,
DeleteThe documentation and code samples above go over everything. Just follow them and you should be set.
DeleteHi Jim, where I have to put the oauth_helper.php, and I have put files On my website, because I have 18 years and recently I'm going into programming ..
ReplyDeletefrom Peru, a big hug ..
The oauth_helper goes in /application/helpers/
Deleteinside my Dropbox? or On my website?, excuse the inconvenience. : (
Deletehelp me plz
ReplyDeletedisplay No direct script access allowed....
ReplyDeleteThe helper goes in the helpers folder of your CodeIgniter application.
DeleteYou sound pretty new to CodeIgniter. You might want to get used to working with CodeIgniter before trying to tackle using this library.
sorry 2 minutes ago I just found out that it is a php framework, you are right ... why not enendia all, thanks
DeleteHi jim
ReplyDeleteI found this really very very help ful but now i am not able to figuree out how do i update my file which is already existing in dropbox.
Any help would be really appreciable.
Thanks
Check out the Dropbox API reference (https://www.dropbox.com/developers/reference/api#files-POST). There is an "overwrite" parameter you can pass to update a file that already exists.
DeleteHi Jim, thanks for the library.
ReplyDeleteMay I know is there any encryption performed during the upload or download? Thanks.
Hi Wendy,
DeleteAll API calls are made over HTTPS meaning you have SSL encryption by default. The library doesn't do any additional encryption beyond that though.
Hi Jim, Thank you very much for your prompt response and useful advice! ^_^
DeleteIf anyone has the following error in log: "Full Dropbox access attempt failed because this app is not configured to have full Dropbox access. Should your access type be app folder ('sandbox') instead?"
ReplyDeletethen set $root="sandbox" instead of "dropbox"
So, method add: $this->dropbox->add('Apps', 'file.zip', array(), $root="sandbox");
That's correct.
DeleteYou can also change the DEFAULT_ROOT constant to enable sandbox access by default. Then you wont need to pass "sandbox" in as the root parameter for every call.
I keep getting this error when I set the relative path -
ReplyDeletestdClass Object ( [error] => Creating a link for a directory is not allowed. )
Any thoughts?
Which method are you calling?
Delete$this->dropbox->media($path, $root='dropbox');
DeleteAre you trying to create a link to a directory? The documentation for that method in the library seems bad. Media is mainly for streaming purposes and therefore specifying a directory really doesn't make sense. Even though in the docs for path it says "@param string $path The path to the file or folder in question". It really should just be for files.
DeleteI'm trying to get all the file's direct links from a specific folder. The purpose is to dynamically display images to a website via dropbox.
DeleteYou will need to use the metadata call to get ever file in the folder. Then use the media call for each files path.
DeleteNot very efficient. You might be able to cut some corners by calling media once, then using part of the returned URL to grab the other files. I can't say for sure that that will work as it's been awhile since I looked at what is returned in the media call. If it doesn't the first approach (calling media for each file) will definitely work.
Is there a way to integrate your library in CI without having to access the request_dropbox function everytime? Basically, I want to integrate in a small tool in my website for logged in users (non-dropbox users) to upload files to my dropbox.
ReplyDeleteSince these people are not dropbox users, is it possible to get OAuth token without opening dropbox site and let the users upload files using my webapp interface to my dropbox account?
Sorry if this something very basic and I'm probably overlooking it, but I'm very new to CI and DropBox.
This is pretty easy to accomplish. You will need to perform OAuth authentication once to get the token data for your account. Then store that data in a config file.
DeleteThen every time your app is used you will recall that data from the config file to authenticate.
Thank you very much sir... you rock. This library is pretty awesome. :)
DeleteThe dropbox->add() function requires the file to be uploaded on the server before it can send it over to dropbox?
ReplyDeleteIs it possible to make AJAX (preferably) or traditional POST call using file input field to upload the file directly to dropbox?
You can do some searching and see if there is a Javascript API that will let you do that but this API is purely for server to server communication.
DeleteI'm also having the issue. Undefined index: oauth_verifier. I have passed the correct key & secret from my dropbox App I created. Is there something else that I forgot? I see also something about consumer key and secret, is that something I must pass to the construct or is it something that I should not touch.
ReplyDeleteI am assuming that this is happening via the get_access_token method call. Does it work on the example controller?
DeleteNo on the example controller I have exactly the same. The returned url is http://localhost:8888/cmstut/cmstut/example/access_dropbox?uid=2549040&oauth_token=t3ypqnip9hrkea2
DeleteNo oath_verifier
Just reviewed the Dropbox spec and it appears they have removed oauth_verifier from the access step. I took it out of the library and tested it and it seems to work fine without it. Grab a copy of the latest version and see if that fixes your issue.
Deletehey man i have the same problemas a Christophe any ideas?
DeleteShould be fixed. Try the latest version.
Deleteman i just download the las version
DeleteAha. much better. I already see my account info. Now just need to test uploading a file to dropbox.
Deleteworks like a charm. I can now add a cron job and my db will backup automatically and send a copy to dropbox. Thanks for sharing this.
DeleteHi Jim,
ReplyDeleteHow to download the file from Dropbox?
for be more especific in mi test_dropbox the api doing this error
ReplyDeletestd
Class Object
(
[error] => Access token not found.
)
That sounds like something is wrong with your implementation or you are executing something before authenticating.
Deleteno man, i just donwload the api, create my developer keys, and start following your advice in the documentacion... when i do the myapp.com/example/request_dropbox --> i go to my account accept the app and later this happens
Deletehttps://www.dropbox.com/evernoteUcab/example/access_dropbox.html?uid=108131828&oauth_token=g1hgndhr760iqt0 later ----> a 404 error
Something is wrong with the implementation. The example controller should not redirect to:
Deletehttps://www.dropbox.com/evernoteUcab/example/access_dropbox.html?uid=108131828&oauth_token=g1hgndhr760iqt0
it should redirect to
http://myapp.com/example/access_dropbox.html?uid=108131828&oauth_token=g1hgndhr760iqt0
Make sure you have codeigniter configured properly.
Actually it also wont have the html extension. So
Deletehttp://myapp.com/example/access_dropbox?uid=108131828&oauth_token=g1hgndhr760iqt0
i see the problem really is that no redirect to
Deletelocalhost/evernoteUcab/example/access_dropbox?uid=108131828&oauth_token=yxouo54fa7f7td0
instead
https://www.dropbox.com/evernoteUcab/example/access_dropbox?uid=108131828&oauth_token=yxouo54fa7f7td0
but i cant really do my app go to
Deletehttp://localhost/evernoteUcab/example/access_dropbox?uid=108131828&oauth_token=yxouo54fa7f7td0
later my app go to https://www.dropbox.com/evernoteUcab/example/access_dropbox?uid=108131828&oauth_token=yxouo54fa7f7td0 I REMOVE THE https://www.dropbox.com FROM URL THE TEST_DROPBOX autentificate.. but why he is doing that URL with that and NOT WITH localhost/evernoteUcab/example/access_dropbox?uid=108131828&oauth_token=yxouo54fa7f7td0
DeleteMy guess is that CodeIgniter is not configured properly. I can't say for sure though but it sounds like the problem isn't with the library it's with the implementation.
Deletebut i what about my codeigniter is no configured ? i have the base url good because i use for others things.. any guess?
DeleteI can't really say without looking at the code.
Deleteany mail if u are so GOOD i sent u the app complete and u tell me if something is wrong if u dont want to publicate ur email i going to understand.. i am tired of looking and when i see this comments i know u can help me
Deletesorry in my last comment i do myapp.com for a example.. the real url is http://localhost/evernoteUcab/ sorry for the mistake
ReplyDeletehi Jim, i have a problem with the library, i cant load a file this is the code.. and the error
ReplyDelete...
$params['access'] = array('oauth_token' => urlencode($this->session->userdata('oauth_token')),
'oauth_token_secret' => urlencode($this->session->userdata('oauth_token_secret')));
$this->load->library('dropbox', $params);
$return = $this->dropbox->add('Photos', 'dropbox/desdeapi.txt',$params,'dropbox');
print_r($return);
AND THE ERROR
stdClass Object ( [error] => Invalid or missing signature )
i dont know what happens
You shouldn't be passing authentication parameters in the add call. Those are only used when loading the library.
Deletewhats wrong with my code?
ReplyDelete$this->dropbox->add('Apps/Test/', 'tmp/jquery.js', array('overwrite' => true), 'dropbox')
- index.php
- applications
- tmp
You saved my life.
ReplyDeleteI'm unable to add file into dropbox using this api. Please help me
ReplyDelete$file = fopen(base_url()."images/text.txt","r");
ReplyDeleteecho fgets($file);
$test = $this->dropbox->add('images',$file);
var_dump($test);
Please read the PHP Doc comments in the library. It clearly states that the second parameter of the add method should be a file path. Not a PHP file handler.
Deletethanks jim. solve this problem.
Deletebut now one problem arise when used get() function for use details info of the file.
please provide one example please. I'm unable to use this.
please help me about this matter.
how to read or download file from dropbox ?
DeleteThis comment has been removed by the author.
DeleteI can't seem to make anything work. (add, get, thumbnail, etc) When I try to print the $result they all return nothing on the page. Is there something I'm missing to edit in the Dropbox.php?
ReplyDeleteAnd I don't get how to turn on the debug mode.
nvm what i said only problem now is add()
Delete[12-Jul-2013 12:51:13 UTC] POST /files/dropbox/started.pdf?file=%2Fresources%2Fstarted.pdf HTTP/1.1
DeleteHost: api-content.dropbox.com
Connection: close
User-Agent: CodeIgniter
Accept-encoding: identity
Authorization:
[12-Jul-2013 12:51:16 UTC] Array
(
[url] => https://api-content.dropbox.com/1/files/dropbox/started.pdf?file=%2Fresources%2Fstarted.pdf
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 2.282
[namelookup_time] => 0.532
[connect_time] => 1.266
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[primary_ip] => 184.73.243.158
[primary_port] => 443
[local_ip] => 192.168.1.8
[local_port] => 51394
[redirect_url] =>
)
[12-Jul-2013 12:51:16 UTC]
Make sure that the root you specified when you set up your application in dropbox is correct. The default library root value is dropbox but I think the default dropbox application root is sandbox
DeleteAll else works except add()
DeleteMy permission in my dropbox app is full dropbox. So I didn't change the library root because it is already dropbox.
Hey, i have a problem by downloading big files from dropbox using your library.
ReplyDeleteAfter some hours i noticed that the script hangs at $response = curl_exec($ch); in the _connect method of Dropbox.php when i actually trying to GET the file. It only gets stuck when the file (in dropbox) is larger than 100 Mb. I tried many solutions like setting limits but nothing works.
Maybe u have a suggestion/solution? Or is there a download limit on dropbox that prevent you from downloading big files (> 100 Mb) via Core API (or curl).
Thanks in advance
I'm not aware of a limit on Dropbox's side, there could be one though. Have you checked the PHP memory limit on your server? This library wasn't really designed for large files so it will load all the file bytes into a PHP variable before writing it to disk. So if you have a memory limit of 100M then the variable can't exceed that.
DeleteHey, i solved my problem. I think it was a problem with the memory, but instead of raising the memory i added some code in front of the curl_exec(). I found this code on many forums that advice this because it will "save" the file instead of writing it in a variable with the headers.
ReplyDelete// check if we need to write the file
if($destination !== false)
{
$fh = fopen($destination, 'w');
curl_setopt($ch, CURLOPT_FILE, $fh);
}
// execute curl
$response = curl_exec($ch);
So everything works and perhaps u can use this code in a next version of your library. And thanks for the library and helping others!
How I download directly from dropbox a file??
ReplyDeletehi jim
ReplyDeletei want to get all the files list in my dropbox. i am using metadata function
it gives me error
stdClass Object
(
[error] => Full Dropbox access attempt failed because this app is not configured to have full Dropbox access. Should your access type be app folder ('sandbox') instead?
)
hi jim, I would like to know how can I run your example, that is, I have to create a view and make the call or put the URL directly ... localhost / mysite / example
ReplyDeletehi jim,
ReplyDeletei need i help. how to show all file in my dropbox folder?
thx gor guide
dropbox library add method not working please help me.That give's error like :
ReplyDeletestdClass Object ( [error] => stdClass Object ( [file] => Expecting a file upload ) )
how do i get the name, size etc of file in dropbox. Actually i want to store the file name, size in db . Please help me with some specific code
ReplyDeletePlease how did you upload?
Deletehi .i m getting an error .I m redirected to dropbox home page but it is showing "This request to link the app is invalid"..
ReplyDeletei need step by step process kindly help
ReplyDeleteHii How can I get all folders from dropbox
ReplyDeleteWow, amazing block structure! How long
ReplyDeleteHave you written a blog before? Working on a blog seems easy.
The overview of your website is pretty good, not to mention what it does.
In the content!
vstpatch.net
MX Player Pro APK Crack
Potplayer Crack
Dropbox Crack
Maxthon Cloud Browser Crack
Minitube Crack
Wow, amazing block structure! How long
ReplyDeleteHave you written a blog before? Working on a blog seems easy.
The overview of your website is pretty good, not to mention what it does.
In the content!
vstpatch.net
PUBG MOBILE MOD APK Crack
Plugin Boutique Scaler Crack
CorelDraw Graphics Suite Crack
StudioRack V11 Crack
Camtasia Studio Crack
I Am Very Impressed With The Crack Of Dropbox That I Found On This Website
ReplyDeleteDropbox Crack
“Thank you so much for sharing all this wonderful info with the how-to's!!!! It is so appreciated!!!” “You always have good humor in your posts/blogs. So much fun and easy to read!
ReplyDeleteScrivener Crack
EarthView Crack
ProgDVB Professional Crack
Dropbox Crack
Great work you done.
ReplyDeleteDropbox Crack