Unable to update file in appDataFolder using Google Drive REST API V3 on Android - google-drive-api

This is the code i'm using to update the file.
File metadata = generateFileMetadata(fileId, thumbnail, properties);
return mService.files().update(fileId, metadata, generateFileContents())
.setFields("id, name, appProperties")
.execute();
This code generates a
java.lang.IllegalArgumentException.
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:111)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
at com.google.api.client.googleapis.media.MediaHttpUploader.setInitiationRequestMethod(MediaHttpUploader.java:872)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.initializeMediaUpload(AbstractGoogleClientRequest.java:237)
at com.google.api.services.drive.Drive$Files$Update.<init>(Drive.java:3163)
at com.google.api.services.drive.Drive$Files.update(Drive.java:3113)
Using breakpoints I could see that the String passed to the setInitiationRequestMethod is PATCH (not POST or PUT):
public MediaHttpUploader setInitiationRequestMethod(String initiationRequestMethod) {
Preconditions.checkArgument(initiationRequestMethod.equals(HttpMethods.POST)
|| initiationRequestMethod.equals(HttpMethods.PUT));
this.initiationRequestMethod = initiationRequestMethod;
return this;
}
this is what i have in my build.gradle
compile 'com.google.android.gms:play-services-identity:8.4.0'
compile('com.google.api-client:google-api-client-android:1.21.0') {
exclude group: 'org.apache.httpcomponents'
}
compile('com.google.apis:google-api-services-drive:v3-rev11-1.21.0') {
exclude group: 'org.apache.httpcomponents'
}
if I remove the file content (generateFileContents()) I'm able to update the metadata just fine.
How do I solve this?

I ran into this bug while writing a Drive REST API integration for an Android app (with Android Studio/Gradle). Since I'm not particularly experienced with Android's build system, resolving the issue cost me a few hours. Maybe this helps somebody with the same problem:
Clone the google-api-java-client repo from GitHub https://github.com/google/google-api-java-client
Install Maven https://maven.apache.org/run-maven/ (e.g. brew install maven on OSX)
On the command line, change into the google-api-client sub dir of the repo you cloned above
Run mvn clean install
This will produce a subdir called target in the google-api-client directory
In there, find google-api-client-1.22.0-SNAPSHOT.jar, rename it to google-api-client-1.21.00.jar (the renaming is probably not needed)
Drop the .jar in the libs folder of your android project
Tell Gradle to ignore the google-api-client dependency of the libraries you use, in my case this was:
compile('com.google.api-client:google-api-client-android:1.21.0') {
exclude group: 'org.apache.httpcomponents'
exclude module: 'google-api-client'
}
compile('com.google.apis:google-api-services-drive:v3-rev14-1.21.0') {
exclude group: 'org.apache.httpcomponents'
exclude module: 'google-api-client'
}
Add the Jackson dependency again, in case you miss it now. Do the same with other google-api-java-client dependencies if you need them.
compile('com.google.http-client:google-http-client-jackson2:1.21.0'){
exclude group: 'org.apache.httpcomponents'
}
Build your project, update(...) should now work.
Make a note to scrap these changes once Google has updated the library.

Take a look at the current commit of the google-api-java-client.
Unfortunately the fix was not released yet (fix on 21 Nov 2015 vs release on 19 Nov 2015), so you may have to build locally the project (with maven for instance)

The MediaHttpUploader javadocs suggests that it will only be used for HttpMethods#POST, and HttpMethods#UPDATE. Using update, based on the Files resource, indicates its using a PATCH method - leading to the IllegalArgumentException.
The overridden update method should only be used if you're uploading media content.

I have the same exception in a Desktop application.
Instead, using the Drive Api V2, the update goes well.

Related

htmlToImage Chrome 64 SecurityError: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules

The new Chrome 64 security update seems to have broken the htmlToImage libraries. None of the styling is correctly calculated and is rendered as if no styling was applied at all.
Does anyone know of a workaround / fix? Do I need to put my CSS on the server and allow CORS?
I just fixed this error.
Forked the lib and made a pull request. Until it gets merged, you can use the forked repo: https://github.com/kmap-io/html-to-image
by replacing the target of html-to-image in your package.json with:
"html-to-image": "git+https://github.com/kmap-io/html-to-image.git"
About the bug
Chrome is complaining (throws an error) about trying to read a property that does not exist. Firefox also complains, but they only throw a warning, instead of an error. The fix consists of replacing
if (sheet.cssRules) {
...
with
if (sheet.hasOwnProperty('cssRules')) {
...
There is no downside (i.e.: when cssRules exists on sheet - which is a stylesheet - the script iterates through the rules and adds them to document, as supposed to).
How to patch (until it gets merged).
For some reason, simply replacing the library's repo with the fork in which I committed the change doesn't work for this package. I asked the lib's author to add instructions on how to build after a pull-request, as they state in the readme pull requests and contributions are welcome. Until then, here's how to apply the fix using patch-package:
add "prepare": "patch-package" inside scripts, in your project's package.json
npm i patch-package --save-dev
In node_modules/html-to-image/lib/embedWebFonts.js, change line 7 from
try {
to
if (sheet.hasOwnProperty('cssRules')) try {
npx patch-package html-to-image
If you have a deployment script that builds your project from scratch, you'll need to apply the patches right before you call npm run build (or similar, depending on your stack):
git apply --ignore-whitespace patches/*.patch
That's about it.
When the fix will be merged, you'll need to run:
npx patch-package html-to-image --reverse

How to enable autocomplete for Google Apps Script in locally-installed IDE

I'm trying to build GAS projects locally using clasp.
Any locally-installed IDE is a huge improvement over Google's Script Editor, so the tool looks very promising. Unfortunately, the autocomplete feature for GAS services doesn't seem to be included in the package.
The documentation says:
The Apps Script CLI uses TypeScript to provide autocompletion and linting when developing. Use an IDE like Visual Studio Code for TypeScript autocompletion.
After going through the steps and installing all required dependencies, I'm still unable to get the autocomplete feature to work. When I execute the clasp pull command for the existing project, it converts the ".gs" extension to ".js". The autocomplete suggestions are simply the result of parsing existing code.
For example, if I call sheet.getRange() somewhere in my code, then the getRange() method will pop up in suggestions, but I can't list available options for, say, PropertiesService, unless it's already used in my code.
Has anybody had any luck with enabling autocomplete feature for Google Apps Script?
I found the solution that partially works, but it may not be applicable to other software. The steps below are for Visual Studio Code:
Install the NPM package containing type definitions for GAS using
https://www.npmjs.com/package/#types/google-apps-script
In your locally-saved script, create a '.js' file and type
import 'google-apps-script';
This answer is a minor variation on the accepted one for IDEs/extensions which support Typescript auto completion based on tsc/tsserver:
Install TypeScript and #types/google-apps-script
https://www.npmjs.com/package/typescript
https://www.npmjs.com/package/#types/google-apps-script
Create a jsconfig.json file in your local project directory:
{
"compilerOptions": {
"checkJs": true
}
}
Alternatively, If you're using typescript along with javascript, then create a tsconfig.json:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"types": ["google-apps-script"]
}
}
Include both filenames in .claspignore, if you're using clasp and if the file is in your local directory.
You can also use any of this config globally, if the config is in your home/parent directory, as tsc searches for this config from project/local folder to root(in which case, you don't need to include it in .claspignore).
If you are using any JetBrains IDE:
Go to Languages & Frameworks -> JavaScript -> Libraries -> Download... and download the library google-apps-script.
Try including the file name, import.js in .claspignore (docs).
This should save some trouble deleting the file before each push every time.
This is an answer provided by Google developers in the "TU17: Enhancing the Google Apps Script Developer Experience with clasp and TypeScript" video.
Add a JavaScript file to your project like "appscript.js" and, in that file, add:
import "google-apps-script";
Save that file but make sure to ignore it when pushing files back to your project using a .claspignore file.

How to validate JSON in Gradle build

I have a Gradle build where a large JSON configuration is bundled into a package for later upload onto a server. Sometimes when changes are made to the file, the file is not valid any more and thus fails to upload on the server.
I would like to find this earlier by adding a validate-step in the Gradle build.
When looking around I could not find a documented way to do this, I saw the project gradle-json-validator which looks promising, but there is no documentation whatsoever, so I am not sure how this can be used...
Any hint on gradle-json-validator or any other way to validate a JSON file as part of the Gradle build steps?
From source, it would seem, the usage would be:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'cz.alenkacz.gradle:json-validator:0.9.9'
}
}
apply plugin: 'cz.alenkacz.gradle.jsonvalidator'
The plugin doesn't seem to have an extension to do configuration. But seems to use jsonSchema and targetJsonFile as input schema and file-to-validate. I would try setting them at the root level of build.gradle
validateJson.jsonSchema = new File('/path/to/schema')
validateJson.targetJsonFile = new File('/path/to/jsonFile')
and the task to run is:
gradle validateJson
I have improved the readme file in the repository with proper usage example.
Hope that helps. https://github.com/alenkacz/gradle-json-validator

How to get the checkout directory of project dependencies in TeamCity?

I am using TeamCity as build server and have a little trouble when configuring projects and their dependencies.
Eventually I want to get the checkout directory of project dependencies to configure certain build steps. For that I have the variable %teamcity.build.checkoutDir% for the checkout directory of the project itself.
However, I did not find something like %dep.<dependencyID>.teamcity.build.checkoutDir%.
Is there a way to get the checkout directory of a dependency?
You can add a parameter (say checkoutDir ) in the first build whose value is equal to %teamcity.build.checkoutDir% . You can then fetch this value in the dependent build (either through snapshot or artefact dependency)
I am using this myself and I can access my dependent Build's Checkout directory with...
%dep.<dependecyID>.teamcity.build.default.checkoutDir%
I believe this will only work with a Snapshot Dependency though

Cocoa Pods and Google Maps SDK

When using CocoaPods to get the Google Maps SDK for iOS, I'm having troubles importing the sdk header file (#import <GoogleMaps/GoogleMaps.h>).
I'm new to CocoaPods but I think I have everything working fine with the other libraries that I use (RestKit, AFNetworking...).
For these APIs I still need to import the lib like this #import <AFNetworking/AFNetworking.h> instead of just #import "AFNetworking". But it works fine.
For Google Maps SDK I need to import it like this #import <Google-Maps-iOS-SDK/GoogleMaps/GoogleMaps.h> which leads to a compilation error because in the GoogleMaps.h header the other files are imported like this:
#import <GoogleMaps/GMSCameraPosition.h>
#import <GoogleMaps/GMSCameraUpdate.h>
#import <GoogleMaps/GMSCircle.h>
...
Did I miss something?
You should not have to import anything linked with CocoaPods using < and >. It should simply be #import "Foo.h". In the case of Google Maps based on my test project I just had to use #import "GoogleMaps.h" and it imported correctly. Make sure you're installing with the newest version of CocoaPods (pod --version currently 0.21.0) otherwise you may need to update it ([sudo] gem update). Also make sure you're opening the created xcworkspace file instead of the xcodeproject
I ran into the same issue(and am using cocoapods), specifically where the error "GoogleMaps.h" file not found. My solution(if the above fails to work), is that your Pods' Target Support Files fail to include the correct header path for "GoogleMaps.h".
Step #1
If you examine your project directory in Finder, click on Pods directory, then Public directory, then GoogleMaps directory, you'll notice that there is a second GoogleMaps directory. Inside that second GoogleMaps directory contains the header files pertaining to the GoogleMaps pod. Now time to check that Pods target support files have this path as the header path for GoogleMaps.
Step #2
Close Xcode Project. Go to the parent directory of your project. For me, it's my home directory, which can be reached at cd ~. Traverse into your Pods' Target support files:
cd ~/{your_project_name}/Pods/Target Support Files/Pods
Then open up your Pods.debug.xcconfig file in your favorite editor:
vi Pods.debug.xcconfig
Edit the line
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/GoogleMaps"
with the new header path
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/GoogleMaps/GoogleMaps"
Leave the rest of the Pods.debug.xcconfig untouched. Follow this same process for Pods.release.xcconfig.
Step #3
Re-open your .xcworkspace file. Clean your project(cmd-shift-k) and then re-build(cmd-b).