Skip to content

Commit

Permalink
Drop CGI support on Python 3.13+
Browse files Browse the repository at this point in the history
  • Loading branch information
mgedmin committed Oct 16, 2024
1 parent d17141c commit d944874
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 21 deletions.
7 changes: 5 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Changelog
=========

3.0.1 (unreleased)
4.0.0 (unreleased)
------------------

- Add support for Python 3.12.
- Remove CGI support if you're using Python 3.13 or newer. You'll have to
use the WSGI support instead.

- Add support for Python 3.12 and 3.13.


3.0.0 (2023-08-28)
Expand Down
23 changes: 16 additions & 7 deletions src/irclog2html/irclogsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
# Released under the terms of the GNU GPL v2 or v3
# https://www.gnu.org/copyleft/gpl.html

import cgi
import cgitb
import io
import os
import re
Expand All @@ -31,6 +29,13 @@
from contextlib import closing
from urllib.parse import quote

try:
import cgi
import cgitb
except ImportError:
# Python 3.13 removed all CGI support
cgi = None

from .irclog2html import (
HOMEPAGE,
RELEASE,
Expand Down Expand Up @@ -240,24 +245,28 @@ def unicode_stdout():
line_buffering=True)


def search_page(stream, form, where, logfile_pattern):
if "q" not in form:
def search_page(stream, query, where, logfile_pattern):
if query is None:
print_search_form(stream)
else:
search_text = form["q"].value
search_text = query
print_search_results(search_text, stream=stream, where=where,
logfile_pattern=logfile_pattern)


def main():
def main(): # pragma: nocover
"""CGI script"""
if cgi is None:
print_cgi_headers(unicode_stdout())
sys.exit('CGI support not available with Python 3.13 or newer')
cgitb.enable()
logfile_path = os.getenv('IRCLOG_LOCATION') or DEFAULT_LOGFILE_PATH
logfile_pattern = os.getenv('IRCLOG_GLOB') or DEFAULT_LOGFILE_PATTERN
form = cgi.FieldStorage()
stream = unicode_stdout()
print_cgi_headers(stream)
search_page(stream, form, logfile_path, logfile_pattern)
query = form["q"].value if "q" in form else None
search_page(stream, query, logfile_path, logfile_pattern)


if __name__ == '__main__':
Expand Down
7 changes: 3 additions & 4 deletions src/irclog2html/irclogserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@
# https://www.gnu.org/copyleft/gpl.html

import argparse
import cgi
import datetime
import io
import os
import time
from operator import attrgetter
from urllib.parse import quote_plus
from urllib.parse import quote_plus, parse_qsl
from wsgiref.simple_server import make_server

from ._version import __date__, __version__
Expand Down Expand Up @@ -192,7 +191,7 @@ def getenv(name, default=None):
chan_path = getenv('IRCLOG_CHAN_DIR')
logfile_path = getenv('IRCLOG_LOCATION') or DEFAULT_LOGFILE_PATH
logfile_pattern = getenv('IRCLOG_GLOB') or DEFAULT_LOGFILE_PATTERN
form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
form = dict(parse_qsl(environ['QUERY_STRING']))
stream = io.TextIOWrapper(io.BytesIO(), 'ascii',
errors='xmlcharrefreplace',
line_buffering=True)
Expand All @@ -213,7 +212,7 @@ def getenv(name, default=None):
dir_listing(stream, chan_path)
result = [stream.buffer.getvalue()]
elif path == 'search':
search_page(stream, form, logfile_path, logfile_pattern)
search_page(stream, form.get('q'), logfile_path, logfile_pattern)
result = [stream.buffer.getvalue()]
elif path == 'irclog.css':
content_type = "text/css"
Expand Down
25 changes: 18 additions & 7 deletions src/irclog2html/tests/test_irclogsearch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import cgi
import datetime
import doctest
import gzip
Expand All @@ -24,6 +23,11 @@
search_page,
)

try:
import cgi
except ImportError:
cgi = None


here = os.path.dirname(__file__)

Expand Down Expand Up @@ -71,6 +75,15 @@ def myrepr(o):
return repr(o)


def skipIf(condition: bool):
"""Skip a doctest if condition is false."""
def wrapper(fn):
if condition:
return None
return fn
return wrapper


def doctest_SearchResultFormatter():
"""Test for SearchResultFormatter
Expand Down Expand Up @@ -253,18 +266,14 @@ def doctest_search_page():
When there is a 'q' param in the GET query, the logs are searched:
>>> form = cgi.FieldStorage(
... environ={'QUERY_STRING': 'q=123', 'HTTP_METHOD': 'GET'})
>>> search_page("The stream", form, "/logs", "#dev*.logs")
>>> search_page("The stream", '123', "/logs", "#dev*.logs")
>>> values['print_search_results'].assert_called_once_with(
... '123', logfile_pattern='#dev*.logs',
... stream='The stream', where='/logs')
When there is no query, the search form is displayed:
>>> form = cgi.FieldStorage(environ={
... 'HTTP_METHOD': 'GET', 'QUERY_STRING': ''})
>>> search_page("The stream", form, "/logs", "#dev*.logs")
>>> search_page("The stream", None, "/logs", "#dev*.logs")
>>> values['print_search_form'].assert_called_once_with('The stream')
Clean up:
Expand All @@ -274,6 +283,7 @@ def doctest_search_page():
"""


@skipIf(cgi is None)
def doctest_main_prints_form():
"""Test for main
Expand Down Expand Up @@ -310,6 +320,7 @@ def doctest_main_prints_form():
"""


@skipIf(cgi is None)
def doctest_main_searches():
r"""Test for main
Expand Down
2 changes: 1 addition & 1 deletion src/irclog2html/tests/test_logs2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,5 +350,5 @@ def doctest_main_extra_args():
def test_suite():
return unittest.TestSuite([
doctest.DocTestSuite(optionflags=doctest.ELLIPSIS | doctest.REPORT_NDIFF),
unittest.makeSuite(TestLogFile),
unittest.defaultTestLoader.loadTestsFromName(__name__),
])

0 comments on commit d944874

Please sign in to comment.