csbackgen.py 6.09 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):
158
      srcpath = str(args[0]).rstrip(os.sep)+os.sep
159
160
    else:
      raise Usage("Invalid argument.")
Daniel Armbruster's avatar
Daniel Armbruster committed
161

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

    # major part
168
169
170
    logger.getLogger().info("Start updating checksumfile in '%s'", srcpath)
    csfile.CsFile(targetDirectory, srcpath=srcpath, recursive=not notRecursive, \
      followLinks=followLinks).update(regexes)
Daniel Armbruster's avatar
Daniel Armbruster committed
171

172
173
174
175
  except Usage as err:
    err.display()
    return 2
  except csfile.CsFileError as err:
176
    logger.getLogger().error("%s", err.msg)
177
178
179
    err.display()
    return 2
  else:
180
    logger.getLogger().info("Checksumfile updated.")
181
182
183
184
185
186
187
188
    return 0
    

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

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