urschrei / pyzotero

Pyzotero: a Python client for the Zotero API
https://pyzotero.readthedocs.org
Other
870 stars 96 forks source link

Automatically upload or update pdfs in zotero with pyzotero #142

Closed Jimmy2027 closed 2 years ago

Jimmy2027 commented 3 years ago

Hi, thanks for the great package!

I'm looking for a way to automatically upload or update pdfs after I've compiled them in latex. Basically, I want to do the same than dragging a pdf file into a zotero collection in python.

Is this possible with pyzotero?

I have tried to upload a pdf with zot.attachment_both([(pdf_name, pdf_path)]) but while the file appears in my zotero, the attachment is not where zotero can find it (File not found error). What is the correct way to do this?

Also, how can I upload to a specific collection or subcollection?

urschrei commented 3 years ago

pdf name is the name you want the attachment to have in Zotero, like "my_pdf_10" and path must be the full file path: /foo/bar/baz.pdf

In order to upload to a specific collection, you have to either attach to an existing item in that collection, or create an item in the collection and attach to that.

Jimmy2027 commented 3 years ago

Is this the right syntax?

pdf_path = Path('~/mypdf.pdf').expanduser()
assert pdf_path.exists()
print(zot.attachment_both([('mypdf', str(pdf_path))]))

This way the file appears in zotero, but the attachment is not found.

urschrei commented 3 years ago

I'm not sure what you mean by "file appears in Zotero, but the attachment is not found". The file is the attachment, and if you don't specify a parent ID, it will appear as a standalone file.

What happens when you double-click it? What happens if you use attachment_simple(['/path/to/filename.pdf'])? What happens if you use attachment_simple(['/path/to/filename.pdf'], parentid)?

Jimmy2027 commented 3 years ago

When I double click it in the Zotero GUI under "My Library/Unfiled Items", I get the error message "File Not Found The attached file could not be found at the following path: /path/to/zotero/storage/ID/mypdf.pdf"

The same happens with attachment_simple(['/path/to/filename.pdf']).

I'm not sure how to use the parentid parameter. Is this the id of an item that already exists in the zotero database? If so, how can I find its id?

I have tried to upload another pdf with attachment_simple, but got the error:

pyzotero.zotero_errors.RequestEntityTooLarge: 
Code: 413
URL: https://api.zotero.org/users/myid/items/id/file
Method: POST
Response: File would exceed quota (300.1 > 300)

Which is strange since the file is only 113 KB big, and I can upload it to zotero via the GUI. Also, strangely the file still appears in the zotero GUI with an existing attachment, but the attachment is stored under the original path instead of the zotero storage under /path/to/zotero/storage/ after executing the command that results in the error.

urschrei commented 3 years ago

The parent ID is the id of an existing item. You can retrieve items in a number of ways (see docs). "id" is a field in the returned dict(s).

Your entity too large error may be related to the total size of your Zotero library. If your storage quota is already full or nearly full, you won't be able to upload additional items.

I can't reproduce the original errors – both attachment methods are working for me both with and without parent IDs using the latest Pyzotero version on macOS.

Jimmy2027 commented 3 years ago

Thanks for the info, I was able to add the attachment to an existing item with the id/key.

You were right, after emptying the bin, the RequestEntityTooLarge error disappeared.

In the dict returned by attachment_simple in the field unchanged[0]["filename"] I have the original file path, is that normal? Should it not be the zotero storage path /path/to/Zotero/storage?

My output looks like this:

{
  "success": [],
  "failure": [],
  "unchanged": [
    {
      "itemType": "attachment",
      "linkMode": "imported_file",
      "title": "mypdf.pdf",
      "accessDate": "",
      "note": "",
      "tags": [],
      "collections": [],
      "relations": {},
      "contentType": "",
      "charset": "",
      "filename": "/path/to/mypdf.pdf",
      "md5": "None",
      "mtime": "None",
      "parentItem": "WKC6M5SL",
      "key": "XR23RHQI"
    }
  ]
}
urschrei commented 3 years ago

I have the original file path, is that normal? Should it not be the zotero storage path /path/to/Zotero/storage

No, the file path that's returned should match your local file path. But from your output above, the dict is in the wrong key: it's in unchanged, and if the file is successfully uploaded (and possibly attached to a parent item), it should be under success.