"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/scripts/spam-remover" (26 Aug 2019, 7116 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "spam-remover": 1.6.1_vs_2.0.0.

    1 #! /usr/bin/env python
    2 # Copyright (C) 2012 Dr. Ralf Schlatterbeck Open Source Consulting.
    3 # Reichergasse 131, A-3411 Weidling.
    4 # Web: http://www.runtux.com Email: rsc@runtux.com
    5 # All rights reserved
    6 #
    7 # Permission is hereby granted, free of charge, to any person obtaining a copy
    8 # of this software and associated documentation files (the "Software"), to deal
    9 # in the Software without restriction, including without limitation the rights
   10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   11 # copies of the Software, and to permit persons to whom the Software is
   12 # furnished to do so, subject to the following conditions:
   13 #
   14 #   The above copyright notice and this permission notice shall be included in
   15 #   all copies or substantial portions of the Software.
   16 #
   17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   23 # SOFTWARE.
   24 
   25 from __future__ import print_function
   26 _doc = '''
   27 %prog [options]
   28 Remove file attachment spam from a tracker:
   29 - Edit the journal of the given issue(s) and remove the links to the
   30   spam-files
   31 - Set the contents of the spam-files involved to zero length
   32 WARNING:
   33 This is a dangerous operation as it will edit the history *and* remove
   34 data that is not in the journal (the contents of files). Be careful with
   35 the file pattern (start of filename) you specify!
   36 '''
   37 
   38 import sys
   39 from   optparse import OptionParser
   40 from   roundup  import instance, hyperdb
   41 
   42 def main():
   43     cmd = OptionParser(usage=_doc)
   44     cmd.add_option \
   45         ( "-i", "--instance"
   46         , help    = "Instance home"
   47         , default = "."
   48         )
   49     cmd.add_option \
   50         ( "-d", "--designator"
   51         , dest    = "designators"
   52         , help    = "Item designator for issue(s), to remove files from,\n"
   53                     "e.g. issue4711"
   54         , action  = "append"
   55         , default = []
   56         )
   57     cmd.add_option \
   58         ( "-f", "--filename"
   59         , dest    = "filenames"
   60         , help    = "Exact spam-filename to remove from issue(s)"
   61         , action  = "append"
   62         , default = []
   63         )
   64     cmd.add_option \
   65         ( "-a", "--action", "--no-dry-run"
   66         , dest    = "doit"
   67         , help    = "Don't perform any action by default unless specified"
   68         , action  = "store_true"
   69         )
   70     cmd.add_option \
   71         ( "-s", "--file-start-pattern"
   72         , dest    = "file_pattern"
   73         , help    = "Start of spam-filename to remove from issue(s)"
   74         , action  = "append"
   75         , default = []
   76         )
   77     cmd.add_option \
   78         ( "-u", "--spam-user"
   79         , dest    = "users"
   80         , help    = "Username that created the spam-files to remove"
   81         , action  = "append"
   82         , default = []
   83         )
   84     cmd.add_option \
   85         ( "-q", "--quiet"
   86         , dest    = "quiet"
   87         , help    = "Be quiet about what we're doing"
   88         , action  = "store_true"
   89         )
   90     opt, args = cmd.parse_args()
   91     # open the instance
   92     if len(args):
   93         print("This command doesn't take arguments", file=sys.stderr)
   94         cmd.show_help()
   95     tracker = instance.open(opt.instance)
   96     db = tracker.open('admin')
   97     db.tx_Source = "cli"
   98 
   99     users = dict.fromkeys (db.user.lookup(u) for u in opt.users)
  100     files_to_remove = {}
  101     for fn in opt.filenames:
  102         for fid in db.file.filter(None,dict(name=fn)):
  103             if db.file.get(fid,'name') == fn:
  104                 files_to_remove[fid] = True
  105     for fn in opt.file_pattern:
  106         for fid in db.file.filter(None,dict(name=fn)):
  107             if db.file.get(fid,'name').startswith(fn):
  108                 files_to_remove[fid] = True
  109     files_found = {}
  110     for d in opt.designators:
  111         clsname, id = hyperdb.splitDesignator(d)
  112         cls = db.getclass(clsname)
  113         issuefiles = dict.fromkeys(cls.get (id, 'files'))
  114         for fid in list(issuefiles.keys()):
  115             f = db.file.getnode(fid)
  116             if fid in files_to_remove or f.creator in users:
  117                 files_to_remove[fid] = True
  118                 files_found[fid] = True
  119                 if not opt.quiet:
  120                     print("deleting file %s from issue" % f)
  121                 del issuefiles[fid]
  122         if opt.doit:
  123             cls.set(id, files=list(issuefiles.keys()))
  124         journal = oldjournal = db.getjournal(clsname, id)
  125         # do this twice, we may have file-removals *before* file
  126         # additions for files to delete and may discover mid-journal
  127         # that there are new files to remove
  128         for x in range(2):
  129             newjournal = []
  130             for j in journal:
  131                 if j[3] == 'set' and 'files' in j[4]:
  132                     if j[4]['files'][0][0] not in ('-', '+') :
  133                         newjournal.append(j)
  134                         continue
  135                     changes = dict(j[4]['files'])
  136                     # only consider file additions by this user
  137                     if j[2] in users and '+' in changes:
  138                         f = dict.fromkeys(changes['+'])
  139                         files_found.update(f)
  140                         files_to_remove.update(f)
  141                         del changes['+']
  142                     # change dict in-place
  143                     for k, v in list(changes.items()):
  144                         new_f = []
  145                         for f in v:
  146                             if f in files_to_remove:
  147                                 files_found[f] = True
  148                             else:
  149                                 new_f.append(f)
  150                         if new_f :
  151                             changes[k] = new_f
  152                         else:
  153                             del changes[k]
  154                     msg = []
  155                     if not opt.quiet:
  156                         msg.append ("Old journal entry: %s" % str(j))
  157                     if changes:
  158                         j[4]['files'] = tuple(changes.items())
  159                     else:
  160                         del j[4]['files']
  161                     if j[4]:
  162                         newjournal.append(j)
  163                         if not opt.quiet:
  164                             msg.append ("New journal entry: %s" % str(j))
  165                     elif not opt.quiet:
  166                         msg.append ("deleted")
  167                     if len(msg) == 2 and msg[0][4:] != msg[1][4:]:
  168                         for m in msg:
  169                             print(m)
  170                 else:
  171                     newjournal.append(j)
  172             journal = newjournal
  173         if newjournal != oldjournal and opt.doit:
  174             db.setjournal(clsname, id, newjournal)
  175     if opt.doit:
  176         for f in files_found:
  177             db.file.set(f, content=' ')
  178         db.commit()
  179     else:
  180         print("Database not changed")
  181 
  182 
  183 if __name__ == '__main__':
  184     main()