blob: dfd73020213480ca39b47c3253d4b6aa18c2f475 [file] [log] [blame]
tiernoc94c3df2018-02-09 15:38:54 +01001#! /usr/bin/python3
2# -*- coding: utf-8 -*-
3
tiernod125caf2018-11-22 16:05:54 +00004# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13# implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
tiernoc94c3df2018-02-09 15:38:54 +010017import getopt
18import sys
tiernoc94c3df2018-02-09 15:38:54 +010019import requests
tiernoc94c3df2018-02-09 15:38:54 +010020from os.path import getsize, basename
21from hashlib import md5
22
23__author__ = "Alfonso Tierno, alfonso.tiernosepulveda@telefonica.com"
24__date__ = "$2018-01-01$"
25__version__ = "0.1"
26version_date = "Jan 2018"
27
28
29def usage():
30 print("Usage: ", sys.argv[0], "[options]")
31 print(" --version: prints current version")
32 print(" -f|--file FILE: file to be sent")
33 print(" -h|--help: shows this help")
34 print(" -u|--url URL: complete server URL")
35 print(" -s|--chunk-size SIZE: size of chunks, by default 1000")
36 print(" -t|--token TOKEN: Authorizaton token, previously obtained from server")
37 print(" -v|--verbose print debug information, can be used several times")
38 return
39
40
tierno2236d202018-05-16 19:05:16 +020041if __name__ == "__main__":
tiernoc94c3df2018-02-09 15:38:54 +010042 try:
43 # load parameters and configuration
garciadeblas4568a372021-03-24 09:19:48 +010044 opts, args = getopt.getopt(
45 sys.argv[1:],
46 "hvu:s:f:t:",
47 ["url=", "help", "version", "verbose", "file=", "chunk-size=", "token="],
48 )
tiernoc94c3df2018-02-09 15:38:54 +010049 url = None
50 chunk_size = 500
51 pkg_file = None
52 verbose = 0
53 token = None
54
55 for o, a in opts:
56 if o == "--version":
garciadeblas4568a372021-03-24 09:19:48 +010057 print("upload version " + __version__ + " " + version_date)
tiernoc94c3df2018-02-09 15:38:54 +010058 sys.exit()
59 elif o in ("-v", "--verbose"):
60 verbose += 1
61 elif o in ("-h", "--help"):
62 usage()
63 sys.exit()
64 elif o in ("-u", "--url"):
65 url = a
66 elif o in ("-s", "--chunk-size"):
67 chunk_size = int(a)
68 elif o in ("-f", "--file"):
69 pkg_file = a
70 elif o in ("-t", "--token"):
71 token = a
72 else:
73 assert False, "Unhandled option"
74 total_size = getsize(pkg_file)
75 index = 0
76 transaction_id = None
77 file_md5 = md5()
garciadeblas4568a372021-03-24 09:19:48 +010078 with open(pkg_file, "rb") as f:
tiernoc94c3df2018-02-09 15:38:54 +010079 headers = {
80 "Content-type": "application/gzip",
81 "Content-Filename": basename(pkg_file),
82 "Accept": "application/json",
83 }
84 if token:
85 headers["Authorization"] = token
86 while index < total_size:
87 chunk_data = f.read(chunk_size)
88 file_md5.update(chunk_data)
89 # payload = {"file_name": pkg_file, "chunk_data": base64.b64encode(chunk_data).decode("utf-8"),
90 # "chunk_size": chunk_size}
91 if transaction_id:
92 headers["Transaction-Id"] = transaction_id
garciadeblas4568a372021-03-24 09:19:48 +010093 if index + len(chunk_data) == total_size:
tiernoc94c3df2018-02-09 15:38:54 +010094 headers["Content-File-MD5"] = file_md5.hexdigest()
95 # payload["id"] = transaction_id
garciadeblas4568a372021-03-24 09:19:48 +010096 headers["Content-range"] = "bytes {}-{}/{}".format(
97 index, index + len(chunk_data) - 1, total_size
98 )
tiernoc94c3df2018-02-09 15:38:54 +010099 # refers to rfc2616: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
100 if verbose:
101 print("TX chunk Headers: {}".format(headers))
102 r = requests.post(url, data=chunk_data, headers=headers, verify=False)
103 if r.status_code not in (200, 201):
104 print("Got {}: {}".format(r.status_code, r.text))
105 exit(1)
106 if verbose > 1:
107 print("RX {}: {}".format(r.status_code, r.text))
108 response = r.json()
109 if not transaction_id:
110 transaction_id = response["id"]
111 index += len(chunk_data)
112 if verbose <= 1:
113 print("RX {}: {}".format(r.status_code, r.text))
114 if "id" in response:
115 print("---\nid: {}".format(response["id"]))
tierno87006042018-10-24 12:50:20 +0200116 except Exception:
tiernoc94c3df2018-02-09 15:38:54 +0100117 raise