1
+ /*!
2
+ * Scribd - Unofficial NodeJS library
3
+ *
4
+ * Copyright(c) 2012 Firejune <to@firejune.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+
9
+ var crypto = require ( 'crypto' )
10
+ , qs = require ( 'querystring' )
11
+ , fs = require ( 'fs' )
12
+ , path = require ( 'path' )
13
+ , mime = require ( 'mime' )
14
+ , request = require ( 'request' )
15
+ , xml2json = require ( 'xml2json' ) . toJson ;
16
+
17
+
18
+ /**
19
+ * Scribd class
20
+ */
21
+
22
+ function Scribd ( apikey , secret ) {
23
+
24
+ this . version = '0.1.0' ;
25
+ this . apikey = apikey ;
26
+ this . secret = secret ;
27
+ this . url = "http://api.scribd.com/api?api_key=" + apikey ;
28
+
29
+ } ;
30
+
31
+
32
+ /**
33
+ * Scribd methods
34
+ */
35
+
36
+ Scribd . prototype = {
37
+
38
+ /**
39
+ * Upload a document from a file
40
+ * @param string file : relative path to file
41
+ * @param string doc_type : PDF, DOC, TXT, PPT, etc.
42
+ * @param string access : public or private. Default is Public.
43
+ * @param int rev_id : id of file to modify
44
+ * @return array containing doc_id, access_key, and secret_password if nessesary.
45
+ */
46
+ upload : function ( callback , file , docType , access , revId ) {
47
+ var method = "docs.upload"
48
+ , params = {
49
+ file : file
50
+ , doc_type : docType || null
51
+ , access : access || null
52
+ , rev_id : revId || null
53
+ } ;
54
+
55
+ postRequest . bind ( this ) ( callback , method , params ) ;
56
+ } ,
57
+
58
+ /**
59
+ * Upload a document from a Url
60
+ * @param string url : absolute URL of file
61
+ * @param string doc_type : PDF, DOC, TXT, PPT, etc.
62
+ * @param string access : public or private. Default is Public.
63
+ * @return array containing doc_id, access_key, and secret_password if nessesary.
64
+ */
65
+ uploadFromUrl : function ( callback , url , docType , access , revId ) {
66
+ var method = "docs.uploadFromUrl"
67
+ , params = {
68
+ url : url
69
+ , doc_type : docType || null
70
+ , access : access || null
71
+ , rev_id : revId || null
72
+ } ;
73
+
74
+ return postRequest . bind ( this ) ( callback , method , params ) ;
75
+ } ,
76
+
77
+ /**
78
+ * Get a list of the current users files
79
+ * @return array containing doc_id, title, description, access_key, and conversion_status for all documents
80
+ */
81
+ getList : function ( callback ) {
82
+ var method = "docs.getList" ;
83
+
84
+ return postRequest . bind ( this ) ( function ( err , res ) {
85
+ callback ( err , res . resultset || res ) ;
86
+ } , method ) ;
87
+ } ,
88
+
89
+ /**
90
+ * Get the current conversion status of a document
91
+ * @param int doc_id : document id
92
+ * @return string containing DISPLAYABLE", "DONE", "ERROR", or "PROCESSING" for the current document.
93
+ */
94
+ getConversionStatus : function ( callback , docId ) {
95
+ var method = "docs.getConversionStatus"
96
+ , params = { doc_id : docId } ;
97
+
98
+ return postRequest . bind ( this ) ( function ( err , res ) {
99
+ callback ( err , res . conversion_status || res ) ;
100
+ } , method , params ) ;
101
+ } ,
102
+
103
+ /**
104
+ * Get settings of a document
105
+ * @return array containing doc_id, title , description , access, tags, show_ads, license, access_key, secret_password
106
+ */
107
+ getSettings : function ( callback , docId ) {
108
+ var method = "docs.getSettings"
109
+ , params = { doc_id : docId } ;
110
+
111
+ return postRequest . bind ( this ) ( callback , method , params ) ;
112
+ } ,
113
+
114
+ /**
115
+ * Change settings of a document
116
+ * @param array doc_ids : document id
117
+ * @param string title : title of document
118
+ * @param string description : description of document
119
+ * @param string access : private, or public
120
+ * @param string license : "by", "by-nc", "by-nc-nd", "by-nc-sa", "by-nd", "by-sa", "c" or "pd"
121
+ * @param string access : private, or public
122
+ * @param array show_ads : default, true, or false
123
+ * @param array tags : list of tags
124
+ * @return string containing DISPLAYABLE", "DONE", "ERROR", or "PROCESSING" for the current document.
125
+ */
126
+ changeSettings : function ( callback , docIds , title , description , access , license , showAds , tags ) {
127
+ var method = "docs.changeSettings"
128
+ , params = {
129
+ doc_ids : docIds
130
+ , title : title || null
131
+ , description : description || null
132
+ , access : access || null
133
+ , license : license || null
134
+ , show_ads : showAds || null
135
+ , tags : tags || null
136
+ } ;
137
+
138
+ return postRequest . bind ( this ) ( callback , method , params ) ;
139
+ } ,
140
+
141
+ /**
142
+ * Delete a document
143
+ * @param int doc_id : document id
144
+ * @return 1 on success;
145
+ */
146
+ remove : function ( callback , docId ) {
147
+ var method = "docs.delete"
148
+ , params = { doc_id : docId } ;
149
+
150
+ return postRequest . bind ( this ) ( callback , method , params ) ;
151
+ } ,
152
+
153
+ /**
154
+ * Search the Scribd database
155
+ * @param string query : search query
156
+ * @param int num_results : number of results to return (10 default, 1000 max)
157
+ * @param int num_start : number to start from
158
+ * @param string scope : scope of search, "all" or "user"
159
+ * @return array of results, each of which contain doc_id, secret password, access_key, title, and description
160
+ */
161
+ search : function ( callback , query , numResults , numStart , scope ) {
162
+ var method = "docs.search"
163
+ , params = {
164
+ query : query
165
+ , num_results : numResults || null
166
+ , num_start : numStart || null
167
+ , scope : scope || null
168
+ } ;
169
+
170
+ return postRequest . bind ( this ) ( function ( err , res ) {
171
+ callback ( err , res . result_set || res ) ;
172
+ } , method , params ) ;
173
+ } ,
174
+
175
+ /**
176
+ * Login as a user
177
+ * @param string username : username of user to log in
178
+ * @param string password : password of user to log in
179
+ * @return array containing session_key, name, username, and user_id of the user;
180
+ */
181
+ login : function ( callback , username , password ) {
182
+ var method = "user.login"
183
+ , params = {
184
+ username : username
185
+ , password : password
186
+ } ;
187
+
188
+ return postRequest . bind ( this ) ( function ( err , res ) {
189
+ if ( ! err ) this . session_key = res [ 'session_key' ] ;
190
+ callback ( err , res ) ;
191
+ } . bind ( this ) , method , params ) ;
192
+ } ,
193
+
194
+ /**
195
+ * Sign up a new user
196
+ * @param string username : username of user to create
197
+ * @param string password : password of user to create
198
+ * @param string email : email address of user
199
+ * @param string name : name of user
200
+ * @return array containing session_key, name, username, and user_id of the user;
201
+ */
202
+ signup : function ( callback , username , password , email , name ) {
203
+ var method = "user.signup"
204
+ , params = {
205
+ username : username
206
+ , password : password
207
+ , email : email
208
+ , name : name || null
209
+ } ;
210
+
211
+ return postRequest . bind ( this ) ( callback , method , params ) ;
212
+ }
213
+ } ;
214
+
215
+ /**
216
+ * Request helper
217
+ */
218
+
219
+ function postRequest ( callback , method , params ) {
220
+ var options = { uri : this . url } ;
221
+
222
+ params = objectExtend ( { method : method } , params ) ;
223
+ params [ 'api_sig' ] = generateSig ( {
224
+ method : method
225
+ , session_key : this . session_key
226
+ , my_user_id : this . my_user_id
227
+ } , this . secret ) ;
228
+
229
+ if ( params . file && fs . existsSync ( params . file ) ) {
230
+ options . headers = { 'content-type' : 'multipart/form-data' } ,
231
+ options . multipart = [ {
232
+ 'Content-Disposition' : 'form-data; name="file"; filename="' + path . basename ( params . file ) + '"'
233
+ , 'Content-Type' : mime . lookup ( params . file )
234
+ , body : fs . readFileSync ( params . file )
235
+ } ] ;
236
+
237
+ Object . keys ( params ) . forEach ( function ( key ) {
238
+ key != 'file' && options . multipart . push ( {
239
+ 'Content-Disposition' : 'form-data; name="' + key + '"'
240
+ , body : params [ key ]
241
+ } )
242
+ } ) ;
243
+ } else {
244
+ options . body = qs . stringify ( params ) ;
245
+ }
246
+
247
+ return request . post ( options , function ( err , res , body ) {
248
+ if ( err ) return callback ( err , body ) ;
249
+ try {
250
+ body = xml2json ( body , { object : true } ) ;
251
+ if ( body . rsp ) {
252
+ if ( body . rsp . stat == 'fail' ) err = body . rsp . stat ;
253
+ callback ( err , body . rsp ) ;
254
+ }
255
+ } catch ( e ) {
256
+ callback ( body )
257
+ }
258
+ } ) ;
259
+ }
260
+
261
+
262
+ /**
263
+ * Object extend
264
+ */
265
+
266
+ function objectExtend ( obj1 , obj2 ) {
267
+ obj2 && Object . keys ( obj2 ) . forEach ( function ( key ) {
268
+ if ( obj2 [ key ] ) obj1 [ key ] = obj2 [ key ] ;
269
+ } ) ;
270
+
271
+ return obj1 ;
272
+ } ;
273
+
274
+
275
+ /**
276
+ * Generate signature
277
+ */
278
+
279
+ function generateSig ( params , secret ) {
280
+ var str = '' ;
281
+
282
+ // Note: make sure that the signature parameter is not already included in params.
283
+ Object . keys ( params ) . forEach ( function ( key ) {
284
+ str += key + params [ key ] ;
285
+ } ) ;
286
+
287
+ str = secret + str ;
288
+
289
+ return crypto . createHash ( 'md5' ) . update ( str ) . digest ( "hex" ) ;
290
+ }
291
+
292
+
293
+
294
+ /**
295
+ * Export intance of Scribd as the module
296
+ */
297
+
298
+ module . exports = Scribd ;
0 commit comments