Bump to python3
This commit is contained in:
parent
bb0259bd72
commit
faa9ff604d
62
debian/rules
vendored
62
debian/rules
vendored
@ -1,13 +1,65 @@
|
|||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
# You must remove unused comment lines for the released package.
|
# -*- makefile -*-
|
||||||
#export DH_VERBOSE = 1
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
export PYBUILD_NAME=fail2ban-p2p
|
|
||||||
DESTDIR=$(CURDIR)/debian/fail2ban-p2p
|
DESTDIR=$(CURDIR)/debian/fail2ban-p2p
|
||||||
|
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@ --with python3 --buildsystem=pybuild --root=$(DESTDIR) --no-compile --install-layout=deb
|
dh $@ --with python2
|
||||||
|
|
||||||
|
# Override auto test because upstream do not use the standard unittest discover
|
||||||
override_dh_auto_test:
|
override_dh_auto_test:
|
||||||
echo "Not running tests - upstream tarball doesn't provide any."
|
|
||||||
|
|
||||||
|
# Override of auto_build
|
||||||
|
override_dh_auto_build:
|
||||||
|
|
||||||
|
# Override of auto_install to remove information from package
|
||||||
|
override_dh_auto_install:
|
||||||
|
#dh_auto_install
|
||||||
|
python setup.py install --root=$(DESTDIR) --no-compile --install-layout=deb
|
||||||
|
|
||||||
|
|
||||||
|
clean: clean-inits
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
rm -f build-stamp configure-stamp
|
||||||
|
rm -rf build
|
||||||
|
# Does not hurt to ask distutils to do their duty
|
||||||
|
python setup.py clean
|
||||||
|
# Enforce removal of *.pyc files. Apparently dh_clean does
|
||||||
|
# not perform find on provided filename patterns.
|
||||||
|
find . -name \*.pyc -exec rm -f {} \;
|
||||||
|
dh_clean
|
||||||
|
|
||||||
|
#
|
||||||
|
# Just to comply with policy 4.8
|
||||||
|
binary-arch:
|
||||||
|
|
||||||
|
# Build architecture-independent files here.
|
||||||
|
binary-indep: install
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
#dh_installchangelogs ChangeLog
|
||||||
|
dh_installdocs
|
||||||
|
dh_installlogrotate
|
||||||
|
dh_python2
|
||||||
|
dh_installinit -- defaults 99
|
||||||
|
#dh_installman man/*.1
|
||||||
|
dh_link
|
||||||
|
dh_compress
|
||||||
|
dh_fixperms
|
||||||
|
dh_installdeb
|
||||||
|
dh_gencontrol
|
||||||
|
dh_md5sums
|
||||||
|
dh_builddeb
|
||||||
|
|
||||||
|
binary: binary-indep
|
||||||
|
.PHONY: build clean binary-indep binary-arch binary install configure copy-inits clean-inits
|
||||||
|
65
debian/rules.old
vendored
65
debian/rules.old
vendored
@ -1,65 +0,0 @@
|
|||||||
#!/usr/bin/make -f
|
|
||||||
# -*- makefile -*-
|
|
||||||
# Sample debian/rules that uses debhelper.
|
|
||||||
# This file was originally written by Joey Hess and Craig Small.
|
|
||||||
# As a special exception, when this file is copied by dh-make into a
|
|
||||||
# dh-make output file, you may use that output file without restriction.
|
|
||||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
|
||||||
|
|
||||||
# Uncomment this to turn on verbose mode.
|
|
||||||
#export DH_VERBOSE=1
|
|
||||||
|
|
||||||
DESTDIR=$(CURDIR)/debian/fail2ban-p2p
|
|
||||||
|
|
||||||
configure: configure-stamp
|
|
||||||
configure-stamp:
|
|
||||||
dh_testdir
|
|
||||||
touch configure-stamp
|
|
||||||
|
|
||||||
build:
|
|
||||||
|
|
||||||
clean: clean-inits
|
|
||||||
dh_testdir
|
|
||||||
dh_testroot
|
|
||||||
rm -f build-stamp configure-stamp
|
|
||||||
rm -rf build
|
|
||||||
# Does not hurt to ask distutils to do their duty
|
|
||||||
python setup.py clean
|
|
||||||
# Enforce removal of *.pyc files. Apparently dh_clean does
|
|
||||||
# not perform find on provided filename patterns.
|
|
||||||
find . -name \*.pyc -exec rm -f {} \;
|
|
||||||
dh_clean
|
|
||||||
|
|
||||||
install: build
|
|
||||||
dh_testdir
|
|
||||||
dh_testroot
|
|
||||||
dh_clean -k
|
|
||||||
dh_installdirs
|
|
||||||
|
|
||||||
# Install the package into debian/fail2ban-p2p.
|
|
||||||
python setup.py install --root=$(DESTDIR) --no-compile --install-layout=deb
|
|
||||||
|
|
||||||
#
|
|
||||||
# Just to comply with policy 4.8
|
|
||||||
binary-arch:
|
|
||||||
|
|
||||||
# Build architecture-independent files here.
|
|
||||||
binary-indep: install
|
|
||||||
dh_testdir
|
|
||||||
dh_testroot
|
|
||||||
#dh_installchangelogs ChangeLog
|
|
||||||
dh_installdocs
|
|
||||||
dh_installlogrotate
|
|
||||||
dh_python2
|
|
||||||
dh_installinit -- defaults 99
|
|
||||||
#dh_installman man/*.1
|
|
||||||
dh_link
|
|
||||||
dh_compress
|
|
||||||
dh_fixperms
|
|
||||||
dh_installdeb
|
|
||||||
dh_gencontrol
|
|
||||||
dh_md5sums
|
|
||||||
dh_builddeb
|
|
||||||
|
|
||||||
binary: binary-indep
|
|
||||||
.PHONY: build clean binary-indep binary-arch binary install configure copy-inits clean-inits
|
|
@ -42,8 +42,8 @@ source_suffix = '.rst'
|
|||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'fail2ban-p2p'
|
project = 'fail2ban-p2p'
|
||||||
copyright = u'2013, Manuel Munz, Johannes Fürmann'
|
copyright = '2013, Manuel Munz, Johannes Fürmann'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
@ -185,8 +185,8 @@ latex_elements = {
|
|||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('index', 'fail2ban-p2p.tex', u'fail2ban-p2p Documentation',
|
('index', 'fail2ban-p2p.tex', 'fail2ban-p2p Documentation',
|
||||||
u'Manuel Munz, Johannes Fürmann', 'manual'),
|
'Manuel Munz, Johannes Fürmann', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
@ -215,8 +215,8 @@ latex_documents = [
|
|||||||
# One entry per manual page. List of tuples
|
# One entry per manual page. List of tuples
|
||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [
|
||||||
('index', 'fail2ban-p2p', u'fail2ban-p2p Documentation',
|
('index', 'fail2ban-p2p', 'fail2ban-p2p Documentation',
|
||||||
[u'Manuel Munz, Johannes Fürmann'], 1)
|
['Manuel Munz, Johannes Fürmann'], 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
@ -229,8 +229,8 @@ man_pages = [
|
|||||||
# (source start file, target name, title, author,
|
# (source start file, target name, title, author,
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
('index', 'fail2ban-p2p', u'fail2ban-p2p Documentation',
|
('index', 'fail2ban-p2p', 'fail2ban-p2p Documentation',
|
||||||
u'Manuel Munz, Johannes Fürmann', 'fail2ban-p2p', 'One line description of project.',
|
'Manuel Munz, Johannes Fürmann', 'fail2ban-p2p', 'One line description of project.',
|
||||||
'Miscellaneous'),
|
'Miscellaneous'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ if c.loadConfig() == False:
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
if not args.d and not args.b:
|
if not args.d and not args.b:
|
||||||
print "Please use the -b argument to specify an IP to ban or -d to request information about banned nodes."
|
print("Please use the -b argument to specify an IP to ban or -d to request information about banned nodes.")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
dump = False
|
dump = False
|
||||||
@ -120,10 +120,10 @@ try:
|
|||||||
s.send(cmdsigned)
|
s.send(cmdsigned)
|
||||||
ret = s.recv(1048576) # we need about 50 Bytes per banned node
|
ret = s.recv(1048576) # we need about 50 Bytes per banned node
|
||||||
if not quiet and args.v:
|
if not quiet and args.v:
|
||||||
print ("Message sent: " + cmdsigned)
|
print(("Message sent: " + cmdsigned))
|
||||||
except:
|
except:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print ("could not connect to "+c.name+" ("+c.addresses[0]+":"+str(c.port)+")")
|
print(("could not connect to "+c.name+" ("+c.addresses[0]+":"+str(c.port)+")"))
|
||||||
finally:
|
finally:
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
@ -135,17 +135,17 @@ if ret:
|
|||||||
elif args.d == "json":
|
elif args.d == "json":
|
||||||
print(ret)
|
print(ret)
|
||||||
elif args.d == "count":
|
elif args.d == "count":
|
||||||
print(len(json.loads(ret)))
|
print((len(json.loads(ret))))
|
||||||
else:
|
else:
|
||||||
banList = json.loads(ret)
|
banList = json.loads(ret)
|
||||||
if len(banList) > 0:
|
if len(banList) > 0:
|
||||||
print("IP".ljust(15, ' ') + "\tTimestamp\t\tBantime\t\tTrustlevel\tStatus")
|
print(("IP".ljust(15, ' ') + "\tTimestamp\t\tBantime\t\tTrustlevel\tStatus"))
|
||||||
for ban in banList:
|
for ban in banList:
|
||||||
status = "PENDING"
|
status = "PENDING"
|
||||||
if int(c.threshold) <= int(ban['Trustlevel']):
|
if int(c.threshold) <= int(ban['Trustlevel']):
|
||||||
status = "BANNED"
|
status = "BANNED"
|
||||||
print(ban['AttackerIP'].ljust(15, ' ') + "\t" + str(ban['Timestamp']) + "\t\t" + str(ban['BanTime']) + "\t\t" + str(ban['Trustlevel'])) + "\t\t" + status
|
print((ban['AttackerIP'].ljust(15, ' ') + "\t" + str(ban['Timestamp']) + "\t\t" + str(ban['BanTime']) + "\t\t" + str(ban['Trustlevel'])) + "\t\t" + status)
|
||||||
else:
|
else:
|
||||||
print("No hosts in banlist")
|
print("No hosts in banlist")
|
||||||
else:
|
else:
|
||||||
print("Answer: " + ret)
|
print(("Answer: " + ret))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
|
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
|
||||||
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
|
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
|
||||||
|
|
||||||
import ConfigParser
|
import configparser
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -49,15 +49,15 @@ class Config:
|
|||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
value = config.get(section, option)
|
value = config.get(section, option)
|
||||||
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
|
except (configparser.NoOptionError, configparser.NoSectionError):
|
||||||
if mandatory:
|
if mandatory:
|
||||||
print "Mandatory option " + option + " not found in config file " + self.configFile
|
print("Mandatory option " + option + " not found in config file " + self.configFile)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
value = default
|
value = default
|
||||||
return value
|
return value
|
||||||
|
|
||||||
config = ConfigParser.RawConfigParser()
|
config = configparser.RawConfigParser()
|
||||||
self.configFile = os.path.join(self.configPath, 'fail2ban-p2p.conf')
|
self.configFile = os.path.join(self.configPath, 'fail2ban-p2p.conf')
|
||||||
|
|
||||||
if os.access(self.configFile, os.R_OK):
|
if os.access(self.configFile, os.R_OK):
|
||||||
@ -74,6 +74,6 @@ class Config:
|
|||||||
self.threshold = get_option('Node', 'threshold', False, 80)
|
self.threshold = get_option('Node', 'threshold', False, 80)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print('ERROR: Configuration directory "' + self.configPath + '" does not exist.\n' +
|
print(('ERROR: Configuration directory "' + self.configPath + '" does not exist.\n' +
|
||||||
'Please create a configuration or specify another valid configuration directory with the "-c" argument.')
|
'Please create a configuration or specify another valid configuration directory with the "-c" argument.'))
|
||||||
return False
|
return False
|
||||||
|
@ -24,8 +24,8 @@ def create_keys():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if os.path.isfile(c.privkey) or os.path.isfile(c.pubkey):
|
if os.path.isfile(c.privkey) or os.path.isfile(c.pubkey):
|
||||||
print "A keypair for this node already exists."
|
print("A keypair for this node already exists.")
|
||||||
ask = raw_input('Do you really want to create a new one? [y/N] ')
|
ask = input('Do you really want to create a new one? [y/N] ')
|
||||||
if ask != "y":
|
if ask != "y":
|
||||||
return
|
return
|
||||||
M2Crypto.Rand.rand_seed (os.urandom (1024))
|
M2Crypto.Rand.rand_seed (os.urandom (1024))
|
||||||
@ -33,11 +33,11 @@ def create_keys():
|
|||||||
keypair = M2Crypto.RSA.gen_key (1024, 65537)
|
keypair = M2Crypto.RSA.gen_key (1024, 65537)
|
||||||
try:
|
try:
|
||||||
keypair.save_key(c.privkey, None)
|
keypair.save_key(c.privkey, None)
|
||||||
os.chmod(c.privkey, 0400)
|
os.chmod(c.privkey, 0o400)
|
||||||
keypair.save_pub_key(c.pubkey)
|
keypair.save_pub_key(c.pubkey)
|
||||||
logger.debug("Private key (secret) was saved to " + c.privkey)
|
logger.debug("Private key (secret) was saved to " + c.privkey)
|
||||||
logger.debug("Public key was saved to " + c.pubkey)
|
logger.debug("Public key was saved to " + c.pubkey)
|
||||||
except IOError, e:
|
except IOError as e:
|
||||||
logger.error("Could not save the keypair, check permissions! " + "%s" % e)
|
logger.error("Could not save the keypair, check permissions! " + "%s" % e)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ def initialize_logging(name="unknown"):
|
|||||||
log2file.setLevel(c.logLevel)
|
log2file.setLevel(c.logLevel)
|
||||||
logger.addHandler(log2file)
|
logger.addHandler(log2file)
|
||||||
except:
|
except:
|
||||||
print("--- WARNING --- LOGFILE " + c.logFile + " IS EITHER NONEXISTENT OR NOT WRITABLE")
|
print(("--- WARNING --- LOGFILE " + c.logFile + " IS EITHER NONEXISTENT OR NOT WRITABLE"))
|
||||||
log2stderr = logging.StreamHandler(sys.stderr)
|
log2stderr = logging.StreamHandler(sys.stderr)
|
||||||
log2stderr.setFormatter(formatter)
|
log2stderr.setFormatter(formatter)
|
||||||
log2stderr.setLevel(c.logLevel)
|
log2stderr.setLevel(c.logLevel)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import config
|
import config
|
||||||
import socket
|
import socket
|
||||||
import thread
|
import _thread
|
||||||
import threading
|
import threading
|
||||||
from command import Command
|
from command import Command
|
||||||
import server
|
import server
|
||||||
@ -74,7 +74,7 @@ class Node:
|
|||||||
for sock in readable:
|
for sock in readable:
|
||||||
client_socket, address = sock.accept()
|
client_socket, address = sock.accept()
|
||||||
logger.debug("connection from "+address[0])
|
logger.debug("connection from "+address[0])
|
||||||
thread.start_new_thread(server.serve, (self, client_socket, address))
|
_thread.start_new_thread(server.serve, (self, client_socket, address))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
# http://opensource.org/licenses/MIT
|
# http://opensource.org/licenses/MIT
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from thread import get_ident as _get_ident
|
from _thread import get_ident as _get_ident
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from dummy_thread import get_ident as _get_ident
|
from _dummy_thread import get_ident as _get_ident
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _abcoll import KeysView, ValuesView, ItemsView
|
from _abcoll import KeysView, ValuesView, ItemsView
|
||||||
@ -90,7 +90,7 @@ class OrderedDict(dict):
|
|||||||
def clear(self):
|
def clear(self):
|
||||||
'od.clear() -> None. Remove all items from od.'
|
'od.clear() -> None. Remove all items from od.'
|
||||||
try:
|
try:
|
||||||
for node in self.__map.itervalues():
|
for node in self.__map.values():
|
||||||
del node[:]
|
del node[:]
|
||||||
root = self.__root
|
root = self.__root
|
||||||
root[:] = [root, root, None]
|
root[:] = [root, root, None]
|
||||||
@ -173,12 +173,12 @@ class OrderedDict(dict):
|
|||||||
for key in other:
|
for key in other:
|
||||||
self[key] = other[key]
|
self[key] = other[key]
|
||||||
elif hasattr(other, 'keys'):
|
elif hasattr(other, 'keys'):
|
||||||
for key in other.keys():
|
for key in list(other.keys()):
|
||||||
self[key] = other[key]
|
self[key] = other[key]
|
||||||
else:
|
else:
|
||||||
for key, value in other:
|
for key, value in other:
|
||||||
self[key] = value
|
self[key] = value
|
||||||
for key, value in kwds.items():
|
for key, value in list(kwds.items()):
|
||||||
self[key] = value
|
self[key] = value
|
||||||
|
|
||||||
__update = update # let subclasses override update without breaking __init__
|
__update = update # let subclasses override update without breaking __init__
|
||||||
@ -214,7 +214,7 @@ class OrderedDict(dict):
|
|||||||
try:
|
try:
|
||||||
if not self:
|
if not self:
|
||||||
return '%s()' % (self.__class__.__name__,)
|
return '%s()' % (self.__class__.__name__,)
|
||||||
return '%s(%r)' % (self.__class__.__name__, self.items())
|
return '%s(%r)' % (self.__class__.__name__, list(self.items()))
|
||||||
finally:
|
finally:
|
||||||
del _repr_running[call_key]
|
del _repr_running[call_key]
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ class OrderedDict(dict):
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
if isinstance(other, OrderedDict):
|
if isinstance(other, OrderedDict):
|
||||||
return len(self)==len(other) and self.items() == other.items()
|
return len(self)==len(other) and list(self.items()) == list(other.items())
|
||||||
return dict.__eq__(self, other)
|
return dict.__eq__(self, other)
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
|
@ -30,7 +30,7 @@ def getDictValue(dict, key):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
return dict[key]
|
return dict[key]
|
||||||
except KeyError, e:
|
except KeyError as e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def parse(msg):
|
def parse(msg):
|
||||||
@ -49,7 +49,7 @@ def parse(msg):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
signed_dict = json.loads(msg)
|
signed_dict = json.loads(msg)
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
logger.warning("The received message does not appear to be valid json.")
|
logger.warning("The received message does not appear to be valid json.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ def serve(n, connection, address):
|
|||||||
else:
|
else:
|
||||||
connection.send("OK\n")
|
connection.send("OK\n")
|
||||||
|
|
||||||
except customexceptions.InvalidMessage, e:
|
except customexceptions.InvalidMessage as e:
|
||||||
connection.send("ERROR Invalid message\n")
|
connection.send("ERROR Invalid message\n")
|
||||||
logger.warn("This message made no sense.")
|
logger.warn("This message made no sense.")
|
||||||
except customexceptions.InvalidSignature, e:
|
except customexceptions.InvalidSignature as e:
|
||||||
connection.send("ERROR invalid signature\n")
|
connection.send("ERROR invalid signature\n")
|
||||||
logger.warn("The Signature could not be verified")
|
logger.warn("The Signature could not be verified")
|
||||||
except customexceptions.InvalidProtocolVersion, e:
|
except customexceptions.InvalidProtocolVersion as e:
|
||||||
connection.send("ERROR invalid protocol version\n")
|
connection.send("ERROR invalid protocol version\n")
|
||||||
else:
|
else:
|
||||||
connection.send("Error\n")
|
connection.send("Error\n")
|
||||||
|
@ -28,9 +28,9 @@ def sort_recursive(dictionary):
|
|||||||
OrderedDict([('a', '2'), ('b', OrderedDict([('d', 1), ('e', 4)])), ('c', 3), ('f', 5)])
|
OrderedDict([('a', '2'), ('b', OrderedDict([('d', 1), ('e', 4)])), ('c', 3), ('f', 5)])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sorted_list = OrderedDict(sorted(dictionary.items(), key = lambda x: x[0]))
|
sorted_list = OrderedDict(sorted(list(dictionary.items()), key = lambda x: x[0]))
|
||||||
# TODO test for cyclic structures.
|
# TODO test for cyclic structures.
|
||||||
for key, value in sorted_list.items():
|
for key, value in list(sorted_list.items()):
|
||||||
if type(value) is dict:
|
if type(value) is dict:
|
||||||
sorted_list[key] = sort_recursive(value)
|
sorted_list[key] = sort_recursive(value)
|
||||||
|
|
||||||
|
8
setup.py
8
setup.py
@ -55,9 +55,9 @@ setup(
|
|||||||
|
|
||||||
# Update config file
|
# Update config file
|
||||||
if argv[1] == "install":
|
if argv[1] == "install":
|
||||||
print
|
print()
|
||||||
print "Please do not forget to update your configuration files."
|
print("Please do not forget to update your configuration files.")
|
||||||
print "They are in /etc/fail2ban-p2p/."
|
print("They are in /etc/fail2ban-p2p/.")
|
||||||
print
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user