csbackgen.py 6.29 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
# 05/01/2012  V0.2  added logging flag to enable a file logging mechanism
35
36
37
# 
# =============================================================================
 
38
39
40
41
import getopt
import os
import sys
import re
42
import pwd
Daniel Armbruster's avatar
Daniel Armbruster committed
43
import logging
44
import csfile
45
import csbacklog
46

47
48
49
50
51
__version__ = "V0.1"
__subversion__ = "$Id$"
__license__ = "GPLv2"
__author__ = "Daniel Armbruster"
__copyright__ = "Copyright (c) 2012 by Daniel Armbruster"
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# -----------------------------------------------------------------------------
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 [...]]]
69
                  [-R|--notrecursive] [-d|--debug] [-f|--followlinks]
70
                  [-t|--target DIR] [-l|--logging] PATH
71
72
73
74
75
76
77
78
79
80
81
82
    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 [...]]]
83
                  [-R|--notrecursive] [-d|--debug] [-f|--followlinks] 
84
                  [-t|--target DIR] [-l|--logging] PATH
85
86
87
88
89
    or: csbackgen -h|--help
-------------------------------------------------------------------------------
 -v|--verbose       Be verbose.
 -h|--help          Display this help.
 -e REGEX           While generating a checksumfile exclude files matching
Daniel Armbruster's avatar
Daniel Armbruster committed
90
                    REGEX(s).
91
92
93
94
 -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.
95
 -t|--target        Target directory for checksumfile.
96
97
 -l|--logging       Switch on logging to files. Logfiles will be located in
                    ~/.csback/log/.
98
99
100
101
102
103
104
105
106
107
 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 main(argv=None):
108
  # configure logger
109
110
  logger = csbacklog.CsbackLog('csbackgen')
  
111
  console = logging.StreamHandler()
112
113
  console.setFormatter(logging.Formatter( \
    '%(name)-8s [%(lineno)d]: %(levelname)-8s %(message)s'))
114

115
116
117
118
  if argv is None:
    argv = sys.argv
  try:
    try:
119
120
      opts, args = getopt.getopt(argv[1:], "vhe:Rdft:l", ["help", "verbose", \
        "notrecursive", "debug", "followlinks", "target=", "logging"])
121
122
123
124
125
126
127
    except getopt.GetoptError as err:
      raise Usage(err.msg)
    verbose = False
    debugMode = False
    notRecursive = False
    followLinks = False
    regexes = []
128
    targetSet = False
129
    enableLogging = False
130
131
132
    for opt, arg in opts:
      if opt in ("-v", "--verbose"):
        verbose = True
133
        console.setLevel(logging.INFO)
134
135
136
137
138
139
140
141
      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"):
        debugMode = True
142
        console.setLevel(logging.DEBUG)
143
144
      elif opt in ("-f", "--followlinks"):
        followLinks = True
145
146
147
      elif opt in ("-t", "--target"):
        targetSet = True
        targetDirectory = str(arg)
148
149
      elif opt in ("-l", "--logging"):
        logger.configure()
150
151
      else:
        raise Usage("Unhandled option chosen.")
152
153

    if verbose or debugMode:
154
      logger.addHandler(console)
155
156

    # fetch arguments   
157
    if 1 == len(args):
Daniel Armbruster's avatar
Daniel Armbruster committed
158
      inputpath = str(args[0]).rstrip(os.sep)+os.sep
159
160
    else:
      raise Usage("Invalid argument.")
Daniel Armbruster's avatar
Daniel Armbruster committed
161

162
163
164
165
166
167
    if not targetSet:
      targetDirectory = inputpath
    if not os.path.isdir(targetDirectory):
      raise Usage("Target directory not a valid directory.")

    # major part
Daniel Armbruster's avatar
Daniel Armbruster committed
168
169
    directories = [inputpath]
    if not notRecursive:
170
      logger.getLogger().info("Collecting subdirectories.")
Daniel Armbruster's avatar
Daniel Armbruster committed
171
      directories.extend(csfile.getSubDirectories(inputpath, regexes, \
172
        followLinks))
Daniel Armbruster's avatar
Daniel Armbruster committed
173
    for dir in directories:
174
175
      logger.getLogger().info( \
        "Update files in directory: %s to checksumfile: %s%s", dir, \
176
        targetDirectory, csfile.CsFile.filename)
Daniel Armbruster's avatar
Daniel Armbruster committed
177
      csfile.CsFile(targetDirectory, srcpath=dir).update(regexes)
Daniel Armbruster's avatar
Daniel Armbruster committed
178

179
180
181
182
183
184
185
  except Usage as err:
    err.display()
    return 2
  except csfile.CsFileError as err:
    err.display()
    return 2
  else:
186
    logger.getLogger().info("Checksumfile updated.")
187
188
189
190
191
192
193
194
    return 0
    

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

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