zotero-api-node icon indicating copy to clipboard operation
zotero-api-node copied to clipboard

Working example of creating an attachment and uploading a file

Open flotob opened this issue 9 years ago • 13 comments

Hey there,

I'm struggling with uploading files with the help of of zotero-node. My first issue is that i cannot seem to construct the valid URL to get an item template. I suppose it'd have to be something akin to lib.get('itemTypes') but all I get is a 404 (I tried different variations). Is there a way to enable debug mode to see which URLs exactly the zotero module is constructing with the information it's given?

Another question then is how to exactly POST files to the API. I see that there is a POST method available through the Client object. But how exactly would I use it to transfer a file to the zotero server? Is there a working example somewhere?

Thanks and best regards,

Flo

flotob avatar May 20 '15 10:05 flotob

I have not implemented uploads yet, but this is definitely something I'd like to add.

All URLs from lib.get will be prefixed with the library prefix; we should consider allowing an override for this, but I'm not sure it is really necessary. You should be able to get the item templates something like this (untested):

lib.client.get('items/new', { itemType: 'book' })

Meanwhile, to enable debug output simply add the modules you would like to debug to the DEBUG environment variable. DEBUG=zotero:* would include all components; but you can be more selective, e.g.: DEBUG=zotero:client,zotero:message.

inukshuk avatar May 20 '15 10:05 inukshuk

Found the problem for itemTypes. The valid URI is https://api.zotero.org/itemTypes. Calling lib.get('itemTypes') however, constructs the following URI: /users/[userId]/itemTypes which results in a 404.

So in the end, the overwrite might be necessary. A suggestion would be to parse for a / preceding the resource name, e.g. lib.get('/itemTypes').

flotob avatar May 21 '15 09:05 flotob

You can do lib.client.get('/itemTypes') — I would hesitate to change lib.get because it literally means 'get a resource of this library', but '/itemTypes' is not a resource of the library.

inukshuk avatar May 21 '15 09:05 inukshuk

Ah, right. client.get('/itemTypes') does the trick ;)

// edit: corrected URI

flotob avatar May 21 '15 10:05 flotob

Hi Folks, I'm learning JavaScript to port an application that I made using Free Pascal/Lazarus. The first thing I need to do is to read all Zotero Database.

I've downloaded the zotero-api-node from GutHub and trying to fetch some data. I already have Node installed on my machine.

Sorry for the generalized question, but every fully working sample will be a HUGE step for me.

What do I need to do to fetch all data of my Zotero libraries and save in the "json" format? Warm regards

debritto avatar Jun 25 '18 03:06 debritto

If you're working with the API, it's best to familiarize yourself with the API documentation. You can use the API using any HTTP library; using this node module provides some common functionality. For example, here is an example how to print all the items in your library in JSON format in a current version of Node.js (using promises and async/await):

    // Insert your user id and api key here.
    // See: https://www.zotero.org/settings/keys
    var USER_ID = '12345678'
    var API_KEY = 'abcdef123'

    var zotero = require('zotero')

    // Let's use the native Promises
    zotero.promisify(require('util').promisify)

    // Set your user id and API key  
    var lib = zotero({ user: USER_ID, key: API_KEY })

    // Here we define a function to print all items in a library in the given format
    async function printItems(format = 'json') {
      // Fetch the first 25 items
      var msg = await lib.items({ limit: 25, format })
      console.log(msg.data)

      // If there are more than 25 items,
      // fetch all the remaining pages until we're done
      if (msg.multi) {
        while (!msg.done) {
          msg = await msg.next()
          console.log(msg.data)
        }
      }
    } 

    // Actually print all items
    printItems()

inukshuk avatar Jun 25 '18 09:06 inukshuk

Hi @inukshuk , Thank you so much for your prompt and kind reply. ! It's exactly this kind of sample code that I was looking for.

I tried to run the code inside VCode, with NODE installed, but I'm getting this message:

[Running] node "c:\Users\Christian\OneDrive\Public\SmCube\Dev\SmCube_Pascal\Extra Components\Não utilizados\libZoteroJS-master\libZoteroJS-master\test\Zotero_API_Teste.js"
(node:1076) UnhandledPromiseRejectionWarning: Error: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>

    at Message.get (c:\Users\Christian\node_modules\zotero\lib\message.js:196:19)
    at Message.<anonymous> (c:\Users\Christian\node_modules\zotero\lib\client.js:150:22)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at Message.emit (events.js:208:7)
    at c:\Users\Christian\node_modules\zotero\lib\message.js:428:12
    at Message.txt (c:\Users\Christian\node_modules\zotero\lib\message.js:581:12)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
(node:1076) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1076) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

[Done] exited with code=0 in 1.182 seconds

Did I made something wrong? Best regards

debritto avatar Jun 25 '18 11:06 debritto

You can enable the debug log by setting the environment variable DEBUG to zotero:* when running the script; this would print exactly what API request you were sending, but my guess is that you did not use a valid user id perhaps?

inukshuk avatar Jun 25 '18 12:06 inukshuk

Hi @inukshuk , I'm so sorry but I have tried to run the code and debug but it's not working. The solution must be simple but it's still hard for me. Do you have another example to share or tips to fix this one?

debritto avatar Jun 26 '18 17:06 debritto

Well, if you've enabled debug, can you tell me which URL request results in the 400 Bad Request?

inukshuk avatar Jun 26 '18 18:06 inukshuk

Please, see here: https://prnt.sc/jzoqgm

debritto avatar Jun 26 '18 19:06 debritto

Unfortunately this does not help. You need to set the environment variable as I explained above. This will print out the request you're making which results in a code 400. (Alternatively you can set a breakpoint here when message.code is 400 and then look at the contents of options -- this would tell you the URL you're accessing.)

inukshuk avatar Jun 26 '18 19:06 inukshuk

I Understand. Sorry, this environment is new for me :(

Please, Can you check if do I settled environment variable correct?

Look Here: https://prnt.sc/jzpa7d https://prnt.sc/jzpagb Warm Regards

debritto avatar Jun 26 '18 20:06 debritto