diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50a0c39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +node_modules/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5653d46 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: + coffee -o lib -c src + +clean: + rm lib/*.js diff --git a/bin/aur-info b/bin/aur-info index 1c6d65d..d08bec9 100755 --- a/bin/aur-info +++ b/bin/aur-info @@ -1,6 +1,5 @@ #!/usr/bin/env node -require ('coffee-script'); var aur = require('../lib/aur'); var argv = require('optimist') diff --git a/bin/aur-publish b/bin/aur-publish index 2502ed1..a207985 100755 --- a/bin/aur-publish +++ b/bin/aur-publish @@ -1,6 +1,5 @@ #!/usr/bin/env node -require ('coffee-script'); var aur = require('../lib/aur'); var argv = require('optimist') diff --git a/lib/aur.js b/lib/aur.js new file mode 100644 index 0000000..42be5d7 --- /dev/null +++ b/lib/aur.js @@ -0,0 +1,164 @@ +// Generated by CoffeeScript 1.6.3 +(function() { + var FormData, aur, cheerio, config, defaultCb, fs, querystring, request, _; + + request = require('request'); + + querystring = require('querystring'); + + FormData = require('form-data'); + + fs = require('fs'); + + _ = require('underscore'); + + config = require('./config'); + + cheerio = require("cheerio"); + + request = request.defaults({ + proxy: process.env['https_proxy'], + jar: false + }); + + aur = module.exports = { + info: function(name, options, cb) { + var url; + if (typeof options === 'function') { + cb = options; + options = {}; + } + cb || (cb = defaultCb); + options = _.extend({}, config, options); + url = options.url.base + options.url.info + name; + return request({ + url: url + }, function(err, resp, body) { + var json; + if (err) { + return cb(err); + } + json = JSON.parse(body); + if (json.type === 'error') { + return cb(new Error(json.results)); + } + return cb(null, json.results); + }); + }, + publish: function(user, password, filePkg, category, options, cb) { + var categories, categoryId; + if (typeof options === 'function') { + cb = options; + options = {}; + } + cb || (cb = defaultCb); + if (typeof category === 'object') { + options = category; + category = null; + } + category || (category = 'system'); + options = _.extend({}, config, options); + categories = { + daemons: 2, + devel: 3, + editors: 4, + emulators: 5, + games: 6, + gnome: 7, + i18n: 8, + kde: 9, + lib: 10, + modules: 11, + multimedia: 12, + network: 13, + office: 14, + science: 15, + system: 16, + x11: 17, + xfce: 18, + kernels: 19 + }; + categoryId = categories[category]; + return this.login(user, password, options, function(err, cookie) { + var form; + if (err) { + return cb(err); + } + form = new FormData(); + form.append('pkgsubmit', '1'); + form.append('token', cookie.replace('AURSID=', '')); + form.append('category', categoryId + ''); + form.append('pfile', fs.createReadStream(filePkg)); + return form.getLength(function(err, length) { + if (err) { + return cb(err); + } + return form.pipe(request({ + method: 'POST', + headers: form.getHeaders({ + 'Cookie': cookie, + 'Content-Length': length + }), + url: options.url.base + (options.url.post || '') + }, function(err, resp, data) { + var $; + if (err) { + return cb(err); + } + $ = cheerio.load(data); + if ($('.pkgoutput').text()) { + return cb(new Error($(".pkgoutput").text())); + } + return cb(null, data); + })); + }); + }); + }, + login: function(user, password, options, cb) { + var dataForm, url; + if (typeof options === 'function') { + cb = options; + options = {}; + } + cb || (cb = defaultCb); + options = _.extend({}, config, options); + url = options.url.base + (options.url.login || ''); + dataForm = querystring.stringify({ + user: user, + passwd: password + }); + return request({ + url: url, + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': dataForm.length + }, + body: dataForm + }, function(err, resp) { + var regex, setCookie, sid; + if (err) { + return cb(err); + } + if (!resp.headers['set-cookie']) { + return cb(new Error('Wrong login or password')); + } + setCookie = resp.headers['set-cookie']; + regex = /AURSID=\w*/; + if (!regex.test(setCookie)) { + return cb(new Error('No SessionID')); + } + sid = regex.exec(setCookie)[0]; + return cb(null, sid); + }); + } + }; + + defaultCb = function(err, results) { + if (err) { + return console.error(err); + } + return console.log(results); + }; + +}).call(this); diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..8241db4 --- /dev/null +++ b/lib/config.js @@ -0,0 +1,12 @@ +// Generated by CoffeeScript 1.6.3 +(function() { + module.exports = { + url: { + base: 'https://aur.archlinux.org/', + info: 'rpc.php?type=info&arg=', + post: 'submit/', + login: 'login/' + } + }; + +}).call(this); diff --git a/package.json b/package.json index b84fae6..84c5424 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Filirom1 ", "name": "aur", "description": "Archlinux AUR cli", - "version": "0.1.2", + "version": "0.1.3", "homepage": "https://github.com/Filirom1/nodejs-aur", "repository": { "type": "git", @@ -12,7 +12,7 @@ "type": "MIT", "url": "http://www.opensource.org/licenses/MIT" }, - "main": "lib/aur.coffee", + "main": "lib/aur", "bin": { "aur-info": "bin/aur-info", "aur-publish": "bin/aur-publish" @@ -24,16 +24,16 @@ "dependencies": { "form-data": "https://github.com/Filirom1/node-form-data/tarball/master", "request": "~2.9.202", - "coffee-script": "~1.3.3", "underscore": "~1.3.3", "optimist": "~0.3.4", "cheerio": "~0.8.3" }, "devDependencies": { + "coffee-script": "~1.6.3", "vows": "0.6.x", "express": "2.5.x" }, "scripts": { - "test": "./node_modules/.bin/vows test/* --spec" + "test": "./node_modules/.bin/vows test/*.coffee --spec" } } diff --git a/lib/aur.coffee b/src/aur.coffee similarity index 96% rename from lib/aur.coffee rename to src/aur.coffee index f512907..21af7f9 100644 --- a/lib/aur.coffee +++ b/src/aur.coffee @@ -72,7 +72,7 @@ aur = module.exports = headers: form.getHeaders 'Cookie': cookie 'Content-Length': length - url: options.url.base + options.url.post + url: options.url.base + (options.url.post || '') , (err, resp, data) -> return cb err if err $ = cheerio.load data @@ -86,7 +86,7 @@ aur = module.exports = options = {} cb or= defaultCb options = _.extend {}, config, options - url = options.url.base + url = options.url.base + (options.url.login || '') # Create the auth data form dataForm = querystring.stringify diff --git a/lib/config.coffee b/src/config.coffee similarity index 71% rename from lib/config.coffee rename to src/config.coffee index 9c83ecf..50c9c68 100644 --- a/lib/config.coffee +++ b/src/config.coffee @@ -2,4 +2,5 @@ module.exports = url: base: 'https://aur.archlinux.org/' info: 'rpc.php?type=info&arg=' - post: 'pkgsubmit.php' + post: 'submit/' + login: 'login/' diff --git a/test/aur.coffee b/test/aur.coffee index 0a480fe..18af871 100644 --- a/test/aur.coffee +++ b/test/aur.coffee @@ -1,7 +1,8 @@ vows = require 'vows' assert = require 'assert' express = require 'express' -aur = require '../lib/aur' +aur = require '../src/aur' +fs = require "fs" app = express.createServer() app.use express.bodyParser() @@ -86,7 +87,8 @@ config = url: base: "http://localhost:#{port}/" info: 'rpc.php?type=info&arg=' - post: 'pkgsubmit.php' + login: 'login/' + post: 'submit/' dummyPkg = Maintainer: 'filirom1' @@ -106,7 +108,7 @@ dummyPkg = app.use express.bodyParser() # Search -app.get '/rpc.php', (req, res)-> +app.get "/rpc.php", (req, res)-> throw new Error 'arg not specified' if not req.query.arg if req.query.arg is 'nodejs-npm2arch' res.json type: 'info', results: dummyPkg @@ -114,7 +116,7 @@ app.get '/rpc.php', (req, res)-> res.json type: 'error', results: 'No results found' # Login -app.post '/', (req, res)-> +app.post "/#{config.url.login}", (req, res)-> if req.body.user is 'user' and req.body.passwd is 'passwd' res.cookie('AURSID','70bd1ee338d6767283b81e3e50c3610b', {httpOnly: true, secure: true, path: '/'}) res.send ''