csbackgen.py 6.05 KB
Newer Older
1
2
#!/usr/bin/env python
## @file csbackgen.py
3
# @brief Generate checksum files.
4
5
6
7
8
9
10
# 
# -----------------------------------------------------------------------------
# 
# $Id$
# @author Daniel Armbruster
# \date 11/09/2011
# 
11
# Purpose: Generate checksum files.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#
# ----
# This file is part of csback.
#
# csback is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# csback is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with csback.  If not, see <http://www.gnu.org/licenses/>.
# ----
# 
30
# Copyright (c) 2012 by Daniel Armbruster
31
32
# 
# REVISIONS and CHANGES 
33
# 02/01/2012  V0.1  Daniel Armbruster
34
35
36
# 
# =============================================================================
 
37
38
39
40
41
import getopt
import os
import sys
import re
import csfile
42

43
44
45
46
47
__version__ = "V0.1"
__subversion__ = "$Id$"
__license__ = "GPLv2"
__author__ = "Daniel Armbruster"
__copyright__ = "Copyright (c) 2012 by Daniel Armbruster"
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# -----------------------------------------------------------------------------
class Error(Exception):

  def __init__(self, msg):
    self.msg = msg

  def display(self):
    sys.stderr.write("csbackgen (ERROR): " + self.msg + "\n")


class Usage(Error):

  def display(self):
    usage_text = "Version: "+__version__+"\nLicense: "+__license__+ \
      "\n"+__subversion__+"\nAuthor: "+__author__+ """
 Usage: csbackgen [-v|--verbose] [-e REGEX [-e REGEX [...]]]
                  [-R|--notrecursive] [-d|--debug] [-f|--followlinks] PATH
    or: csbackgen -h|--help\n"""
    sys.stderr.write("csbackgen: " + self.msg + "\n")
    sys.stderr.write(usage_text)

# -----------------------------------------------------------------------------
def help():
  """
  Printing helptext to stdout.
  """
  help_text = "Version: "+__version__+"\nLicense: "+__license__+"\n"+ \
    __subversion__+"\nAuthor: "+__author__+"""
 Usage: csbackgen [-v|--verbose] [-e REGEX [-e REGEX [...]]]
                  [-R|--notrecursive] [-d|--debug] [-f|--followlinks] PATH
    or: csbackgen -h|--help
-------------------------------------------------------------------------------
 -v|--verbose       Be verbose.
 -h|--help          Display this help.
 -e REGEX           While generating a checksumfile exclude files matching
                    REGEX.
 -R|--notrecursive  Do not generate checksumfiles for subdirectories.
 -d|--debug         Debug mode. Be really verbose.
 -f|--followlinks   Follow symbolic links. Only available if option -R is not
                    set. Note that this option can lead to infinite recursion.
 PATH               Path to generate checksumfile for.
-------------------------------------------------------------------------------
csbackgen.py will either generate a checksumfile if still no checksumfile is
available or in case there is an existing checksumfile csbackgen.py will append
the not yet registered files to the current checksumfile. In the latter case
csbackgen.py is working in its update mode.\n"""
  sys.stdout.write(help_text)

# -----------------------------------------------------------------------------
def getSubDirectories(path, regexes, followLinks=False):
  """
  To generate a list of subdirectories of path using os.walk(). Note that path
  itself was not appended to the list.
  """
  subDirs = []
  try:
    # collect subdirectories
    for root, dirs, files in os.walk(path, True, None, followLinks):
      for dir in dirs:
        subDirs.append(os.path.join(root, dir))
    # exclude directories matching regexes
    if [] != regexes:
      subDirs = [dir for dir in subDirs for regex in regexes \
        if None == re.match(str(regex),dir)]
  except OSError as err:
    raise Error("[Errno "+str(err.errno)+"] "+err.strerror+": "+err.filename)
  else:
    return subDirs

# -----------------------------------------------------------------------------
def main(argv=None):
  if argv is None:
    argv = sys.argv
  try:
    try:
      opts, args = getopt.getopt(argv[1:], "vhe:Rdf", ["help", "verbose",\
        "notrecursive", "debug", "followlinks"])
    except getopt.GetoptError as err:
      raise Usage(err.msg)
    verbose = False
    debugMode = False
    notRecursive = False
    followLinks = False
    regexes = []
    # collect arguments
    for opt, arg in opts:
      if opt in ("-v", "--verbose"):
        verbose = True
      elif opt in ("-h", "--help"):
        sys.exit(help())
      elif opt in ("-R", "--notrecursive"):
        notRecursive = True
      elif opt in ("-e"):
        regexes.append(arg)
      elif opt in ("-d", "--debug"):
        verbose = True
        debugMode = True
        csfile.debugMode = True
      elif opt in ("-f", "--followlinks"):
        followLinks = True
      else:
        raise Usage("Unhandled option chosen.")
    if 1 == len(args):
      inputpath = str(args[0])
    else:
      raise Usage("Invalid argument.")
    if notRecursive:
      if verbose or debugMode:
        sys.stdout.write("csbackgen.py: Generating checksumfile in: '"+ \
          path+"'\n")
      csfile.CsFile(inputpath).update(regexes)
    else:
      if verbose or debugMode:
        sys.stdout.write("csbackgen.py: Collecting subdirectories.\n")
      directories = [inputpath]
      directories.extend(getSubDirectories(inputpath, regexes, \
        followLinks))
      if verbose or debugMode:
        sys.stdout.write( \
          "csbackgen.py: Generating checksumfiles in subdirectories.\n")
      for dir in directories:
        csfile.CsFile(dir).update(regexes)
  except Usage as err:
    err.display()
    return 2
  except csfile.CsFileError as err:
    err.display()
    return 2
  else:
    return 0
    

# -----------------------------------------------------------------------------
if __name__ == "__main__":
  sys.exit(main())

# ----- END OF csbackgen.py -----