4

I want to make historic files read-only so that no one reading them (even me) can accidentally edit them. I'd like to make this transparent to the users, so having to open them in a different way is not a great solution.

Now, I guess I can easily do this for others when I share it (making their access View only). How do I make the file read-only even to me?

4 Answers 4

3
  1. Create a new account to be used as "librarian" / "archivist"
  2. Transfer the ownership of the file to that account.

Note:The new account should have the same domain as the current owner of the file.

1
  • As this is a work account, I don't have the access to create new accounts. Is it really impossible to make a file read-only in Drive? I thought this was supposed to be a business-strength filesystem! This is an unbelievable restriction. Commented Apr 6, 2021 at 6:54
3

You can lock your files, but unfortunately that is not a very simple action. No one can edit the file after locking, but unlocking is relatively straight forward. Here are the steps you need to take (Credit to https://www.labnol.org/code/read-only-google-drive-file-201011)

  1. Get the shareable link for the file you want to lock. Right-click on the file, click on the "get link" option and copy the link that you will see in the pop-up menu. Set the permissions of the link to edit, otherwise, the script can't lock the file.
  2. Create a new tab in your browser and go to the URL https://script.new. This will open a new Google App script.
  3. Copy the following code in the editor:
const makeFileReadyOnly = () => {
  const fileUrl = '<<FILE URL>>';
  const [fileId] = fileUrl.split('/').filter((e) => /[_-\w]{25,}/.test(e));
  UrlFetchApp.fetch(`https://www.googleapis.com/drive/v3/files/${fileId}?supportsAllDrives=true`, {
    method: 'PATCH',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
    },
    payload: JSON.stringify({
      contentRestrictions: [
        {
          readOnly: true,
          reason: 'Prevent accidental editing',
        },
      ],
    }),
  });
  // For requesting correct scope, do not delete
  // var file = DriveApp.getFileById().setName()
};
  1. Replace the <<FILE URL>> in line #2 with the URL of the Drive file that you copied in the previous step.
  2. Save project and run the function. You will be asked for permissions, accept them and the file will be locked.
  3. If you wish to unlock the file, simply right click on the file and select "unlock". You can find the script in https://script.google.com/home if you want to lock the file again.
1
  • Tested in Summer 2022: This does work with a private Google Drive, but not with shared drives (404 file not found). If someone knows a way to amend the script, please help out. Thank you.
    – myhd
    Commented Jul 11, 2022 at 11:54
1

Please note the (original) answer provided by stacklars doesn't work with files on a shared drive. The fix turns out to be simple. Just add ?supportsAllDrives=true to the API URL:

UrlFetchApp.fetch(`https://www.googleapis.com/drive/v3/files/${fileId}?supportsAllDrives=true`, {
...

I found this query parameter is needed, per https://stackoverflow.com/questions/67622131 and https://developers.google.com/drive/api/guides/enable-shareddrives.

(Sorry, I do not have enough reputation here to post this as a comment.)

0

The following seems to work reasonably well:

from google.colab import drive
drive.mount('/content/drive')

from google.colab import auth
auth.authenticate_user()

import subprocess
subprocess.run(["pip", "install", "xattr"])

def get_file_id(path):
  return subprocess.getoutput(f"xattr -p user.drive.id {path}")

import google.auth
from googleapiclient.discovery import build

def lock_file_by_id( file_id ):
  creds, _ = google.auth.default()
  with build('drive', 'v3', credentials=creds) as service:
    file_attributes = service.files().get(fileId=file_id, fields="contentRestrictions").execute()
    if 'contentRestrictions' in file_attributes:
      if  file_attributes['contentRestrictions'][0]['readOnly']: ## already set to read only
        return
    service.files().update( fileId=file_id,
                body={ "contentRestrictions":
                       [{"readOnly": "true", "reason": "Handle with care"}] }).execute()

test_file = "/content/drive/MyDrive/test.txt"
id = get_file_id(test_file)
lock_file_by_id( id )

That code was written with some inspiration from Amit Agarwal's Google Apps script.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.