python 2.7 compatibility changes
parent
08af800b52
commit
5aae20523c
|
@ -1,17 +1,42 @@
|
|||
default:
|
||||
image: python:3.8-alpine
|
||||
before_script:
|
||||
- pip3 install -r librefi/requirements.txt
|
||||
- pip3 install -r librefi/dev_requirements.txt
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements_dev.txt
|
||||
|
||||
unit_tests:
|
||||
py2.7-unit_tests:
|
||||
image: python:2.7-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
integration_test:
|
||||
py3.8-unit_tests:
|
||||
image: python:3.8-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py2.7-integration_test:
|
||||
image: python:2.7-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python -m librefi
|
||||
|
||||
py3.8-integration_test:
|
||||
image: python:3.8-buster
|
||||
before_script:
|
||||
- pip3 install -r librefi/requirements.txt
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.9-integration_test:
|
||||
image: python:3.9-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include README.md LICENSE
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .librefi import LibreFi
|
||||
|
||||
__all__ = ['LibreFi']
|
|
@ -1,5 +1,18 @@
|
|||
from .librefi import LibreFi
|
||||
from .logger import LOG_LEVELS
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
librefi = LibreFi(log_level=LOG_LEVELS.DEBUG)
|
||||
librefi._periodical_check()
|
||||
import sys
|
||||
|
||||
if __package__ is None and not hasattr(sys, 'frozen'):
|
||||
# direct call of __main__.py
|
||||
import os.path
|
||||
path = os.path.realpath(os.path.abspath(__file__))
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(path)))
|
||||
|
||||
from librefi import LibreFi
|
||||
from .logger import _Logger, LOG_LEVELS
|
||||
|
||||
librefi = LibreFi(logger=_Logger, log_level=LOG_LEVELS.DEBUG)
|
||||
|
||||
if __name__ == '__main__':
|
||||
librefi._periodical_check()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,12 @@
|
|||
import sys
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ..compat import compat_sys_platform
|
||||
from ..utils import LFiError
|
||||
|
||||
|
||||
def get_connector():
|
||||
if sys.platform == "linux":
|
||||
if compat_sys_platform == "linux":
|
||||
from .networkmanager import NetworkManagerConnector
|
||||
return NetworkManagerConnector
|
||||
raise LFiError('Could not find a connector')
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import subprocess
|
||||
import pipes
|
||||
import re
|
||||
|
@ -7,20 +10,22 @@ class NetworkManagerConnector:
|
|||
NMCLI_BASE = ["nmcli", "--mode", "tabular", "--terse", "--colors", "no"]
|
||||
|
||||
def _call_nmcli(self, args, parse=True):
|
||||
subp = subprocess.run(self.NMCLI_BASE + args,
|
||||
capture_output=True, text=True)
|
||||
try:
|
||||
subp = subprocess.check_output(self.NMCLI_BASE + args).decode("utf-8")
|
||||
except subprocess.CalledProcessError as err:
|
||||
subp = err.output.decode("utf-8")
|
||||
|
||||
if parse:
|
||||
# if no output
|
||||
if subp.stdout.strip() == "":
|
||||
if subp.strip() == "":
|
||||
return []
|
||||
|
||||
return [
|
||||
[field.replace("\\:", ":")
|
||||
for field in re.split(r"(?<!\\):", line)]
|
||||
for line in subp.stdout.strip().split("\n")]
|
||||
for line in subp.strip().split("\n")]
|
||||
|
||||
return subp.stdout
|
||||
return subp
|
||||
|
||||
def status(self):
|
||||
infs = self._call_nmcli(["--fields", "TYPE,NAME",
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._map import fxckers_map
|
||||
|
||||
__all__ = ['fxckers_map']
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import requests
|
||||
|
||||
from ..utils import get_user_agent, absolute_url
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._dummy import DummyFxcker
|
||||
from .umwarszawa import UMWarszawaFxcker
|
||||
from .ledatel import LedatelFxcker
|
||||
|
@ -16,3 +19,5 @@ fxckers_map = [
|
|||
"_PKP_WIFI",
|
||||
], JustWifiFxcker),
|
||||
]
|
||||
|
||||
__all__ = ['fxckers_map']
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, dump_qs
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, absolute_url, dump_qs
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, dump_qs
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
||||
from .connectors import get_connector
|
||||
from .fxckers._map import fxckers_map
|
||||
from .logger import _Logger, LOG_LEVELS
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
||||
|
||||
class LibreFi:
|
||||
def __init__(self, log_level=LOG_LEVELS.INFO, logger=_Logger):
|
||||
|
@ -47,6 +49,7 @@ class LibreFi:
|
|||
self._assign_fxcker_to_network(
|
||||
{"ssid": status["connection_name"]})
|
||||
if self.current_fxcker:
|
||||
self.log.debug("Checking internet access")
|
||||
check_req = requests.get(
|
||||
"http://detectportal.firefox.com/success.txt",
|
||||
allow_redirects=False)
|
||||
|
@ -63,9 +66,9 @@ class LibreFi:
|
|||
fxcker = None
|
||||
for fxck_element in fxckers_map:
|
||||
for fxck_net_name in fxck_element[0]:
|
||||
if fxck_net_name[:3] == "re:":
|
||||
if re.fullmatch(fxck_net_name,
|
||||
"re:" + network["ssid"]):
|
||||
if fxck_net_name[:len("re:")] == "re:":
|
||||
if re.match(fxck_net_name,
|
||||
network["ssid"][len("re:"):]):
|
||||
fxcker = fxck_element[1]
|
||||
break
|
||||
elif fxck_net_name == network["ssid"]:
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class LOG_LEVELS:
|
||||
DEBUG = -10
|
||||
INFO = 0
|
||||
|
@ -6,7 +10,8 @@ class LOG_LEVELS:
|
|||
|
||||
|
||||
class _Logger:
|
||||
printer = print
|
||||
def printer(self, x):
|
||||
print(x)
|
||||
|
||||
def __init__(self, key="--no-key--", log_level=LOG_LEVELS.INFO):
|
||||
self.KEY = key
|
||||
|
|
|
@ -1,10 +1,27 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# flake8: noqa: E501
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
from urllib.parse import parse_qs, quote as qs_quote, urlparse
|
||||
from datetime import datetime
|
||||
import random
|
||||
|
||||
from .compat import (
|
||||
compat_parse_qs as parse_qs,
|
||||
compat_urllib_parse_quote as qs_quote,
|
||||
compat_urllib_parse_urlparse as urlparse,
|
||||
compat_str,
|
||||
py_major_ver,
|
||||
)
|
||||
|
||||
|
||||
class LFiError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FxckerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_user_agent():
|
||||
if bool(random.getrandbits(1)):
|
||||
|
@ -112,15 +129,19 @@ def regex_search_string(regexes, string, default=None, multiple=False, whole_mat
|
|||
|
||||
|
||||
def dump_qs(obj):
|
||||
old_qs = []
|
||||
if py_major_ver == 2:
|
||||
old_qs = obj.iteritems()
|
||||
else:
|
||||
old_qs = list(obj.items())
|
||||
# sorting by key to unify the result string between python versions
|
||||
# https://stackoverflow.com/a/3295662/8222484
|
||||
old_qs.sort()
|
||||
qs = []
|
||||
for key in obj:
|
||||
old_qs.append((key, obj[key]))
|
||||
not_flat = True
|
||||
while not_flat:
|
||||
not_flat = False
|
||||
for old_qs_element in old_qs:
|
||||
if isinstance(old_qs_element[1], (str, int, float)):
|
||||
if isinstance(old_qs_element[1], (compat_str, int, float)):
|
||||
qs.append((old_qs_element[0], old_qs_element[1]))
|
||||
elif isinstance(old_qs_element[1], (dict)):
|
||||
for subkey in old_qs_element[1]:
|
||||
|
@ -134,7 +155,7 @@ def dump_qs(obj):
|
|||
element = old_qs_element[1][index]
|
||||
if element is not None:
|
||||
qs.append(
|
||||
(old_qs_element[0] + "[" + str(index) + "]", element))
|
||||
(old_qs_element[0] + "[" + compat_str(index) + "]", element))
|
||||
if isinstance(element, (dict, list)):
|
||||
not_flat = True
|
||||
if not_flat:
|
||||
|
@ -142,12 +163,12 @@ def dump_qs(obj):
|
|||
qs = []
|
||||
strng = ""
|
||||
for el in qs:
|
||||
strng += qs_quote(str(el[0]), encoding="utf8") + "=" + \
|
||||
qs_quote(str(el[1]), encoding="utf8") + "&"
|
||||
strng += qs_quote(compat_str(el[0]).encode("utf-8")) + "=" + \
|
||||
qs_quote(compat_str(el[1]).encode("utf-8")) + "&"
|
||||
return strng[:-1]
|
||||
|
||||
|
||||
def absolute_url(new_url: str, old_url: str):
|
||||
def absolute_url(new_url, old_url):
|
||||
if new_url.startswith("http:") or new_url.startswith("https:"):
|
||||
return new_url
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '2020.11.28'
|
|
@ -0,0 +1,6 @@
|
|||
[wheel]
|
||||
universal = True
|
||||
|
||||
[flake8]
|
||||
exclude = librefi/compat.py,setup.py
|
||||
ignore = E501
|
|
@ -0,0 +1,111 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
from shutil import rmtree
|
||||
|
||||
from setuptools import find_packages, setup, Command
|
||||
|
||||
NAME = 'librefi'
|
||||
DESCRIPTION = 'LibreFi logs into public Wi-Fis without user interaction. Just access the network!'
|
||||
URL = 'https://git.sakamoto.pl/laudom/librefi'
|
||||
EMAIL = 'librefi@selfisekai.rocks'
|
||||
AUTHOR = 'Lauren Liberda'
|
||||
REQUIRES_PYTHON = '==2.7, >=3.8'
|
||||
|
||||
REQUIRED = [
|
||||
'requests',
|
||||
]
|
||||
|
||||
EXTRAS = {
|
||||
# 'traffic debugging': ['mitmproxy'],
|
||||
}
|
||||
|
||||
# Get the version without importing the package (copied from youtube-dl)
|
||||
exec(compile(open('librefi/version.py').read(),
|
||||
'librefi/version.py', 'exec'))
|
||||
|
||||
VERSION = __version__
|
||||
|
||||
try:
|
||||
with io.open('README.md', encoding='utf-8') as f:
|
||||
long_description = '\n' + f.read()
|
||||
except FileNotFoundError:
|
||||
long_description = DESCRIPTION
|
||||
|
||||
|
||||
class UploadCommand(Command):
|
||||
"""Support setup.py upload."""
|
||||
|
||||
description = 'Build and publish the package.'
|
||||
user_options = []
|
||||
|
||||
@staticmethod
|
||||
def status(s):
|
||||
"""Prints things in bold."""
|
||||
print('\033[1m%s\033[0m' % (s))
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.status('Removing previous builds…')
|
||||
rmtree(os.path.join(here, 'dist'))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
self.status('Building Source and Wheel (universal) distribution…')
|
||||
os.system('%s setup.py sdist bdist_wheel --universal' % (sys.executable))
|
||||
|
||||
self.status('Uploading the package to PyPI via Twine…')
|
||||
os.system('twine upload dist/*')
|
||||
|
||||
self.status('Pushing git tags…')
|
||||
os.system('git tag v%s' % (VERSION))
|
||||
os.system('git push v%s' % (VERSION))
|
||||
|
||||
sys.exit()
|
||||
|
||||
|
||||
# Where the magic happens:
|
||||
setup(
|
||||
name=NAME,
|
||||
version=VERSION,
|
||||
description=DESCRIPTION,
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/markdown',
|
||||
author=AUTHOR,
|
||||
author_email=EMAIL,
|
||||
python_requires=REQUIRES_PYTHON,
|
||||
url=URL,
|
||||
py_modules=['librefi'],
|
||||
entry_points={
|
||||
'console_scripts': ['librefi=librefi:cli'],
|
||||
},
|
||||
install_requires=REQUIRED,
|
||||
extras_require=EXTRAS,
|
||||
include_package_data=True,
|
||||
license='GPL-3.0-or-later',
|
||||
classifiers=[
|
||||
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
],
|
||||
# $ setup.py publish support.
|
||||
cmdclass={
|
||||
'upload': UploadCommand,
|
||||
},
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from os import listdir, path
|
||||
import re
|
||||
|
||||
|
||||
def test_fxcker_files_py2_compatibility():
|
||||
dir = path.join('.', 'librefi', 'fxckers')
|
||||
fxckers = listdir(dir)
|
||||
for fxcker in fxckers:
|
||||
if re.match(r'^\w+\.py$', fxcker):
|
||||
with open(path.join(dir, fxcker), 'r') as file:
|
||||
content = file.read()
|
||||
if re.match(r'^(#!.+\r?\n)?\s*(# (-\*- )?coding: utf-8( -\*-)?\r?\n)?\s*(from __future__ import (\w+, )*unicode_literals)',
|
||||
content) is None:
|
||||
print(content)
|
||||
print(fxcker)
|
||||
raise AssertionError('fxcker %s not containing required compat imports' % (fxcker))
|
|
@ -1,4 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from librefi.utils import dump_qs
|
||||
from librefi.compat import compat_str
|
||||
from hashlib import sha512
|
||||
|
||||
|
||||
|
@ -12,7 +16,7 @@ def test_dump():
|
|||
{"przestań mi": ["kurwa", "rodzinę prześladować"]}],
|
||||
}
|
||||
result = dump_qs(obj)
|
||||
assert isinstance(result, str)
|
||||
assert isinstance(result, compat_str)
|
||||
assert sha512(result.encode("utf-8")).hexdigest(
|
||||
# flake8: noqa: E501
|
||||
) == "80cb0feb585e8a5969598797b74c6f7f2f314ee97dfd2d6f4aaf431b800f6c7a1dfe77efd550a1009d41ef2886b21b87ce1d9e4f11444af554a916987344aee1"
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from librefi.utils import regex_search_string
|
||||
from librefi.compat import compat_str
|
||||
|
||||
HTML_STRING = """
|
||||
<form method="POST" action="/?your=mother">
|
||||
|
@ -47,7 +51,7 @@ def test_regex_search_multiple_results():
|
|||
assert isinstance(results, list)
|
||||
assert len(results) == len(EXPECTED_RESULT_2)
|
||||
for i in range(len(results)):
|
||||
assert isinstance(results[i], str)
|
||||
assert isinstance(results[i], compat_str)
|
||||
assert results[i] == EXPECTED_RESULT_2[i]
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from librefi.utils import get_user_agent, get_email_address
|
||||
from librefi.compat import compat_str
|
||||
import re
|
||||
|
||||
|
||||
def test_email_address():
|
||||
email = get_email_address()
|
||||
assert isinstance(email, str)
|
||||
assert isinstance(email, compat_str)
|
||||
assert re.search(
|
||||
# intentionally dumb and not covering a lot of actual emails
|
||||
r"^[a-zA-Z\d](?:[a-zA-Z\d._-]*[a-zA-Z\d])?@[a-z-\d]+(?:\.[a-z-\d]+)+$",
|
||||
|
@ -14,5 +18,5 @@ def test_email_address():
|
|||
|
||||
def test_user_agent():
|
||||
ua = get_user_agent()
|
||||
assert isinstance(ua, str)
|
||||
assert isinstance(ua, compat_str)
|
||||
pass
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from librefi.utils import absolute_url
|
||||
from librefi.compat import compat_str
|
||||
|
||||
OLD_URL = "https://sakamoto.pl/ddd"
|
||||
NEW_URL_RELATIVE = "/DDD?test=yes"
|
||||
|
@ -9,7 +13,7 @@ NEW_URL_ABSOLUTE = "https://sakamoto.pl/DDD?test=yes"
|
|||
|
||||
def test_basic():
|
||||
abso = absolute_url(NEW_URL_RELATIVE, OLD_URL)
|
||||
assert isinstance(abso, (str))
|
||||
assert isinstance(abso, (compat_str))
|
||||
print(abso)
|
||||
assert abso == NEW_URL_ABSOLUTE
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue