Permalink
Browse files

Added CLI

  • Loading branch information...
1 parent 03856fc commit 30630d1c07fa50b8d0f5b5029d60d5890a01c936 @teozkr committed Nov 4, 2012
Showing with 76 additions and 0 deletions.
  1. +2 −0 README.rst
  2. +61 −0 rotx.py
  3. +13 −0 setup.py
View
@@ -9,6 +9,8 @@ rotx.py contains a single function, ``rot``. The signature for this function is
To decrypt, invert ``n``. ``alphabetical_only`` decides whether to only encrypt the ASCII letters (like a true caesar cipher, leaving the other characters intact, including numbers) or to use the full spectrum of the encoding in use (all 8 bits if a bytestring, up to 0xFFFF or 0x10FFFF for unicode depending on whether your Python installation was compiled with UCS-2/UTF-16 or UCS-4/UTF-32).
+There is also a CLI provided, run ``rotx -h`` for more documentation.
+
Testing
=======
Testing is done using tox and Pythonbrew, run the following assuming both of these have been installed to run the tests::
View
61 rotx.py
@@ -1,3 +1,20 @@
+"""Usage: rotx [options] <key> [<input> ...]
+
+Rotates a string byte-wise
+
+-h, --help Show this
+-d, --decrypt Reverse the rotation (equivalent to a negative key)
+<key> The key to rotate by
+<input> The string to rotate, will read from STDIN if not provided
+
+--rotate=<kind> can be:
+* letters Only rotate letters
+* all Rotate all characters
+"""
+
+import sys
+
+
try: # Detect whether the Python build uses UCS-4 or UCS-2, used to determine when to wrap around
unichr(0x10FFFF)
_py_ucs4 = True
@@ -71,3 +88,47 @@ def rot(input, n, alphabetical_only=True):
_type = type(input)
_chr = _type_chr(_type)
return _type().join(_chr(_rot_letter(i, n, alphabetical_only)) for i in input)
+
+
+def _main():
+ from docopt import docopt
+ from schema import Schema, Use, Or, SchemaError
+
+ schema = Schema({
+ '<key>': Use(int, error='The key must be an integer'),
+ '<input>': Use(' '.join),
+ '--decrypt': bool,
+ '--help': bool,
+ '--rotate': Or(None, lambda x: x in ['all', 'letters'], error='Invalid value for --rotate'),
+ })
+ try:
+ arguments = schema.validate(docopt(__doc__))
+ except SchemaError as exc:
+ sys.exit(exc.code)
+
+ decrypt = arguments['--decrypt']
+ rotate = arguments['--rotate']
+ input = arguments['<input>']
+ n = arguments['<key>']
+
+ if decrypt:
+ n *= -1
+ alphabetical_only = rotate != 'all'
+
+ if input:
+ print rot(input, n, alphabetical_only)
+ else:
+ buffer = ""
+ while True:
+ char = sys.stdin.read(1)
+ if char == '\n':
+ sys.stdout.write(rot(buffer, n, alphabetical_only))
+ sys.stdout.write('\n')
+ sys.stdout.flush()
+ buffer = ""
+ else:
+ buffer += char
+
+
+if __name__ == '__main__':
+ _main()
View
@@ -17,6 +17,19 @@ def run_tests(self):
setup(
name='rotx',
license='MIT',
+ py_modules=[
+ 'rotx',
+ ],
+ install_requires=[
+ 'docopt>=0.5.0',
+ 'schema>=0.1.1',
+ ],
+ entry_points={
+ 'console_scripts': [
+ 'rot = rotx:_main',
+ 'rotx = rotx:_main',
+ ],
+ },
tests_require=[
'pytest>=2.3.2',
],

0 comments on commit 30630d1

Please sign in to comment.