Turn Your Google Drive Folder In An Online Album Viewer

Working with Google Drive API is fun. The documentation is good and will let you get started with the API pretty quickly. I have my whole complete family album on OneDrive, but the API is still a bit hard to use as compared to Google Drive API or maybe it is just for me. But while playing around with Drive API I ended up creating a small razor based web page application which will allow you to show your folder as an online web album. I have the source code at Github.

To get started register your application on the Google Developer Console. Here is a complete guide on how to use the Google APIs.

Registering the application on Google Dev Console

Copy the API keys and save it on the notepad. The basic usage example on the Google Drive API reference page uses a file called client_secrets.json which actually holds the API key. You can find this file in the bin folder.

{
  "installed": {
    "client_id": "524339914714.apps.googleusercontent.com",
    "client_secret": "_Lq8D_Ai-T2IbhU8m2zXlQa"
  } 
}

You also have to enable the Drive API before you start using it.

Enable API in Google Dev Console

I created a wrapper around the Google Drive API so I can use it in my other projects. Here is the complete code of my GoogleDrive class.

using System;
using System.Collections.Generic;
using System.Web;
using Google;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Download;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Logging;
using Google.Apis.Services;
using System.Threading.Tasks;
using System.Threading;
//using Google.Apis.Upload;
 
public class GoogleDrive
{
    DriveService service = null;
    public GoogleDrive()
    {
        Run().Wait();
    }
 
 
    private File GetFileByID(string fileID, DriveService service)
    {
        File file = service.Files.Get(fileID).Execute();
        if (file.ExplicitlyTrashed == null)
            return file;
        return null;
    }
 
    public string GetFolderID(string FolderName)
    {
        FilesResource.ListRequest request = service.Files.List();
        request.Q = "title = '" + FolderName + "'";
        FileList files = request.Execute();
        return files.Items[0].Id;
    }
    public List<File> ListFolderContent(string FolderID)
    {
        ChildrenResource.ListRequest request = service.Children.List(FolderID);
        List<File> files = new List<File>();
        //request.Q = "mimeType = 'image/jpeg'";
 
        request.Q = "'" + FolderID + "' in parents";
 
        do
        {
            try
            {
                ChildList children = request.Execute();
 
                foreach (ChildReference child in children.Items)
                {
                    files.Add(GetFileByID(child.Id, service));
                }
 
                request.PageToken = children.NextPageToken;
 
            }
            catch (Exception e)
            {
                request.PageToken = null;
            }
        } while (!String.IsNullOrEmpty(request.PageToken));
        return files;
    }
 
    public List<File> ListRootFileFolders()
    {
        List<File> result = new List<File>();
        FilesResource.ListRequest request = service.Files.List();
        do
        {
            try
            {
                FileList files = request.Execute();
 
                result.AddRange(files.Items);
                request.PageToken = files.NextPageToken;
            }
            catch (Exception e)
            {
                request.PageToken = null;
            }
        } while (!String.IsNullOrEmpty(request.PageToken));
        return result;
    }
 
    public byte[] DownloadFile(string fileID)
    {
        File file = service.Files.Get(fileID).Execute();
        var bytes = service.HttpClient.GetByteArrayAsync(file.DownloadUrl);
        return  bytes.Result;
    }
 
 
    private async Task Run()
    {
        try
        {
            GoogleWebAuthorizationBroker.Folder = "Files";
            UserCredential credential;
            using (var stream = new System.IO.FileStream("client_secrets.json",
                System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets, DriveConstants.Scopes, "user", CancellationToken.None);
            }
 
            var drvService = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Drive API Sample",
 
            });
 
            if (drvService != null)
            {
                service = drvService;
            }
        }
        catch { }
    }
}

The Storage class uses Biggy for the document storage. You have to manually add the names of the folder (considered as albums) on settings page. This will get added/appended in settings.json file in the Data folder which is in the web root of DriveGallery. Here is my settings file.

{"AlbumName":"Atlassian"}
{"AlbumName":"DivX"}
{"AlbumName":"Envato"}
{"AlbumName":"Disqus"}

Settings page from where I can add the names of folders/albums. No view and delete options as of now, but I will soon add it.

Adding a new album

The added albums will be listed on the main/default page. The user will then have to click the name of the album to view the contents which should only images. At the moment there is no check which prevents it to show other files rather than only image files.

App home page

Google Drive is slow when it comes to handle high amount of data. Google Drive storage is not like Azure or Amazon storage. It’s different and will not get you large results in appropriate time. If you want to use Drive Gallery make sure that you don’t use more than 25-50 images in a folder. Querying 25-50 files in a single go will be long but not more than if you have more than 50. Better option is to break your folder in parts like volume I & II or Part 1 or 2.

I will try to make it look more attractive but for the moment it solves the purpose for me. Click on the View button to view the album. The View page accepts a query string name, which has the name of the folder/album. Google Drive API does not understand the name of the folder, so I have to get the folder id from the name. I will use the GetFolderID method of the GoogleDrive class which gives me the folder id. The received folder id is then passed to ListFolderContent method which will list all the files in the folder.

Please note that, for the moment there is no check to retrieve only images from the folder. GoogleDrive.cs class is a generic version of the class I am using in my other projects. You just need to be sure that you have only images in the folder and not any other file.

Album output

Click the View button to view the full size image in the browser else click the Download button to download it directly. Basically Drive API does not have any property which holds the value of the URL to view the image online. So I tweaked the thumbnail URL in the ViewURL property so I can view the images online without having to download it.

public class Albums
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string AlbumName { get; set; }
    public string DownloadURL { get; set; }
    public string ViewURL
    {
        get
        {
            return ThumbnailLink.Replace("=s220", "=s4000");
        }
    }
    public string ThumbnailLink { get; set; }
}

Taking the ThumbnailLink property and replace the =s220 to =s4000 does the trick.

Note: The URLs are not permanent, it will change when the request expires.

Properties of the Album class:

  • Id: File/Image id.
  • Tilte: Title of the image/file.
  • AlbumName: Name of the album/folder.
  • DownloadURL: Download URL of the image/file. Original Drive API property name: DownloadUrl.
  • ViewURL: URL which allows user to view the image in the browser.
  • ThumbnailLink: URL of the thumbnail image. Original Drive API property name: ThumbnailLink.

The duration of the operation depends on the amount of images you have in your folder. The lesser the number of images the fast the query will get executed. Here just for fun I have used Biggy JSON store to save the content details of the folder. If you want to remove it from your implementation, please do so. You may have to change some functions in order to get all other things working fine.

You can download the complete source code from Github. I am still working on it to make it more flexible and good looking. As I am not a designer and I seriously lack when it comes to web designs. Thanks to Twitter bootstrap to make it look a bit good.

comments powered by Disqus