From c344f205e8ac2ddf41c0d9c0f4e438a3a046e82e Mon Sep 17 00:00:00 2001 From: Andrew Ferrier <andrewferrier@example.com> Date: Mon, 22 Jun 2015 19:19:01 +0100 Subject: [PATCH] Fix some more pylint issues. --- Makefile | 2 +- email2pdf | 66 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 0b27e55..f3e8f3e 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ unittest_verbose: analysis: # Debian version is badly packaged, make sure we are using Python 3. /usr/bin/env python3 $(FLAKE8) --max-line-length=132 --max-complexity 10 . - pylint --report=n --disable=line-too-long --disable=missing-docstring email2pdf + pylint --report=n --disable=line-too-long --disable=missing-docstring --disable=locally-disabled email2pdf coverage: rm -rf cover/ diff --git a/email2pdf b/email2pdf index b9de8cd..fd9a3a4 100755 --- a/email2pdf +++ b/email2pdf @@ -1,11 +1,12 @@ #!/usr/bin/env python3 +from PyPDF2 import PdfFileReader, PdfFileWriter +from PyPDF2.generic import NameObject, createStringObject from bs4 import BeautifulSoup from datetime import datetime from email.header import decode_header from itertools import chain -from PyPDF2.generic import NameObject, createStringObject -from PyPDF2 import PdfFileReader, PdfFileWriter +from requests.exceptions import RequestException from subprocess import Popen, PIPE from sys import platform as _platform import argparse @@ -29,6 +30,8 @@ HEADER_MAPPING = {'Author': 'From', 'Title': 'Subject', 'X-email2pdf-To': 'To'} +FORMATTED_HEADERS_TO_INCLUDE = frozenset(['Subject', 'From', 'To', 'Date']) + MIME_TYPES_BLACKLIST = frozenset(['text/html', 'text/plain']) AUTOCALCULATED_FILENAME_EXTENSION_BLACKLIST = frozenset(['.jpe', '.jpeg']) @@ -231,7 +234,7 @@ def handle_message_body(input_email, header_info): warning("Could not find image cid " + matchobj.group(1) + " in email content.") return "broken" - payload = re.sub('cid:([\w_@.-]+)', functools.partial(cid_replace, cid_parts_used), + payload = re.sub(r'cid:([\w_@.-]+)', functools.partial(cid_replace, cid_parts_used), str(payload, charset)) return (header_info + payload, cid_parts_used) @@ -299,7 +302,7 @@ def remove_invalid_urls(payload): # See https://github.com/kennethreitz/requests/issues/1882#issuecomment-44596534 request.connection.close() request.raise_for_status() - except: + except RequestException: logger.warning("Could not retrieve img URL " + src + ", replacing with blank.") del img['src'] else: @@ -333,7 +336,7 @@ def handle_attachments(input_email, output_directory, add_prefix_date, ignore_fl assert filename is not None if add_prefix_date: - if not re.search("\d\d\d\d[-_]\d\d[-_]\d\d", filename): + if not re.search(r"\d\d\d\d[-_]\d\d[-_]\d\d", filename): filename = datetime.now().strftime("%Y-%m-%d-") + filename logger.info("Extracting attachment " + filename) @@ -349,6 +352,10 @@ def handle_attachments(input_email, output_directory, add_prefix_date, ignore_fl def add_update_pdf_metadata(filename, update_dictionary): + # This seems to be the only way to modify the existing PDF metadata. + # + # pylint: disable=protected-access, no-member + def add_prefix(value): return '/' + value @@ -371,7 +378,7 @@ def add_update_pdf_metadata(filename, update_dictionary): assert full_update_dictionary[key] is not None info_dict.update({NameObject(key): createStringObject(full_update_dictionary[key])}) - unused_f_handle, temp_file_name = tempfile.mkstemp(prefix="email2pdf_add_update_pdf_metadata", suffix=".pdf") + _, temp_file_name = tempfile.mkstemp(prefix="email2pdf_add_update_pdf_metadata", suffix=".pdf") with open(temp_file_name, 'wb') as file_out: pdf_output.write(file_out) @@ -441,14 +448,12 @@ def find_all_attachments(message, parts_to_ignore): return parts -def get_formatted_header_info(email): - HEADERS = frozenset(['Subject', 'From', 'To', 'Date']) - +def get_formatted_header_info(input_email): header_info = "" - for header in HEADERS: - if email[header]: - header_info = header_info + '<b>' + header + '</b>: ' + email[header] + '<br/>' + for header in FORMATTED_HEADERS_TO_INCLUDE: + if input_email[header]: + header_info = header_info + '<b>' + header + '</b>: ' + input_email[header] + '<br/>' return header_info + '<br/>' @@ -458,6 +463,7 @@ def get_formatted_header_info(email): def get_mime_type(buffer_data): + # pylint: disable=no-member if 'from_buffer' in dir(magic): mime_type = str(magic.from_buffer(buffer_data, mime=True), 'utf-8') else: @@ -479,28 +485,43 @@ def warning(message): class FatalException(Exception): def __init__(self, value): + Exception.__init__(self, value) self.value = value def __str__(self): return repr(self.value) + +def call_main(): + # pylint: disable=bare-except + + try: + main(sys.argv, syslog_handler, syserr_handler) + except FatalException as exception: + logger_setup.error(exception.value) + sys.exit(2) + except: + traceback.print_exc() + sys.exit(3) + + if __name__ == "__main__": - logger = logging.getLogger("email2pdf") - logger.propagate = False - logger.setLevel(logging.DEBUG) + logger_setup = logging.getLogger("email2pdf") + logger_setup.propagate = False + logger_setup.setLevel(logging.DEBUG) syserr_handler = logging.StreamHandler(stream=sys.stderr) syserr_handler.setLevel(logging.WARNING) syserr_formatter = logging.Formatter('%(levelname)s: %(message)s') syserr_handler.setFormatter(syserr_formatter) - logger.addHandler(syserr_handler) + logger_setup.addHandler(syserr_handler) if _platform == "linux" or _platform == "linux2": SYSLOG_ADDRESS = '/dev/log' elif _platform == "darwin": SYSLOG_ADDRESS = '/var/run/syslog' else: - logger.warning("I don't know this platform (" + _platform + "); cannot log to syslog.") + logger_setup.warning("I don't know this platform (" + _platform + "); cannot log to syslog.") SYSLOG_ADDRESS = None if SYSLOG_ADDRESS and os.path.exists(SYSLOG_ADDRESS): @@ -508,18 +529,11 @@ if __name__ == "__main__": syslog_handler.setLevel(logging.INFO) SYSLOG_FORMATTER = logging.Formatter('%(pathname)s[%(process)d] %(levelname)s %(lineno)d %(message)s') syslog_handler.setFormatter(SYSLOG_FORMATTER) - logger.addHandler(syslog_handler) + logger_setup.addHandler(syslog_handler) else: syslog_handler = None - try: - main(sys.argv, syslog_handler, syserr_handler) - except FatalException as exception: - logger.error(exception.value) - sys.exit(2) - except: - traceback.print_exc() - sys.exit(3) + call_main() if warning_pending: sys.exit(1)