Commit 13221a10 authored by kochi@chromium.org's avatar kochi@chromium.org

Add FileResource/FileList parser.

Still multiple list (uses next_link and token), parent
folder handling etc. are missing, but minimal information
is captured.

BUG=chromium:127728
TEST=unit_tests --gtest_filter="DriveApiParserTest.*"

Review URL: https://chromiumcodereview.appspot.com/10829056

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149377 0039d316-1c4b-4281-b951-d872f2087c98
parent caa5c4df
...@@ -34,6 +34,9 @@ bool GetGURLFromString(const base::StringPiece& url_string, GURL* result) { ...@@ -34,6 +34,9 @@ bool GetGURLFromString(const base::StringPiece& url_string, GURL* result) {
// Common // Common
const char kKind[] = "kind"; const char kKind[] = "kind";
const char kId[] = "id";
const char kETag[] = "etag";
const char kItems[] = "items";
// About Resource: // About Resource:
const char kAboutKind[] = "drive#about"; const char kAboutKind[] = "drive#about";
...@@ -49,8 +52,6 @@ const char kIconUrl[] = "iconUrl"; ...@@ -49,8 +52,6 @@ const char kIconUrl[] = "iconUrl";
// Apps Resource: // Apps Resource:
const char kAppKind[] = "drive#app"; const char kAppKind[] = "drive#app";
const char kId[] = "id";
const char kETag[] = "etag";
const char kName[] = "name"; const char kName[] = "name";
const char kObjectType[] = "objectType"; const char kObjectType[] = "objectType";
const char kSupportsCreate[] = "supportsCreate"; const char kSupportsCreate[] = "supportsCreate";
...@@ -66,8 +67,23 @@ const char kIcons[] = "icons"; ...@@ -66,8 +67,23 @@ const char kIcons[] = "icons";
// Apps List: // Apps List:
const char kAppListKind[] = "drive#appList"; const char kAppListKind[] = "drive#appList";
const char kItems[] = "items";
// File Resource:
const char kFileKind[] = "drive#file";
const char kMimeType[] = "mimeType";
const char kTitle[] = "title";
const char kModifiedByMeDate[] = "modifiedByMeDate";
const char kDownloadUrl[] = "downloadUrl";
const char kFileExtension[] = "fileExtension";
const char kMd5Checksum[] = "md5Checksum";
const char kFileSize[] = "fileSize";
const char kDriveFolderMimeType[] = "application/vnd.google-apps.folder";
// Files List:
const char kFileListKind[] = "drive#fileList";
const char kNextPageToken[] = "nextPageToken";
const char kNextLink[] = "nextLink";
// Maps category name to enum IconCategory. // Maps category name to enum IconCategory.
struct AppIconCategoryMap { struct AppIconCategoryMap {
...@@ -205,7 +221,7 @@ AppResource::~AppResource() {} ...@@ -205,7 +221,7 @@ AppResource::~AppResource() {}
// static // static
void AppResource::RegisterJSONConverter( void AppResource::RegisterJSONConverter(
base::JSONValueConverter<AppResource>* converter) { base::JSONValueConverter<AppResource>* converter) {
converter->RegisterStringField(kId, &AppResource::id_); converter->RegisterStringField(kId, &AppResource::application_id_);
converter->RegisterStringField(kName, &AppResource::name_); converter->RegisterStringField(kName, &AppResource::name_);
converter->RegisterStringField(kObjectType, &AppResource::object_type_); converter->RegisterStringField(kObjectType, &AppResource::object_type_);
converter->RegisterBoolField(kSupportsCreate, &AppResource::supports_create_); converter->RegisterBoolField(kSupportsCreate, &AppResource::supports_create_);
...@@ -279,4 +295,95 @@ bool AppList::Parse(const base::Value& value) { ...@@ -279,4 +295,95 @@ bool AppList::Parse(const base::Value& value) {
return true; return true;
} }
////////////////////////////////////////////////////////////////////////////////
// FileResource implementation
FileResource::FileResource() {}
FileResource::~FileResource() {}
// static
void FileResource::RegisterJSONConverter(
base::JSONValueConverter<FileResource>* converter) {
converter->RegisterStringField(kId, &FileResource::file_id_);
converter->RegisterStringField(kETag, &FileResource::etag_);
converter->RegisterStringField(kMimeType, &FileResource::mime_type_);
converter->RegisterStringField(kTitle, &FileResource::title_);
converter->RegisterCustomField<base::Time>(
kModifiedByMeDate,
&FileResource::modified_by_me_date_,
&gdata::util::GetTimeFromString);
converter->RegisterCustomField<GURL>(kDownloadUrl,
&FileResource::download_url_,
GetGURLFromString);
converter->RegisterStringField(kFileExtension,
&FileResource::file_extension_);
converter->RegisterStringField(kMd5Checksum, &FileResource::md5_checksum_);
converter->RegisterCustomField<int64>(kFileSize,
&FileResource::file_size_,
&base::StringToInt64);
}
// static
scoped_ptr<FileResource> FileResource::CreateFrom(const base::Value& value) {
scoped_ptr<FileResource> resource(new FileResource());
if (!IsResourceKindExpected(value, kFileKind) || !resource->Parse(value)) {
LOG(ERROR) << "Unable to create: Invalid FileResource JSON!";
return scoped_ptr<FileResource>(NULL);
}
return resource.Pass();
}
bool FileResource::IsDirectory() const {
return mime_type_ == kDriveFolderMimeType;
}
bool FileResource::Parse(const base::Value& value) {
base::JSONValueConverter<FileResource> converter;
if (!converter.Convert(value, this)) {
LOG(ERROR) << "Unable to parse: Invalid FileResource";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// FileList implementation
FileList::FileList() {}
FileList::~FileList() {}
// static
void FileList::RegisterJSONConverter(
base::JSONValueConverter<FileList>* converter) {
converter->RegisterStringField(kETag, &FileList::etag_);
converter->RegisterStringField(kNextPageToken, &FileList::next_page_token_);
converter->RegisterCustomField<GURL>(kNextLink,
&FileList::next_link_,
GetGURLFromString);
converter->RegisterRepeatedMessage<FileResource>(kItems,
&FileList::items_);
}
// static
scoped_ptr<FileList> FileList::CreateFrom(const base::Value& value) {
scoped_ptr<FileList> resource(new FileList());
if (!IsResourceKindExpected(value, kFileListKind) ||
!resource->Parse(value)) {
LOG(ERROR) << "Unable to create: Invalid FileList JSON!";
return scoped_ptr<FileList>(NULL);
}
return resource.Pass();
}
bool FileList::Parse(const base::Value& value) {
base::JSONValueConverter<FileList> converter;
if (!converter.Convert(value, this)) {
LOG(ERROR) << "Unable to parse: Invalid FileList";
return false;
}
return true;
}
} // namespace gdata } // namespace gdata
...@@ -136,7 +136,7 @@ class AppResource { ...@@ -136,7 +136,7 @@ class AppResource {
static scoped_ptr<AppResource> CreateFrom(const base::Value& value); static scoped_ptr<AppResource> CreateFrom(const base::Value& value);
// Returns application ID, which is 12-digit decimals (e.g. "123456780123"). // Returns application ID, which is 12-digit decimals (e.g. "123456780123").
const std::string& id() const { return id_; } const std::string& application_id() const { return application_id_; }
// Returns application name. // Returns application name.
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
...@@ -205,7 +205,7 @@ class AppResource { ...@@ -205,7 +205,7 @@ class AppResource {
// Return false if parsing fails. // Return false if parsing fails.
bool Parse(const base::Value& value); bool Parse(const base::Value& value);
std::string id_; std::string application_id_;
std::string name_; std::string name_;
std::string object_type_; std::string object_type_;
bool supports_create_; bool supports_create_;
...@@ -257,6 +257,115 @@ class AppList { ...@@ -257,6 +257,115 @@ class AppList {
DISALLOW_COPY_AND_ASSIGN(AppList); DISALLOW_COPY_AND_ASSIGN(AppList);
}; };
// FileResource reporesents a file or folder metadata in Drive.
// https://developers.google.com/drive/v2/reference/files
class FileResource {
public:
~FileResource();
// Registers the mapping between JSON field names and the members in this
// class.
static void RegisterJSONConverter(
base::JSONValueConverter<FileResource>* converter);
static scoped_ptr<FileResource> CreateFrom(const base::Value& value);
// Returns true if this is a directory.
// Note: "folder" is used elsewhere in this file to match Drive API reference,
// but outside this file we use "directory" to match HTML5 filesystem API.
bool IsDirectory() const;
// Returns file ID. This is unique in all files in Google Drive.
const std::string& file_id() const { return file_id_; }
// Returns ETag for this file.
const std::string& etag() const { return etag_; }
// Returns MIME type of this file.
const std::string& mime_type() const { return mime_type_; }
// Returns the title of this file.
const std::string& title() const { return title_; }
// Returns modification time by the user.
const base::Time& modified_by_me_date() const { return modified_by_me_date_; }
// Returns the download URL.
const GURL& download_url() const { return download_url_; }
// Returns the extension part of the filename.
const std::string& file_extension() const { return file_extension_; }
// Returns MD5 checksum of this file.
const std::string& md5_checksum() const { return md5_checksum_; }
// Returns the size of this file in bytes.
int64 file_size() const { return file_size_; }
private:
friend class base::internal::RepeatedMessageConverter<FileResource>;
friend class FileList;
FileResource();
// Parses and initializes data members from content of |value|.
// Return false if parsing fails.
bool Parse(const base::Value& value);
std::string file_id_;
std::string etag_;
std::string mime_type_;
std::string title_;
base::Time modified_by_me_date_;
GURL download_url_;
std::string file_extension_;
std::string md5_checksum_;
int64 file_size_;
DISALLOW_COPY_AND_ASSIGN(FileResource);
};
// FileList represents a collection of files and folders.
// https://developers.google.com/drive/v2/reference/files/list
class FileList {
public:
~FileList();
// Registers the mapping between JSON field names and the members in this
// class.
static void RegisterJSONConverter(
base::JSONValueConverter<FileList>* converter);
static scoped_ptr<FileList> CreateFrom(const base::Value& value);
// Returns the ETag of the list.
const std::string& etag() const { return etag_; }
// Returns the page token for the next page of files, if the list is large
// to fit in one response. If this is empty, there is no more file lists.
const std::string& next_page_token() const { return next_page_token_; }
// Returns a link to the next page of files. The URL includes the next page
// token.
const GURL& next_link() const { return next_link_; }
// Returns a set of files in this list.
const ScopedVector<FileResource>& items() const { return items_; }
private:
friend class DriveAPIParserTest;
FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, FileListParser);
FileList();
// Parses and initializes data members from content of |value|.
// Return false if parsing fails.
bool Parse(const base::Value& value);
std::string etag_;
std::string next_page_token_;
GURL next_link_;
ScopedVector<FileResource> items_;
DISALLOW_COPY_AND_ASSIGN(FileList);
};
} // namespace gdata } // namespace gdata
#endif // CHROME_BROWSER_CHROMEOS_GDATA_DRIVE_API_PARSER_H_ #endif // CHROME_BROWSER_CHROMEOS_GDATA_DRIVE_API_PARSER_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/gdata/drive_api_parser.h" #include "chrome/browser/chromeos/gdata/drive_api_parser.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -18,14 +19,6 @@ using base::Value; ...@@ -18,14 +19,6 @@ using base::Value;
using base::DictionaryValue; using base::DictionaryValue;
using base::ListValue; using base::ListValue;
#define IF_EXPECT_EQ(arg1, arg2) \
EXPECT_EQ(arg1, arg2); \
if (arg1 == arg2)
#define IF_EXPECT_TRUE(arg) \
EXPECT_TRUE(arg); \
if (arg)
namespace gdata { namespace gdata {
class DriveAPIParserTest : public testing::Test { class DriveAPIParserTest : public testing::Test {
...@@ -77,82 +70,127 @@ TEST_F(DriveAPIParserTest, AppListParser) { ...@@ -77,82 +70,127 @@ TEST_F(DriveAPIParserTest, AppListParser) {
EXPECT_EQ("\"Jm4BaSnCWNND-noZsHINRqj4ABC/tuqRBw0lvjUdPtc_2msA1tN4XYZ\"", EXPECT_EQ("\"Jm4BaSnCWNND-noZsHINRqj4ABC/tuqRBw0lvjUdPtc_2msA1tN4XYZ\"",
applist->etag()); applist->etag());
IF_EXPECT_EQ(2U, applist->items().size()) { ASSERT_EQ(2U, applist->items().size());
// Check Drive app 1 // Check Drive app 1
const AppResource& app1 = *applist->items()[0]; const AppResource& app1 = *applist->items()[0];
EXPECT_EQ("123456788192", app1.id()); EXPECT_EQ("123456788192", app1.application_id());
EXPECT_EQ("Drive app 1", app1.name()); EXPECT_EQ("Drive app 1", app1.name());
EXPECT_EQ("", app1.object_type()); EXPECT_EQ("", app1.object_type());
EXPECT_TRUE(app1.supports_create()); EXPECT_TRUE(app1.supports_create());
EXPECT_TRUE(app1.supports_import()); EXPECT_TRUE(app1.supports_import());
EXPECT_TRUE(app1.is_installed()); EXPECT_TRUE(app1.is_installed());
EXPECT_FALSE(app1.is_authorized()); EXPECT_FALSE(app1.is_authorized());
EXPECT_EQ("https://chrome.google.com/webstore/detail/" EXPECT_EQ("https://chrome.google.com/webstore/detail/"
"abcdefghabcdefghabcdefghabcdefgh", "abcdefghabcdefghabcdefghabcdefgh",
app1.product_url().spec()); app1.product_url().spec());
IF_EXPECT_EQ(1U, app1.primary_mimetypes().size()) { ASSERT_EQ(1U, app1.primary_mimetypes().size());
EXPECT_EQ("application/vnd.google-apps.drive-sdk.123456788192", EXPECT_EQ("application/vnd.google-apps.drive-sdk.123456788192",
*app1.primary_mimetypes()[0]); *app1.primary_mimetypes()[0]);
}
ASSERT_EQ(2U, app1.secondary_mimetypes().size());
IF_EXPECT_EQ(2U, app1.secondary_mimetypes().size()) { EXPECT_EQ("text/html", *app1.secondary_mimetypes()[0]);
EXPECT_EQ("text/html", *app1.secondary_mimetypes()[0]); EXPECT_EQ("text/plain", *app1.secondary_mimetypes()[1]);
EXPECT_EQ("text/plain", *app1.secondary_mimetypes()[1]);
} ASSERT_EQ(2U, app1.primary_file_extensions().size());
EXPECT_EQ("exe", *app1.primary_file_extensions()[0]);
IF_EXPECT_EQ(2U, app1.primary_file_extensions().size()) { EXPECT_EQ("com", *app1.primary_file_extensions()[1]);
EXPECT_EQ("exe", *app1.primary_file_extensions()[0]);
EXPECT_EQ("com", *app1.primary_file_extensions()[1]); EXPECT_EQ(0U, app1.secondary_file_extensions().size());
}
ASSERT_EQ(6U, app1.icons().size());
EXPECT_EQ(0U, app1.secondary_file_extensions().size()); const DriveAppIcon& icon1 = *app1.icons()[0];
EXPECT_EQ(DriveAppIcon::APPLICATION, icon1.category());
IF_EXPECT_EQ(6U, app1.icons().size()) { EXPECT_EQ(10, icon1.icon_side_length());
const DriveAppIcon& icon1 = *app1.icons()[0]; EXPECT_EQ("http://www.example.com/10.png", icon1.icon_url().spec());
EXPECT_EQ(DriveAppIcon::APPLICATION, icon1.category());
EXPECT_EQ(10, icon1.icon_side_length()); const DriveAppIcon& icon6 = *app1.icons()[5];
EXPECT_EQ("http://www.example.com/10.png", icon1.icon_url().spec()); EXPECT_EQ(DriveAppIcon::SHARED_DOCUMENT, icon6.category());
EXPECT_EQ(16, icon6.icon_side_length());
const DriveAppIcon& icon6 = *app1.icons()[5]; EXPECT_EQ("http://www.example.com/ds16.png", icon6.icon_url().spec());
EXPECT_EQ(DriveAppIcon::SHARED_DOCUMENT, icon6.category());
EXPECT_EQ(16, icon6.icon_side_length()); // Check Drive app 2
EXPECT_EQ("http://www.example.com/ds16.png", icon6.icon_url().spec()); const AppResource& app2 = *applist->items()[1];
} EXPECT_EQ("876543210000", app2.application_id());
EXPECT_EQ("Drive app 2", app2.name());
// Check Drive app 2 EXPECT_EQ("", app2.object_type());
const AppResource& app2 = *applist->items()[1]; EXPECT_FALSE(app2.supports_create());
EXPECT_EQ("876543210000", app2.id()); EXPECT_FALSE(app2.supports_import());
EXPECT_EQ("Drive app 2", app2.name()); EXPECT_TRUE(app2.is_installed());
EXPECT_EQ("", app2.object_type()); EXPECT_FALSE(app2.is_authorized());
EXPECT_FALSE(app2.supports_create()); EXPECT_EQ("https://chrome.google.com/webstore/detail/"
EXPECT_FALSE(app2.supports_import()); "hgfedcbahgfedcbahgfedcbahgfedcba",
EXPECT_TRUE(app2.is_installed()); app2.product_url().spec());
EXPECT_FALSE(app2.is_authorized());
EXPECT_EQ("https://chrome.google.com/webstore/detail/" ASSERT_EQ(3U, app2.primary_mimetypes().size());
"hgfedcbahgfedcbahgfedcbahgfedcba", EXPECT_EQ("image/jpeg", *app2.primary_mimetypes()[0]);
app2.product_url().spec()); EXPECT_EQ("image/png", *app2.primary_mimetypes()[1]);
EXPECT_EQ("application/vnd.google-apps.drive-sdk.876543210000",
IF_EXPECT_EQ(3U, app2.primary_mimetypes().size()) { *app2.primary_mimetypes()[2]);
EXPECT_EQ("image/jpeg",
*app2.primary_mimetypes()[0]); EXPECT_EQ(0U, app2.secondary_mimetypes().size());
EXPECT_EQ("image/png", EXPECT_EQ(0U, app2.primary_file_extensions().size());
*app2.primary_mimetypes()[1]); EXPECT_EQ(0U, app2.secondary_file_extensions().size());
EXPECT_EQ("application/vnd.google-apps.drive-sdk.876543210000",
*app2.primary_mimetypes()[2]); ASSERT_EQ(3U, app2.icons().size());
} const DriveAppIcon& icon2 = *app2.icons()[1];
EXPECT_EQ(DriveAppIcon::DOCUMENT, icon2.category());
EXPECT_EQ(0U, app2.secondary_mimetypes().size()); EXPECT_EQ(10, icon2.icon_side_length());
EXPECT_EQ(0U, app2.primary_file_extensions().size()); EXPECT_EQ("http://www.example.com/d10.png", icon2.icon_url().spec());
EXPECT_EQ(0U, app2.secondary_file_extensions().size()); }
IF_EXPECT_EQ(3U, app2.icons().size()) { // Test file list parsing.
const DriveAppIcon& icon2 = *app2.icons()[1]; TEST_F(DriveAPIParserTest, FileListParser) {
EXPECT_EQ(DriveAppIcon::DOCUMENT, icon2.category()); std::string error;
EXPECT_EQ(10, icon2.icon_side_length()); scoped_ptr<Value> document(LoadJSONFile("filelist.json"));
EXPECT_EQ("http://www.example.com/d10.png", icon2.icon_url().spec()); ASSERT_TRUE(document.get());
}
} ASSERT_EQ(Value::TYPE_DICTIONARY, document->GetType());
scoped_ptr<FileList> filelist(new FileList);
EXPECT_TRUE(filelist->Parse(*document));
EXPECT_EQ("\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/zyHTfoHpnRHovyi8bWpwK0DXABC\"",
filelist->etag());
EXPECT_EQ("EAIaggELEgA6egpi96It9mH_____f_8AAP__AAD_okhU-cHLz83KzszMxsjMzs_Ry"
"NGJnridyrbHs7u9tv8AAP__AP7__n__AP8AokhU-cHLz83KzszMxsjMzs_RyNGJnr"
"idyrbHs7u9tv8A__4QZCEiXPTi_wtIgTkAAAAAngnSXUgCDEAAIgsJPgart10AAAA"
"ABC", filelist->next_page_token());
EXPECT_EQ(GURL("https://www.googleapis.com/drive/v2/files?pageToken=EAIaggEL"
"EgA6egpi96It9mH_____f_8AAP__AAD_okhU-cHLz83KzszMxsjMzs_RyNGJ"
"nridyrbHs7u9tv8AAP__AP7__n__AP8AokhU-cHLz83KzszMxsjMzs_RyNGJ"
"nridyrbHs7u9tv8A__4QZCEiXPTi_wtIgTkAAAAAngnSXUgCDEAAIgsJPgar"
"t10AAAAABC"), filelist->next_link());
ASSERT_EQ(3U, filelist->items().size());
// Check file 1 (a file)
const FileResource& file1 = *filelist->items()[0];
EXPECT_EQ("0B4v7G8yEYAWHUmRrU2lMS2hLABC", file1.file_id());
EXPECT_EQ("\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/MTM0MzM2NzgwMDIXYZ\"",
file1.etag());
EXPECT_EQ("My first file data", file1.title());
EXPECT_EQ("application/octet-stream", file1.mime_type());
base::Time modified_time;
ASSERT_TRUE(gdata::util::GetTimeFromString("2012-07-27T05:43:20.269Z",
&modified_time));
EXPECT_EQ(modified_time, file1.modified_by_me_date());
EXPECT_EQ(GURL("https://www.example.com/download"), file1.download_url());
EXPECT_EQ("ext", file1.file_extension());
EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", file1.md5_checksum());
EXPECT_EQ(1000U, file1.file_size());
// Check file 2 (a Google Document)
const FileResource& file2 = *filelist->items()[1];
EXPECT_EQ("Test Google Document", file2.title());
EXPECT_EQ("application/vnd.google-apps.document", file2.mime_type());
EXPECT_EQ(0U, file2.file_size());
// Check file 3 (a folder)
const FileResource& file3 = *filelist->items()[2];
EXPECT_EQ(0U, file3.file_size());
EXPECT_EQ("TestFolder", file3.title());
EXPECT_EQ("application/vnd.google-apps.folder", file3.mime_type());
ASSERT_TRUE(file3.IsDirectory());
} }
} // namespace gdata } // namespace gdata
{
"kind": "drive#fileList",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/zyHTfoHpnRHovyi8bWpwK0DXABC\"",
"selfLink": "https://www.googleapis.com/drive/v2/files",
"nextPageToken": "EAIaggELEgA6egpi96It9mH_____f_8AAP__AAD_okhU-cHLz83KzszMxsjMzs_RyNGJnridyrbHs7u9tv8AAP__AP7__n__AP8AokhU-cHLz83KzszMxsjMzs_RyNGJnridyrbHs7u9tv8A__4QZCEiXPTi_wtIgTkAAAAAngnSXUgCDEAAIgsJPgart10AAAAABC",
"nextLink": "https://www.googleapis.com/drive/v2/files?pageToken=EAIaggELEgA6egpi96It9mH_____f_8AAP__AAD_okhU-cHLz83KzszMxsjMzs_RyNGJnridyrbHs7u9tv8AAP__AP7__n__AP8AokhU-cHLz83KzszMxsjMzs_RyNGJnridyrbHs7u9tv8A__4QZCEiXPTi_wtIgTkAAAAAngnSXUgCDEAAIgsJPgart10AAAAABC",
"items": [
{
"kind": "drive#file",
"id": "0B4v7G8yEYAWHUmRrU2lMS2hLABC",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/MTM0MzM2NzgwMDIXYZ\"",
"selfLink": "https://www.googleapis.com/drive/v2/files/0B4v7G8yEYAWHUmRrU2lMS2hLABC",
"webContentLink": "https://docs.google.com/uc?id=0B4v7G8yEYAWHUmRrU2lMS2hLABC&export=download",
"alternateLink": "https://docs.google.com/file/d/0B4v7G8yEYAWHUmRrU2lMS2hLABC/edit",
"title": "My first file data",
"mimeType": "application/octet-stream",
"labels": {
"starred": false,
"hidden": false,
"trashed": false,
"restricted": false,
"viewed": true
},
"createdDate": "2012-07-24T08:51:16.570Z",
"modifiedDate": "2012-07-27T05:43:20.269Z",
"modifiedByMeDate": "2012-07-27T05:43:20.269Z",
"lastViewedByMeDate": "2012-07-27T05:43:20.269Z",
"parents": [
{
"kind": "drive#parentReference",
"id": "0B4v7G8yEYAWHYW1OcExsUVZLABC",
"selfLink": "https://www.googleapis.com/drive/v2/files/0B4v7G8yEYAWHNGpYVHJINEFFABC/parents/0B4v7G8yEYAWHYW1OcExsUVZLABC",
"parentLink": "https://www.googleapis.com/drive/v2/files/0B4v7G8yEYAWHYW1OcExsUVZLABC",
"isRoot": false
}
],
"downloadUrl": "https://www.example.com/download",
"userPermission": {
"kind": "drive#permission",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/LKOJhhwatz2OKj-OblM3EvO8XYZ\"",
"id": "me",
"role": "owner",
"type": "user"
},
"originalFilename": "Untitled Document.ext",
"fileExtension": "ext",
"md5Checksum": "d41d8cd98f00b204e9800998ecf8427e",
"fileSize": "1000",
"quotaBytesUsed": "1000",
"ownerNames": [
"Test User"
],
"lastModifyingUserName": "Test User",
"editable": true,
"writersCanShare": true
},
{
"kind": "drive#file",
"id": "1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/MTM0MzM2NDg1MTAXYZ\"",
"selfLink": "https://www.googleapis.com/drive/v2/files/1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC",
"alternateLink": "https://docs.google.com/a/chromium.org/document/d/1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC/edit",
"embedLink": "https://docs.google.com/a/chromium.org/document/d/1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC/preview",
"thumbnailLink": "https://docs.google.com/feeds/vt?gd=true&id=1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC&v=3&s=AMedNnoAAAAAUBJyB0g8HbxZaLRnlztxefZPS24LiXYZ&sz=s220",
"title": "Test Google Document",
"mimeType": "application/vnd.google-apps.document",
"labels": {
"starred": true,
"hidden": false,
"trashed": false,
"restricted": false,
"viewed": true
},
"createdDate": "2012-07-27T04:54:09.686Z",
"modifiedDate": "2012-07-27T04:54:11.030Z",
"modifiedByMeDate": "2012-07-27T04:54:11.030Z",
"lastViewedByMeDate": "2012-07-27T04:54:11.030Z",
"parents": [
{
"kind": "drive#parentReference",
"id": "0AIv7G8yEYAWHUk9ABC",
"selfLink": "https://www.googleapis.com/drive/v2/files/1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC/parents/0AIv7G8yEYAWHUk9ABC",
"parentLink": "https://www.googleapis.com/drive/v2/files/0AIv7G8yEYAWHUk9ABC",
"isRoot": true
}
],
"exportLinks": {
"application/msword": "https://docs.google.com/feeds/download/documents/export/Export?id=1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC&exportFormat=doc",
"text/html": "https://docs.google.com/feeds/download/documents/export/Export?id=1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC&exportFormat=html",
"application/pdf": "https://docs.google.com/feeds/download/documents/export/Export?id=1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC&exportFormat=pdf"
},
"userPermission": {
"kind": "drive#permission",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/LKOJhhwatz2OKj-OblM3EvO8XYZ\"",
"id": "me",
"role": "owner",
"type": "user"
},
"quotaBytesUsed": "0",
"ownerNames": [
"Test User"
],
"lastModifyingUserName": "Test User",
"editable": true,
"writersCanShare": true
},
{
"kind": "drive#file",
"id": "0B4v7G8yEYAWHYW1OcExsUVZLABC",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/MTM0MzM2NDE5ODUXYZ\"",
"selfLink": "https://www.googleapis.com/drive/v2/files/0B4v7G8yEYAWHYW1OcExsUVZLABC",
"alternateLink": "https://docs.google.com/a/chromium.org/folder/d/0B4v7G8yEYAWHYW1OcExsUVZLABC/edit",
"title": "TestFolder",
"mimeType": "application/vnd.google-apps.folder",
"labels": {
"starred": false,
"hidden": false,
"trashed": false,
"restricted": false,
"viewed": true
},
"createdDate": "2012-07-02T09:53:18.422Z",
"modifiedDate": "2012-07-27T04:43:18.507Z",
"modifiedByMeDate": "2012-07-27T04:43:18.507Z",
"lastViewedByMeDate": "2012-07-27T04:40:52.371Z",
"parents": [
{
"kind": "drive#parentReference",
"id": "0AIv7G8yEYAWHUk9ABC",
"selfLink": "https://www.googleapis.com/drive/v2/files/0B4v7G8yEYAWHYW1OcExsUVZLABC/parents/0AIv7G8yEYAWHUk9ABC",
"parentLink": "https://www.googleapis.com/drive/v2/files/0AIv7G8yEYAWHUk9ABC",
"isRoot": true
}
],
"userPermission": {
"kind": "drive#permission",
"etag": "\"WtRjAPZWbDA7_fkFjc5ojsEvDEF/LKOJhhwatz2OKj-OblM3EvO8XYZ\"",
"id": "me",
"role": "owner",
"type": "user"
},
"quotaBytesUsed": "0",
"ownerNames": [
"Test User"
],
"lastModifyingUserName": "Test User",
"editable": true,
"writersCanShare": true
}
]
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment