Script for File upload in google drive - Error encountered: An unexpected error occurred - file-upload

I use a script to upload document into google spreadsheet and automatically put link to it into current cell. Since yesterday all was gone fine, but since this morning i receive this generic error:
https://docs.google.com
Error encountered: An unexpected error occurred
This is the code:
// upload document into google spreadsheet
// and put link to it into current cell
function onOpen(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var menuEntries = [];
menuEntries.push({name: "Accedi al modulo per allegare un file...", functionName: "doGet"});
ss.addMenu("Carica scheda di rilevazione dati...", menuEntries);
}
function doGet(e) {
var app = UiApp.createApplication().setTitle("FORM per il caricamento della scheda di rilevazione dati");
SpreadsheetApp.getActiveSpreadsheet().show(app);
var form = app.createFormPanel().setId('frm').setEncoding('multipart/form-data');
var formContent = app.createVerticalPanel();
form.add(formContent);
formContent.add(app.createFileUpload().setName('thefile'));
// these parameters need to be passed by form
// in doPost() these cannot be found out anymore
formContent.add(app.createHidden("activeCell", SpreadsheetApp.getActiveRange().getA1Notation()));
formContent.add(app.createHidden("activeSheet", SpreadsheetApp.getActiveSheet().getName()));
formContent.add(app.createHidden("activeSpreadsheet", SpreadsheetApp.getActiveSpreadsheet().getId()));
formContent.add(app.createSubmitButton('Invia ed archivia scheda'));
app.add(form);
SpreadsheetApp.getActiveSpreadsheet().show(app);
return app;
}
function doPost(e) {
var app = UiApp.getActiveApplication();
app.createLabel('sto salvando...');
var fileBlob = e.parameter.thefile;
var doc = DocsList.getFolderById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').createFile(fileBlob);
var label = app.createLabel('file caricato con successo');
// write value into current cell
var value = 'hyperlink("' + doc.getUrl() + '";"' + doc.getName() + '")'
var activeSpreadsheet = e.parameter.activeSpreadsheet;
var activeSheet = e.parameter.activeSheet;
var activeCell = e.parameter.activeCell;
var label = app.createLabel('file memorizzato correttamente');
app.add(label);
SpreadsheetApp.openById(activeSpreadsheet).getSheetByName(activeSheet).getRange(activeCell).setFormula(value);
app.close();
return app;
}

According to Your Question
Since yesterday all was gone fine, but since this morning i receive this generic error: https://docs.google.com Error encountered: An unexpected error occurred
According to Google developers page
So, I think problem may be in
var doc = DocsList.getFolderById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').createFile(fileBlob);
try to use DriveApp instead of DocList. more info

Related

AWS S3 CopyObjectAsync fails with key does not exist, but get/put succeeds

I fought with this for several hours and never found the solution. Here's the scenario:
var copyObjectRequest = new CopyObjectRequest
{
SourceBucket = s3Event.S3.Bucket.Name,
SourceKey = s3Event.S3.Object.Key,
DestinationBucket = OutputBucketName,
DestinationKey = s3Event.S3.Object.Key,
};
var deleteRequest = new DeleteObjectRequest
{
BucketName = copyObjectRequest.SourceBucket,
Key = copyObjectRequest.SourceKey,
};
await S3Client.CopyObjectAsync(copyObjectRequest);
await S3Client.DeleteObjectAsync(deleteRequest);
S3Client.CopyObjectAsync throws the error: "The specified key does not exist." (S3Client.DeleteObjectAsync is never reached.)
However, the following code works (for the same values):
var request = new GetObjectRequest
{
BucketName = copyObjectRequest.SourceBucket,
Key = copyObjectRequest.SourceKey,
};
var response = await S3Client.GetObjectAsync(request);
var tempPath = $"{Guid.NewGuid():D}";
await response.WriteResponseStreamToFileAsync(tempPath, false, CancellationToken.None);
var putRequest = new PutObjectRequest
{
BucketName = copyObjectRequest.DestinationBucket,
Key = copyObjectRequest.DestinationKey,
FilePath = tempPath,
};
var putResponse = await S3Client.PutObjectAsync(putRequest);
if (putResponse.HttpStatusCode == HttpStatusCode.OK)
{
var deleteRequest = new DeleteObjectRequest
{
BucketName = copyObjectRequest.SourceBucket,
Key = copyObjectRequest.SourceKey,
};
await S3Client.DeleteObjectAsync(deleteRequest);
}
For brevity I removed almost all error checking, logging, etc. but if requested I'm happy to share the full function.
Note that this is running in a C# Lambda Function, using Core 2.0.
I've ruled out security as the second set of calls requires the same permissions (I believe) as the CopyObject call does (please do correct me if I'm wrong).
There's no doubt the object is at the bucket and key specified as the second set uses the exact same structure.
The key doesn't exist in the destination bucket.
Both the source and destination buckets have the same permissions.
There are no special characters in the key (sample keys that I've tested are "/US/ID/Teton/EC2ClientDemo.zip" and "testkey").
The files I'm testing with are tiny (that sample file is 30Kb).
I've tried it with and without a CannedACL value in CopyObjectRequest (I don't think it should require one for my purposes, all the files it's moving around are private).
I've validated that all buckets are in the same region (USWest2).
I can't figure out why CopyObjectAsync fails. I've tried digging down through the disassembled code for CopyObjectAsync, but it's called so indirectly I didn't get very far. At this point my best guess is that it's a bug in CopyObjectAsync.
Any suggestions would be appreciated,
Thanks for reading!
Additional: I want to make it clear that this works from the regular AWSSDK library (either CopyObjectAsync or CopyObject), it only fails in the Core 2.0 async call CopyObjectAsync in the Lambda environment.
OK, so I figured it out and it is definitely a bug in the core 2.0 CopyObjectAsync(). Here's the scenario:
We are using keys that have slashes at the beginning, an example would be '/US/ID/Teton/EC2ClientDemo.zip'. When I turned on S3 logging (thank you #Michael-sqlbot) what I saw was this:
[13/Jul/2018:17:44:18 +0000] 34.221.84.59 arn:aws:sts::434371411556:assumed-role/LambdaFunctionCreation/TestFunction 489A5570C2E840AC REST.COPY.OBJECT_GET US/ID/Teton/EC2ClientDemo.zip - 404 NoSuchKey
As you can see the CopyObjectAsync() function stripped off the first slash before making the call. Get, Put, and Delete handle these particular keys just fine (and I tested this in the non-Core library and both the synchronous and asynchronous versions of CopyObjectAsync() handle the keys just fine as well).
What I had to do to fix it was the following:
var copyObjectRequest = new CopyObjectRequest
{
SourceBucket = s3Event.S3.Bucket.Name,
SourceKey = "/" + s3Event.S3.Object.Key,
DestinationBucket = OutputBucketName,
DestinationKey = "/" + s3Event.S3.Object.Key,
CannedACL = S3CannedACL.BucketOwnerFullControl,
};
Note the added slashes on the SourceKey and DestinationKey? Without those the keys are mangled.
Here is the complete final code:
var copyObjectRequest = new CopyObjectRequest
{
SourceBucket = s3Event.S3.Bucket.Name,
SourceKey = s3Event.S3.Object.Key,
DestinationBucket = OutputBucketName,
DestinationKey = s3Event.S3.Object.Key,
CannedACL = S3CannedACL.BucketOwnerFullControl,
};
try
{
await s3Client.CopyObjectAsync(copyObjectRequest);
}
catch (AmazonS3Exception ase) when (ase.Message.Contains("key does not exist"))
{
try
{
// If this failed due to Key not found, then fix up the request for the CopyObjectAsync bug in the Core 2.0 library and try again.
var patchedCopyObjectRequest = new CopyObjectRequest()
{
SourceBucket = copyObjectRequest.SourceBucket,
SourceKey = "/" + copyObjectRequest.SourceKey,
DestinationBucket = copyObjectRequest.DestinationBucket,
DestinationKey = "/" + copyObjectRequest.DestinationKey,
CannedACL = copyObjectRequest.CannedACL,
};
await s3Client.CopyObjectAsync(patchedCopyObjectRequest);
}
catch (AmazonS3Exception)
{
// Rethrow the initial exception, since we don't want a confusing message to contain the modified keys.
throw ase;
}
}

Pentaho - upload file using API

I need to upload a file using an API.
I tried REST CLIENT and didn't find any options.
Tried with HTTP POST and that responded with 415.
Please suggest how to accomplish this
Error 415 is “Unsupported media type”.
You may need to change the media type of the request or check whether that type of file us accepted by the remote server.
https://en.m.wikipedia.org/wiki/List_of_HTTP_status_codes
This solution uses only standard classes of jre 7. Add a step Modified Java Script Value in your transformation. You will have to add two columns in the flow: URL_FORM_POST_MULTIPART_COLUMN and FILE_URL_COLUMN, you can add as many files as you want, you will just have to call outputStreamToRequestBody.write more times.
try
{
//in this step you will need to add two columns from the previous flow -> URL_FORM_POST_MULTIPART_COLUMN, FILE_URL_COLUMN
var serverUrl = new java.net.URL(URL_FORM_POST_MULTIPART_COLUMN);
var boundaryString = "999aaa000zzz09za";
var openBoundary = java.lang.String.format("\n\n--%s\nContent-Disposition: form-data\nContent-Type: text/xml\n\n" , boundaryString);
var closeBoundary = java.lang.String.format("\n\n--%s--\n", boundaryString);
// var netIPSocketAddress = java.net.InetSocketAddress("127.0.0.1", 8888);
// var proxy = java.net.Proxy(java.net.Proxy.Type.HTTP , netIPSocketAddress);
// var urlConnection = serverUrl.openConnection(proxy);
var urlConnection = serverUrl.openConnection();
urlConnection.setDoOutput(true); // Indicate that we want to write to the HTTP request body
urlConnection.setRequestMethod("POST");
//urlConnection.addRequestProperty("Authorization", "Basic " + Authorization);
urlConnection.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
var outputStreamToRequestBody = urlConnection.getOutputStream();
outputStreamToRequestBody.write(openBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.write(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(FILE_URL_COLUMN)));
outputStreamToRequestBody.write(closeBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.flush();
var httpResponseReader = new java.io.BufferedReader(new java.io.InputStreamReader(urlConnection.getInputStream()));
var lineRead = "";
var finalText = "";
while((lineRead = httpResponseReader.readLine()) != null) {
finalText += lineRead;
}
var status = urlConnection.getResponseCode();
var result = finalText;
var time = new Date();
}
catch(e)
{
Alert(e);
}
I solved this by using the solution from http://www.dietz-solutions.com/2017/06/pentaho-data-integration-multi-part.html
Thanks Ben.
He's written a Java class for Multi-part Form submission. I extendd by adding a header for Authorization...

Crunchbase Data API v3.1 to Google Sheets

I'm trying to pull data from the Crunchbase Open Data Map to a Google Spreadsheet. I'm following Ben Collins's script but it no longer works since the upgrade from v3 to v3.1. Anyone had any luck modifying the script for success?
var USER_KEY = 'insert your API key in here';
// function to retrive organizations data
function getCrunchbaseOrgs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Organizations');
var query = sheet.getRange(3,2).getValue();
// URL and params for the Crunchbase API
var url = 'https://api.crunchbase.com/v/3/odm-organizations?query=' + encodeURI(query) + '&user_key=' + USER_KEY;
var json = getCrunchbaseData(url,query);
if (json[0] === "Error:") {
// deal with error with fetch operation
sheet.getRange(5,1,sheet.getLastRow(),2).clearContent();
sheet.getRange(6,1,1,2).setValues([json]);
}
else {
if (json[0] !== 200) {
// deal with error from api
sheet.getRange(5,1,sheet.getLastRow(),2).clearContent();
sheet.getRange(6,1,1,2).setValues([["Error, server returned code:",json[0]]]);
}
else {
// correct data comes back, filter down to match the name of the entity
var data = json[1].data.items.filter(function(item) {
return item.properties.name == query;
})[0].properties;
// parse into array for Google Sheet
var outputData = [
["Name",data.name],
["Homepage",data.homepage_url],
["Type",data.primary_role],
["Short description",data.short_description],
["Country",data.country_code],
["Region",data.region_name],
["City name",data.city_name],
["Blog url",data.blog_url],
["Facebook",data.facebook_url],
["Linkedin",data.linkedin_url],
["Twitter",data.twitter_url],
["Crunchbase URL","https://www.crunchbase.com/" + data.web_path]
];
// clear any old data
sheet.getRange(5,1,sheet.getLastRow(),2).clearContent();
// insert new data
sheet.getRange(6,1,12,2).setValues(outputData);
// add image with formula and format that row
sheet.getRange(5,2).setFormula('=image("' + data.profile_image_url + '",4,50,50)').setHorizontalAlignment("center");
sheet.setRowHeight(5,60);
}
}
}
This code no longer pulls data as expected.
I couldn't confirm about the error messages when you ran the script. So I would like to show about the clear difference point. It seems that the endpoint was changed from https://api.crunchbase.com/v/3/ to https://api.crunchbase.com/v3.1/. So how about this modification?
From :
var url = 'https://api.crunchbase.com/v/3/odm-organizations?query=' + encodeURI(query) + '&user_key=' + USER_KEY;
To :
var url = 'https://api.crunchbase.com/v3.1/odm-organizations?query=' + encodeURI(query) + '&user_key=' + USER_KEY;
Note :
From your script, I couldn't also find query. So if the script doesn't work even when you modified the endpoint, please confirm about it. You can see the detail of API v3 Compared to API v3.1 is here.
References :
API v3 Compared to API v3.1
Using the API
If this was not useful for you, I'm sorry.

EPiServer 9 - Add block to new page programmatically

I have found some suggestions on how to add a block to a page, but can't get it to work the way I want, so perhaps someone can help out.
What I want to do is to have a scheduled job that reads through a file, creating new pages with a certain pagetype and in the new page adding some blocks to a content property. The blocks fields will be updated with data from the file that is read.
I have the following code in the scheduled job, but it fails at
repo.Save((IContent) newBlock, SaveAction.Publish);
giving the error
The page name must contain at least one visible character.
This is my code:
public override string Execute()
{
//Call OnStatusChanged to periodically notify progress of job for manually started jobs
OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));
//Create Person page
PageReference parent = PageReference.StartPage;
//IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
//var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//var slaegtPage = repository.GetDefault<SlaegtPage>(ContentReference.StartPage);
IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
SlaegtPage slaegtPage = contentRepository.GetDefault<SlaegtPage>(parent, contentTypeRepository.Load("SlaegtPage").ID);
if (slaegtPage.MainContentArea == null) {
slaegtPage.MainContentArea = new ContentArea();
}
slaegtPage.PageName = "001 Kim";
//Create block
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var newBlock = repo.GetDefault<SlaegtPersonBlock1>(ContentReference.GlobalBlockFolder);
newBlock.PersonId = "001";
newBlock.PersonName = "Kim";
newBlock.PersonBirthdate = "01 jan 1901";
repo.Save((IContent) newBlock, SaveAction.Publish);
//Add block
slaegtPage.MainContentArea.Items.Add(new ContentAreaItem
{
ContentLink = ((IContent) newBlock).ContentLink
});
slaegtPage.URLSegment = UrlSegment.CreateUrlSegment(slaegtPage);
contentRepository.Save(slaegtPage, EPiServer.DataAccess.SaveAction.Publish);
_stopSignaled = true;
//For long running jobs periodically check if stop is signaled and if so stop execution
if (_stopSignaled) {
return "Stop of job was called";
}
return "Change to message that describes outcome of execution";
}
You can set the Name by
((IContent) newBlock).Name = "MyName";

Eventbrite API date range parameter for organizer_list_events

I need a way to search via the eventbrite api past events, by organizer, that are private, but I also need to be able to limit the date range. I have not found a viable solution for this search. I assume the organizer_list_events api would be the preferred method, but the request paramaters don't seem to allow for the date range, and I am getting FAR too many returns.
I'm having some similar issues I posted a question to get a response about parsing the timezone, here's the code I'm using to get the dates though and exclude any events before today (unfortunately like you said I'm still getting everything sent to me and paring things out client side)
Note this is an AngularJS control but the code is just using the EventBrite javascript API.
function EventCtrl($http, $scope)
{
$scope.events=[];
$scope.noEventsDisplay = "Loading events...";
Eventbrite({'app_key': "EVC36F6EQZZ4M5DL6S"}, function(eb){
// define a few parameters to pass to the API
// Options are listed here: http://developer.eventbrite.com/doc/organizers/organizer_list_events/
//3877641809
var options = {
'id' : "3588304527",
};
// provide a callback to display the response data:
eb.organizer_list_events( options, function( response ){
validEvents = [];
var now = new Date().getTime();
for(var i = 0; i<response.events.length; i++)
{
var sd = response.events[i].event.start_date;
var ed = response.events[i].event.end_date;
var parsedSD = sd.split(/[:-\s]/);
var parsedED = ed.split(/[:-\s]/);
var startDate = new Date(parsedSD[0], parsedSD[1]-1, parsedSD[2], parsedSD[3], parsedSD[4], parsedSD[5]);
var endDate = new Date(parsedED[0], parsedED[1]-1, parsedED[2], parsedED[3], parsedED[4], parsedED[5]);
if(endDate.getTime()<now)
continue;
response.events[i].event.formattedDate = date.toDateString();
validEvents.push(response.events[i])
}
if(validEvents.length == 0)
{
$scope.$apply(function(scope){scope.noEventsDisplay = "No upcoming events to display, please check back soon.";});
}
else
{
$scope.$apply(function(scope){scope.noEventsDisplay = "";});
}
$scope.$apply(function(scope){scope.events = validEvents;});
//$('.event_list').html(eb.utils.eventList( response, eb.utils.eventListRow ));
});
});
}