tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

upload.py (3874B)


      1 #!/usr/bin/python
      2 #
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this
      5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 #
      7 # When run directly, this script expects the following environment variables
      8 # to be set:
      9 # UPLOAD_PATH    : path on that host to put the files in
     10 #
     11 # Files are simply copied to UPLOAD_PATH.
     12 #
     13 # All files to be uploaded should be passed as commandline arguments to this
     14 # script. The script takes one other parameter, --base-path, which you can use
     15 # to indicate that files should be uploaded including their paths relative
     16 # to the base path.
     17 
     18 import os
     19 import shutil
     20 import sys
     21 from optparse import OptionParser
     22 
     23 
     24 def OptionalEnvironmentVariable(v):
     25    """Return the value of the environment variable named v, or None
     26    if it's unset (or empty)."""
     27    if v in os.environ and os.environ[v] != "":
     28        return os.environ[v]
     29    return None
     30 
     31 
     32 def FixupMsysPath(path):
     33    """MSYS helpfully translates absolute pathnames in environment variables
     34    and commandline arguments into Windows native paths. This sucks if you're
     35    trying to pass an absolute path on a remote server. This function attempts
     36    to un-mangle such paths."""
     37    if "OSTYPE" in os.environ and os.environ["OSTYPE"] == "msys":
     38        # sort of awful, find out where our shell is (should be in msys2/usr/bin
     39        # or msys/bin) and strip the first part of that path out of the other path
     40        if "SHELL" in os.environ:
     41            sh = os.environ["SHELL"]
     42            msys = sh[: sh.find("/bin")]
     43            if path.startswith(msys):
     44                path = path[len(msys) :]
     45    return path
     46 
     47 
     48 def GetBaseRelativePath(path, local_file, base_path):
     49    """Given a remote path to upload to, a full path to a local file, and an
     50    optional full path that is a base path of the local file, construct the
     51    full remote path to place the file in. If base_path is not None, include
     52    the relative path from base_path to file."""
     53    if base_path is None or not local_file.startswith(base_path):
     54        return path
     55 
     56    dir = os.path.dirname(local_file)
     57    # strip base_path + extra slash and make it unixy
     58    dir = dir[len(base_path) + 1 :].replace("\\", "/")
     59    return path + dir
     60 
     61 
     62 def CopyFilesLocally(path, files, verbose=False, base_path=None):
     63    """Copy each file in the list of files to `path`.  The `base_path` argument is treated
     64    as it is by UploadFiles."""
     65    if not path.endswith("/"):
     66        path += "/"
     67    if base_path is not None:
     68        base_path = os.path.abspath(base_path)
     69    for file in files:
     70        file = os.path.abspath(file)
     71        if not os.path.isfile(file):
     72            raise OSError("File not found: %s" % file)
     73        # first ensure that path exists remotely
     74        target_path = GetBaseRelativePath(path, file, base_path)
     75        if not os.path.exists(target_path):
     76            os.makedirs(target_path)
     77        if verbose:
     78            print("Copying " + file + " to " + target_path)
     79        shutil.copy(file, target_path)
     80 
     81 
     82 if __name__ == "__main__":
     83    path = OptionalEnvironmentVariable("UPLOAD_PATH")
     84 
     85    if sys.platform == "win32":
     86        if path is not None:
     87            path = FixupMsysPath(path)
     88 
     89    parser = OptionParser(usage="usage: %prog [options] <files>")
     90    parser.add_option(
     91        "-b",
     92        "--base-path",
     93        action="store",
     94        help="Preserve file paths relative to this path when uploading. "
     95        "If unset, all files will be uploaded directly to UPLOAD_PATH.",
     96    )
     97    (options, args) = parser.parse_args()
     98    if len(args) < 1:
     99        print("You must specify at least one file to upload")
    100        sys.exit(1)
    101 
    102    try:
    103        CopyFilesLocally(path, args, base_path=options.base_path, verbose=True)
    104    except OSError as strerror:
    105        print(strerror)
    106        sys.exit(1)