diff -Nru librecaptcha-0.3.3/debian/changelog librecaptcha-0.4.0/debian/changelog --- librecaptcha-0.3.3/debian/changelog 2018-02-19 03:42:53.000000000 +0000 +++ librecaptcha-0.4.0/debian/changelog 2018-02-28 00:59:50.000000000 +0000 @@ -1,3 +1,11 @@ +librecaptcha (0.4.0-1) unstable; urgency=medium + + * New upstream release + - Drop UTF-8 patch included upstream + - Now uses display from imagemagick, add dep + + -- Paul Wise Wed, 28 Feb 2018 08:59:50 +0800 + librecaptcha (0.3.3-1) unstable; urgency=medium * New upstream release diff -Nru librecaptcha-0.3.3/debian/control librecaptcha-0.4.0/debian/control --- librecaptcha-0.3.3/debian/control 2018-02-19 03:00:56.000000000 +0000 +++ librecaptcha-0.4.0/debian/control 2018-02-28 00:59:50.000000000 +0000 @@ -18,6 +18,7 @@ Package: python3-librecaptcha Architecture: all Depends: + imagemagick, ${misc:Depends}, ${python3:Depends}, Recommends: diff -Nru librecaptcha-0.3.3/debian/patches/0001-Open-README.rst-using-the-UTF-8-encoding.patch librecaptcha-0.4.0/debian/patches/0001-Open-README.rst-using-the-UTF-8-encoding.patch --- librecaptcha-0.3.3/debian/patches/0001-Open-README.rst-using-the-UTF-8-encoding.patch 2018-02-19 03:39:53.000000000 +0000 +++ librecaptcha-0.4.0/debian/patches/0001-Open-README.rst-using-the-UTF-8-encoding.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -From 8377b6157a6f717c9dd32d3a5899ad6a06fedd37 Mon Sep 17 00:00:00 2001 -Forwarded: https://github.com/nickolas360/librecaptcha/pull/2 -From: Paul Wise -Date: Mon, 19 Feb 2018 11:21:40 +0800 -Subject: [PATCH] Open README.rst using the UTF-8 encoding - -Traceback (most recent call last): - File "setup.py", line 43, in - long_description=long_description(), - File "setup.py", line 32, in long_description - lines = f.read().splitlines() - File "/usr/lib/python3.6/encodings/ascii.py", line 26, in decode - return codecs.ascii_decode(input, self.errors)[0] -UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 594: ordinal not in range(128) ---- - setup.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/setup.py b/setup.py -index c3247ec..8fc50e3 100755 ---- a/setup.py -+++ b/setup.py -@@ -28,7 +28,7 @@ DESC_REPLACEMENTS = { - - - def long_description(): -- with open(os.path.join(SCRIPT_DIR, "README.rst")) as f: -+ with open(os.path.join(SCRIPT_DIR, "README.rst"), encoding='utf-8') as f: - lines = f.read().splitlines() - result = [] - for line in lines: --- -2.16.1 - diff -Nru librecaptcha-0.3.3/debian/patches/series librecaptcha-0.4.0/debian/patches/series --- librecaptcha-0.3.3/debian/patches/series 2018-02-19 03:40:08.000000000 +0000 +++ librecaptcha-0.4.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -0001-Open-README.rst-using-the-UTF-8-encoding.patch diff -Nru librecaptcha-0.3.3/librecaptcha/librecaptcha.py librecaptcha-0.4.0/librecaptcha/librecaptcha.py --- librecaptcha-0.3.3/librecaptcha/librecaptcha.py 2018-02-18 10:38:33.000000000 +0000 +++ librecaptcha-0.4.0/librecaptcha/librecaptcha.py 2018-02-28 00:38:09.000000000 +0000 @@ -29,10 +29,11 @@ import os import os.path import re +import subprocess import sys import time -__version__ = "0.3.3" +__version__ = "0.4.0" BASE_URL = "https://www.google.com/recaptcha/api2/" API_JS_URL = "https://www.google.com/recaptcha/api.js" @@ -211,9 +212,36 @@ draw.text(text_loc, str(i + 1), fill=(255, 255, 255), font=FONT) -class DynamicSolver: - def __init__(self, recaptcha, pmeta): +class Solver: + def __init__(self, recaptcha): self.rc = recaptcha + self._image_procs = [] + + def show_image(self, image): + if not os.path.isfile("/usr/bin/env"): + image.show() + return + + img_buffer = io.BytesIO() + image.save(img_buffer, "png") + img_bytes = img_buffer.getvalue() + + proc = subprocess.Popen( + ["/usr/bin/env", "display", "-"], stdin=subprocess.PIPE, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + proc.stdin.write(img_bytes) + proc.stdin.close() + self._image_procs.append(proc) + + def hide_images(self): + for proc in self._image_procs: + proc.terminate() + self._image_procs.clear() + + +class DynamicSolver(Solver): + def __init__(self, recaptcha, pmeta): + super().__init__(recaptcha) self.original_selections = [] self.selections = [] @@ -236,7 +264,7 @@ "k": self.rc.api_key, }).content) draw_indices(image, self.num_rows, self.num_columns) - image.show() + self.show_image(image) print("Take a look at the grid of tiles that just appeared. ", end="") print("({} rows, {} columns)".format(self.num_rows, self.num_columns)) @@ -248,58 +276,56 @@ indices = read_indices( "Enter numbers separated by spaces: ", self.num_tiles, ) + self.hide_images() self.original_selections += indices print() def select_tile(self, index): + selected = True + current_index = index + while selected: + last_request_time = time.monotonic() + selected = self.tile_iteration(current_index) + time_elapsed = time.monotonic() - last_request_time + sleep_duration = max(DYNAMIC_SELECT_DELAY - time_elapsed, 0) + + if sleep_duration >= 0.25: + print("Waiting (to avoid sending requests too quickly)...") + print() + time.sleep(sleep_duration) + current_index = self.current_index + + def tile_iteration(self, index): self.selections.append(index) r = self.rc.post("replaceimage", data={ "c": self.rc.current_token, "ds": "[{}]".format(index), }) - last_request_time = time.monotonic() - while True: - data = load_rc_json(r.text) - self.current_index += 1 - - self.rc.current_token = data[1] - replacement_id = data[2][0] - - image = get_image(self.rc.get("payload", api=False, params={ - "c": self.rc.current_token, - "k": self.rc.api_key, - "id": replacement_id, - }).content) - image.show() - - print("Take a look at the image that just appeared.") - select = input( - "Should this image be selected? [y/N] ", - ).lower().startswith("y") - - time_elapsed = time.monotonic() - last_request_time - sleep_duration = max(DYNAMIC_SELECT_DELAY - time_elapsed, 0) + data = load_rc_json(r.text) + self.current_index += 1 - if sleep_duration >= 0.25: - print("Waiting (to avoid sending requests too quickly)...") - print() + self.rc.current_token = data[1] + replacement_id = data[2][0] - time.sleep(sleep_duration) - if not select: - return + image = get_image(self.rc.get("payload", api=False, params={ + "c": self.rc.current_token, + "k": self.rc.api_key, + "id": replacement_id, + }).content) + self.show_image(image) - self.selections.append(self.current_index) - r = self.rc.post("replaceimage", data={ - "c": self.rc.current_token, - "ds": "[{}]".format(self.current_index), - }) - last_request_time = time.monotonic() + print("Take a look at the image that just appeared.") + selected = input( + "Should this image be selected? [y/N] ", + )[:1].lower() == "y" + self.hide_images() + return selected -class MultiCaptchaSolver: +class MultiCaptchaSolver(Solver): def __init__(self, recaptcha, pmeta): - self.rc = recaptcha + super().__init__(recaptcha) self.selection_groups = [] self.num_rows = None @@ -331,20 +357,21 @@ print("Take a look at the grid of tiles that just appeared. ", end="") print("({} rows, {} columns)".format(self.num_rows, self.num_columns)) print("Which tiles should be selected?") - print("(Top-left tile is 1, bottom-right tile is {})".format( + print("(Top-left tile is 1; bottom-right tile is {}.)".format( self.num_tiles, )) indices = read_indices( "Enter numbers separated by spaces: ", self.num_tiles, ) + self.hide_images() self.selection_groups.append(list(sorted(indices))) print() def show_image(self, image): draw_lines(image, self.num_rows, self.num_columns) draw_indices(image, self.num_rows, self.num_columns) - image.show() + super().show_image(image) def first_payload(self): image = get_image(self.rc.get("payload", api=False, params={ diff -Nru librecaptcha-0.3.3/README.rst librecaptcha-0.4.0/README.rst --- librecaptcha-0.3.3/README.rst 2018-02-18 10:38:33.000000000 +0000 +++ librecaptcha-0.4.0/README.rst 2018-02-28 00:38:09.000000000 +0000 @@ -1,7 +1,7 @@ librecaptcha ============ -Version 0.3.3 +Version 0.4.0 librecaptcha is a free/libre program and library that allows you to solve `reCAPTCHA`_ challenges. @@ -92,8 +92,13 @@ What’s new ---------- -Version 0.3.3: +Version 0.4.0: +* Image windows are now automatically closed when questions are answered. + +Version 0.3.x: + +* Fixed possible encoding issue in ``setup.py``. * librecaptcha can now be installed from PyPI, or from the Git repository with pip or ``setup.py``. diff -Nru librecaptcha-0.3.3/setup.py librecaptcha-0.4.0/setup.py --- librecaptcha-0.3.3/setup.py 2018-02-18 10:38:33.000000000 +0000 +++ librecaptcha-0.4.0/setup.py 2018-02-28 00:38:09.000000000 +0000 @@ -28,7 +28,7 @@ def long_description(): - with open(os.path.join(SCRIPT_DIR, "README.rst")) as f: + with open(os.path.join(SCRIPT_DIR, "README.rst"), encoding='utf-8') as f: lines = f.read().splitlines() result = [] for line in lines: @@ -38,7 +38,7 @@ setup( name="librecaptcha", - version="0.3.3", + version="0.4.0", description="A free/libre interface for solving reCAPTCHA challenges.", long_description=long_description(), url="https://github.com/nickolas360/librecaptcha",