After watching a Generating a Google Drive Hosted Website with tools you have lying around in your kitchen by Ali Afshar I got interested in doing the same thing with dart.
Had to ask my self a few questions first?
- Can the discovery_api_dart_client_generator create drive_v2_api code that would allow us to access drive from the console?
- Can dart process markdown?
- Can we make the webViewLink easier to read and share?
At the time I started this investigation the discovery_api_dart_client_generator did not have OAuth2 support for installed applications. Knowing that pub does use OAuth2 in a similar fashion, I decided to peek inside of pub to see what it is doing.
After reviewing the pub source code, it’s interested to see how they handle getting tokens from the Google OAuth2 Authorization Server back to the client application. pub first checks if the client applications has a ~/.pub-cache/credentials.json
file stored, if the credentials.json
is not found or invalid pub will generate an authorization url. The authorization url is copied and pasted by the user into a web browser and asks the user if they will allow access to some scopes. When the user accepts access the redirect url with token the Google OAuth2 Authorization Server redirects to a listening http server on localhost. This server was started by the pub application, now pub has the token and stores it for later use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
After some initial slicing and dicing I was able to take what was needed from pub and merge it into dart-google-oauth2-library that discovery_api_dart_client_generator depends on for OAuth2 support. pub was structured such that all files are dart libraries, so ripping out parts was easy, I found the most issues with http package. The client requests ContentType
could only be set as application/x-www-form-urlencoded
when making requests, this did not seem to play nicely with Google APIs. Took many hours of debugging to figure out why POST
method would fail but GET
method would not. Stumbled on some Google mailing lists that mentioned some services do work with ContentType
application/x-www-form-urlencoded
and some only with application/json
. So I created a separate client that does the POST
, PATCH
, PUT
, DELETE
methods required for the Google Client APIs.
Big thanks to Gerwin Sturm for working on this merge with me, in a very short amount of time we’ve been able to push the dart-google-oauth2-library and discovery_api_dart_client_generator into almost complete solutions for dart and Google Client API services.
The markdown.dart processor was for the most part a total freebie, Bob Nystrom had already created a markdown processor which eventually got rolled into Dartdoc. All that was needed here is picking out the code from the dart repo, updating libraries and import, minor code clean up and hosting it on github.
One of my all time favorite Google APIs is the url-shortener API. Even without OAuth2 you can use this service, now that we have patched up dart-google-oauth2-library and discovery_api_dart_client_generator shortening the long webViewLink will be easy. A site note, goo.gl links work great as for landing slides when giving a presentation, easy and short enough for audience to type into mobile phone, tablet or laptop to pull down your slides and follow along.
Now we have all the parts needed to create a simple application that reads in some markdown, processes it to html, creates a website folder on drive, uploads the final html, then generates a shortened url.
We are still working on the best way to publish the Dart Google Client APIs, so please don’t depend on the links below for too long, they will be out dated soon. This was just for testing.
Starting off with our pubspec.yaml
file we add the dependencies needed for the application.
1 2 3 4 5 6 7 8 9 |
|
Getting a identifier
and secret
is simple, just goto your Google APIs Console and pull out Client ID
and Client secret
for a Client ID for installed applications
that was previously created. If you don’t have one already they are easy to create.
Apply identifier
and secret
to your code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Now with identifier
and secret
the setup for a dart application to use Drive
and Urlshortener
is easy, create a new OAuth2Console
and pass them along to the constructor of Drive
and Urlshortener
. Note that the flag makeAuthRequests
has been set on both objects, that allows us to make authroized calls on behalf of the user. You could create the Google Client API objects without a OAuth2 token and leave the makeAuthRequests
as false, the objects would then only be allowed to access non-authenticated resources on the Google servers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
I have to admit, updating permissions took me awhile to figure out. I first tried to update by calling drive.files.update
with a modified drivelib.File
. That was not the proper way to change permissions on drive. The correct way is to call the drive.permissions.*
methods, lesson learned after some Googling and searching on stackoverflow drive-sdk. Setting the Permissions
and mimeType
are the most important parts to note here, thats what change the folder into a public website hosted on drive viewable to anyone.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Now we get to the meat and potatoes of our application. At this point we have a public web folder that can host our content. We do the follow steps
- Read in the markdown and html template file
- Replace a tag in the template with the markdown
- Insert the file into drive
- Add a parent reference to the file
- Get the url to the folder
- Shorten the url
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
The code for this sample can be found on github drive_publish_markdown. Executing the sample follows the flow explained above
- Ask user to generate token
- Get token from redirect
- Store token
- Make drive and url-shortener requests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Thats all, have fun with this really simple and easy to get started sample.