diff options
author | kochi@chromium.org <kochi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-01 05:20:41 +0000 |
---|---|---|
committer | kochi@chromium.org <kochi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-01 05:20:41 +0000 |
commit | 13221a10ea133d5d9187d26e7a28a581ddceacdb (patch) | |
tree | 8a1012d60448a9b3d78e226295728ffc7837dab2 /chrome | |
parent | caa5c4df48a4c02d79d6998f811c29fb4ec776f4 (diff) | |
download | chromium_src-13221a10ea133d5d9187d26e7a28a581ddceacdb.zip chromium_src-13221a10ea133d5d9187d26e7a28a581ddceacdb.tar.gz chromium_src-13221a10ea133d5d9187d26e7a28a581ddceacdb.tar.bz2 |
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
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/chromeos/gdata/drive_api_parser.cc | 115 | ||||
-rw-r--r-- | chrome/browser/chromeos/gdata/drive_api_parser.h | 113 | ||||
-rw-r--r-- | chrome/browser/chromeos/gdata/drive_api_parser_unittest.cc | 206 | ||||
-rw-r--r-- | chrome/test/data/chromeos/drive/filelist.json | 151 |
4 files changed, 495 insertions, 90 deletions
diff --git a/chrome/browser/chromeos/gdata/drive_api_parser.cc b/chrome/browser/chromeos/gdata/drive_api_parser.cc index 6f1cf75..6fbc0bf 100644 --- a/chrome/browser/chromeos/gdata/drive_api_parser.cc +++ b/chrome/browser/chromeos/gdata/drive_api_parser.cc @@ -34,6 +34,9 @@ bool GetGURLFromString(const base::StringPiece& url_string, GURL* result) { // Common const char kKind[] = "kind"; +const char kId[] = "id"; +const char kETag[] = "etag"; +const char kItems[] = "items"; // About Resource: const char kAboutKind[] = "drive#about"; @@ -49,8 +52,6 @@ const char kIconUrl[] = "iconUrl"; // Apps Resource: const char kAppKind[] = "drive#app"; -const char kId[] = "id"; -const char kETag[] = "etag"; const char kName[] = "name"; const char kObjectType[] = "objectType"; const char kSupportsCreate[] = "supportsCreate"; @@ -66,8 +67,23 @@ const char kIcons[] = "icons"; // Apps List: 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. struct AppIconCategoryMap { @@ -205,7 +221,7 @@ AppResource::~AppResource() {} // static void AppResource::RegisterJSONConverter( base::JSONValueConverter<AppResource>* converter) { - converter->RegisterStringField(kId, &AppResource::id_); + converter->RegisterStringField(kId, &AppResource::application_id_); converter->RegisterStringField(kName, &AppResource::name_); converter->RegisterStringField(kObjectType, &AppResource::object_type_); converter->RegisterBoolField(kSupportsCreate, &AppResource::supports_create_); @@ -279,4 +295,95 @@ bool AppList::Parse(const base::Value& value) { 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 diff --git a/chrome/browser/chromeos/gdata/drive_api_parser.h b/chrome/browser/chromeos/gdata/drive_api_parser.h index 097f4b8..e1b08f8 100644 --- a/chrome/browser/chromeos/gdata/drive_api_parser.h +++ b/chrome/browser/chromeos/gdata/drive_api_parser.h @@ -136,7 +136,7 @@ class AppResource { static scoped_ptr<AppResource> CreateFrom(const base::Value& value); // 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. const std::string& name() const { return name_; } @@ -205,7 +205,7 @@ class AppResource { // Return false if parsing fails. bool Parse(const base::Value& value); - std::string id_; + std::string application_id_; std::string name_; std::string object_type_; bool supports_create_; @@ -257,6 +257,115 @@ class 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 #endif // CHROME_BROWSER_CHROMEOS_GDATA_DRIVE_API_PARSER_H_ diff --git a/chrome/browser/chromeos/gdata/drive_api_parser_unittest.cc b/chrome/browser/chromeos/gdata/drive_api_parser_unittest.cc index 61dc97b..d939ab1 100644 --- a/chrome/browser/chromeos/gdata/drive_api_parser_unittest.cc +++ b/chrome/browser/chromeos/gdata/drive_api_parser_unittest.cc @@ -11,6 +11,7 @@ #include "base/utf_string_conversions.h" #include "base/values.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 "testing/gtest/include/gtest/gtest.h" @@ -18,14 +19,6 @@ using base::Value; using base::DictionaryValue; 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 { class DriveAPIParserTest : public testing::Test { @@ -77,82 +70,127 @@ TEST_F(DriveAPIParserTest, AppListParser) { EXPECT_EQ("\"Jm4BaSnCWNND-noZsHINRqj4ABC/tuqRBw0lvjUdPtc_2msA1tN4XYZ\"", applist->etag()); - IF_EXPECT_EQ(2U, applist->items().size()) { - // Check Drive app 1 - const AppResource& app1 = *applist->items()[0]; - EXPECT_EQ("123456788192", app1.id()); - EXPECT_EQ("Drive app 1", app1.name()); - EXPECT_EQ("", app1.object_type()); - EXPECT_TRUE(app1.supports_create()); - EXPECT_TRUE(app1.supports_import()); - EXPECT_TRUE(app1.is_installed()); - EXPECT_FALSE(app1.is_authorized()); - EXPECT_EQ("https://chrome.google.com/webstore/detail/" - "abcdefghabcdefghabcdefghabcdefgh", - app1.product_url().spec()); - - IF_EXPECT_EQ(1U, app1.primary_mimetypes().size()) { - EXPECT_EQ("application/vnd.google-apps.drive-sdk.123456788192", - *app1.primary_mimetypes()[0]); - } - - IF_EXPECT_EQ(2U, app1.secondary_mimetypes().size()) { - EXPECT_EQ("text/html", *app1.secondary_mimetypes()[0]); - EXPECT_EQ("text/plain", *app1.secondary_mimetypes()[1]); - } - - IF_EXPECT_EQ(2U, app1.primary_file_extensions().size()) { - EXPECT_EQ("exe", *app1.primary_file_extensions()[0]); - EXPECT_EQ("com", *app1.primary_file_extensions()[1]); - } - - EXPECT_EQ(0U, app1.secondary_file_extensions().size()); - - IF_EXPECT_EQ(6U, app1.icons().size()) { - const DriveAppIcon& icon1 = *app1.icons()[0]; - EXPECT_EQ(DriveAppIcon::APPLICATION, icon1.category()); - EXPECT_EQ(10, icon1.icon_side_length()); - EXPECT_EQ("http://www.example.com/10.png", icon1.icon_url().spec()); - - const DriveAppIcon& icon6 = *app1.icons()[5]; - EXPECT_EQ(DriveAppIcon::SHARED_DOCUMENT, icon6.category()); - EXPECT_EQ(16, icon6.icon_side_length()); - EXPECT_EQ("http://www.example.com/ds16.png", icon6.icon_url().spec()); - } - - // Check Drive app 2 - const AppResource& app2 = *applist->items()[1]; - EXPECT_EQ("876543210000", app2.id()); - EXPECT_EQ("Drive app 2", app2.name()); - EXPECT_EQ("", app2.object_type()); - EXPECT_FALSE(app2.supports_create()); - EXPECT_FALSE(app2.supports_import()); - EXPECT_TRUE(app2.is_installed()); - EXPECT_FALSE(app2.is_authorized()); - EXPECT_EQ("https://chrome.google.com/webstore/detail/" - "hgfedcbahgfedcbahgfedcbahgfedcba", - app2.product_url().spec()); - - IF_EXPECT_EQ(3U, app2.primary_mimetypes().size()) { - EXPECT_EQ("image/jpeg", - *app2.primary_mimetypes()[0]); - EXPECT_EQ("image/png", - *app2.primary_mimetypes()[1]); - EXPECT_EQ("application/vnd.google-apps.drive-sdk.876543210000", - *app2.primary_mimetypes()[2]); - } - - EXPECT_EQ(0U, app2.secondary_mimetypes().size()); - EXPECT_EQ(0U, app2.primary_file_extensions().size()); - EXPECT_EQ(0U, app2.secondary_file_extensions().size()); - - IF_EXPECT_EQ(3U, app2.icons().size()) { - const DriveAppIcon& icon2 = *app2.icons()[1]; - EXPECT_EQ(DriveAppIcon::DOCUMENT, icon2.category()); - EXPECT_EQ(10, icon2.icon_side_length()); - EXPECT_EQ("http://www.example.com/d10.png", icon2.icon_url().spec()); - } - } + ASSERT_EQ(2U, applist->items().size()); + // Check Drive app 1 + const AppResource& app1 = *applist->items()[0]; + EXPECT_EQ("123456788192", app1.application_id()); + EXPECT_EQ("Drive app 1", app1.name()); + EXPECT_EQ("", app1.object_type()); + EXPECT_TRUE(app1.supports_create()); + EXPECT_TRUE(app1.supports_import()); + EXPECT_TRUE(app1.is_installed()); + EXPECT_FALSE(app1.is_authorized()); + EXPECT_EQ("https://chrome.google.com/webstore/detail/" + "abcdefghabcdefghabcdefghabcdefgh", + app1.product_url().spec()); + + ASSERT_EQ(1U, app1.primary_mimetypes().size()); + EXPECT_EQ("application/vnd.google-apps.drive-sdk.123456788192", + *app1.primary_mimetypes()[0]); + + ASSERT_EQ(2U, app1.secondary_mimetypes().size()); + EXPECT_EQ("text/html", *app1.secondary_mimetypes()[0]); + EXPECT_EQ("text/plain", *app1.secondary_mimetypes()[1]); + + ASSERT_EQ(2U, app1.primary_file_extensions().size()); + 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()); + const DriveAppIcon& icon1 = *app1.icons()[0]; + EXPECT_EQ(DriveAppIcon::APPLICATION, icon1.category()); + EXPECT_EQ(10, icon1.icon_side_length()); + EXPECT_EQ("http://www.example.com/10.png", icon1.icon_url().spec()); + + const DriveAppIcon& icon6 = *app1.icons()[5]; + EXPECT_EQ(DriveAppIcon::SHARED_DOCUMENT, icon6.category()); + EXPECT_EQ(16, icon6.icon_side_length()); + EXPECT_EQ("http://www.example.com/ds16.png", icon6.icon_url().spec()); + + // Check Drive app 2 + const AppResource& app2 = *applist->items()[1]; + EXPECT_EQ("876543210000", app2.application_id()); + EXPECT_EQ("Drive app 2", app2.name()); + EXPECT_EQ("", app2.object_type()); + EXPECT_FALSE(app2.supports_create()); + EXPECT_FALSE(app2.supports_import()); + EXPECT_TRUE(app2.is_installed()); + EXPECT_FALSE(app2.is_authorized()); + EXPECT_EQ("https://chrome.google.com/webstore/detail/" + "hgfedcbahgfedcbahgfedcbahgfedcba", + app2.product_url().spec()); + + ASSERT_EQ(3U, app2.primary_mimetypes().size()); + EXPECT_EQ("image/jpeg", *app2.primary_mimetypes()[0]); + EXPECT_EQ("image/png", *app2.primary_mimetypes()[1]); + EXPECT_EQ("application/vnd.google-apps.drive-sdk.876543210000", + *app2.primary_mimetypes()[2]); + + EXPECT_EQ(0U, app2.secondary_mimetypes().size()); + EXPECT_EQ(0U, app2.primary_file_extensions().size()); + EXPECT_EQ(0U, app2.secondary_file_extensions().size()); + + ASSERT_EQ(3U, app2.icons().size()); + const DriveAppIcon& icon2 = *app2.icons()[1]; + EXPECT_EQ(DriveAppIcon::DOCUMENT, icon2.category()); + EXPECT_EQ(10, icon2.icon_side_length()); + EXPECT_EQ("http://www.example.com/d10.png", icon2.icon_url().spec()); +} + +// Test file list parsing. +TEST_F(DriveAPIParserTest, FileListParser) { + std::string error; + scoped_ptr<Value> document(LoadJSONFile("filelist.json")); + 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 diff --git a/chrome/test/data/chromeos/drive/filelist.json b/chrome/test/data/chromeos/drive/filelist.json new file mode 100644 index 0000000..f6d2fd8 --- /dev/null +++ b/chrome/test/data/chromeos/drive/filelist.json @@ -0,0 +1,151 @@ +{ + "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 + } + ] +} |