~mterry/duplicity/gdrive

« back to all changes in this revision

Viewing changes to duplicity/commandline.py

  • Committer: bescoto
  • Date: 2002-10-29 01:49:46 UTC
  • Revision ID: vcs-imports@canonical.com-20021029014946-3m4rmm5plom7pl6q
Initial checkin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2002 Ben Escoto
 
2
#
 
3
# This file is part of duplicity.
 
4
#
 
5
# duplicity is free software; you can redistribute it and/or modify it
 
6
# under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA
 
8
# 02139, USA; either version 2 of the License, or (at your option) any
 
9
# later version; incorporated herein by reference.
 
10
 
 
11
"""Parse command line, check for consistency, and set globals"""
 
12
 
 
13
import getopt, re, sys
 
14
import backends, globals, log, path, selection, gpg, dup_time
 
15
 
 
16
select_opts = [] # Will hold all the selection options
 
17
full_backup = None # Will be set to true if -f or --full option given
 
18
 
 
19
def parse_cmdline_options(arglist):
 
20
        """Parse argument list"""
 
21
        global select_opts, full_backup
 
22
        try: optlist, args = getopt.getopt(arglist, "firt:v:V",
 
23
                 ["allow-source-mismatch", "archive-dir=", "current-time=",
 
24
                  "encrypt-key=", "exclude=", "exclude-device-files",
 
25
                  "exclude-filelist=", "exclude-filelist-stdin",
 
26
                  "exclude-other-filesystems", "exclude-regexp=",
 
27
                  "file-to-restore=", "full", "incremental", "include=",
 
28
                  "include-filelist=", "include-filelist-stdin",
 
29
                  "include-regexp=", "null-separator", "restore-dir=",
 
30
                  "restore-time=", "sign-key=", "verbosity="])
 
31
        except getopt.error, e:
 
32
                command_line_error("%s" % (str(e),))
 
33
 
 
34
        for opt, arg in optlist:
 
35
                if opt == "--allow-source-mismatch": globals.allow_source_mismatch = 1
 
36
                elif opt == "--archive-dir": set_archive_dir(arg)
 
37
                elif opt == "--current-time":
 
38
                        globals.current_time = get_int(arg, "current-time")
 
39
                elif opt == "--encrypt-key":
 
40
                        globals.gpg_profile.recipients.append(arg)
 
41
                elif (opt == "--exclude" or opt == "--exclude-regexp" or
 
42
                        opt == "--include" or opt == "--include-regexp"):
 
43
                        select_opts.append((opt, arg))
 
44
                elif (opt == "--exclude-device-files" or
 
45
                          opt == "--exclude-other-filesystems"):
 
46
                        select_opts.append((opt, None))
 
47
                elif opt == "--exclude-filelist" or opt == "--include-filelist":
 
48
                        select_opts.append((opt, (arg, open(arg, "rb"))))
 
49
                elif (opt == "--exclude-filelist-stdin" or
 
50
                          opt == "--include-filelist-stdin"):
 
51
                        select_opts.append((opt, ("stdin", sys.stdin)))
 
52
                elif opt == "-f" or opt == "--full": full_backup = 1
 
53
                elif opt == "-i" or opt == "--incremental": globals.incremental = 1
 
54
                elif opt == "-r" or opt == "--file-to-restore":
 
55
                        globals.restore_dir = arg
 
56
                elif opt == "-t" or opt == "--restore-time":
 
57
                        globals.restore_time = dup_time.genstrtotime(arg)
 
58
                elif opt == "--sign-key": set_sign_key(arg)
 
59
                elif opt == "-V":
 
60
                        print "duplicity version", str(globals.version)
 
61
                        sys.exit(0)
 
62
                elif opt == "-v" or opt == "--verbosity": log.setverbosity(int(arg))
 
63
                else: command_line_error("Unknown option %s" % opt)
 
64
 
 
65
        return args
 
66
 
 
67
def command_line_error(message):
 
68
        """Indicate a command line error and exit"""
 
69
        sys.stderr.write("Command line error: %s\n" % (message,))
 
70
        sys.stderr.write("See the duplicity manual page for instructions\n")
 
71
        sys.exit(1)
 
72
 
 
73
def get_int(int_string, description):
 
74
        """Require that int_string be an integer, return int value"""
 
75
        try: return int(int_string)
 
76
        except ValueError: log.FatalError("Received '%s' for %s, need integer" %
 
77
                                                                          (int_string, description))
 
78
 
 
79
def set_archive_dir(dirstring):
 
80
        """Check archive dir and set global"""
 
81
        archive_dir = path.Path(dirstring)
 
82
        if not archive_dir.isdir():
 
83
                log.FatalError("Specified archive directory '%s' does not exist "
 
84
                                           " or is not a directory" % (archive_dir.name,))
 
85
        globals.archive_dir = archive_dir
 
86
 
 
87
def set_sign_key(sign_key):
 
88
        """Set globals.sign_key assuming proper key given"""
 
89
        if not len(sign_key) == 8 or not re.search("^[0-9A-F]*$", sign_key):
 
90
                log.FatalError("Sign key should be an 8 character hex string, like "
 
91
                                           "'AA0E73D2'.\nReceived '%s' instead." % (sign_key,))
 
92
        globals.gpg_profile.sign_key = sign_key
 
93
 
 
94
def get_action(args):
 
95
        """Figure out the main action from the arguments"""
 
96
 
 
97
        if len(args) < 3: command_line_error("Too few arguments")
 
98
        command = args[0]
 
99
        if command != "restore" and len(args) < 4:
 
100
                command_line_error("Too few arguments")
 
101
        if len(args) > 4: command_line_error("Too many arguments")
 
102
 
 
103
        if command == "inc" or command == "increment": command = "inc"
 
104
        return command, args[1:]
 
105
 
 
106
def set_selection():
 
107
        """Return selection iter starting at filename with arguments applied"""
 
108
        global select_opts
 
109
        sel = selection.Select(globals.local_path)
 
110
        sel.ParseArgs(select_opts)
 
111
        globals.select = sel.set_iter()
 
112
 
 
113
def set_backend(arg1, arg2):
 
114
        """Figure out which arg is url, set backend
 
115
 
 
116
        Return value is pair (path_first, path) where is_first is true iff
 
117
        path made from arg1.
 
118
 
 
119
        """
 
120
        backend1, backend2 = backends.get_backend(arg1), backends.get_backend(arg2)
 
121
        if not backend1 and not backend2:
 
122
                log.FatalError(
 
123
"""One of the arguments must be an URL.  Examples of URL strings are
 
124
"scp://user@host.net:1234/path" and "file:///usr/local".  See the man
 
125
page for more information.""")
 
126
        if backend1 and backend2:
 
127
                command_line_error("Two URLs specified.  "
 
128
                                                   "One argument should be a path.")
 
129
        if backend1:
 
130
                globals.backend = backend1
 
131
                return (None, arg2)
 
132
        elif backend2:
 
133
                globals.backend = backend2
 
134
                return (1, arg1)
 
135
 
 
136
def process_local_dir(action, local_pathname):
 
137
        """Check local directory, set globals.local_path"""
 
138
        local_path = path.Path(path.Path(local_pathname).get_canonical())
 
139
        if action == "restore":
 
140
                if local_path.exists() and not local_path.isemptydir():
 
141
                        log.FatalError("Restore destination directory %s already "
 
142
                                                   "exists.\nWill not overwrite." % (local_pathname,))
 
143
        else:
 
144
                assert action == "full" or action == "inc"
 
145
                if not local_path.exists():
 
146
                        log.FatalError("Backup source directory %s does not exist."
 
147
                                                   % (local_path.name,))
 
148
        globals.local_path = local_path
 
149
 
 
150
def check_consistency(action):
 
151
        """Final consistency check, see if something wrong with command line"""
 
152
        global full_backup, select_opts
 
153
        if action == "restore":
 
154
                if full_backup:
 
155
                        command_line_error("--full option cannot be used when restoring")
 
156
                elif globals.incremental:
 
157
                        command_line_error("--incremental option cannot be used when "
 
158
                                                           "restoring")
 
159
                elif select_opts:
 
160
                        command_line_error("Selection options --exclude/--include\n"
 
161
                                                           "currently work only when backing up, "
 
162
                                                           "not restoring.")
 
163
        else:
 
164
                assert action == "inc" or action == "full"
 
165
                if globals.restore_dir:
 
166
                        log.FatalError("--restore-dir option incompatible with %s backup"
 
167
                                                   % (action,))
 
168
 
 
169
def ProcessCommandLine(cmdline_list):
 
170
        """Process command line, set globals, return action
 
171
 
 
172
        action will be "restore", "full", or "inc".
 
173
 
 
174
        """
 
175
        global full_backup
 
176
        globals.gpg_profile = gpg.GPGProfile()
 
177
 
 
178
        args = parse_cmdline_options(cmdline_list)
 
179
        if len(args) < 2: command_line_error("Too few arguments")
 
180
        elif len(args) > 2: command_line_error("Too many arguments")
 
181
 
 
182
        backup, local_pathname = set_backend(args[0], args[1])
 
183
        if backup:
 
184
                if full_backup: action = "full"
 
185
                else: action = "inc"
 
186
        else: action = "restore"
 
187
 
 
188
        process_local_dir(action, local_pathname)
 
189
        if backup: set_selection()
 
190
        check_consistency(action)
 
191
        return action