From 3fdf2f7baaa3a67880de95948d6ee76bc698fbc9 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Fri, 11 Aug 2023 14:00:49 +0300 Subject: [PATCH] Feat(bin): Port scripts to Python 3 --- bin/GET.py | 115 ++++++++++++++++++------------ bin/HEAD.py | 93 ++++++++++++++++-------- bin/PS | 4 +- bin/abspath.py | 2 +- bin/browser-stack.py | 2 +- bin/cmp.py | 14 ++-- bin/compyle4vim.py | 3 +- bin/decode-URLs.py | 10 ++- bin/get_html_encoding.py | 11 +-- bin/get_xml_encoding.py | 4 +- bin/iconv.py | 32 +++++---- bin/iconvx.py | 33 ++++----- bin/idna.py | 14 ++-- bin/koi2lat | 8 +-- bin/lat2koi | 8 +-- bin/mc_type.py | 4 +- bin/recode-filenames-recursive.py | 52 +++++++------- bin/recode_filenames.py | 94 ++++++++++++------------ bin/rm-pyc | 4 +- bin/text-wrap.py | 104 ++++++++++++++------------- bin/unzip.py | 8 ++- bin/webbrowser | 2 +- bin/webbrowser-encode-url | 65 ++++++++++------- bin/wget-download | 87 ++++++++++++++-------- bin/zip.py | 9 ++- 25 files changed, 444 insertions(+), 338 deletions(-) diff --git a/bin/GET.py b/bin/GET.py index f7fddbd..0e18f5f 100755 --- a/bin/GET.py +++ b/bin/GET.py @@ -1,71 +1,96 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 -import sys -url = sys.argv[1] +try: + PY2 = False + from urllib.parse import parse_qsl, urlencode, \ + quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery + from urllib.request import urlretrieve + import urllib.request +except ImportError: + PY2 = True + from cgi import parse_qsl + from urllib import urlencode, quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery, urlretrieve +import os +import sys import urllib -urllib._urlopener = urllib.FancyURLopener() - -from cgi import parse_qsl from m_lib.defenc import default_encoding -protocol, request = urllib.splittype(url) +url = sys.argv[1] +if PY2: + _urlopener = urllib._urlopener = urllib.FancyURLopener() +else: + _urlopener = urllib.request._opener = urllib.request.FancyURLopener() + +protocol, request = splittype(url) user, password, port = None, None, None -host, path = urllib.splithost(request) +host, path = splithost(request) if host: - user, host = urllib.splituser(host) - if user: - user, password = urllib.splitpasswd(user) - host, port = urllib.splitport(host) - if port: port = int(port) -path, tag = urllib.splittag(path) -path, query = urllib.splitquery(path) -path = urllib.unquote(path) -if tag: tag = urllib.unquote_plus(tag) + user, host = splituser(host) + if user: + user, password = splitpasswd(user) + host, port = splitport(host) + if port: port = int(port) +path, tag = splittag(path) +path, query = splitquery(path) +path = unquote(path) +if tag: tag = unquote_plus(tag) if query: - qlist = [] - for name, value in parse_qsl(query): - qlist.append((name, value)) + qlist = [] + for name, value in parse_qsl(query): + qlist.append((name, value)) url = protocol + "://" if user: - url += urllib.quote(user) - if password: - url += ':' + urllib.quote(password) - url += '@' + url += quote(user) + if password: + url += ':' + quote(password) + url += '@' if host: - url += host.decode(default_encoding).encode('idna') - if port: - url += ':%d' % port + if PY2: + host = host.decode(default_encoding) + host = host.encode('idna') + if not PY2: + host = host.decode('ascii') + url += host + if port: + url += ':%d' % port if path: - if protocol == "file": - url += urllib.quote(path) - else: - url += urllib.quote(path) + if protocol == "file": + url += quote(path) + else: + url += quote(path) if query: - url += '?' + urllib.urlencode(qlist) + url += '?' + urlencode(qlist) if tag: - url += '#' + urllib.quote_plus(tag) + url += '#' + quote_plus(tag) # I remember seeing some sites that return broken HTML or even HTTP response # without "compatible" user agent; I don't know if such sites are still around, # but this header doesn't cause any harm so I'd better continue to use it. # UPDATE: I saw a number of sites that forbid "Mozilla compatible" -server_version = "Python-urllib/%s" % urllib.__version__ -urllib._urlopener.addheaders[0] = ('User-agent', server_version) -urllib._urlopener.addheaders.append(('Accept-Charset', "koi8-r;q=1.0")) +if PY2: + urllib_version = urllib.__version__ +else: + urllib_version = urllib.request.__version__ +server_version = "Python-urllib/%s" % urllib_version -import os -dest_file = os.path.basename(url) +_urlopener.addheaders[0] = ('User-agent', server_version) +_urlopener.addheaders.append(('Accept-Charset', "koi8-r;q=1.0")) +dest_file = os.path.basename(url) if not dest_file: - dest_file = "_index.html" + dest_file = "_index.html" -filename, headers = urllib.urlretrieve(url, dest_file) +filename, headers = urlretrieve(url, filename=dest_file) -if headers.has_key("last-modified"): - from m_lib.net.www.util import parse_time - last_modified = parse_time(headers["last-modified"]) - if last_modified: - os.utime(dest_file, (last_modified, last_modified)) +if "last-modified" in headers: + from m_lib.net.www.util import parse_time + last_modified = parse_time(headers["last-modified"]) + if last_modified: + os.utime(dest_file, (last_modified, last_modified)) diff --git a/bin/HEAD.py b/bin/HEAD.py index c7b3764..c5d06a6 100755 --- a/bin/HEAD.py +++ b/bin/HEAD.py @@ -1,61 +1,92 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 -import sys -url = sys.argv[1] +try: + PY2 = False + from http.client import HTTPConnection + from urllib.parse import parse_qsl, urlencode, \ + quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery + import urllib.request +except ImportError: + PY2 = True + from cgi import parse_qsl + from urllib import urlencode, quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery + from httplib import HTTPConnection -import socket -socket.setdefaulttimeout(30) - -from cgi import parse_qsl +import sys import urllib from m_lib.defenc import default_encoding -protocol, request = urllib.splittype(url) +url = sys.argv[1] + +protocol, request = splittype(url) user, password, port = None, None, None -host, path = urllib.splithost(request) +host, path = splithost(request) if host: - user, host = urllib.splituser(host) - if user: - user, password = urllib.splitpasswd(user) - host, port = urllib.splitport(host) - if port: port = int(port) -path, tag = urllib.splittag(path) -path, query = urllib.splitquery(path) -path = urllib.unquote(path) -if tag: tag = urllib.unquote_plus(tag) + user, host = splituser(host) + if user: + user, password = splitpasswd(user) + host, port = splitport(host) + if port: port = int(port) +path, tag = splittag(path) +path, query = splitquery(path) +path = unquote(path) +if tag: tag = unquote_plus(tag) if query: - qlist = [] - for name, value in parse_qsl(query): - qlist.append((name, value)) + qlist = [] + for name, value in parse_qsl(query): + qlist.append((name, value)) -url = '' -host = host.decode(default_encoding).encode('idna') +url = protocol + "://" +if user: + url += quote(user) + if password: + url += ':' + quote(password) + url += '@' +if host: + if PY2: + host = host.decode(default_encoding) + host = host.encode('idna') + if not PY2: + host = host.decode('ascii') + url += host + if port: + url += ':%d' % port if path: - url += urllib.quote(path) + if protocol == "file": + url += quote(path) + else: + url += quote(path) if query: - url += '?' + urllib.urlencode(qlist) + url += '?' + urlencode(qlist) if tag: - url += '#' + urllib.quote_plus(tag) + url += '#' + quote_plus(tag) -import httplib -server = httplib.HTTP(host, port) +server = HTTPConnection(host, port) server.set_debuglevel(1) server.putrequest("HEAD", path) if port: server.putheader("Host", '%s:%d' % (host, port)) else: - server.putheader("Host", host) + server.putheader("Host", host) # I remember seeing some sites that return broken HTML or even HTTP response # without "compatible" user agent; I don't know if such sites are still around, # but this header doesn't cause any harm so I'd better continue to use it. # UPDATE: I saw a number of sites that forbid "Mozilla compatible" -client_version = "Python-urllib/%s" % urllib.__version__ +if PY2: + urllib_version = urllib.__version__ +else: + urllib_version = urllib.request.__version__ +client_version = "Python-urllib/%s" % urllib_version server.putheader('User-agent', client_version) server.putheader('Accept-Charset', "koi8-r;q=1.0") server.endheaders() -server.getreply() +server.getresponse() diff --git a/bin/PS b/bin/PS index 67574b5..7fbd8b1 100755 --- a/bin/PS +++ b/bin/PS @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys, os @@ -13,5 +13,5 @@ if pager == 'less': opt = 'S' if opt not in less: less = opt + less - os.environ["LESS"] = less + os.environ["LESS"] = less os.system("ps %s | %s" % (args, pager)) diff --git a/bin/abspath.py b/bin/abspath.py index 9dbfebe..cbda1c8 100755 --- a/bin/abspath.py +++ b/bin/abspath.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys, os print(os.path.abspath(sys.argv[1])) diff --git a/bin/browser-stack.py b/bin/browser-stack.py index 0deb390..7120479 100755 --- a/bin/browser-stack.py +++ b/bin/browser-stack.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 from __future__ import print_function import sys, os diff --git a/bin/cmp.py b/bin/cmp.py index 37cc0ff..800e119 100755 --- a/bin/cmp.py +++ b/bin/cmp.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 """cmp.py: compare two files. Replace cmp because standard cmp cannot compare large files. """ @@ -6,11 +6,11 @@ large files. import sys, os if sys.argv[1] in ("-h", "--help"): - print "Broytman cmp.py 1.0, Copyright (C) 2003 PhiloSoft Design" - print "Usage: cmp.py [-h|--help|-V|--version] [-i] file1 file2" + print("Broytman cmp.py 1.0, Copyright (C) 2003-2023 PhiloSoft Design") + print("Usage: cmp.py [-h|--help|-V|--version] [-i] file1 file2") sys.exit() elif sys.argv[1] in ("-V", "--version"): - print "Broytman cmp.py 1.0, Copyright (C) 2003 PhiloSoft Design" + print("Broytman cmp.py 1.0, Copyright (C) 2003-2023 PhiloSoft Design") sys.exit() elif sys.argv[1] == "-i": show_pbar = False @@ -31,7 +31,7 @@ if show_pbar: try: size = os.path.getsize(fname1) except: - print filename, ": no such file" + print(filename, ": no such file") sys.exit(1) if show_pbar: @@ -62,7 +62,7 @@ while True: pbar.display(file1.tell()) if block1 and block2: - if len(block1) <> len(block2): + if len(block1) != len(block2): report() break elif block1: @@ -74,7 +74,7 @@ while True: else: break - if block1 <> block2: + if block1 != block2: report() break diff --git a/bin/compyle4vim.py b/bin/compyle4vim.py index 88a5705..08f9324 100755 --- a/bin/compyle4vim.py +++ b/bin/compyle4vim.py @@ -1,5 +1,4 @@ -#! /usr/bin/env python - +#! /usr/bin/env python3 import sys, os diff --git a/bin/decode-URLs.py b/bin/decode-URLs.py index 4d58193..ef04664 100755 --- a/bin/decode-URLs.py +++ b/bin/decode-URLs.py @@ -1,12 +1,16 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 -import sys, urllib +try: + from urllib.parse import unquote +except ImportError: + from urllib import unquote +import sys while True: url = sys.stdin.readline() if not url: break - unqoted = urllib.unquote(url.strip()) + unqoted = unquote(url.strip()) if unqoted.startswith('file://'): unqoted = unqoted[len('file://'):] print(unqoted) diff --git a/bin/get_html_encoding.py b/bin/get_html_encoding.py index 4ffb449..381be9c 100755 --- a/bin/get_html_encoding.py +++ b/bin/get_html_encoding.py @@ -1,18 +1,13 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 - -from HTMLParser import HTMLParseError from m_lib.net.www.html import HTMLParser as _HTMLParser - class HTMLHeadDone(Exception): pass - class HTMLParser(_HTMLParser): def end_head(self): raise HTMLHeadDone() - def do_meta(self, attrs): http_equiv = "" content = "" @@ -41,14 +36,14 @@ def parse_html(filename): for line in infile: try: parser.feed(line) - except (HTMLParseError, HTMLHeadDone): + except HTMLHeadDone: break infile.close() try: parser.close() - except (HTMLParseError, HTMLHeadDone): + except HTMLHeadDone: pass if hasattr(parser, "charset"): diff --git a/bin/get_xml_encoding.py b/bin/get_xml_encoding.py index ec79c1a..cdd9b6b 100755 --- a/bin/get_xml_encoding.py +++ b/bin/get_xml_encoding.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 charset = None def xml_decl_handler(version, encoding, standalone): @@ -12,7 +12,7 @@ if __name__ == '__main__': import xml.parsers.expat parser = xml.parsers.expat.ParserCreate() parser.XmlDeclHandler = xml_decl_handler - parser.ParseFile(open(sys.argv[1], 'r')) + parser.ParseFile(open(sys.argv[1], 'rb')) except: pass if charset: print(charset) diff --git a/bin/iconv.py b/bin/iconv.py index 83de413..9cb164f 100755 --- a/bin/iconv.py +++ b/bin/iconv.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 "Recode to default charset" import sys @@ -10,19 +10,23 @@ to_charset = default_encoding options, arguments = getopt(sys.argv[1:], 'f:t:') for option, value in options: - if option == '-f': - from_charset = value - elif option == '-t': - to_charset = value + if option == '-f': + from_charset = value + elif option == '-t': + to_charset = value + +output = getattr(sys.stdout, 'buffer', sys.stdout) + if arguments: - for file in arguments: - infile = open(file) - try: - for line in infile: - sys.stdout.write(line.decode(from_charset, "replace").encode(to_charset, "replace")) - except: - infile.close() + for file in arguments: + with open(file, 'rb') as infile: + for line in infile: + output.write( + line.decode(from_charset, "replace"). + encode(to_charset, "replace")) else: - for line in sys.stdin: - sys.stdout.write(line.decode(from_charset, "replace").encode(to_charset, "replace")) + input = getattr(sys.stdin, 'buffer', sys.stdin) + for line in input: + output.write( + line.decode(from_charset, "replace").encode(to_charset, "replace")) diff --git a/bin/iconvx.py b/bin/iconvx.py index d3c20d1..b4c990e 100755 --- a/bin/iconvx.py +++ b/bin/iconvx.py @@ -1,37 +1,38 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 "iconv wrapper" -import sys from getopt import getopt +import os, shutil, sys, tempfile options, arguments = getopt(sys.argv[1:], 'f:t:') from_charset = to_charset = None for option, value in options: - if option == '-f': - from_charset = value - elif option == '-t': - to_charset = value + if option == '-f': + from_charset = value + elif option == '-t': + to_charset = value if from_charset is None: - raise ValueError("you must use -f param to name source charset") + raise ValueError("you must use -f param to name source charset") if to_charset is None: - raise ValueError("you must use -t param to name destination charset") + raise ValueError("you must use -t param to name destination charset") -import tempfile, os, shutil tempfname = "_iconvx" + tempfile.gettempprefix() + "tmp" if arguments: - try: - for file in arguments: - os.system("iconv.py -f '%s' -t '%s' '%s' > '%s'" % (from_charset, to_charset, file, tempfname)) + try: + for file in arguments: + os.system( + "iconv.py -f '%s' -t '%s' '%s' > '%s'" % ( + from_charset, to_charset, file, tempfname)) shutil.copy2(tempfname, file) - finally: - os.unlink(tempfname) + finally: + os.unlink(tempfname) -else: # filter stdin => stdout - os.system("iconv.py -f '%s' -t '%s'" % (from_charset, to_charset)) +else: # filter stdin => stdout + os.system("iconv.py -f '%s' -t '%s'" % (from_charset, to_charset)) diff --git a/bin/idna.py b/bin/idna.py index fd2c8e5..44843ac 100755 --- a/bin/idna.py +++ b/bin/idna.py @@ -1,6 +1,8 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys +from m_lib.defenc import default_encoding + l = len(sys.argv) if (l == 2) and (sys.argv[1] != '-r'): @@ -12,9 +14,11 @@ elif (l == 3) and (sys.argv[1] == '-r'): else: sys.exit('Usage: %s [-r] name.domain' % sys.argv[0]) -from m_lib.defenc import default_encoding - if reverse: - print(address.decode("idna").encode(default_encoding)) + if not isinstance(address, bytes): + address = address.encode('ascii') + print(address.decode("idna")) else: - print(address.decode(default_encoding).encode("idna")) + if isinstance(address, bytes): + address = address.decode(default_encoding) + print(address.encode("idna").decode('ascii')) diff --git a/bin/koi2lat b/bin/koi2lat index e5cd63b..4687100 100755 --- a/bin/koi2lat +++ b/bin/koi2lat @@ -1,10 +1,8 @@ -#! /usr/bin/env python - +#! /usr/bin/env python3 import sys from m_lib.rus import rus2lat - for line in sys.stdin: - if line[-1] == '\n': line = line[:-1] - print rus2lat.rus2lat(line) + if line[-1] == '\n': line = line[:-1] + print(rus2lat.rus2lat(line)) diff --git a/bin/lat2koi b/bin/lat2koi index c4ed131..9c43755 100755 --- a/bin/lat2koi +++ b/bin/lat2koi @@ -1,10 +1,8 @@ -#! /usr/bin/env python - +#! /usr/bin/env python3 import sys from m_lib.rus import lat2rus - for line in sys.stdin: - if line[-1] == '\n': line = line[:-1] - print lat2rus.lat2rus(line) + if line[-1] == '\n': line = line[:-1] + print(lat2rus.lat2rus(line)) diff --git a/bin/mc_type.py b/bin/mc_type.py index dbcf94d..d2e9884 100755 --- a/bin/mc_type.py +++ b/bin/mc_type.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys, subprocess @@ -13,6 +13,8 @@ stdout, stderr = mc.communicate() if mc.returncode or stderr: sys.exit('Error reading mc version: (%d) %s' % (mc.returncode, stderr)) +if not isinstance(stdout, type('')): + stdout = stdout.decode() mc_version = stdout.split('\n')[0] if mc_version.startswith('Midnight Commander'): mc_version = mc_version.split()[2] diff --git a/bin/recode-filenames-recursive.py b/bin/recode-filenames-recursive.py index 186d500..b7787e4 100755 --- a/bin/recode-filenames-recursive.py +++ b/bin/recode-filenames-recursive.py @@ -1,39 +1,37 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys, os +from recode_filenames import _recode if len(sys.argv) == 3: - start_dir = '.' + start_dir = '.' elif len(sys.argv) == 4: - start_dir = sys.argv[3] + start_dir = sys.argv[3] else: - sys.exit("Usage: %s src_enc dst_enc [start_dir]" % sys.argv[0]) - + sys.exit("Usage: %s src_enc dst_enc [start_dir]" % sys.argv[0]) -def _p(plist, dirname, names): - plist.append((dirname, names)) +def _onerror(exc): + raise exc -plist = [] -os.path.walk(start_dir, _p, plist) -plist.reverse() +plist = list(os.walk(start_dir, topdown=False, onerror=_onerror)) -from recode_filenames import _recode - save_dir = os.getcwd() -for dirname, names in plist: - os.chdir(dirname) - for filename in names: - # if not exists - it was renamed already - if os.path.exists(filename) and \ - os.path.isfile(filename): - newname = _recode(filename) - if newname != filename: - os.rename(filename, newname) - os.chdir('..') - dirname = os.path.basename(dirname) - newname = _recode(dirname) - if newname != dirname: - os.rename(dirname, newname) - os.chdir(save_dir) +for dirname, _subdirs, fnames in plist: + if dirname == '.': + continue + os.chdir(dirname) + for filename in fnames: + # if not exists - it was renamed already + if os.path.exists(filename) and \ + os.path.isfile(filename): + newname = _recode(filename) + if newname != filename: + os.rename(filename, newname) + os.chdir('..') + dirname = os.path.basename(dirname) + newname = _recode(dirname) + if newname != dirname: + os.rename(dirname, newname) + os.chdir(save_dir) diff --git a/bin/recode_filenames.py b/bin/recode_filenames.py index 7e25a16..ae2b50b 100755 --- a/bin/recode_filenames.py +++ b/bin/recode_filenames.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 # -*- coding: koi8-r -*- import sys @@ -7,61 +7,61 @@ src_encoding = sys.argv[1] dst_encoding = sys.argv[2] if src_encoding == "translit": - if dst_encoding == "koi8-r": - from m_lib.rus.lat2rus import lat2koi as _recode - elif dst_encoding == "cp1251": - from m_lib.rus.lat2rus import lat2win as _recode - else: - raise NotImplementedError("destination encoding must be koi8-r or cp1251, not `%s'" % dst_encoding) + if dst_encoding == "koi8-r": + from m_lib.rus.lat2rus import lat2koi as _recode + elif dst_encoding == "cp1251": + from m_lib.rus.lat2rus import lat2win as _recode + else: + raise NotImplementedError("destination encoding must be koi8-r or cp1251, not `%s'" % dst_encoding) elif dst_encoding == "translit": - if src_encoding == "koi8-r": - from m_lib.rus.rus2lat import koi2lat as _recode - elif src_encoding == "cp1251": - from m_lib.rus.rus2lat import win2lat as _recode - else: - raise NotImplementedError("source encoding must be koi8-r or cp1251, not `%s'" % src_encoding) + if src_encoding == "koi8-r": + from m_lib.rus.rus2lat import koi2lat as _recode + elif src_encoding == "cp1251": + from m_lib.rus.rus2lat import win2lat as _recode + else: + raise NotImplementedError("source encoding must be koi8-r or cp1251, not `%s'" % src_encoding) - from m_lib.rus.rus2lat import koi2lat_d - koi2lat_d["ÿ"] = '' # remove apostrophs - - koi2lat_d["ø"] = '' # they are not very good characters in filenames - koi2lat_d["ß"] = '' # especially on Windoze - koi2lat_d["Ø"] = '' # :-) + from m_lib.rus.rus2lat import koi2lat_d + koi2lat_d["ÿ"] = '' # remove apostrophs - + koi2lat_d["ø"] = '' # they are not very good characters in filenames + koi2lat_d["ß"] = '' # especially on Windoze + koi2lat_d["Ø"] = '' # :-) elif src_encoding == "url": - try: - src_encoding, dst_encoding = dst_encoding.split('/') - except ValueError: - src_encoding = dst_encoding - from m_lib.opstring import recode - import urllib - def _recode(s): - s = urllib.unquote(s) - if src_encoding != dst_encoding: - s = recode(s, src_encoding, dst_encoding, "replace") - return s + try: + src_encoding, dst_encoding = dst_encoding.split('/') + except ValueError: + src_encoding = dst_encoding + from m_lib.opstring import recode + import urllib + def _recode(s): + s = urllib.unquote(s) + if src_encoding != dst_encoding: + s = recode(s, src_encoding, dst_encoding, "replace") + return s elif dst_encoding == "url": - try: - src_encoding, dst_encoding = src_encoding.split('/') - except ValueError: - dst_encoding = src_encoding - from m_lib.opstring import recode - import urllib - def _recode(s): - if src_encoding != dst_encoding: - s = recode(s, src_encoding, dst_encoding, "replace") - return urllib.quote(s, safe=";/?:@&=+$,()'") # wget treats them as safe + try: + src_encoding, dst_encoding = src_encoding.split('/') + except ValueError: + dst_encoding = src_encoding + from m_lib.opstring import recode + import urllib + def _recode(s): + if src_encoding != dst_encoding: + s = recode(s, src_encoding, dst_encoding, "replace") + return urllib.quote(s, safe=";/?:@&=+$,()'") # wget treats them as safe else: - from m_lib.opstring import recode - def _recode(s): - return recode(s, src_encoding, dst_encoding, "replace") + from m_lib.opstring import recode + def _recode(s): + return recode(s, src_encoding, dst_encoding, "replace") if __name__ == "__main__": - import os - for filename in sys.argv[3:]: - new_name = _recode(filename) - if new_name != filename: - os.rename(filename, new_name) + import os + for filename in sys.argv[3:]: + new_name = _recode(filename) + if new_name != filename: + os.rename(filename, new_name) diff --git a/bin/rm-pyc b/bin/rm-pyc index 1f9d7ce..8f51b3c 100755 --- a/bin/rm-pyc +++ b/bin/rm-pyc @@ -1,2 +1,4 @@ #! /bin/sh -exec find . -name '*.py[co]' -delete + +find . -name '*.py[co]' -delete && +exec find . -name __pycache__ -type d -empty -delete diff --git a/bin/text-wrap.py b/bin/text-wrap.py index a8e4871..ecfafa8 100755 --- a/bin/text-wrap.py +++ b/bin/text-wrap.py @@ -1,71 +1,73 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 +from __future__ import print_function import sys def usage(code=0): - sys.stderr.write("Usage: %s [-0|--null] [-n|--no-newline] [-s|--space] [-w|--width] [width]\n" % sys.argv[0]) - sys.exit(code) + sys.stderr.write("Usage: %s [-0|--null] [-n|--no-newline] [-s|--space] [-w|--width] [width]\n" % sys.argv[0]) + sys.exit(code) def get_args(): - from getopt import getopt, GetoptError - - try: - options, arguments = getopt(sys.argv[1:], "0nsw:", - ["null", "no-newline", "space", "width="]) - except GetoptError: - usage(1) - - print0 = False - newline = True - space = '' - width = None - - for option, value in options: - if option in ("-h", "--help"): - usage() - elif option in ("-0", "--null"): - print0 = True - elif option in ("-n", "--no-newline"): - newline = False - elif option in ("-s", "--space"): - space = u' ' - elif option in ("-w", "--width"): - width = int(value) - else: - usage(2) - - if arguments: - if width is not None: - usage(3) - elif len(arguments) > 1: - usage(4) - else: - width = int(arguments[0]) - - return print0, newline, space, width + from getopt import getopt, GetoptError + + try: + options, arguments = getopt( + sys.argv[1:], "0nsw:", + ["null", "no-newline", "space", "width="]) + except GetoptError: + usage(1) + + print0 = False + newline = True + space = '' + width = None + + for option, value in options: + if option in ("-h", "--help"): + usage() + elif option in ("-0", "--null"): + print0 = True + elif option in ("-n", "--no-newline"): + newline = False + elif option in ("-s", "--space"): + space = u' ' + elif option in ("-w", "--width"): + width = int(value) + else: + usage(2) + + if arguments: + if width is not None: + usage(3) + elif len(arguments) > 1: + usage(4) + else: + width = int(arguments[0]) + + return print0, newline, space, width print0, newline, space, width = get_args() -from m_lib.defenc import default_encoding -text = sys.stdin.read().decode(default_encoding) +text = sys.stdin.read() if not newline: - text = text.rstrip() + text = text.rstrip() if width: - import textwrap - text = textwrap.fill(text, width - 2*len(space), - initial_indent=space, subsequent_indent=space) - if space: - text = u'\n'.join([line+space for line in text.split(u'\n')]) + import textwrap + text = textwrap.fill( + text, width - 2*len(space), + initial_indent=space, subsequent_indent=space) + if space: + text = u'\n'.join([line+space for line in text.split(u'\n')]) else: - text = u"%s%s%s" % (space, text, space) + text = u"%s%s%s" % (space, text, space) -sys.stdout.write(text.encode(default_encoding)) +sys.stdout.write(text) if print0: - sys.stdout.write('\0') + sys.stdout.write('\0') elif newline: - print + print() diff --git a/bin/unzip.py b/bin/unzip.py index 8fd7426..e88e526 100755 --- a/bin/unzip.py +++ b/bin/unzip.py @@ -1,7 +1,7 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 """Unzip with encoded filenames - Written by Oleg Broytman. Copyright (C) 2009-2016 PhiloSoft Design. + Written by Oleg Broytman. Copyright (C) 2009-2023 PhiloSoft Design. """ import sys, os, time @@ -28,7 +28,9 @@ for zinfo in zf.infolist(): path = zinfo.filename if isinstance(path, bytes): path = path.decode('cp866') - recoded_path = path.encode(default_encoding) + recoded_path = path.encode(default_encoding) + else: + recoded_path = path print(recoded_path) if path.startswith('./'): diff --git a/bin/webbrowser b/bin/webbrowser index 146da8c..a4c2024 100755 --- a/bin/webbrowser +++ b/bin/webbrowser @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys, os diff --git a/bin/webbrowser-encode-url b/bin/webbrowser-encode-url index e82c48c..8c88c9a 100755 --- a/bin/webbrowser-encode-url +++ b/bin/webbrowser-encode-url @@ -1,13 +1,13 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 try: from urllib.parse import parse_qsl, urlencode, \ - quote, unquote, unquote_plus, \ + quote, quote_plus, unquote, unquote_plus, \ splittype, splithost, splituser, splitpasswd, \ splitport, splittag, splitquery except ImportError: from cgi import parse_qsl - from urllib import urlencode, quote, unquote, unquote_plus, \ + from urllib import urlencode, quote, quote_plus, unquote, unquote_plus, \ splittype, splithost, splituser, splitpasswd, \ splitport, splittag, splitquery from getopt import getopt, GetoptError @@ -51,41 +51,54 @@ protocol, request = splittype(url) user, password, port = None, None, None host, path = splithost(request) if host: - user, host = splituser(host) - if user: - user, password = splitpasswd(user) - host, port = splitport(host) - if port: port = int(port) + user, host = splituser(host) + if user: + user, password = splitpasswd(user) + host, port = splitport(host) + if port: port = int(port) path, tag = splittag(path) path, query = splitquery(path) path = unquote(path) if tag: tag = unquote_plus(tag) if query: - qlist = [] - for name, value in parse_qsl(query): - name = unicode(name, default_encoding).encode(encoding) - value = unicode(value, default_encoding).encode(encoding) - qlist.append((name, value)) + qlist = [] + for name, value in parse_qsl(query): + if isinstance(name, bytes): + name = name.decode(default_encoding) + value = value.decode(default_encoding) + name = name.encode(encoding) + value = value.encode(encoding) + qlist.append((name, value)) url = protocol + "://" if user: - url += quote(unicode(user, default_encoding).encode(encoding)) - if password: - url += ':' + quote(unicode(password, default_encoding).encode(encoding)) - url += '@' + if isinstance(user, bytes): + user = user.decode(default_encoding) + url += quote(user.encode(encoding)) + if password: + if isinstance(password, bytes): + password = password.decode(default_encoding) + url += ':' + quote(password.encode(encoding)) + url += '@' if host: - url += host.decode(encoding).encode('idna') - if port: - url += ':%d' % port + if isinstance(host, bytes): + host = host.decode(encoding) + url += host.encode('idna').decode('ascii') + if port: + url += ':%d' % port if path: - if protocol == "file": - url += quote(path) - else: - url += quote(unicode(path, default_encoding).encode(encoding)) + if protocol == "file": + url += quote(path) + else: + if isinstance(path, bytes): + path = path.decode(default_encoding) + url += quote(path.encode(encoding)) if query: - url += '?' + urlencode(qlist) + url += '?' + urlencode(qlist) if tag: - url += '#' + quote_plus(unicode(tag, default_encoding).encode(encoding)) + if isinstance(tag, bytes): + tag = tag.decode(default_encoding) + url += '#' + quote_plus(tag.encode(encoding)) webbrowser.open(url, new) diff --git a/bin/wget-download b/bin/wget-download index da7ea39..dbd6ef5 100755 --- a/bin/wget-download +++ b/bin/wget-download @@ -1,9 +1,18 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 -from cgi import parse_qsl +try: + from urllib.parse import parse_qsl, urlencode, \ + quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery +except ImportError: + from cgi import parse_qsl + from urllib import urlencode, quote, quote_plus, unquote, unquote_plus, \ + splittype, splithost, splituser, splitpasswd, \ + splitport, splittag, splitquery from getopt import getopt, GetoptError import os, posixpath -import sys, urllib +import sys from m_lib.defenc import default_encoding def usage(): @@ -27,43 +36,59 @@ if not encoding: encoding = default_encoding url = arguments[0] -protocol, request = urllib.splittype(url) +protocol, request = splittype(url) user, password, port = None, None, None -host, path = urllib.splithost(request) +host, path = splithost(request) if host: - user, host = urllib.splituser(host) - if user: - user, password = urllib.splitpasswd(user) - host, port = urllib.splitport(host) - if port: port = int(port) -path, tag = urllib.splittag(path) -path, query = urllib.splitquery(path) -path = urllib.unquote(path) + user, host = splituser(host) + if user: + user, password = splitpasswd(user) + host, port = splitport(host) + if port: port = int(port) +path, tag = splittag(path) +path, query = splitquery(path) +path = unquote(path) +if tag: tag = unquote_plus(tag) if query: - qlist = [] - for name, value in parse_qsl(query): - name = unicode(name, default_encoding).encode(encoding) - value = unicode(value, default_encoding).encode(encoding) - qlist.append((name, value)) + qlist = [] + for name, value in parse_qsl(query): + if isinstance(name, bytes): + name = name.decode(default_encoding) + value = value.decode(default_encoding) + name = name.encode(encoding) + value = value.encode(encoding) + qlist.append((name, value)) url = protocol + "://" if user: - url += urllib.quote(unicode(user, default_encoding).encode(encoding)) - if password: - url += ':' + urllib.quote(unicode(password, default_encoding).encode(encoding)) - url += '@' + if isinstance(user, bytes): + user = user.decode(default_encoding) + url += quote(user.encode(encoding)) + if password: + if isinstance(password, bytes): + password = password.decode(default_encoding) + url += ':' + quote(password.encode(encoding)) + url += '@' if host: - url += host.decode(encoding).encode('idna') - if port: - url += ':%d' % port + if isinstance(host, bytes): + host = host.decode(encoding) + url += host.encode('idna').decode('ascii') + if port: + url += ':%d' % port if path: - if protocol == "file": - url += urllib.quote(path) - else: - url += urllib.quote(unicode(path, default_encoding).encode(encoding)) -#if query: -# url += '?' + urllib.urlencode(qlist) + if protocol == "file": + url += quote(path) + else: + if isinstance(path, bytes): + path = path.decode(default_encoding) + url += quote(path.encode(encoding)) +if query: + url += '?' + urlencode(qlist) +if tag: + if isinstance(tag, bytes): + tag = tag.decode(default_encoding) + url += '#' + quote_plus(tag.encode(encoding)) name = posixpath.basename(path) os.system('exec wget-wrapper -O "%s" "%s"' % (name, url)) diff --git a/bin/zip.py b/bin/zip.py index e99c9a8..35bf0e6 100755 --- a/bin/zip.py +++ b/bin/zip.py @@ -1,7 +1,7 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 """Zip (zip -r9) with encoded filenames - Written by Oleg Broytman. Copyright (C) 2009, 2010 PhiloSoft Design. + Written by Oleg Broytman. Copyright (C) 2009-2023 PhiloSoft Design. """ import sys, os @@ -23,7 +23,10 @@ if len(arguments) < 2: def addToZip(zf, path): if os.path.isfile(path): print(path) - recoded_path = path.decode(default_encoding).encode('cp866') + if isinstance(path, bytes): + recoded_path = path.decode(default_encoding).encode('cp866') + else: + recoded_path = path zf.write(path, recoded_path, ZIP_DEFLATED) elif os.path.isdir(path): for nm in os.listdir(path): -- 2.39.2