mirror of
https://github.com/Tygs/0bin.git
synced 2023-08-10 21:13:00 +03:00
Merge pull request #39 from mk-fg/add_zerobinpaste_cli_tool
Add simple "zerobinpaste" cli tool
This commit is contained in:
commit
09d7bb4f24
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,6 +15,10 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
|
|
||||||
|
/tools/zerobinpaste.js
|
||||||
|
/tools/zerobinpaste.min
|
||||||
|
/tools/zerobinpaste
|
||||||
|
|
||||||
# files generated by setuptools
|
# files generated by setuptools
|
||||||
|
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
@ -57,7 +57,8 @@ Other features
|
|||||||
- copy paste to clipboard in a click;
|
- copy paste to clipboard in a click;
|
||||||
- get paste short URL in a click;
|
- get paste short URL in a click;
|
||||||
- own previous pastes history;
|
- own previous pastes history;
|
||||||
- visual hash of a paste to easily tell it apart from others in a list.
|
- visual hash of a paste to easily tell it apart from others in a list;
|
||||||
|
- optional command-line tool to encrypt and paste data from shell or scripts.
|
||||||
|
|
||||||
Technologies used
|
Technologies used
|
||||||
==================
|
==================
|
||||||
@ -69,6 +70,7 @@ Technologies used
|
|||||||
- Bootstrap_, the Twitter HTML5/CSS3 framework
|
- Bootstrap_, the Twitter HTML5/CSS3 framework
|
||||||
- VizHash.js_ to create visual hashes from pastes
|
- VizHash.js_ to create visual hashes from pastes
|
||||||
- Cherrypy_ (server only)
|
- Cherrypy_ (server only)
|
||||||
|
- `node.js`_ (for optional command-line tool only)
|
||||||
|
|
||||||
|
|
||||||
Known issues
|
Known issues
|
||||||
@ -96,5 +98,6 @@ What does 0bin not implement?
|
|||||||
.. _Bootstrap: http://twitter.github.com/bootstrap/
|
.. _Bootstrap: http://twitter.github.com/bootstrap/
|
||||||
.. _VizHash.js: https://github.com/sametmax/VizHash.js
|
.. _VizHash.js: https://github.com/sametmax/VizHash.js
|
||||||
.. _Cherrypy: http://www.cherrypy.org/ (server only)
|
.. _Cherrypy: http://www.cherrypy.org/ (server only)
|
||||||
|
.. _node.js: http://nodejs.org/
|
||||||
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
|
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
|
||||||
.. _WTF licence: http://en.wikipedia.org/wiki/WTFPL
|
.. _WTF licence: http://en.wikipedia.org/wiki/WTFPL
|
||||||
|
@ -45,7 +45,8 @@ Other features
|
|||||||
- copy paste to clipboard in a click;
|
- copy paste to clipboard in a click;
|
||||||
- get paste short URL in a click;
|
- get paste short URL in a click;
|
||||||
- own previous pastes history;
|
- own previous pastes history;
|
||||||
- visual hash of a paste to easily tell it apart from others in a list.
|
- visual hash of a paste to easily tell it apart from others in a list;
|
||||||
|
- `optional command-line tool`_ to encrypt and paste data from shell or scripts.
|
||||||
|
|
||||||
Technologies used
|
Technologies used
|
||||||
==================
|
==================
|
||||||
@ -57,6 +58,7 @@ Technologies used
|
|||||||
- Bootstrap_, the Twitter HTML5/CSS3 framework
|
- Bootstrap_, the Twitter HTML5/CSS3 framework
|
||||||
- VizHash.js_ to create visual hashes from pastes
|
- VizHash.js_ to create visual hashes from pastes
|
||||||
- Cherrypy_ (server only)
|
- Cherrypy_ (server only)
|
||||||
|
- `node.js`_ (for optional command-line tool only)
|
||||||
|
|
||||||
|
|
||||||
Known issues
|
Known issues
|
||||||
@ -84,4 +86,6 @@ What does 0bin not implement?
|
|||||||
.. _Bootstrap: http://twitter.github.com/bootstrap/
|
.. _Bootstrap: http://twitter.github.com/bootstrap/
|
||||||
.. _VizHash.js: https://github.com/sametmax/VizHash.js
|
.. _VizHash.js: https://github.com/sametmax/VizHash.js
|
||||||
.. _Cherrypy: http://www.cherrypy.org/ (server only)
|
.. _Cherrypy: http://www.cherrypy.org/ (server only)
|
||||||
|
.. _node.js: http://nodejs.org/
|
||||||
|
.. _optional command-line tool: ./zerobinpaste_tool
|
||||||
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
|
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
|
||||||
|
100
docs/en/zerobinpaste_tool.rst
Normal file
100
docs/en/zerobinpaste_tool.rst
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
==============================
|
||||||
|
zerobinpaste command-line tool
|
||||||
|
==============================
|
||||||
|
|
||||||
|
zerobinpaste is a simple CLI tool (analogous to pastebinit or wgetpaste) to use
|
||||||
|
with files or shell redirection in terminal or simple scripts.
|
||||||
|
|
||||||
|
Example use-cases might look like::
|
||||||
|
|
||||||
|
% zerobinpaste README.rst
|
||||||
|
http://some.0bin.site/paste/0cc3d8a8...
|
||||||
|
|
||||||
|
% grep error /var/log/syslog | zerobinpaste
|
||||||
|
http://some.0bin.site/paste/81fd1324...
|
||||||
|
|
||||||
|
% zerobinpaste docs/en/*.rst
|
||||||
|
easy_install.rst http://some.0bin.site/paste/9adc576a...
|
||||||
|
apache_install.rst http://some.0bin.site/paste/01408cbd...
|
||||||
|
options.rst http://some.0bin.site/paste/921b2768...
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
% ps axlf | zerobinpaste | mail -s "Process tree on $(date)" root
|
||||||
|
|
||||||
|
Produced links can then be copy-pasted to some IRC channel or used in whatever
|
||||||
|
other conceivable way.
|
||||||
|
|
||||||
|
Tool does encryption by itself on the client machine and key (after hashmark) is
|
||||||
|
never sent to server or anywhere but the tool's stdout stream (e.g. terminal).
|
||||||
|
|
||||||
|
Tool has to be built with `node.js`_ separately (see below).
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
At least the pastebin site (main URL where you'd paste stuff with the browser)
|
||||||
|
has to be specified for the tool to use either via -u (--url) option (can be
|
||||||
|
simplified with shell alias - e.g. ``alias zp='zerobinpaste -u http://some.0bin.site``)
|
||||||
|
or in the "~/.zerobinpasterc" configuration file (json format).
|
||||||
|
|
||||||
|
| Non-option arguments are interpreted as files to upload/paste contents of.
|
||||||
|
| If no arguments are specified, data to paste will be read from stdin stream.
|
||||||
|
|
||||||
|
Simple configuration file may look like this:
|
||||||
|
|
||||||
|
{"url": "http://some.0bin.site"}
|
||||||
|
|
||||||
|
Any options (in the long form, e.g. "url" for --url above) that are allowed on
|
||||||
|
the command-line can be specified there.
|
||||||
|
|
||||||
|
Run the tool with -h or --help option to see full list of supported parameters.
|
||||||
|
|
||||||
|
|
||||||
|
Build / Installation
|
||||||
|
====================
|
||||||
|
|
||||||
|
In essence:
|
||||||
|
|
||||||
|
0bin% cd tools
|
||||||
|
0bin/tools% make
|
||||||
|
...
|
||||||
|
0bin/tools% cp zerobinpaste ~/bin # install to PATH
|
||||||
|
|
||||||
|
"npm" binary (packaged and installed with node.js) is required to pull in build
|
||||||
|
dependencies, if necessary, and "node" binary is required for produced binary to
|
||||||
|
run.
|
||||||
|
|
||||||
|
Use "make" in "tools" path to produce non-minified runnable "zerobinpaste"
|
||||||
|
script there.
|
||||||
|
|
||||||
|
``make ugly`` command can be used instead of ``make`` to create "minified"
|
||||||
|
version (using/installing uglifyjs_, about 25% smaller in size).
|
||||||
|
|
||||||
|
Resulting "zerobinpaste" script requires only node.js ("node" binary) installed
|
||||||
|
to run and can be placed in any of the PATH dirs (e.g. "~/bin",
|
||||||
|
"/usr/local/bin") to be run just as "zerobinpaste".
|
||||||
|
|
||||||
|
|
||||||
|
Why node.js and not python
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Unfortunately, it's fairly complex and unreliable to replicate non-trivial and
|
||||||
|
undocumented encryption protocol that SJCL_ convenience methods employ, and any
|
||||||
|
mistake in encryption is guaranteed to produce unreadable paste.
|
||||||
|
|
||||||
|
Current implementation uses same JavaScript code (and V8 node.js engine) that
|
||||||
|
browsers do, hence can be fairly simple and robust.
|
||||||
|
|
||||||
|
Future development plans include supporting configurable, less complex and more
|
||||||
|
widespread encryption schemas, allowing for simplier non-javascript client as
|
||||||
|
well.
|
||||||
|
|
||||||
|
See `related pull request`_ for more details.
|
||||||
|
|
||||||
|
|
||||||
|
.. _node.js: http://nodejs.org/
|
||||||
|
.. _uglifyjs: https://github.com/mishoo/UglifyJS
|
||||||
|
.. _SJCL: http://crypto.stanford.edu/sjcl/
|
||||||
|
.. _related pull request: https://github.com/sametmax/0bin/pull/39
|
@ -22,6 +22,7 @@
|
|||||||
| en/using_supervisor | fr/using_supervisor |
|
| en/using_supervisor | fr/using_supervisor |
|
||||||
| en/theming | fr/theming |
|
| en/theming | fr/theming |
|
||||||
| en/options | fr/options |
|
| en/options | fr/options |
|
||||||
|
| en/zerobinpaste_tool | |
|
||||||
| | |
|
| | |
|
||||||
|`Report a bug`_ |`Signaler un bug`_ |
|
|`Report a bug`_ |`Signaler un bug`_ |
|
||||||
+-------------------------+--------------------------------+
|
+-------------------------+--------------------------------+
|
||||||
|
25
tools/Makefile
Normal file
25
tools/Makefile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
zerobinpaste: zerobinpaste.js commander.js ../zerobin/static/js/sjcl.js ../zerobin/static/js/lzw.js
|
||||||
|
echo '#!/usr/bin/env node' > zerobinpaste
|
||||||
|
cat commander.js ../zerobin/static/js/sjcl.js ../zerobin/static/js/lzw.js >> zerobinpaste
|
||||||
|
cat zerobinpaste.js >> zerobinpaste
|
||||||
|
chmod +x zerobinpaste
|
||||||
|
|
||||||
|
ugly: zerobinpaste
|
||||||
|
uglifyjs=$$(PATH="$$(npm bin):$$PATH" which uglifyjs 2>/dev/null) \
|
||||||
|
|| { npm install uglify-js; uglifyjs=$$(PATH="$$(npm bin):$$PATH" which uglifyjs); } \
|
||||||
|
&& sed -i 1d zerobinpaste \
|
||||||
|
&& $${uglifyjs} -o zerobinpaste.min zerobinpaste \
|
||||||
|
&& echo '#!/usr/bin/env node' > zerobinpaste \
|
||||||
|
&& cat zerobinpaste.min >> zerobinpaste \
|
||||||
|
&& chmod +x zerobinpaste
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f zerobinpaste{,.js,.min}
|
||||||
|
|
||||||
|
zerobinpaste.js: zerobinpaste.coffee
|
||||||
|
coffee=$$(PATH="$$(npm bin):$$PATH" which coffee 2>/dev/null) \
|
||||||
|
|| { npm install coffee-script; coffee=$$(PATH="$$(npm bin):$$PATH" which coffee); } \
|
||||||
|
&& $$coffee -c zerobinpaste.coffee
|
||||||
|
|
||||||
|
.PHONY: uglify
|
1118
tools/commander.js
Normal file
1118
tools/commander.js
Normal file
File diff suppressed because it is too large
Load Diff
103
tools/zerobinpaste.coffee
Normal file
103
tools/zerobinpaste.coffee
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
program
|
||||||
|
.version('0.0.1')
|
||||||
|
.usage('[options] [ file ... ]\n\n' + ' Paste contents of file(s) or stdin to 0bin site.')
|
||||||
|
.option('-u, --url [url]', 'URL of a 0bin site.')
|
||||||
|
.option('-e, --expire [period]',
|
||||||
|
'Expiration period - one of: 1_view, 1_day (default), 1_month, never.', '1_day')
|
||||||
|
.option('-c, --config [path]', 'Path to zerobin configuration file (default: ~/.zerobinpasterc).\n'\
|
||||||
|
+ ' Should be json-file with the same keys as can be specified on the command line.\n'\
|
||||||
|
+ ' Example contents: {"url": "http://some-0bin.com"}', '~/.zerobinpasterc')
|
||||||
|
.parse(process.argv);
|
||||||
|
|
||||||
|
|
||||||
|
[http, url, qs, fs, path] = ['http', 'url', 'querystring', 'fs', 'path'].map(require)
|
||||||
|
|
||||||
|
|
||||||
|
# Parse config file, if any
|
||||||
|
config = program.config.replace(/^~\/+/, '')
|
||||||
|
config = path.resolve(process.env.HOME, config)
|
||||||
|
|
||||||
|
try
|
||||||
|
if fs.statSync(config).isFile()
|
||||||
|
config = JSON.parse(fs.readFileSync(config))
|
||||||
|
(program[k] = v) for own k, v of config
|
||||||
|
|
||||||
|
|
||||||
|
# Sanity checks and option processing
|
||||||
|
if not program.url
|
||||||
|
console.error('ERROR: URL option must be specified.')
|
||||||
|
process.exit(1)
|
||||||
|
|
||||||
|
if program.expire == '1_view'
|
||||||
|
# "burn_after_reading" is too damn long for cli
|
||||||
|
program.expire = 'burn_after_reading'
|
||||||
|
|
||||||
|
expire_opts = ['burn_after_reading', '1_day', '1_month', 'never']
|
||||||
|
if program.expire not in expire_opts
|
||||||
|
console.error(
|
||||||
|
"ERROR: --expire value (provided: '#{program.expire}')"\
|
||||||
|
+ ' must be one of: ' + expire_opts.join(', ') + "." )
|
||||||
|
process.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# Paste one dump and print URL, optionally prefixed with name
|
||||||
|
paste_file = (content, name) ->
|
||||||
|
|
||||||
|
content = sjcl.codec.utf8String.toBits(content)
|
||||||
|
content = sjcl.codec.base64.fromBits(content)
|
||||||
|
# content = lzw.compress(content)
|
||||||
|
|
||||||
|
key = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0)
|
||||||
|
content = sjcl.encrypt(key, content)
|
||||||
|
content = qs.stringify
|
||||||
|
content: content
|
||||||
|
expiration: program.expire
|
||||||
|
|
||||||
|
# host.com -> http://host.com
|
||||||
|
if not program.url.match(/^https?:\/\//)
|
||||||
|
program.url = 'http://' + program.url.replace(/^\/+/, '')
|
||||||
|
|
||||||
|
req_opts = url.parse(program.url)
|
||||||
|
req_opts.method = 'POST'
|
||||||
|
req_opts.headers =
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
'Content-Length': content.length
|
||||||
|
|
||||||
|
req_url_base = req_opts.path
|
||||||
|
.replace(/\/paste\/create\/?$/, '').replace(/\/+$/, '')
|
||||||
|
req_opts.path = req_url_base + '/paste/create'
|
||||||
|
|
||||||
|
req = http.request req_opts, (res) ->
|
||||||
|
req_reply = ''
|
||||||
|
res.setEncoding('utf8')
|
||||||
|
res.on 'data', (chunk) -> req_reply += chunk
|
||||||
|
res.on 'end', ->
|
||||||
|
req_reply = JSON.parse(req_reply)
|
||||||
|
if req_reply.status != 'ok'
|
||||||
|
console.error("ERROR: failure posting #{name} - " + req_reply.message)
|
||||||
|
return
|
||||||
|
|
||||||
|
req_opts.pathname = req_url_base + '/paste/' + req_reply.paste
|
||||||
|
req_opts.hash = key
|
||||||
|
paste = url.format(req_opts)
|
||||||
|
|
||||||
|
console.log(if name then "#{name} #{paste}" else paste)
|
||||||
|
|
||||||
|
req.write(content)
|
||||||
|
req.end()
|
||||||
|
|
||||||
|
|
||||||
|
# Loop over file args or read stdin
|
||||||
|
if not program.args or not program.args.length
|
||||||
|
process.stdin.resume()
|
||||||
|
process.stdin.setEncoding('utf8')
|
||||||
|
|
||||||
|
stdin_data = ''
|
||||||
|
process.stdin.on 'data', (chunk) -> stdin_data += chunk
|
||||||
|
process.stdin.on 'end', -> paste_file(stdin_data)
|
||||||
|
|
||||||
|
else
|
||||||
|
for file in program.args
|
||||||
|
paste_file( fs.readFileSync(file, 'utf8'),
|
||||||
|
if program.args.length > 1 then path.basename(file) else null )
|
@ -107,5 +107,4 @@ var lzw = {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user