aboutsummaryrefslogtreecommitdiffstats
path: root/minidinstall
diff options
context:
space:
mode:
authorLibravatarKrytarik Raido <krytarik@tuxgarage.com>2018-04-03 06:50:04 +0200
committerLibravatarKrytarik Raido <krytarik@tuxgarage.com>2018-04-03 06:50:04 +0200
commitdc580be8f9ef38a1c0903820b04e1b5c7217da16 (patch)
tree4a214d88d3e094efdb9e4ff70920537a4d33ae9b /minidinstall
parent23ac25c0b388b5ffebf66154b12a3950b89b977a (diff)
Various improvements in coding style.
Diffstat (limited to 'minidinstall')
-rw-r--r--minidinstall/ChangeFile.py77
-rw-r--r--minidinstall/DebianSigVerifier.py13
-rw-r--r--minidinstall/Dnotify.py49
-rwxr-xr-xminidinstall/DpkgControl.py124
-rw-r--r--minidinstall/DpkgDatalist.py31
-rw-r--r--minidinstall/GPGSigVerifier.py25
-rw-r--r--minidinstall/OrderedDict.py11
-rwxr-xr-xminidinstall/SafeWriteFile.py12
-rwxr-xr-xminidinstall/SignedFile.py32
-rw-r--r--minidinstall/mail.py24
-rw-r--r--minidinstall/misc.py30
-rw-r--r--minidinstall/tweet.py17
12 files changed, 192 insertions, 253 deletions
diff --git a/minidinstall/ChangeFile.py b/minidinstall/ChangeFile.py
index 3b0cf48..4a65af6 100644
--- a/minidinstall/ChangeFile.py
+++ b/minidinstall/ChangeFile.py
@@ -1,8 +1,8 @@
-# ChangeFile
+# ChangeFile -*- mode: python; coding: utf-8 -*-
# A class which represents a Debian change file.
-# Copyright 2002 Colin Walters <walters@gnu.org>
+# Copyright (c) 2002 Colin Walters <walters@gnu.org>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,11 +18,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, re, sys, string, stat
-import threading, queue
+import os, re, stat
import logging
-from minidinstall import DpkgControl, SignedFile
-from minidinstall import misc
+from .DpkgControl import *
+from .SignedFile import *
+from . import misc
class ChangeFileException(Exception):
def __init__(self, value):
@@ -30,19 +30,19 @@ class ChangeFileException(Exception):
def __str__(self):
return repr(self._value)
-class ChangeFile(DpkgControl.DpkgParagraph):
- md5_re = r'^(?P<md5>[0-9a-f]{32})[ \t]+(?P<size>\d+)[ \t]+(?P<section>[-/a-zA-Z0-9]+)[ \t]+(?P<priority>[-a-zA-Z0-9]+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
- sha1_re = r'^(?P<sha1>[0-9a-f]{40})[ \t]+(?P<size>\d+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
- sha256_re = r'^(?P<sha256>[0-9a-f]{64})[ \t]+(?P<size>\d+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
+class ChangeFile(DpkgParagraph):
+ md5_re = r'^(?P<hashsum>[0-9a-f]{32})[ \t]+(?P<size>\d+)[ \t]+(?P<section>[-/a-zA-Z0-9]+)[ \t]+(?P<priority>[-a-zA-Z0-9]+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
+ sha1_re = r'^(?P<hashsum>[0-9a-f]{40})[ \t]+(?P<size>\d+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
+ sha256_re = r'^(?P<hashsum>[0-9a-f]{64})[ \t]+(?P<size>\d+)[ \t]+(?P<file>[0-9a-zA-Z][-+:.,=~0-9a-zA-Z_]+)$'
def __init__(self):
- DpkgControl.DpkgParagraph.__init__(self)
+ DpkgParagraph.__init__(self)
self._logger = logging.getLogger("mini-dinstall")
self._file = ''
def load_from_file(self, filename):
self._file = filename
- f = SignedFile.SignedFile(open(self._file))
+ f = SignedFile(open(self._file))
self.load(f)
f.close()
@@ -52,57 +52,50 @@ class ChangeFile(DpkgControl.DpkgParagraph):
def _get_checksum_from_changes(self):
""" extract checksums and size from changes file """
output = {}
- hashes = { 'md5': ['files', re.compile(self.md5_re)],
- 'sha1': ['checksums-sha1', re.compile(self.sha1_re)],
- 'sha256': ['checksums-sha256', re.compile(self.sha256_re)]
- }
- hashes_checked = hashes.copy()
+ hashes = {
+ 'md5': ['files', re.compile(self.md5_re)],
+ 'sha1': ['checksums-sha1', re.compile(self.sha1_re)],
+ 'sha256': ['checksums-sha256', re.compile(self.sha256_re)]
+ }
- try:
- self['files']
- except KeyError:
+ if 'files' not in self:
return []
- for hash in hashes:
- try:
- self[hashes[hash][0]]
- except KeyError:
+ for (hash, (field, regex)) in list(hashes.items()):
+ if field not in self:
self._logger.warn("Can't find %s checksum in changes file '%s'" % (hash, os.path.basename(self._file)))
- hashes_checked.pop(hash)
-
- for hash in hashes_checked:
+ continue
output[hash] = []
- for line in self[hashes[hash][0]]:
- if line == '':
+ for line in self[field].splitlines():
+ if not line:
continue
- match = hashes[hash][1].match(line)
- if (match is None):
- raise ChangeFileException("Couldn't parse file entry \"%s\" in Files field of .changes" % (line,))
- output[hash].append([match.group(hash), match.group('size'), match.group('file') ])
+ match = regex.match(line)
+ if not match:
+ raise ChangeFileException("Couldn't parse file entry \"%s\" in %s field of .changes" % (line, self.trueFieldCasing[field]))
+ output[hash].append([match.group('hashsum'), match.group('size'), match.group('file')])
return output
def verify(self, sourcedir):
""" verify size and hash values from changes file """
checksum = self._get_checksum_from_changes()
- for hash in list(checksum.keys()):
- for (hashsum, size, filename) in checksum[hash]:
+ for (hash, value) in list(checksum.items()):
+ for (hashsum, size, filename) in value:
self._verify_file_integrity(os.path.join(sourcedir, filename), int(size), hash, hashsum)
-
def _verify_file_integrity(self, filename, expected_size, hash, expected_hashsum):
""" check uploaded file integrity """
- self._logger.debug('Checking integrity of %s' % (filename,))
+ self._logger.debug('Checking integrity of %s' % filename)
try:
statbuf = os.stat(filename)
if not stat.S_ISREG(statbuf[stat.ST_MODE]):
- raise ChangeFileException("%s is not a regular file" % (filename,))
+ raise ChangeFileException("%s is not a regular file" % filename)
size = statbuf[stat.ST_SIZE]
except OSError as e:
- raise ChangeFileException("Can't stat %s: %s" % (filename,e.strerror))
+ raise ChangeFileException("Can't stat %s: %s" % (filename, e.strerror))
if size != expected_size:
- raise ChangeFileException("File size for %s does not match that specified in .dsc" % (filename,))
- if (misc.get_file_sum(self, hash, filename) != expected_hashsum):
- raise ChangeFileException("%ssum for %s does not match that specified in .dsc" % (hash, filename,))
+ raise ChangeFileException("File size for %s does not match that specified in .dsc" % filename)
+ if misc.get_file_sum(self, hash, filename) != expected_hashsum:
+ raise ChangeFileException("%ssum for %s does not match that specified in .dsc" % (hash, filename))
self._logger.debug('Verified %ssum %s and size %s for %s' % (hash, expected_hashsum, expected_size, filename))
# vim:ts=4:sw=4:et:
diff --git a/minidinstall/DebianSigVerifier.py b/minidinstall/DebianSigVerifier.py
index d441a58..17a6ec2 100644
--- a/minidinstall/DebianSigVerifier.py
+++ b/minidinstall/DebianSigVerifier.py
@@ -2,7 +2,7 @@
# A class for verifying signed files, using Debian keys
-# Copyright © 2002 Colin Walters <walters@gnu.org>
+# Copyright (c) 2002 Colin Walters <walters@gnu.org>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,18 +18,19 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, re, sys, string, stat, logging
-from minidinstall.GPGSigVerifier import GPGSigVerifier
+import os
+from .GPGSigVerifier import *
class DebianSigVerifier(GPGSigVerifier):
_dpkg_ring = '/etc/dpkg/local-keyring.gpg'
+
def __init__(self, keyrings=None, extra_keyrings=None):
- if keyrings is None:
+ if not keyrings:
keyrings = ['/usr/share/keyrings/debian-keyring.gpg', '/usr/share/keyrings/debian-keyring.pgp']
if os.access(self._dpkg_ring, os.R_OK):
keyrings.append(self._dpkg_ring)
- if not extra_keyrings is None:
- keyrings += extra_keyrings
+ if extra_keyrings:
+ keyrings.extend(extra_keyrings)
GPGSigVerifier.__init__(self, keyrings)
# vim:ts=4:sw=4:et:
diff --git a/minidinstall/Dnotify.py b/minidinstall/Dnotify.py
index 18606e1..cdc2c48 100644
--- a/minidinstall/Dnotify.py
+++ b/minidinstall/Dnotify.py
@@ -2,7 +2,7 @@
# A simple FAM-like beast in Python
-# Copyright © 2002 Colin Walters <walters@gnu.org>
+# Copyright (c) 2002 Colin Walters <walters@gnu.org>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,9 +18,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, re, sys, string, stat, threading, queue, time
+import os, stat, threading, queue, time
import logging
-from minidinstall import misc
+from . import misc
class DnotifyException(Exception):
def __init__(self, value):
@@ -29,7 +29,7 @@ class DnotifyException(Exception):
return repr(self._value)
class DirectoryNotifierFactory:
- def create(self, dirs, use_dnotify=1, poll_time=30, logger=None, cancel_event=None):
+ def create(self, dirs, use_dnotify=False, poll_time=30, logger=None, cancel_event=None):
if use_dnotify and os.access('/usr/bin/dnotify', os.X_OK):
if logger:
logger.debug("Using dnotify directory notifier")
@@ -47,11 +47,11 @@ class DirectoryNotifier:
def __init__(self, dirs, logger, cancel_event=None):
self._cwd = os.getcwd()
self._dirs = dirs
- if cancel_event is None:
+ if not cancel_event:
self._cancel_event = threading.Event()
else:
self._cancel_event = cancel_event
- if logger is None:
+ if not logger:
self._logger = logging.getLogger("Dnotify")
self._logger.addFilter(DnotifyNullLoggingFilter())
else:
@@ -62,13 +62,13 @@ class DirectoryNotifier:
class DirectoryNotifierAsyncWrapper(threading.Thread):
def __init__(self, dnotify, queue, logger=None, name=None):
- if not name is None:
+ if name:
threading.Thread.__init__(self, name=name)
else:
threading.Thread.__init__(self)
self._eventqueue = queue
self._dnotify = dnotify
- if logger is None:
+ if not logger:
self._logger = logging.getLogger("Dnotify")
self._logger.addFilter(DnotifyNullLoggingFilter())
else:
@@ -78,7 +78,7 @@ class DirectoryNotifierAsyncWrapper(threading.Thread):
self._cancel_event.set()
def run(self):
- self._logger.info('Created new thread (%s) for async directory notification' % (self.getName()))
+ self._logger.info('Created new thread (%s) for async directory notification' % self.getName())
while not self._dnotify.cancelled():
dir = self._dnotify.poll()
self._eventqueue.put(dir)
@@ -97,7 +97,7 @@ class MtimeDirectoryNotifier(DirectoryNotifier):
timeout_time = None
if timeout:
timeout_time = time.time() + timeout
- while self._changed == []:
+ while not self._changed:
if timeout_time and time.time() > timeout_time:
return None
self._logger.debug('Polling...')
@@ -105,16 +105,15 @@ class MtimeDirectoryNotifier(DirectoryNotifier):
oldtime = self._dirmap[dir]
mtime = os.stat(os.path.join(self._cwd, dir))[stat.ST_MTIME]
if oldtime < mtime:
- self._logger.debug('Directory "%s" has changed' % (dir,))
+ self._logger.debug('Directory "%s" has changed' % dir)
self._changed.append(dir)
self._dirmap[dir] = mtime
- if self._changed == []:
+ if not self._changed:
for x in range(self._polltime):
if self._cancel_event.isSet():
return None
time.sleep(1)
- ret = self._changed[0]
- self._changed = self._changed[1:]
+ ret = self._changed.pop(0)
return ret
class DnotifyDirectoryNotifier(DirectoryNotifier):
@@ -127,11 +126,11 @@ class DnotifyDirectoryNotifier(DirectoryNotifier):
def poll(self, timeout=None):
# delete duplicates
i = self._queue.qsize()
- self._logger.debug('Queue size: %d', (i,))
+ self._logger.debug('Queue size: %d' % i)
set = {}
- while i > 0:
+ while i:
dir = self._queue_get(timeout)
- if dir is None:
+ if not dir:
# We shouldn't have to do this; no one else is reading
# from the queue. But we do it just to be safe.
for key in list(set.keys()):
@@ -142,11 +141,11 @@ class DnotifyDirectoryNotifier(DirectoryNotifier):
for key in list(set.keys()):
self._queue.put(key)
i = self._queue.qsize()
- self._logger.debug('Queue size (after duplicate filter): %d', (i,))
+ self._logger.debug('Queue size (after duplicate filter): %d' % i)
return self._queue_get(timeout)
def _queue_get(self, timeout):
- if timeout is None:
+ if not timeout:
return self._queue.get()
timeout_time = time.time() + timeout
while True:
@@ -179,21 +178,21 @@ class DnotifyThread(threading.Thread):
os.close(outfd)
stdout = os.fdopen(infd)
c = 'x'
- while c != '':
+ while c:
curline = ''
c = stdout.read(1)
- while c != '' and c != '\0':
+ while c and c != '\0':
curline += c
c = stdout.read(1)
- if c == '':
+ if not c:
break
- self._logger.debug('Directory "%s" changed' % (curline,))
+ self._logger.debug('Directory "%s" changed' % curline)
self._queue.put(curline)
(pid, status) = os.waitpid(pid, 0)
- if status is None:
+ if not status:
ecode = 0
else:
ecode = os.WEXITSTATUS(status)
- raise DnotifyException("dnotify exited with code %s" % (ecode,))
+ raise DnotifyException("dnotify exited with code %s" % ecode)
# vim:ts=4:sw=4:et:
diff --git a/minidinstall/DpkgControl.py b/minidinstall/DpkgControl.py
index be08155..02e3567 100755
--- a/minidinstall/DpkgControl.py
+++ b/minidinstall/DpkgControl.py
@@ -1,7 +1,10 @@
-# DpkgControl.py
+#!/usr/bin/python3
+# DpkgControl -*- mode: python; coding: utf-8 -*-
#
# This module implements control file parsing.
#
+# Copyright (c) 2001 Adam Heath <doogie@debian.org>
+#
# DpkgParagraph is a low-level class, that reads/parses a single paragraph
# from a file object.
#
@@ -16,9 +19,7 @@
# To test this, pass it a filetype char, a filename, then, optionally,
# the key to a paragraph to display, and if a fourth arg is given, only
# show that field.
-#
-# Copyright 2001 Adam Heath <doogie@debian.org>
-#
+
# This file 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 2 of the License, or
@@ -33,20 +34,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import re, string
from .DpkgDatalist import *
-from minidinstall.SignedFile import *
+from .SignedFile import *
class DpkgParagraph(DpkgOrderedDatalist):
- caseSensitive = 0
trueFieldCasing = {}
- def setCaseSensitive( self, value ): self.caseSensitive = value
-
def load( self, f ):
- "Paragraph data from a file object."
+ """Paragraph data from a file object"""
key = None
- value = None
while True:
line = f.readline()
if not line:
@@ -57,85 +53,53 @@ class DpkgParagraph(DpkgOrderedDatalist):
continue
else:
return
- line = line[ :-1 ]
if line[ 0 ] != ' ':
- key, value = line.split( ":", 1 )
- if value: value = value[ 1: ]
- if not self.caseSensitive:
- newkey = key.lower()
- if key not in self.trueFieldCasing:
- self.trueFieldCasing[ newkey ] = key
- key = newkey
+ ( truekey, value ) = line.split( ":", 1 )
+ key = truekey.lower()
+ self.trueFieldCasing[ key ] = truekey
+ self[ key ] = value.strip()
else:
- if isinstance( value, list ):
- value.append( line[ 1: ] )
- else:
- value = [ value, line[ 1: ] ]
- self[ key ] = value
+ self[ key ] += "\n%s" % line.strip()
def _storeField( self, f, value, lead = " " ):
- if isinstance( value, list ):
- value = "\n".join(list(map( lambda v, lead = lead: v and ( lead + v ) or v, value )))
- else:
- if value: value = lead + value
- f.write( "%s\n" % ( value ) )
+ value = "\n".join(list(map( lambda v, lead = lead: lead + v if v else "", value.splitlines() )))
+ f.write( "%s\n" % value )
def _store( self, f ):
- "Write our paragraph data to a file object"
- for key in list(self.keys()):
- value = self[ key ]
- if key in self.trueFieldCasing:
- key = self.trueFieldCasing[ key ]
- f.write( "%s:" % key )
+ """Write our paragraph data to a file object"""
+ for ( key, value ) in list(self.items()):
+ truekey = self.trueFieldCasing[ key ]
+ f.write( "%s:" % truekey )
self._storeField( f, value )
-class DpkgControl(DpkgOrderedDatalist):
-
- key = "package"
- caseSensitive = 0
-
- def setkey( self, key ): self.key = key
- def setCaseSensitive( self, value ): self.caseSensitive = value
-
- def _load_one( self, f ):
- p = DpkgParagraph( None )
- p.setCaseSensitive( self.caseSensitive )
- p.load( f )
- return p
-
- def load( self, f ):
+class DpkgControl(DpkgParagraph):
+ def load( self, f, source = False ):
while True:
- p = self._load_one( f )
- if not p: break
- self[ p[ self.key ] ] = p
+ para = DpkgParagraph()
+ para.load( f )
+ if not para:
+ break
+ if "source" not in para:
+ self[ para[ "package" ] ] = para
+ elif source:
+ self[ "source" ] = para
def _store( self, f ):
- "Write our control data to a file object"
-
- for key in list(self.keys()):
- self[ key ]._store( f )
- f.write( "\n" )
-
-class DpkgSourceControl( DpkgControl ):
- source = None
-
+ """Write our control data to a file object"""
+ keys = list(self.keys())
+ while keys:
+ self[ keys.pop( 0 ) ]._store( f )
+ if keys:
+ f.write( "\n" )
+
+class DpkgSourceControl(DpkgControl):
def load( self, f ):
- f = SignedFile(f)
- self.source = self._load_one( f )
- DpkgControl.load( self, f )
-
- def __repr__( self ):
- return self.source.__repr__() + "\n" + DpkgControl.__repr__( self )
-
- def _store( self, f ):
- "Write our control data to a file object"
- self.source._store( f )
- f.write( "\n" )
- DpkgControl._store( self, f )
+ f = SignedFile( f )
+ DpkgControl.load( self, f, source = True )
if __name__ == "__main__":
import sys
- types = { 'p' : DpkgParagraph, 'c' : DpkgControl, 's' : DpkgSourceControl }
+ types = { 'p': DpkgParagraph, 'c': DpkgControl, 's': DpkgSourceControl }
type = sys.argv[ 1 ]
if type not in types:
print( "Unknown type `%s'!" % type )
@@ -144,11 +108,13 @@ if __name__ == "__main__":
data = types[ type ]()
data.load( file )
if len( sys.argv ) > 3:
- para = data[ sys.argv[ 3 ] ]
- if len( sys.argv ) > 4:
- para._storeField( sys.stdout, para[ sys.argv[ 4 ] ], "" )
+ rargs = sys.argv[ 3: ]
+ if type != 'p':
+ data = data[ rargs.pop( 0 ) ]
+ if rargs:
+ data._storeField( sys.stdout, data[ rargs[ 0 ].lower() ], "" )
else:
- para._store( sys.stdout )
+ data._store( sys.stdout )
else:
data._store( sys.stdout )
diff --git a/minidinstall/DpkgDatalist.py b/minidinstall/DpkgDatalist.py
index 68f9940..e7abbd2 100644
--- a/minidinstall/DpkgDatalist.py
+++ b/minidinstall/DpkgDatalist.py
@@ -1,10 +1,10 @@
-# DpkgDatalist.py
+# DpkgDatalist -*- mode: python; coding: utf-8 -*-
#
# This module implements DpkgDatalist, an abstract class for storing
# a list of objects in a file. Children of this class have to implement
# the load and _store methods.
#
-# Copyright 2001 Wichert Akkerman <wichert@linux.com>
+# Copyright (c) 2001 Wichert Akkerman <wichert@linux.com>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -20,34 +20,31 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, sys
-from collections import UserDict
-from collections import OrderedDict
-from minidinstall.SafeWriteFile import SafeWriteFile
+import sys
+from collections import UserDict, OrderedDict
+from .SafeWriteFile import SafeWriteFile
class DpkgDatalistException(Exception):
UNKNOWN = 0
SYNTAXERROR = 1
- def __init__(self, message="", reason=UNKNOWN, file=None, line=None):
+ def __init__(self, message=None, reason=UNKNOWN, file=None, line=None):
self.message=message
self.reason=reason
self.filename=file
self.line=line
class _DpkgDatalist:
- def __init__(self, fn=""):
- '''Initialize a DpkgDatalist object. An optional argument is a
- file from which we load values.'''
-
+ def __init__(self, fn=None):
+ """Initialize a DpkgDatalist object. An optional argument is a
+ file from which we load values."""
self.filename=fn
if self.filename:
self.load(self.filename)
def store(self, fn=None):
- "Store variable data in a file."
-
- if fn==None:
+ """Store variable data in a file."""
+ if not fn:
fn=self.filename
# Special case for writing to stdout
if not fn:
@@ -64,15 +61,13 @@ class _DpkgDatalist:
if isinstance(fn, str):
vf.close()
-
class DpkgDatalist(UserDict, _DpkgDatalist):
- def __init__(self, fn=""):
+ def __init__(self, fn=None):
UserDict.__init__(self)
_DpkgDatalist.__init__(self, fn)
-
class DpkgOrderedDatalist(OrderedDict, _DpkgDatalist):
- def __init__(self, fn=""):
+ def __init__(self, fn=None):
OrderedDict.__init__(self)
_DpkgDatalist.__init__(self, fn)
diff --git a/minidinstall/GPGSigVerifier.py b/minidinstall/GPGSigVerifier.py
index 2e0dee5..0d47379 100644
--- a/minidinstall/GPGSigVerifier.py
+++ b/minidinstall/GPGSigVerifier.py
@@ -2,7 +2,7 @@
# A class for verifying signed files
-# Copyright © 2002 Colin Walters <walters@gnu.org>
+# Copyright (c) 2002 Colin Walters <walters@gnu.org>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,8 +18,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, re, sys, string, stat
-from minidinstall import misc
+import os
+from . import misc
class GPGSigVerifierException(Exception):
def __init__(self, value):
@@ -40,10 +40,10 @@ class GPGSigVerificationFailure(Exception):
class GPGSigVerifier:
def __init__(self, keyrings, gpgv=None):
self._keyrings = keyrings
- if gpgv is None:
+ if not gpgv:
gpgv = '/usr/bin/gpgv'
if not os.access(gpgv, os.X_OK):
- raise GPGSigVerifierException("Couldn't execute \"%s\"" % (gpgv,))
+ raise GPGSigVerifierException("Couldn't execute \"%s\"" % gpgv)
self._gpgv = gpgv
def verify(self, filename, sigfilename=None):
@@ -53,25 +53,24 @@ class GPGSigVerifier:
os.close(stdin)
misc.dup2(stdout, 1)
misc.dup2(stdout, 2)
- args = []
+ args = [self._gpgv]
for keyring in self._keyrings:
- args.append('--keyring')
- args.append(keyring)
+ args.extend(['--keyring', keyring])
if sigfilename:
args.append(sigfilename)
- args = [self._gpgv] + args + [filename]
+ args.append(filename)
os.execv(self._gpgv, args)
os.exit(1)
os.close(stdout)
output = os.fdopen(stdin).readlines()
(pid, status) = os.waitpid(pid, 0)
- if not (status is None or (os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0)):
+ if status or (not os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0):
if os.WIFEXITED(status):
- msg = "gpgv exited with error code %d" % (os.WEXITSTATUS(status),)
+ msg = "gpgv exited with error code %d" % os.WEXITSTATUS(status)
elif os.WIFSTOPPED(status):
- msg = "gpgv stopped unexpectedly with signal %d" % (os.WSTOPSIG(status),)
+ msg = "gpgv stopped unexpectedly with signal %d" % os.WSTOPSIG(status)
elif os.WIFSIGNALED(status):
- msg = "gpgv died with signal %d" % (os.WTERMSIG(status),)
+ msg = "gpgv died with signal %d" % os.WTERMSIG(status)
raise GPGSigVerificationFailure(msg, output)
return output
diff --git a/minidinstall/OrderedDict.py b/minidinstall/OrderedDict.py
index 7c842b0..dab57db 100644
--- a/minidinstall/OrderedDict.py
+++ b/minidinstall/OrderedDict.py
@@ -1,10 +1,10 @@
-# OrderedDict.py
+# OrderedDict -*- mode: python; coding: utf-8 -*-
#
# This class functions almost exactly like UserDict. However, when using
# the sequence methods, it returns items in the same order in which they
# were added, instead of some random order.
#
-# Copyright 2001 Adam Heath <doogie@debian.org>
+# Copyright (c) 2001 Adam Heath <doogie@debian.org>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ class OrderedDict(UserDict):
def __init__(self, dict=None):
UserDict.__init__(self)
self.__order=[]
- if dict is not None and dict.__class__ is not None:
+ if dict and dict.__class__:
self.update(dict)
def __cmp__(self, dict):
@@ -57,8 +57,7 @@ class OrderedDict(UserDict):
def copy(self):
if self.__class__ is OrderedDict:
return OrderedDict(self)
- import copy
- return copy.copy(self)
+ return self.copy()
def keys(self):
return self.__order
@@ -70,7 +69,7 @@ class OrderedDict(UserDict):
return list(map(lambda x, self=self: self.__getitem__(x), self.__order))
def update(self, dict):
- for k, v in list(dict.items()):
+ for (k, v) in list(dict.items()):
self.__setitem__(k, v)
# vim:ts=4:sw=4:et:
diff --git a/minidinstall/SafeWriteFile.py b/minidinstall/SafeWriteFile.py
index 591c4f0..38262f2 100755
--- a/minidinstall/SafeWriteFile.py
+++ b/minidinstall/SafeWriteFile.py
@@ -1,11 +1,12 @@
-# SafeWriteFile.py
+#!/usr/bin/python3
+# SafeWriteFile -*- mode: python; coding: utf-8 -*-
#
# This file is a writable file object. It writes to a specified newname,
# and when closed, renames the file to the realname. If the object is
# deleted, without being closed, this rename isn't done. If abort() is
# called, it also disables the rename.
#
-# Copyright 2001 Adam Heath <doogie@debian.org>
+# Copyright (c) 2001 Adam Heath <doogie@debian.org>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -27,11 +28,9 @@ from os import rename
class ObjectNotAllowed(Exception):
pass
-
class InvalidMode(Exception):
pass
-
class SafeWriteFile:
def __init__(self, newname, realname, mode="w", bufsize=-1):
@@ -47,7 +46,7 @@ class SafeWriteFile:
self.fobj=open(newname, mode, bufsize)
self.newname=newname
self.realname=realname
- self.__abort=0
+ self.__abort=False
def close(self):
self.fobj.close()
@@ -55,7 +54,7 @@ class SafeWriteFile:
rename(self.newname, self.realname)
def abort(self):
- self.__abort=1
+ self.__abort=True
def __del__(self):
self.abort()
@@ -67,7 +66,6 @@ class SafeWriteFile:
except:
return eval("self.fobj." + attr)
-
if __name__ == "__main__":
import time
f=SafeWriteFile("sf.new", "sf.data")
diff --git a/minidinstall/SignedFile.py b/minidinstall/SignedFile.py
index efc4730..5a1f7f6 100755
--- a/minidinstall/SignedFile.py
+++ b/minidinstall/SignedFile.py
@@ -1,9 +1,10 @@
+#!/usr/bin/python3
# SignedFile -*- mode: python; coding: utf-8 -*-
# SignedFile offers a subset of file object operations, and is
# designed to transparently handle files with PGP signatures.
-# Copyright © 2002 Colin Walters <walters@gnu.org>
+# Copyright (c) 2002 Colin Walters <walters@gnu.org>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -19,23 +20,22 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import re,string
-
class SignedFile:
_stream = None
- _eof = 0
- _signed = 0
+ _eof = False
+ _signed = False
_signature = None
_signatureversion = None
_initline = None
+
def __init__(self, stream):
self._stream = stream
line = stream.readline()
- if (line == "-----BEGIN PGP SIGNED MESSAGE-----\n"):
- self._signed = 1
+ if line == "-----BEGIN PGP SIGNED MESSAGE-----\n":
+ self._signed = True
while True:
line = stream.readline()
- if (len(line) == 0 or line == '\n'):
+ if not line or line == '\n':
break
else:
self._initline = line
@@ -51,13 +51,13 @@ class SignedFile:
if not self._signed:
return line
elif line == "-----BEGIN PGP SIGNATURE-----\n":
- self._eof = 1
+ self._eof = True
self._signature = []
self._signatureversion = self._stream.readline()
self._stream.readline() # skip blank line
while True:
line = self._stream.readline()
- if len(line) == 0 or line == "-----END PGP SIGNATURE-----\n":
+ if not line or line == "-----END PGP SIGNATURE-----\n":
break
self._signature.append(line)
self._signature = ''.join(self._signature)
@@ -68,7 +68,7 @@ class SignedFile:
ret = []
while True:
line = self.readline()
- if (line != ''):
+ if line:
ret.append(line)
else:
break
@@ -86,22 +86,22 @@ class SignedFile:
def getSignatureVersion(self):
return self._signatureversion
-if __name__=="__main__":
+if __name__ == "__main__":
import sys
- if len(sys.argv) == 0:
+ if not sys.argv:
print("Need one file as an argument")
sys.exit(1)
filename = sys.argv[1]
- f=SignedFile(open(filename))
+ f = SignedFile(open(filename))
if f.getSigned():
print("**** SIGNED ****")
else:
print("**** NOT SIGNED ****")
- lines=f.readlines()
+ lines = f.readlines()
print(lines)
if not f.getSigned():
assert(len(lines) == len(actuallines))
else:
- print("Signature: %s" % (f.getSignature()))
+ print("Signature: %s" % f.getSignature())
# vim:ts=4:sw=4:et:
diff --git a/minidinstall/mail.py b/minidinstall/mail.py
index 50df462..305d822 100644
--- a/minidinstall/mail.py
+++ b/minidinstall/mail.py
@@ -1,8 +1,8 @@
# mail -*- mode: python; coding: utf-8 -*-
-"""Simple mail support for mini-dinstall."""
+# Simple mail support for mini-dinstall.
-# Copyright © 2008 Stephan Sürken <absurd@debian.org>
+# Copyright (c) 2008 Stephan Sürken <absurd@debian.org>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -21,24 +21,22 @@
import smtplib
import email.mime.text
import email.utils
-
import logging
def send(smtp_server, smtp_from, smtp_to, body, subject="mini-dinstall mail notice"):
"""Send email; on error, log and continue."""
-
logger = logging.getLogger("mini-dinstall")
- try:
- # Create a mime body
- mime_body = email.mime.text.MIMEText(body, 'plain', 'utf-8')
- mime_body['Subject'] = subject
- mime_body['From'] = smtp_from
- mime_body['To'] = smtp_to
- mime_body['Date'] = email.utils.formatdate(localtime=True)
- mime_body['Message-ID'] = email.utils.make_msgid()
- mime_body.add_header('X-Mini-Dinstall', 'YES')
+ # Create a mime body
+ mime_body = email.mime.text.MIMEText(body, 'plain', 'utf-8')
+ mime_body['Subject'] = subject
+ mime_body['From'] = smtp_from
+ mime_body['To'] = smtp_to
+ mime_body['Date'] = email.utils.formatdate(localtime=True)
+ mime_body['Message-ID'] = email.utils.make_msgid()
+ mime_body.add_header('X-Mini-Dinstall', 'YES')
+ try:
# Send via SMTP server
smtp = smtplib.SMTP(smtp_server)
smtp.sendmail(smtp_from, [smtp_to], mime_body.as_string())
diff --git a/minidinstall/misc.py b/minidinstall/misc.py
index 372c450..5f7fb71 100644
--- a/minidinstall/misc.py
+++ b/minidinstall/misc.py
@@ -2,7 +2,7 @@
# misc tools for mini-dinstall
-# Copyright © 2004 Thomas Viehmann <tv@beamnet.de>
+# Copyright (c) 2004 Thomas Viehmann <tv@beamnet.de>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,26 +18,25 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, errno, time, string, re, hashlib
+import os, errno, time, re, hashlib
-def dup2(fd,fd2):
+def dup2(fd, fd2):
# dup2 with EBUSY retries (cf. dup2(2) and Debian bug #265513)
- success = 0
+ success = False
tries = 0
- while (not success):
+ while not success:
try:
- os.dup2(fd,fd2)
- success = 1
+ os.dup2(fd, fd2)
+ success = True
except OSError as e:
- if (e.errno != errno.EBUSY) or (tries >= 3):
+ if e.errno != errno.EBUSY or tries >= 3:
raise
- # wait 0-2 seconds befor next try
+ # wait 0-2 seconds before next try
time.sleep(tries)
tries += 1
def format_changes(L):
""" remove changelog header and all lines with only a dot """
-
dotmatch = re.compile('^\.$')
L1 = []
@@ -48,16 +47,11 @@ def format_changes(L):
def get_file_sum(self, type, filename):
""" generate hash sums for file """
- if type == 'md5':
- sum = hashlib.md5()
- elif type == 'sha1':
- sum = hashlib.sha1()
- elif type == 'sha256':
- sum = hashlib.sha256()
+ sum = getattr(hashlib, type)()
self._logger.debug("Generate %s (python-internal) for %s" % (type, filename))
- f = open(filename,'rb')
+ f = open(filename, 'rb')
buf = f.read(8192)
- while buf != '':
+ while buf:
sum.update(buf)
buf = f.read(8192)
return sum.hexdigest()
diff --git a/minidinstall/tweet.py b/minidinstall/tweet.py
index 7106085..3a4a4ef 100644
--- a/minidinstall/tweet.py
+++ b/minidinstall/tweet.py
@@ -1,8 +1,8 @@
-# mail -*- mode: python; coding: utf-8 -*-
+# tweet -*- mode: python; coding: utf-8 -*-
-"""Simple tweet support for mini-dinstall."""
+# Simple tweet support for mini-dinstall.
-# Copyright © 2010 Christopher R. Gabriel <cgabriel@truelite.it>
+# Copyright (c) 2010 Christopher R. Gabriel <cgabriel@truelite.it>
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -18,10 +18,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
import logging
import urllib.request
-import base64
def send(tweet_body, tweet_server, tweet_user, tweet_password):
"""Send tweet; on error, log and continue."""
@@ -37,8 +35,8 @@ def send(tweet_body, tweet_server, tweet_user, tweet_password):
if not post_url:
logger.exception("Unknown tweet site")
- if not tweet_user or not tweet_password:
- logger.exception("Missing username or password for twitting")
+ if not (tweet_user and tweet_password):
+ logger.exception("Missing username or password for tweeting")
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm=auth_realm,
@@ -49,10 +47,9 @@ def send(tweet_body, tweet_server, tweet_user, tweet_password):
req = urllib.request.Request(post_url)
req.add_data("status=%s" % tweet_body)
- handle = None
try:
handle = m_http_opener.open(req)
- a = handle.read()
+ result = handle.read()
logger.info("Tweet sent to %s (%s)" % (tweet_server, tweet_user))
except Exception as e:
- logger.exception("Error sending tweet to %s ('%s') via %s: %s: %s", tweet_server, tweet_body, tweet_user, type(e), e.args)
+ logger.exception("Error sending tweet to %s ('%s') via %s: %s: %s" % (tweet_server, tweet_body, tweet_user, type(e), e.args))