Is it possible to force a copy of a protected Google doc? [closed] - copy

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
Google docs can “lock” a page so that it’s impossible to copy from its text. This seems wrong to me; shouldn't a computer’s ability to copy and paste be intrinsic? I can’t understand how a webpage can “overstep” its authority and prevent my computer from doing something totally natural. It seems that if I can be served and display text that I should be able to copy it.
How does this webpage prevent my machine from copying?

Here is how to copy (or print) the protected google sheet values.
NOTE: With this technique you can copy the cells from each sheet; it's not possible to duplicate the spreadsheet file itself. Formatting is preserved but formulas are not.
Change the URL to:
https://docs.google.com/spreadsheets/u/1/d/***[document id]***/preview
The document ID is the random string found in the google sheet URL that is normally 40 to 45 characters long.
For each sheet, type Ctrl+A, Ctrl+C
Paste the cells into another spreadsheet. Formatting

As of the 10th of May, 2018, disabling JavaScript will not load the document at all, and changing the 'edit' to 'preview' also no longer works.
I have found that if you click on the three dots and go to:
More Tools > Developer Tools and then click on console, and type in 'document.body.innerText', it loads the entire document as a text file, so that you can copy to your heart's content.

Disable javascript in with developer tools, right click the page, click 'print', change the print destination from your printer to 'save as pdf', and you've got it.

I tried the other options and none worked for me - then, tried downloading webpage and saving link. Re-opened from docs, and then I was able to download as PDF.

EDIT: This doesn't work anymore
I've found out how they're disabling copying, so I'm turning my comment into an answer.
Here's the script that runs on the page that prevents copying:
function rtcScript() {
document.oncontextmenu = null;
document.onselectstart = null;
document.onmousedown = null;
document.onclick = null;
document.oncopy = null;
document.oncut = null;
var elements = document.getElementsByTagName('*');
for (var i = 0; i < elements.length; i++) {
elements[i].oncontextmenu = null;
elements[i].onselectstart = null;
elements[i].onmousedown = null;
elements[i].oncopy = null;
elements[i].oncut = null;
}
function preventShareThis() {
document.getSelection = window.getSelection = function() {
return {isCollapsed: true};
}
}
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src.indexOf('w.sharethis.com') > -1) {
preventShareThis();
}
}
if (typeof Tynt != 'undefined') {
Tynt = null;
}
}
rtcScript();
setInterval(rtcScript, 2000);
Notice that it's setting every element to not be copyable, selectable, or cuttable, as well as disabling the context menus. This is trivial to bypass by disabling scripts on the page. See this question for how to do it on Chrome. I've tested this myself - if you disable JavaScript via that method while viewing the locked document, you can immediately begin selecting and copying the text with no issues.

Related

Is there a tool/extension/script I can run for Visual Studio Code to Bulk handle errors?

I have a rather large Dynamics 365 Business Central Extension written in AL code on Visual Studio Code platform. Microsoft is changing a rule in AL code that will result in widespread errors if not addressed before the next release. This change is that "implicit with" cannot be used, so every record reference in the code has to be qualified with "Rec.". There are several hundred places this will need to be addressed in this extension, and it is just not practical to manually adjust them one by one. For reference,
This:
field(TradeNumber; TradeNumber)
{
ApplicationArea = All;
Caption = 'Trade No.';
Editable = False;
}
field(TradeType; TradeType)
{
ApplicationArea = All;
Caption = 'Trade Type';
}
Becomes this:
field(TradeNumber; Rec.TradeNumber)
{
ApplicationArea = All;
Caption = 'Trade No.';
Editable = False;
}
field(TradeType; Rec.TradeType)
{
ApplicationArea = All;
Caption = 'Trade Type';
}
So if the error (or "problem" as it is now) is the same for these several hundred instances, is there a way to bulk-correct so to speak and just apply "Rec." to the beginning of every reference that has been flagged across the multiple files and folders?
The standard AL Code extension for VS Code will include Code Actions to fix these errors. ("Qualify with Rec.")
There are 3rd party extensions available on the Visual Studio Code marketplace to fix these en-mass automatically, e.g. AL CodeActions
As you only mention Implicit, you should note that explicit WITH statements are also being 'obsoleted.' The reason for this is that the behavior of both types of 'With' statement become unpredictable when dealing with extensions; this blog post explains it in more detail.

how to disable pasting on google form?

i want to create a google form that i dont want people answer the questions by pasting from somewhere else, I want them to type their answers.
How can I do this?
I have tried to add js codes to google script but it didn't work.
It's not worh to prevent pasting because it will never be 100% effective, users can tweak prevention and do what they want.
But you can try using javascript.
This will prevent all inputs in your form:
let input = document.querySelector('input');
input.addEventListener('paste', (e) => {
e.preventDefault(); // This is what prevents pasting.
});
And this one will prevent only on an input that is specified by it's ID:
window.onload = function (){
var input = document.getElementById('inputId');
input.onpaste = functino(e){
e.preventDefault();
}
}
Update based on your comment
Here is a complete tutorial on how to create a google form and add scripts to it. It's not the exact same problem, but it's a clue.

How to get MS Word total pages count using Open XML SDK?

I am using below code to get the page count but it is not giving actual page count(PFA). What is the better way to get the total pages count?
var pageCount = doc.ExtendedFilePropertiesPart.Properties.Pages.Text.Trim();
Note: We cannot use the Office Primary Interop Assemblies in my Azure web app service
Thanks in advance.
In theory, the following property can return that information from the Word Open XML file, using the Open XML SDK:
int pageCount = (int) document.ExtendedFilePropertiesPart.Properties.Pages.Text;
In practice, however, this isn't reliable. It might work, but then again, it might not - it all depends on 1) What Word managed to save in the file before it was closed and 2) what kind of editing may have been done on the closed file.
The only sure way to get a page number or a page count is to open a document in the Word application interface. Page count and number of pages is calculated dynamically, during editing, by Word. When a document is closed, this information is static and not necessarily what it will be when the document is open or printed.
See also https://github.com/OfficeDev/Open-XML-SDK/issues/22 for confirmation.
This code worked for me. It adds "Page X of Y" to the document.
para = new Paragraph(new Run(
new Text() { Text = "Page ", Space = SpaceProcessingModeValues.Preserve },
new SimpleField() { Instruction = "PAGE" },
new Text() { Text = " of ", Space = SpaceProcessingModeValues.Preserve },
new SimpleField() { Instruction = "NUMPAGES \\*MERGEFORMAT" }));

iTextSharp insert image PushbuttonField not working

I have searched and searched and cannot find the answer to my problem. I've tried many different approaches in my code, but I've hit a wall and I'm not sure where to go from here. I seem to be wanting to do the same thing as these two threads:
Trying to insert an image into a pdf‏ in c#
Add image in an existing PDF with itextsharp
They are very similar and the answer is the same. However, when I use that exact code, the result is a PDF without an image. Here is my code:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(#"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
I have tried to rule out all of the obvious things. My path to the image is correct, the field is indeed a PushbuttonField when I read the existing PDF field and get the field type. If I open the PDF in Adobe Reader and click on the placeholder for the image, it allows me to pick a file from my PC. When I place an image in the file, save, and then read in that PDF, I can then change my code to this:
imageField.ProportionalIcon = false;
And now all of sudden the image is stretched on the saved copy. So I see that it is changing this part but this is when I enter the image manually in Adobe Reader. When I read in the field after I set that image in Adobe Reader and it shows correctly, I see a couple interesting things. The field.Image property IS NULL and the field.IconReference is NOT NULL. When I use the original code to try and insert the image, it is reversed, where Image is NOT NULL but IconReference IS NULL
Any help would be greatly appreciated, thank you!!
EDIT 1: Ok so I didn't see it the first time, but I went back and checked more thoroughly and I did find that key. Here it is:
Several things are at play here.
Usage Rights:
The PDF is digitally signed with a private key owned by Adobe.
You can see this using RUPS here (in your screen shot you didn't go deep enough):
This has two implications:
The signature unlocks special permissions in Adobe Reader, such as the permission to save a filled out form locally.
Making any changes to the original PDF breaks the signature and removes the special permissions leading to an ugly error message in Adobe Reader.
This functionality is deprecated in (and even removed from) PDF 2.0. It's old technology that became obsolete with the emergence of PDF viewers other than Adobe Reader.
My suggestion: remove the usage rights to avoid breaking the signature. See the FAQ entry "Why do I get an error saying that "use of extended features is no longer available"?" iText 7 / iText 5
This is the iText 7 code:
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
This is the iText 5 code:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
This is the iText 5 answer.
Hybrid Form:
If you click on the /AcroForm entry, you see this:
There is a /Fields array with references to field dictionaries that are also widget annotations. That means that the document has an AcroForm form inside. However, there is also an /XFA entry with a series of XML snippets. That means that the document has an XFA form inside.
In other words: the same form description is added twice inside. You are changing a button in one form (the AcroForm part), but not in the other (the XFA form) and that leads to inconsistencies.
XFA has been deprecated in PDF 2.0 because there weren't many vendors supporting that technology. It's kind of frustrating to be confronted with forms that use deprecated technology.
My suggestion: I would remove the XFA part. See the FAQ entry "Is it safe to remove XFA?" iText 5 / iText 7
In iText 5, removing XFA is done like this:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
Important: my suggestion is to remove all the deprecated functionality from the PDF, but if the government expects that functionality to be present, then you're out of luck. In that case, you will need to use Adobe software to process the form. If that's the case, you could complain to the government that their requirements lead to a de facto vendor lock-in. By the way: iText Software is also a vendor. It's an open source company that offers open source software under the AGPL license. The AGPL license allows free use under certain circumstances (see How do I make sure my software complies with AGPL: How can I use iText for free?) If you don't meet those requirements, you will have to purchase a commercial license for your use of iText.

Google Apps Script DialogBox show from clienthandler [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am trying to create an 'Are You Sure' type dialog using a DialogBox. So when someone clicks a button, a popup shows with yes/no buttons for the user to confirm they wish to proceed with the action.
I have figured most of it out, however I can't figure out how to make it show without calling back to a server handler.
I tried using the show() command with a Client Handler, but it doesn't work. I tried using setVisibility() also, but couldn't get this working either.
I don't want to have to make a round trip just to show the dialog box for the obvious user experience reasons.
Does anyone have any suggestions?
Thanks in advance
Chris
Here is a small snippet i have created for just this reason. It does however use a server handler...
function MsgBox(message, title, id, buttons, handler, modal, autoHide){
this.message=message;
this.title=title;
this.id=id;
this.buttons=buttons;
this.handler=handler;
this.modal=(modal)?true:false;//Default is false
this.autoHide=(autoHide)?new Boolean(autoHide):true;//Default is true
this.position={};
this.position.top=100;
this.position.left=550;
this.position.width=400;
this.button={};
this.button.ok={name:"Ok",id:"OK_BTN"};
this.button.yes={name:"Yes",id:"YES_BTN"};
this.button.no={name:"No",id:"NO_BTN"};
this.button.cancel={name:"Cancel",id:"CANCEL_BTN"};
this.button.retry={name:"Retry",id:"RETRY_BTN"};
this.addButton=function(btn){
try{
if(this.buttons==undefined){this.buttons=[];}
if(typeof btn=="string"){btn=this.button[btn.toLowerCase()];}//If a string, convert to the intended object
if(btn.name==undefined){return this;}//Check if we've actualy got one of the buttons by checking one of it's properties. Exit if not.
this.buttons.push(btn);
}catch(err){
Logger.log(err.message);
}
return this;
};
this.show=function(e, app){
if(app==undefined){app=UiApp.getActiveApplication();}
if(this.buttons==undefined){this.buttons=[this.button.ok];}//The default is one 'Ok' button
var dialog=app.createDialogBox(true,true).setId(this.id).setText(this.title);
dialog.setPopupPosition(this.position.left,this.position.top);
dialog.setGlassEnabled(this.modal);
dialog.setAutoHideEnabled(this.autoHide);
var basePanel=app.createVerticalPanel().setWidth(this.position.width+"");
basePanel.add(app.createLabel(this.message).setWordWrap(true).setStyleAttribute("padding", "10px"));//Add message
var buttonPanel=app.createHorizontalPanel().setId("ButtonPanel");
basePanel.add(buttonPanel.setStyleAttribute("display", "block").setStyleAttribute("margin-left", "auto").setStyleAttribute("margin-right", "auto"));
var btnHandler=app.createServerHandler("msgBox_close").addCallbackElement(buttonPanel);
for(var i=0;i<this.buttons.length;i++){
var btn=app.createButton(this.buttons[i].name, btnHandler).setId(this.buttons[i].id).setTag(this.id);
if(this.handler!=undefined){btn.addClickHandler(this.handler);}
buttonPanel.add(btn);
}
dialog.add(basePanel).show();
return app;
};
}
function msgBox_close(e, app){
if(app==undefined){app=UiApp.getActiveApplication();}
var dialogId=e.parameter[e.parameter.source+"_tag"];
app.getElementById(dialogId).hide();
return app;
}
Here is a smal example how to use it.
var msgBox=new MsgBox("Testing 123...", "This is a test", "MyMsgBox");
msgBox.show(e, app);
By using the '_tag' parameter to reference its own ID you make a clean roundtrip with little hassle.
You can add standard buttons by calling the .addButton() function.
Example:
msgBox.addButton("yes").addButton("no");
By passing your own handler, you can call your own functions.
Example:
function myOwnHandler(e, app){
if(app==undefined){app=UiApp.getActiveApplication();}
if(e.parameter.source.indexOf("YES_BTN")!=-1){
}
return app;
}