Google Cloud Print with Zebra printer - google-cloud-print

We are trying to print a PDF file on a Zebra thermo printer via Google Cloud Print. The printer is connected to GCP via the Windows Chrome Browser GCP proxy on Windows 10.
NB: Chrome can only print the PDF correctly on this printer when using System Print Dialog. Printing with the Chrome dialog causes the same effect.
Printing works, but the image is scaled into the wrong dimensions.
We use the following CJT:
{
"version":"1.0",
"print":{
"copies":{
"copies":1
},
"page_orientation":{
"type":0
},
"margins": {
"top_microns":0,
"bottom_microns":0,
"left_microns":0,
"right_microns":0
},
"fit_to_page": {
"type": "NO_FITTING"
},
"dpi": {
"horizontal_dpi":203,
"vertical_dpi":203
},
"media_size": {
"width_microns": 100000,
"height_microns": 37000,
"is_continuous_feed": True
}
}
}
The PDF has a mediaBox, trimBox, bleedBox, artBox set to [0, 0, 238.46460, 108.88190]. The printers page properties are set 10cm width, 3.7cm height.
With this settings, only the center part of the label is printed (and the part is scaled too small).
We also tried different fit_to_page settings.
PDF: https://drive.google.com/file/d/0B1m2K70eVXaXZF9raG5OakthZnc/view?usp=sharing
Printout: https://goo.gl/photos/J74VFS1coMDteSpm8

Related

Images in Strapi media library not showing

I just deployed my strapi cms to heroku, and the problem is when I add assets into media library, the images will not showing after few minutes, it looks like this
The URL of the images exists on the API, but when I check it manually, it shown 'not found' message. Any solution of this case?
This Issue may be solved. According to the #strapi/provider-upload-cloudinary documentation
According to that, we need to add the below code to ./config/middlewares.js file.
module.exports = [
// ...
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'dl.airtable.com', 'res.cloudinary.com'],
'media-src': ["'self'", 'data:', 'blob:', 'dl.airtable.com', 'res.cloudinary.com'],
upgradeInsecureRequests: null,
},
},
},
},
// ...
];
This should resolve the issue and we should be able to see the image thumbnails in the Strapi media library.

SSO on Microsoft Edge not working but does work on IE11, Chrome, Safari, Firefox - via Office.js add-in

The following oAuth2 SSO code in my Office.js addin application works great in IE11, Chrome, Safari and Firefox, but doesn't work in Microsoft Edge. I can see the bearer token is being returned to the pop-up dialog via the url:
https://localhost:3000/login?access_token=ya29.ImG6By-0ZWPQB4MsYxxxxxxxxxxxxxxxxxxxxxxxxxxxxE5XsM9v7SBi-OaUBBQucO05luKVP0pYoSrcYzbaUKAAX&token_type=Bearer
I can also see that the asyncResult.status == succeeded, i.e.
[object Object]: {status: "succeeded", value: Object}
status: "succeeded"
value: Object
addEventHandler: function (){var d=OSF.DDA.SyncMethodCalls[OSF.DDA.SyncMethodNames.AddMessageHandler.id],c=d.verifyAndExtractCall(arguments,a,b),e=c[Microsoft.Office.WebExtension.Parameters.EventType],f=c[Microsoft.Office.WebExtension.Parameters.Handler];return b.addEventHandlerAndFireQueuedEvent(e,f)}
arguments: null
caller: null
length: 0
name: "value"
prototype: Object
proto: function() { [native code] }
close: function (){var c=OSF._OfficeAppFactory.getHostFacade()[OSF.DDA.DispIdHost.Methods.CloseDialog];c(arguments,g,b,a)}
sendMessage: function (){var c=OSF._OfficeAppFactory.getHostFacade()[OSF.DDA.DispIdHost.Methods.SendMessage];return c(arguments,b,a)}
proto: Object
proto: Object
However, the "console.log('hello');" doesn't get called when Microsoft Edge is running the sidebar/add-in.
The pop-up dialog is showing this in the F12 debug console:
HTTP403: FORBIDDEN - The server understood the request, but is refusing to fulfill it.
(XHR)POST - https://browser.pipe.aria.microsoft.com/Collector/3.0/?qsp=true&content-type=application%2Fbond-compact-binary&client-id=NO_AUTH&sdk-version=AWT-Web-JS-1.1.1&x-apikey=a387cfcf60114a43a7699f9fbb49289e-9bceb9fe-1c06-460f-96c5-6a0b247358bc-7238&client-time-epoch-millis=1579626709267&time-delta-to-apply-millis=961
Any ideas?
export function loginUsingOAuth() {
try {
const sealUrl = getFromStorage('seal_url', STORAGE_TYPE.LOCAL_STORAGE);
const redirectUrl = `${window.location.protocol}//${window.location.host}/login`;
let displayInIframe = false;
let promptBeforeOpen = false;
if (typeof sealUrl !== 'undefined' && sealUrl) {
const oAuthUrl = `${sealUrl}/seal-ws/oauth2/login?redirect_uri=${redirectUrl}`;
Office.context.ui.displayDialogAsync(
oAuthUrl,
{
height: 80,
width: 80,
displayInIframe,
promptBeforeOpen
},
asyncResult => {
console.log('asyncResult');
console.log(asyncResult);
addLog(LOG_TYPE.INFO, 'authentication.loginUsingOAuth', asyncResult);
if (asyncResult.status !== 'failed') {
const dialog = asyncResult.value;
dialog.addEventHandler(Office.EventType.DialogMessageReceived, args => {
console.log('hello');
Maybe this is actually a routing issue when executing in Edge? The "/login" callback is routed to the AuthCallback.js component:
const Routes = () => (
<BrowserRouter>
<Switch>
<Route exact path="/login" component={AuthCallback} />
<Route path="/" component={BaseLayout} />
</Switch>
</BrowserRouter>
);
The constructor of the AuthCallback.js component calls messageParent after a short pause:
constructor(props) {
super(props);
const paramsObj = queryString.parse(props.location.search);
const paramsStr = JSON.stringify(paramsObj);
setTimeout(() => {
Office.context.ui.messageParent(paramsStr);
}, 1200);
}
I'm starting to wonder if Edge is messing with the redirect. In the image below you can see that IE and Edge are returning different status codes for the same sign-on operation:
There seems to be two problems with the Edge browser.
The redirect/callback is not calling the components constructor when displayInIframe=false when running on Microsoft Edge. All other browsers work as expected. I've added conditional logic to set displayInIframe=true for the Edge browser use-case
The messageParent method also does not work for the Edge browser when displayInIframe=true. Therefore I've had to extract the auth token in the pop-up dialog callback and stash it away in the local_storage. The parent (the sidebar) is then polling the local_storage to detect that the sign-in has completed. Again, Chrome, Firefox, Safari, IE11 (both Mac and PC) are all fine - its just the Edge browser that is failing.
Whilst this is an ugly solution to the problem it is also imperfect because IF the end-user is not already signed-in to SSO then the Google [Account Selector] dialog is shown, which is a problem when displayInIframe=true as this throws an iframe exception.
I don't see any other option open to us, because the O/S build number and MSWord version dictates which browser is used to render the sidebar. The inability to choose whether IE11 or Edge is used would be bearable if Edge didn't have these functional deficits.

Google Cloud Print from Web

I wrote a script that prints some test pages from url on Web-site,
and every time I press a print button, a dialog frame for choosing printer appears . But I want to avoid this because my account synchronized with printer.
window.onload = function() {
var gadget = new cloudprint.Gadget();
gadget.setPrintButton(
cloudprint.Gadget.createDefaultPrintButton("print_button_container")); // div id to contain the button
gadget.setPrintDocument("url", "Test Page", "https://www.google.com/landing/cloudprint/testpage.pdf");
}
You could use oath and an html button rather than a gadget to accomplish this. This requires using the google developer console to get oauth permissions.
Then you need to authorize the cloud print service.
The following set of functions are specifically good for use in Google Apps Scripts, but can be adapted. The first thing to do is Log a url link that you can go to in order to Authorize the cloud print service.
function showURL() {
var cpService = getCloudPrintService();
if (!cpService.hasAccess()) {
Logger.log(cpService.getAuthorizationUrl());
}
}
In the following component of this set of functions, make sure to replace the client Id and Secret.
function getCloudPrintService() {
return OAuth2.createService('print')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setClientId('**YOUR CLIENT ID FROM GOOGLE DEVELOPER CONSOLE**')
.setClientSecret('**YOUR CLIENT SECRET**')
.setCallbackFunction('authCallback')
.setPropertyStore(PropertiesService.getUserProperties())
.setScope('https://www.googleapis.com/auth/cloudprint')
.setParam('login_hint', Session.getActiveUser().getEmail())
.setParam('access_type', 'offline')
.setParam('approval_prompt', 'force');
}
function authCallback(request) {
var isAuthorized = getCloudPrintService().handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput('You can now use Google Cloud Print from Apps Script.');
} else {
return HtmlService.createHtmlOutput('Cloud Print Error: Access Denied');
}
}
Next, get the ID of the Cloud Print Printer that you want to use. This can be obtained in the settings menu of Chrome. Settings --> Show Advanced Settings --> Under Cloud Print " Manage" --> Select the Printer that you want to use "Manage" -->Advanced Details
To initiate cloud print, you need to add the details to a ticket:
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR",
vendor_id: "Color"
},
duplex: {
type: "LONG_EDGE"
},
copies: {copies: 1},
media_size: {
width_microns: 215900,
height_microns:279400
},
page_orientation: {
type: "PORTRAIT"
},
margins: {
top_microns:0,
bottom_microns:0,
left_microns:0,
right_microns:0
},
page_range: {
interval:
[{start:1,
end:????}]
}
}
};
There are many options that you can add to the ticket. See documentation
Finally, you need to initiate the Cloud Print Service. Here is where you get to define the specific printer that you want.
var payload = {
"printerid" : '**COPY YOUR PRINTER ID HERE**',
"title" : "Prep Print",
"content" : PUT YOUR CONTENT HERE...(e.g. If you do all of this using Google Apps Script...HtmlService.createHtmlOutput(VARIABLE).getAs('application/pdf')),
"contentType": 'text/html',
"ticket" : JSON.stringify(ticket)
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);}
var outcome = response.message;
}

filepicker exportFile and popup blocker

I program a webapp which use ink filepicker for opening/saving text files from/to the cloud. In mobile browsers, when I open a file via :
filepicker.pick({extension: '.txt'},
function(FPFile) {
filepicker.read(FPFile, function(data) {
// Open file
});
});
There is no problem, whether or not the "block popup" option is activated in browser. But when I save file via :
filepicker.store(
mycontent64,
{base64decode: true, mimetype: 'text/plain'},
function(InkBlob) {
filepicker.exportFile(
InkBlob,
{suggestedFilename:"myfile.txt",extension: ".txt"},
function(InkBlob) {
// ******* Save file
},
function(FPError) {
console.log(FPError.toString());
});
},
function(FPError) {
console.log(FPError.toString());
}
);
it only works when the "block popup" option is deactivated in the browser (Safari on iPad or Android stock browser, or google chrome Android...).
If it's activated, browser refuse to open export dialog in a new tab, and with "FPError 131" in console...
I can't tell my users to deactivate this option !
So is there any workaround that do the trick ?
Thank's !
Some workaround would be open filepicker dialog inside filepicker in the same page.
For mobile devices change filepicker.exportFile options:
filepicker.store(
mycontent64,
{base64decode: true, mimetype: 'text/plain'},
function(InkBlob) {
filepicker.exportFile(
InkBlob,
{
suggestedFilename:"myfile.txt",
extension: ".txt"
container: "yourIframeId",
mobile: true
},
function(InkBlob) {
// ******* Save file
},
function(FPError) {
console.log(FPError.toString());
});
},
function(FPError) {
console.log(FPError.toString());
}
);
"yourIframeId" is Id of iFrame tag inside your website.
'mobile: true' will force mobile - responsive version of dialog.
Check docs: https://developers.filepicker.io/docs/web/#export

Chrome Extension API v17: webRequest onErrorOccurred.addListener

I am attempting to set up a chrome extension similar to http://code.google.com/chrome/extensions/trunk/samples.html#webrequest except that it would us the onErrorOccurred listener instead to redirect to a specific known page when the get request fails for any reason.
manifest.json:
{
"name": "Custom Error",
"version": "0.1",
"description": "Redirect all navigation errors to specified location/file.",
"permissions": [
"webRequest",
"tabs",
"<all_urls>"
],
"background": {
"page": ["error_listener.html"]
}
}
error_listener.html:
<!doctype html>
<script>
chrome.webRequest.onErrorOccurred.addListener(
function onErrorOccurred(details) {
console.log('onBeforeRequest ', details.url);
return { redirectUrl: 'http://www.google.com' }
},
{urls: ["<all_urls>"]}
//{urls: ["http://*/*", "https://*/*"]}
);
//chrome.tabs.update(details.tabId, {url: "http://www.google.com", ['blocking']});
//alert("what?");
</script>
The extension loads without any errors indicated yet the browser tab is not redirected. I have tried this using both Chrome 16 and Chrome 17; when using Chrome 16, I did change "chrome.webRequest" to "chrome.experimental.webRequest" and added "experimental" to the permissions list.
So far it seems like the problem is that while the extension appears to be loaded when looking at chrome://extensions, the files are not actually loaded--when using Developer Tools, I don't see any reference to error_listener.html.
I have also tried running Chrome 17 with the following flags:
8611 25/01/12-11:22:05> google-chrome --restore-last-session
--debug-on-start --log-level=0 --enable-logging
--enable-extension-activity-logging --enable-extension-alerts
--debug-plugin-loading --debug-print | tee > log1.txt
Obviously, I am just kind of poking around in the dark with that command line. Anyone have any clue as to how to get this working? Thanks in advance for your help!
There is no webRequest.onErrorOccurred event. You may use webNavigation.onErrorOccurred. If you want to catch DNS errors and redirect to another url you may use the code:
<script>
chrome.webNavigation.onErrorOccurred.addListener(function(details)
{
if (details.frameId != 0) //ignore subframes. 0 is main frame
{ return; }
chrome.tabs.update(details.tabId, {url: "https://www.google.com/search?q=" + details.url});
});
</script>
In Chrome 16, you should be using:
"background_page": "background.html"
rather than
"background": {
"page": ["error_listener.html"]
}
This fixes the problem with the background page not loading. It looks like this may have changed in the trunk docs compared to the current docs, and I'm not sure which version of Chrome starts implementing the new manifest.json format.