|
| 1 | +#!/usr/bin/env python |
| 2 | +## |
| 3 | +# The MIT License (MIT) |
| 4 | +# |
| 5 | +# Copyright (c) 2015 Indigen Solution. |
| 6 | +# |
| 7 | +# Permission is hereby granted, free of charge, to any person obtaining a copy |
| 8 | +# of this software and associated documentation files (the "Software"), to deal |
| 9 | +# in the Software without restriction, including without limitation the rights |
| 10 | +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 11 | +# copies of the Software, and to permit persons to whom the Software is |
| 12 | +# furnished to do so, subject to the following conditions: |
| 13 | +# |
| 14 | +# The above copyright notice and this permission notice shall be included in |
| 15 | +# all copies or substantial portions of the Software. |
| 16 | +# |
| 17 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 18 | +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 19 | +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 20 | +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 21 | +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 22 | +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 23 | +# THE SOFTWARE. |
| 24 | +## |
| 25 | + |
| 26 | +import sys |
| 27 | +import argparse |
| 28 | +import swiftclient |
| 29 | + |
| 30 | +VERSION="@@VERSION@@" |
| 31 | + |
| 32 | +## |
| 33 | +# This stream wrapper simmulate end of stream after "split" byte have been read. |
| 34 | +# If "split" parameter is set to -1 it will behave like a normal stream. |
| 35 | +# Don't forget to call restart to restart the stream. |
| 36 | +## |
| 37 | +class StreamSplitter: |
| 38 | + def __init__(self, stream, splitSize = -1): |
| 39 | + self._stream = stream; |
| 40 | + self._splitSize = splitSize; |
| 41 | + self._readSize = 0; |
| 42 | + self._eof = False; |
| 43 | + |
| 44 | + def reset(self): |
| 45 | + self._readSize = 0; |
| 46 | + |
| 47 | + def isEOF(self): |
| 48 | + return self._eof; |
| 49 | + |
| 50 | + def read(self, size = -1): |
| 51 | + if (self._splitSize == -1): |
| 52 | + pass |
| 53 | + elif (self._readSize == self._splitSize): |
| 54 | + return ""; |
| 55 | + elif (size + self._readSize > self._splitSize): |
| 56 | + size = self._splitSize - self._readSize; |
| 57 | + |
| 58 | + result = self._stream.read(size); |
| 59 | + length = len(result); |
| 60 | + self._readSize += length; |
| 61 | + |
| 62 | + if (length == 0): |
| 63 | + self._eof = True; |
| 64 | + |
| 65 | + return result; |
| 66 | + |
| 67 | +## |
| 68 | +# Convert human readable size to int (Ex 128.3M -> 128 300 000) |
| 69 | +## |
| 70 | +class SizeArgparseAction(argparse.Action): |
| 71 | + def __call__(self, parser, namespace, values, option_string=None): |
| 72 | + setattr(namespace, self.dest, self.human2bytes(values)); |
| 73 | + |
| 74 | + @staticmethod |
| 75 | + def human2bytes(s): |
| 76 | + UNITS = {'B' : 1, |
| 77 | + 'K' : 1024, |
| 78 | + 'M' : 1048576, |
| 79 | + 'G' : 1073741824} |
| 80 | + mult = 1; |
| 81 | + if (s[-1:] in UNITS): |
| 82 | + mult = UNITS[s[-1:]]; |
| 83 | + s = s[:-1]; |
| 84 | + |
| 85 | + return int(float(s) * mult) |
| 86 | + |
| 87 | +def main(): |
| 88 | + |
| 89 | + parser = argparse.ArgumentParser(description = """This program read the standard input and |
| 90 | + send it as a file on a OpenStack swift server.""") |
| 91 | + parser.add_argument("--version", action="version", version="Version : %s" % VERSION) |
| 92 | + parser.add_argument("-a", "--authUrl", required = 1, metavar = "SWIFT_AUTHURL", |
| 93 | + help = "e.g. http://exemple.com/auth") |
| 94 | + parser.add_argument("-u", "--user", required = 1, metavar = "SWIFT_USERNAME", |
| 95 | + help = "e.g. Bob") |
| 96 | + parser.add_argument("-p", "--password", required = 1, metavar = "SWIFT_PASSWORD", |
| 97 | + help = "e.g. *********") |
| 98 | + parser.add_argument("container", help = "The remote container name") |
| 99 | + parser.add_argument("filename", help = "The remote file name") |
| 100 | + |
| 101 | + parser.add_argument("-s", "--split", |
| 102 | + metavar = 'SIZE', |
| 103 | + default = -1, |
| 104 | + action = SizeArgparseAction, |
| 105 | + help = """If specified this option will split output file every SIZE |
| 106 | + bytes. The filename will be change to name, name.part00, name.part01, name.part02 .... |
| 107 | + (ex: 10B, 42K, 12M, 13.4G)""") |
| 108 | + |
| 109 | + |
| 110 | + args = parser.parse_args() |
| 111 | + conn = swiftclient.Connection( |
| 112 | + user = args.user, |
| 113 | + key = args.password, |
| 114 | + authurl = args.authUrl |
| 115 | + ) |
| 116 | + |
| 117 | + stream = StreamSplitter(sys.stdin, args.split); |
| 118 | + i = 0; |
| 119 | + while (stream.isEOF() == False): |
| 120 | + conn.put_object("default", "%s.part%02d" % (args.filename, i) , contents=stream) |
| 121 | + stream.reset(); |
| 122 | + i = i + 1; |
| 123 | + |
| 124 | +main() |
0 commit comments