Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
a2e50a0c18 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
|||
.jython_cache/
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/python,linux,windows,macos,jetbrains,visualstudiocode
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=python,linux,windows,macos,jetbrains,visualstudiocode
|
||||
|
|
147
.gitlab-ci.yml
147
.gitlab-ci.yml
|
@ -1,151 +1,18 @@
|
|||
default:
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements_dev.txt
|
||||
|
||||
py2.7-unit_tests:
|
||||
image: python:2.7-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.4-unit_tests:
|
||||
image: python:3.4-alpine
|
||||
allow_failure: true
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.5-unit_tests:
|
||||
image: python:3.5-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.6-unit_tests:
|
||||
image: python:3.6-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.7-unit_tests:
|
||||
image: python:3.7-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.8-unit_tests:
|
||||
image: python:3.8-alpine
|
||||
before_script:
|
||||
- pip3 install -r librefi/requirements.txt
|
||||
- pip3 install -r librefi/dev_requirements.txt
|
||||
|
||||
unit_tests:
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.9-unit_tests:
|
||||
image: python:3.9-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
py3.10-rc-unit_tests:
|
||||
image: python:3.10-rc-alpine
|
||||
script:
|
||||
- nosetests tests/*.py
|
||||
- python setup.py sdist bdist_wheel
|
||||
|
||||
jy2.7-unit_tests:
|
||||
image: openjdk:11-slim
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
- apt-get -y install wget
|
||||
- ./devel_scripts/install_jython.sh
|
||||
- export PATH="$HOME/jython/bin:$PATH"
|
||||
- jython -m pip install -r requirements.txt
|
||||
- jython -m pip install -r requirements_dev.txt
|
||||
script:
|
||||
- jython -m nose tests/*.py
|
||||
# wheel building doesn't work on jython
|
||||
- jython setup.py sdist
|
||||
|
||||
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.4-integration_test:
|
||||
image: python:3.4-buster
|
||||
allow_failure: true
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.5-integration_test:
|
||||
image: python:3.5-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.6-integration_test:
|
||||
image: python:3.6-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.7-integration_test:
|
||||
image: python:3.7-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.8-integration_test:
|
||||
integration_test:
|
||||
image: python:3.8-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- pip3 install -r librefi/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:
|
||||
- python3 -m librefi
|
||||
|
||||
py3.10-rc-integration_test:
|
||||
image: python:3.10-rc-buster
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- apt-get -y update
|
||||
- apt-get -y install network-manager
|
||||
script:
|
||||
- python3 -m librefi
|
||||
|
||||
jy2.7-integration_tests:
|
||||
image: openjdk:11-slim
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
- apt-get -y install wget network-manager
|
||||
- ./devel_scripts/install_jython.sh
|
||||
- export PATH="$HOME/jython/bin:$PATH"
|
||||
- jython -m pip install -r requirements.txt
|
||||
script:
|
||||
- jython -m librefi
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
include README.md LICENSE
|
40
README.md
40
README.md
|
@ -1,40 +0,0 @@
|
|||
# LibreFi
|
||||
## Free Wi-Fi was so great that we created Free Wi-Fi 2
|
||||
|
||||
Note: work is still in progress, this is not stable, may not be usable or useful
|
||||
|
||||
## How to use:
|
||||
release (not to be confused with: _stable_):
|
||||
```sh
|
||||
# you may want to use python3.9, python2, python, jython or something like that
|
||||
$ python3 -m pip install librefi
|
||||
$ python3 -m librefi # no daemon yet, run to connect
|
||||
```
|
||||
|
||||
development:
|
||||
```sh
|
||||
$ git clone https://git.sakamoto.pl/laudom/librefi.git
|
||||
$ cd librefi
|
||||
$ pip3 install -r ./requirements.txt
|
||||
$ pip3 install -r ./requirements_dev.txt
|
||||
$ python3 -m librefi # no daemon yet, run to connect
|
||||
```
|
||||
|
||||
## A bit of technical things
|
||||
- Requires Python 3.4+ or 2.7 (preferably 3.8+)
|
||||
- Requires NetworkManager (only Linux and some Unix-like systems) to connect with Wi-Fi networks for now, however, it's ready to implement other connectors.
|
||||
- Only tested with CPython and Jython, other implementations may work by accident.
|
||||
- Only works with [these networks](https://git.sakamoto.pl/laudom/librefi/-/blob/master/librefi/fxckers/_map.py)
|
||||
|
||||
## Contributing
|
||||
If you want to contribute, please contact with either [Lauren](https://selfisekai.rocks) or [Dominika](https://sakamoto.pl) for a [git.sakamoto.pl](https://git.sakamoto.pl) account, or just [submit patches by e-mail](https://devconnected.com/how-to-create-and-apply-git-patch-files/#Create_Git_Patch_Files) to <librefi-patches@selfisekai.rocks>
|
||||
|
||||
## Maintainers:
|
||||
### Core:
|
||||
- Lauren Liberda <lauren@selfisekai.rocks>
|
||||
- Dominika Liberda <sdomi@sakamoto.pl>
|
||||
### Fxckers:
|
||||
- Poland:
|
||||
- Warsaw:
|
||||
- Lauren Liberda <lauren@selfisekai.rocks>
|
||||
- Dominika Liberda <sdomi@sakamoto.pl>
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import librefi
|
||||
|
||||
if __name__ == '__main__':
|
||||
librefi.main()
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/sh
|
||||
# https://git.sakamoto.pl/laudom/haruhi-dl/-/blob/master/devscripts/install_jython.sh
|
||||
|
||||
wget https://repo1.maven.org/maven2/org/python/jython-installer/2.7.2/jython-installer-2.7.2.jar
|
||||
if [ "$(sha512sum jython-installer-2.7.2.jar | awk '{print $1}')" != "d3ae09ebcb1ad27123d1b325729a18aa9e793039ca3428167455ce51217f10735949d2acea39f89e5414015c97bdd319657aced3753b764dddb09200e8cff40e" ]; then
|
||||
echo "invalid sha512 checksum for jython installer"
|
||||
exit 2137
|
||||
fi
|
||||
|
||||
java -jar jython-installer-2.7.2.jar -s -d "$HOME/jython"
|
|
@ -1,30 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
|
||||
from .librefi import LibreFi
|
||||
from .logger import _Logger, LOG_LEVELS
|
||||
from .utils import LFiError, FxckerError
|
||||
|
||||
|
||||
def _real_main(argv=None):
|
||||
librefi = LibreFi(logger=_Logger, log_level=LOG_LEVELS.DEBUG)
|
||||
librefi._periodical_check()
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
try:
|
||||
_real_main(argv)
|
||||
except LFiError:
|
||||
sys.exit('ERROR (core): report this to librefi@selfisekai.rocks')
|
||||
except FxckerError:
|
||||
sys.exit('ERROR (fxcker): report this to librefi@selfisekai.rocks')
|
||||
except KeyboardInterrupt:
|
||||
sys.exit('\nERROR: Interrupted by user')
|
||||
|
||||
|
||||
__all__ = [
|
||||
'LibreFi',
|
||||
'main',
|
||||
]
|
|
@ -1,15 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
from .librefi import LibreFi
|
||||
from .logger import LOG_LEVELS
|
||||
|
||||
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 main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
librefi = LibreFi(log_level=LOG_LEVELS.DEBUG)
|
||||
librefi._periodical_check()
|
||||
|
|
3075
librefi/compat.py
3075
librefi/compat.py
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ..compat import compat_sys_platform
|
||||
from ..utils import LFiError
|
||||
import sys
|
||||
|
||||
|
||||
def get_connector():
|
||||
if compat_sys_platform == "linux":
|
||||
if sys.platform == "linux":
|
||||
from .networkmanager import NetworkManagerConnector
|
||||
return NetworkManagerConnector
|
||||
raise LFiError('Could not find a connector')
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import subprocess
|
||||
import pipes
|
||||
import re
|
||||
|
||||
|
||||
|
@ -9,22 +7,20 @@ class NetworkManagerConnector:
|
|||
NMCLI_BASE = ["nmcli", "--mode", "tabular", "--terse", "--colors", "no"]
|
||||
|
||||
def _call_nmcli(self, args, parse=True):
|
||||
try:
|
||||
subp = subprocess.check_output(self.NMCLI_BASE + args).decode("utf-8")
|
||||
except subprocess.CalledProcessError as err:
|
||||
subp = err.output.decode("utf-8")
|
||||
subp = subprocess.run(self.NMCLI_BASE + args,
|
||||
capture_output=True, text=True)
|
||||
|
||||
if parse:
|
||||
# if no output
|
||||
if subp.strip() == "":
|
||||
if subp.stdout.strip() == "":
|
||||
return []
|
||||
|
||||
return [
|
||||
[field.replace("\\:", ":")
|
||||
for field in re.split(r"(?<!\\):", line)]
|
||||
for line in subp.strip().split("\n")]
|
||||
for line in subp.stdout.strip().split("\n")]
|
||||
|
||||
return subp
|
||||
return subp.stdout
|
||||
|
||||
def status(self):
|
||||
infs = self._call_nmcli(["--fields", "TYPE,NAME",
|
||||
|
@ -66,4 +62,4 @@ class NetworkManagerConnector:
|
|||
|
||||
def connect(self, network):
|
||||
self._call_nmcli(["device", "wifi", "connect",
|
||||
network["ssid"]], parse=False)
|
||||
pipes.quote(network["ssid"])], parse=False)
|
||||
|
|
1
librefi/dev_requirements.txt
Normal file
1
librefi/dev_requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
nose
|
|
@ -1,6 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._map import fxckers_map
|
||||
|
||||
__all__ = ['fxckers_map']
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import requests
|
||||
|
||||
from ..utils import get_user_agent, absolute_url
|
||||
|
@ -17,7 +14,7 @@ class BaseFxcker:
|
|||
return self.__class__.__name__[:-6]
|
||||
|
||||
def request(self, method, url, resource=None,
|
||||
follow_redirects=True, redirect_count=0, **kwargs):
|
||||
follow_redirects=True, **kwargs):
|
||||
kwargs["cookies"] = self.cookie_jar
|
||||
if not kwargs.get("headers"):
|
||||
kwargs["headers"] = {}
|
||||
|
@ -26,11 +23,8 @@ class BaseFxcker:
|
|||
if not kwargs.get("allow_redirects"):
|
||||
kwargs["allow_redirects"] = False
|
||||
self.log.info("Requesting " +
|
||||
(resource if resource is not None
|
||||
else (str(method) + " " + str(url)))
|
||||
+ (" (redirect #%d)" % (redirect_count)
|
||||
if redirect_count > 0
|
||||
else ""))
|
||||
resource if resource is not None
|
||||
else (str(method) + " " + str(url)))
|
||||
sess = requests.Session()
|
||||
req = sess.request(method, url, **kwargs)
|
||||
self.cookie_jar.update(sess.cookies)
|
||||
|
@ -41,6 +35,5 @@ class BaseFxcker:
|
|||
return self.request("GET", new_url,
|
||||
resource=resource,
|
||||
follow_redirects=follow_redirects,
|
||||
redirect_count=(redirect_count + 1),
|
||||
**kwargs)
|
||||
return req
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._dummy import DummyFxcker
|
||||
from .umwarszawa import UMWarszawaFxcker
|
||||
from .ledatel import LedatelFxcker
|
||||
from .ipartners import IPartnersFxcker
|
||||
from .kfchotspot import KFCHotspotFxcker
|
||||
from .justwifi import JustWifiFxcker
|
||||
from .netiawifi import NetiaWifiFxcker
|
||||
|
||||
fxckers_map = [
|
||||
([r"re:MZK Opole \d{3}(?: (?:2.4|5)GHz)?"], DummyFxcker),
|
||||
|
@ -17,8 +15,6 @@ fxckers_map = [
|
|||
([
|
||||
"Intercity_WiFi",
|
||||
"_PKP_WIFI",
|
||||
"Poznan Airport by JustWiFi",
|
||||
], JustWifiFxcker),
|
||||
(["COSTA COFFEE"], NetiaWifiFxcker),
|
||||
]
|
||||
|
||||
__all__ = ['fxckers_map']
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, dump_qs
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, absolute_url, dump_qs
|
||||
|
||||
|
@ -62,14 +59,15 @@ class JustWifiFxcker(BaseFxcker):
|
|||
})
|
||||
cnt_url = regex_search_string([
|
||||
r"var cnt_url = '([^']+)';",
|
||||
r'<input [^>]*name="adv_step\[url\]" value="([^"]+)"',
|
||||
r'<input [^>]*name="adv_step\[url\] " value="([^"]+)"',
|
||||
], sgu_after.text)
|
||||
banner_url_encoded = regex_search_string([
|
||||
r"var banner_url_encoded = '([^']+)';",
|
||||
r'<input [^>]*name="adv_step\[url\] " value="([^"]+)"',
|
||||
], sgu_after.text, default="")
|
||||
bannerzone = regex_search_string([
|
||||
r"\$\(\"input\[name='adv_step\[bannerZone\]']\"\)\.val\('([^']+)'\);",
|
||||
r'<input [^>]*name="adv_step\[bannerZone\]" value="([^"]+)"',
|
||||
r"\$\(\"input\[name='adv_step\[bannerZone\]']\"\).val\('([^']+)'\);",
|
||||
r'<input [^>]*name="adv_step\[bannerZone\] " value="([^"]+)"',
|
||||
], sgu_after.text)
|
||||
sgu_after_token = regex_search_string([
|
||||
r'<input [^>]*name="adv_step\[_token\] " value="([^"]+)"',
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
|
||||
|
||||
|
|
67
librefi/fxckers/netiawifi.py
Normal file
67
librefi/fxckers/netiawifi.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, dump_qs
|
||||
import re
|
||||
from urllib.parse import unquote
|
||||
|
||||
|
||||
class NetiaWifiFxcker(BaseFxcker):
|
||||
def unfxck(self, location=None):
|
||||
start = self.request("GET", location)
|
||||
initial_redir_url = regex_search_string(
|
||||
r'<form [^>]*action="([^"]+)"', start.text)
|
||||
start_form = {}
|
||||
for param in ["mac", "ip", "apname", "essid", "url", "switch_url"]:
|
||||
start_form[param] = regex_search_string(
|
||||
r'<input [^>]*name="%s" value="([^"]+)"' % (re.escape(param)),
|
||||
start.text)
|
||||
initial_redir = self.request(
|
||||
"POST", initial_redir_url, data=dump_qs(start_form), headers={
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
})
|
||||
splash_url = regex_search_string(
|
||||
r'<form [^>]*action="([^"]+)"', initial_redir.text)
|
||||
splash = self.request("POST", splash_url, data=dump_qs({
|
||||
"initialRedirect": True,
|
||||
}))
|
||||
accept_url = regex_search_string(
|
||||
r"form\.setAttribute\('action', '([^']+)'\)", splash.text)
|
||||
accept_page = self.request("POST", accept_url, data=dump_qs({
|
||||
"ie11postFix": "sendPost",
|
||||
}), headers={
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
})
|
||||
|
||||
# what the fuck is that, Netia?
|
||||
for match in regex_search_string(
|
||||
# flake8: noqa: E501
|
||||
r"document\.cookie\s*=\s*'([^']+)'\s*\+\s*decodeURIComponent\('([^']+)'\)\s*\+\s*'([^']+)';",
|
||||
accept_page.text, multiple=True, whole_match=True):
|
||||
self.cookie_jar.set_cookie(match.group(
|
||||
1) + unquote(match.group(2)) + match.group(3))
|
||||
for match in regex_search_string(
|
||||
# flake8: noqa: E501
|
||||
r"document\.cookie\s*=\s*'([^']+)'\s*\+\s*'([^']+)'\s*\+\s*'([^']+)';",
|
||||
accept_page.text, multiple=True, whole_match=True):
|
||||
self.cookie_jar.set_cookie(match.group(
|
||||
1) + match.group(2) + match.group(3))
|
||||
for match in regex_search_string(
|
||||
# flake8: noqa: E501
|
||||
r"document\.cookie\s*=\s*'([^']+)';",
|
||||
accept_page.text, multiple=True, whole_match=True):
|
||||
self.cookie_jar.set_cookie(match.group(1))
|
||||
|
||||
login_url = regex_search_string(
|
||||
r'<form [^>]*action="([^"]+)"', accept_page.text)
|
||||
login_form = {}
|
||||
for match in regex_search_string(
|
||||
r'<input [^>]*name="([^"]+)" value="([^"]*)"',
|
||||
accept_page.text, multiple=True, whole_match=True):
|
||||
login_form[match.group(1)] = match.group(2)
|
||||
login_page = self.request("GET", login_url + "?" + dump_qs(login_form))
|
||||
|
||||
welcome_url = unquote(regex_search_string(
|
||||
r'<meta http-equiv="refresh" content="\d+; url=([^"]+)"',
|
||||
login_page.text))
|
||||
welcome_page = self.request("GET", welcome_url)
|
||||
|
||||
return True
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ._common import BaseFxcker
|
||||
from ..utils import regex_search_string, dump_qs
|
||||
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#!/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):
|
||||
|
@ -49,7 +47,6 @@ 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)
|
||||
|
@ -66,17 +63,16 @@ class LibreFi:
|
|||
fxcker = None
|
||||
for fxck_element in fxckers_map:
|
||||
for fxck_net_name in fxck_element[0]:
|
||||
if fxck_net_name[:len("re:")] == "re:":
|
||||
if re.match(fxck_net_name,
|
||||
network["ssid"][len("re:"):]):
|
||||
if fxck_net_name[:3] == "re:":
|
||||
if re.fullmatch(fxck_net_name,
|
||||
"re:" + network["ssid"]):
|
||||
fxcker = fxck_element[1]
|
||||
break
|
||||
elif fxck_net_name == network["ssid"]:
|
||||
fxcker = fxck_element[1]
|
||||
break
|
||||
if fxcker:
|
||||
self.log.info("Switching fxcker to {}".format(fxcker.FXCKER_KEY))
|
||||
self.current_fxcker = fxcker(
|
||||
logger=self.logger, log_level=self.log_level)
|
||||
self.log.info("Switched fxcker to {}".format(
|
||||
self.current_fxcker.FXCKER_KEY))
|
||||
return self.current_fxcker
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class LOG_LEVELS:
|
||||
DEBUG = -10
|
||||
INFO = 0
|
||||
|
@ -10,28 +6,24 @@ class LOG_LEVELS:
|
|||
|
||||
|
||||
class _Logger:
|
||||
def printer(self, x):
|
||||
print(x)
|
||||
printer = print
|
||||
|
||||
def __init__(self, key="--no-key--", log_level=LOG_LEVELS.INFO):
|
||||
self.KEY = key
|
||||
self.LOG_LEVEL = log_level
|
||||
|
||||
def _do_log(self, message):
|
||||
self.printer("[" + str(self.KEY) + "] " + str(message))
|
||||
|
||||
def debug(self, message):
|
||||
if self.LOG_LEVEL <= LOG_LEVELS.DEBUG:
|
||||
self._do_log(message)
|
||||
self.printer("[" + self.KEY + "] " + message)
|
||||
|
||||
def info(self, message):
|
||||
if self.LOG_LEVEL <= LOG_LEVELS.INFO:
|
||||
self._do_log(message)
|
||||
self.printer("[" + self.KEY + "] " + message)
|
||||
|
||||
def error(self, message):
|
||||
if self.LOG_LEVEL <= LOG_LEVELS.ERROR:
|
||||
self._do_log(message)
|
||||
self.printer("[" + self.KEY + "] " + message)
|
||||
|
||||
def fatal(self, message):
|
||||
if self.LOG_LEVEL <= LOG_LEVELS.FATAL:
|
||||
self._do_log(message)
|
||||
self.printer("[" + self.KEY + "] " + message)
|
||||
|
|
354
librefi/utils.py
354
librefi/utils.py
|
@ -1,30 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# flake8: noqa: E501
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
from datetime import date
|
||||
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
|
||||
|
||||
|
||||
TEST_URL = "http://detectportal.firefox.com/success.txt"
|
||||
|
||||
|
||||
def get_user_agent():
|
||||
if bool(random.getrandbits(1)):
|
||||
|
@ -88,253 +68,25 @@ def get_user_agent():
|
|||
|
||||
|
||||
def get_email_address():
|
||||
day_today = date.today().strftime('%m-%d')
|
||||
if day_today in ( # "MM-DD"
|
||||
'05-17', # https://en.wikipedia.org/wiki/International_Day_Against_Homophobia,_Transphobia_and_Biphobia
|
||||
'09-28', # https://en.wikipedia.org/wiki/International_Safe_Abortion_Day
|
||||
'11-20', # https://en.wikipedia.org/wiki/Transgender_Day_of_Remembrance
|
||||
'12-10', # https://en.wikipedia.org/wiki/Human_Rights_Day
|
||||
):
|
||||
return random.choice((
|
||||
time_now = datetime.now()
|
||||
if time_now.month == 5 and time_now.day == 17:
|
||||
# https://en.wikipedia.org/wiki/International_Day_Against_Homophobia,_Transphobia_and_Biphobia
|
||||
return random.choice([
|
||||
"biuro@ordoiuris.pl",
|
||||
"kontakt@stronazycia.pl",
|
||||
"kontakt@petycjaonline.pl",
|
||||
"gejprzeciwkoswiatu@gmail.com",
|
||||
"biuro.prasowe@konfederacja.net",
|
||||
"biuro@pis.org.pl",
|
||||
"Zbigniew.Ziobro@sejm.pl",
|
||||
"Sebastian.Kaleta@sejm.pl",
|
||||
"Michal.Wojcik@sejm.pl",
|
||||
"Tomasz.Rzymkowski@sejm.pl",
|
||||
])
|
||||
|
||||
# LGB Alliance
|
||||
"developers@lgballiance.org.uk",
|
||||
"koalicjalgb@gmail.com",
|
||||
"frentelgb@gmail.com",
|
||||
"alianzalgb@gmail.com",
|
||||
"lgsolidarnamreza@gmail.com",
|
||||
"redlesbianasgaysbisexuales@gmail.com",
|
||||
|
||||
# Agenda Europe - https://agendaeurope.wordpress.com/links-2/
|
||||
"info@acton.org",
|
||||
"istitutoacton@acton.org",
|
||||
"info@institutoacton.com.ar",
|
||||
"kmauren@acton.org",
|
||||
"sgregg@acton.org",
|
||||
"kabbs@acton.org",
|
||||
"tvogt@acton.org",
|
||||
"sbarrows@acton.org",
|
||||
"croelofs@acton.org",
|
||||
"kmauren@acton.org",
|
||||
"ekohn@acton.org",
|
||||
"mseverance@acton.org",
|
||||
"info@c-fam.org",
|
||||
"Media@c-fam.org",
|
||||
"Hannah@c-fam.org",
|
||||
"press@citizengo.org",
|
||||
"english@citizengo.org",
|
||||
"admin@dialoguedynamics.com",
|
||||
"ipf@ipfe.org",
|
||||
"internationalipf@ipfe.org",
|
||||
"ehertfelder@ipfe.org",
|
||||
"donor@lifesitenews.com",
|
||||
"support@lifesitenews.com",
|
||||
"corrections@lifesitenews.com",
|
||||
"advertising@lifesitenews.com",
|
||||
"marketing@lifesitenews.com",
|
||||
"submit@lifesitenews.com",
|
||||
"info@od.org.au",
|
||||
"finland@od.org",
|
||||
"contacto@puertasabiertasal.org",
|
||||
"philippines@od.org",
|
||||
"info@puertasabiertas.org",
|
||||
"info@opendoors.at",
|
||||
"info@portesouvertes.ch",
|
||||
"contact@portesouvertes.fr",
|
||||
"info@opendoors.pl",
|
||||
"sweden@od.org",
|
||||
"sarab@od.org",
|
||||
"presskontakt@od.org",
|
||||
"falecom@portasabertas.org.br",
|
||||
"info@opendoors.de",
|
||||
"youth@opendoors.de",
|
||||
"pressebuero@opendoors.de",
|
||||
"info@od.org.nz",
|
||||
"info@porti-deschise.org",
|
||||
"info@portesouvertes.ch",
|
||||
"opendoorsca@odcan.org",
|
||||
"enquiryhk@od.org",
|
||||
"norway@od.org",
|
||||
"mortena@od.org",
|
||||
"lindaa@od.org",
|
||||
"southafrica@od.org",
|
||||
"inspire@opendoorsuk.org",
|
||||
"odireland@opendoorsuk.org",
|
||||
"denmark@od.org",
|
||||
"info@porteaperteitalia.org",
|
||||
"cristinam@od.org",
|
||||
"cristiann@od.org",
|
||||
"odi-nl@od.org",
|
||||
"info@fedsoc.org",
|
||||
"Info@C-FAM.org",
|
||||
"info@womenworldplatform.com",
|
||||
"info@wcfverona.org",
|
||||
"webadmin@ifamnews.com",
|
||||
"info@profam.org",
|
||||
"wya@wya.net",
|
||||
"africa@wya.net",
|
||||
"asiapacific@wya.net",
|
||||
"europe@wya.net",
|
||||
"latinamerica@wya.net",
|
||||
"mena@wya.net",
|
||||
"northamerica@wya.net",
|
||||
"info@europeanrenewal.org",
|
||||
"secretariat@eclj.org",
|
||||
"office@ecpm.info",
|
||||
"office@europeandignitywatch.org",
|
||||
"info@oneofus.eu",
|
||||
"info@familienforum.at",
|
||||
"postbox@imabe.org",
|
||||
"office@ief.at",
|
||||
"office@youthforlife.net",
|
||||
"office@kairos-pr.com",
|
||||
"office@lebenskonferenz.at",
|
||||
"info@pro-life.by",
|
||||
"svabulgaria@gmail.com",
|
||||
"press@uimeobitelji.net",
|
||||
"cenap@cenap.cz",
|
||||
"info@hnutiprozivot.cz",
|
||||
"rodiny@rodiny.cz",
|
||||
"oujezdska@rodiny.cz",
|
||||
"charvatova@rodiny.cz",
|
||||
"horakova@rodiny.cz",
|
||||
"pavlisova@rodiny.cz",
|
||||
"kucerova@rodiny.cz",
|
||||
"jegvilleve@rettentilliv.dk",
|
||||
"leder@abortlinien.dk",
|
||||
"ung@rettentilliv.dk",
|
||||
"web@rettentilliv.dk",
|
||||
"regnskab@rettentilliv.dk",
|
||||
"elukultuur@gmail.com",
|
||||
"info@saptk.ee",
|
||||
"presse@fondationlejeune.org",
|
||||
"info@alfa-ev.de",
|
||||
"berlin@bv-lebensrecht.de",
|
||||
"info@cdl-online.de",
|
||||
"info@datenschutz.ekd.de",
|
||||
"datenschutz@ojc.de",
|
||||
"kontakt@familien-schutz.de",
|
||||
"info@jvl-ev.de",
|
||||
"zfl@juristen-vereinigung-lebensrecht.de",
|
||||
"kontakt@familie-geht-vor.de",
|
||||
"info@agalia.org.gr",
|
||||
"kapcsolat@egyuttazeletert.hu",
|
||||
"asszonyszovetseg@asszonyszovetseg.hu",
|
||||
"info@familyandlife.org",
|
||||
"info@ionainstitute.ie",
|
||||
"info@famigliadomani.it",
|
||||
"contact@novaeterrae.eu",
|
||||
"giuristiperlavita2@gmail.com",
|
||||
"postmaster@giuristiperlavita.org",
|
||||
"webmaster@giuristiperlavita.org",
|
||||
"redazione@lanuovabq.it",
|
||||
"segreteria@lanuovabq.it",
|
||||
"inserzioni@lanuovabq.it",
|
||||
"segreteria@lamanifpourtous.it",
|
||||
"press@lamanifpourtous.it",
|
||||
"info@provitaefamiglia.it",
|
||||
"stampa@provitaefamiglia.it",
|
||||
"redazione@provitaefamiglia.it",
|
||||
"asociacijagimene@gmail.com",
|
||||
"info@schwanger.li",
|
||||
"beratung@schwanger.li",
|
||||
"info@schwanger.li",
|
||||
"af@ateitis.lt",
|
||||
"info@propatria.lt",
|
||||
"contact@moldovacrestina.md",
|
||||
"secretariaat@provita.nl",
|
||||
"info@schreeuwomleven.nl",
|
||||
"morten@menneskeverd.no",
|
||||
"kristin@menneskeverd.no",
|
||||
"maria@menneskeverd.no",
|
||||
"susanne@menneskeverd.no",
|
||||
"ingrid@menneskeverd.no",
|
||||
"sara@menneskeverd.no",
|
||||
"fredrik@menneskeverd.no",
|
||||
"bjarne@menneskeverd.no",
|
||||
"ingridbs@menneskeverd.no",
|
||||
"annekari@menneskeverd.no",
|
||||
"post@menneskeverd.no",
|
||||
"fundacja@glosdlazycia.pl",
|
||||
"biuro@mamaitata.org.pl",
|
||||
"biuro@ordoiuris.pl",
|
||||
"rzecznik@ordoiuris.pl",
|
||||
"interwencja@ordoiuris.pl",
|
||||
"f.p.p.vida@gmail.com",
|
||||
"office@alianta-familiilor.ro",
|
||||
"asociatiadiaconia@yahoo.com",
|
||||
"redactia@culturavietii.ro",
|
||||
"contact@asociatiaprovita.ro",
|
||||
"profamilia.ru@gmail.com",
|
||||
"info@familypolicy.ru",
|
||||
"info@alianciazarodinu.sk",
|
||||
"donumvitaeoz@gmail.com",
|
||||
"forumzivota@forumzivota.sk",
|
||||
"info@zavod-zivim.si",
|
||||
"info@cidevida.org",
|
||||
"forofamilia@forofamilia.org",
|
||||
"prensa@forofamilia.org",
|
||||
"prensa@hazteoir.org",
|
||||
"info@profesionalesetica.org",
|
||||
"asistencia24@redmadre.es",
|
||||
"info@valoresysociedad.org",
|
||||
"info@respektlivet.nu",
|
||||
"info@shrl.eu",
|
||||
"info@starke-muetter.com",
|
||||
"family_institute@ucu.edu.ua",
|
||||
"info@christianconcern.com",
|
||||
"press@c4m.org.uk",
|
||||
"admin@c4m.org.uk",
|
||||
"info@core-issues.org",
|
||||
"info@righttolife.org.uk",
|
||||
"information@spuc.org.uk",
|
||||
"info@spucscotland.org",
|
||||
"belfast@spuc.org.uk",
|
||||
"info@christian.org.uk",
|
||||
"info@vfjuk.org",
|
||||
))
|
||||
|
||||
# random first name
|
||||
email = random.choice((
|
||||
# ok, you got me, not so much random
|
||||
"laura", "dominika", "patrycja",
|
||||
# bromine and barium
|
||||
"andrea", "brock", "jesse", "walter", "mike", "flynn", "marie", "hank", "gustavo", "saul",
|
||||
# an edgy teenager and her friends
|
||||
"haruhi", "kyon", "mikuru", "yuki", "itsuki", "ryouko",
|
||||
# that's totally how they live
|
||||
"yuuko", "mai", "mio", "nano", "hakase", "sakamoto", "misato", "izumi", "yoshino", "haruna"
|
||||
))
|
||||
email += random.choice(("", ".", "_", "-"))
|
||||
# random a-z chars
|
||||
for i in range(random.randint(3, 9)):
|
||||
email = ""
|
||||
for i in range(random.randint(6, 18)):
|
||||
email += chr(97 + random.randint(0, 24))
|
||||
# ~50% chance
|
||||
if random.getrandbits(1):
|
||||
# random digits
|
||||
email += compat_str(random.randint(0, 9999))
|
||||
return email + "@" + random.choice((
|
||||
# only include big corp e-mail domains here, fuck centralization
|
||||
"gmail.com",
|
||||
"outlook.com",
|
||||
"live.com",
|
||||
"hotmail.com",
|
||||
"hotmail.co.uk",
|
||||
"yahoo.com",
|
||||
"aol.com",
|
||||
"aim.com",
|
||||
"yandex.ru",
|
||||
"mail.ru",
|
||||
))
|
||||
return email + "@" + random.choice([
|
||||
"gmail.com", "outlook.com", "live.com",
|
||||
])
|
||||
|
||||
|
||||
def regex_search_string(regexes, string, default=None, multiple=False, whole_match=False):
|
||||
|
@ -360,19 +112,15 @@ def regex_search_string(regexes, string, default=None, multiple=False, whole_mat
|
|||
|
||||
|
||||
def dump_qs(obj):
|
||||
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()
|
||||
old_qs = []
|
||||
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], (compat_str, int, float)):
|
||||
if isinstance(old_qs_element[1], (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]:
|
||||
|
@ -386,7 +134,7 @@ def dump_qs(obj):
|
|||
element = old_qs_element[1][index]
|
||||
if element is not None:
|
||||
qs.append(
|
||||
(old_qs_element[0] + "[" + compat_str(index) + "]", element))
|
||||
(old_qs_element[0] + "[" + str(index) + "]", element))
|
||||
if isinstance(element, (dict, list)):
|
||||
not_flat = True
|
||||
if not_flat:
|
||||
|
@ -394,12 +142,12 @@ def dump_qs(obj):
|
|||
qs = []
|
||||
strng = ""
|
||||
for el in qs:
|
||||
strng += qs_quote(compat_str(el[0]).encode("utf-8")) + "=" + \
|
||||
qs_quote(compat_str(el[1]).encode("utf-8")) + "&"
|
||||
strng += qs_quote(str(el[0]), encoding="utf8") + "=" + \
|
||||
qs_quote(str(el[1]), encoding="utf8") + "&"
|
||||
return strng[:-1]
|
||||
|
||||
|
||||
def absolute_url(new_url, old_url):
|
||||
def absolute_url(new_url: str, old_url: str):
|
||||
if new_url.startswith("http:") or new_url.startswith("https:"):
|
||||
return new_url
|
||||
|
||||
|
@ -418,63 +166,3 @@ def absolute_url(new_url, old_url):
|
|||
|
||||
# like "hostname/path?query", if other checks fail
|
||||
return scheme + "://" + new_url
|
||||
|
||||
|
||||
# from youtube-dl
|
||||
def js_to_json(code):
|
||||
COMMENT_RE = r'/\*(?:(?!\*/).)*?\*/|//[^\n]*'
|
||||
SKIP_RE = r'\s*(?:{comment})?\s*'.format(comment=COMMENT_RE)
|
||||
INTEGER_TABLE = (
|
||||
(r'(?s)^(0[xX][0-9a-fA-F]+){skip}:?$'.format(skip=SKIP_RE), 16),
|
||||
(r'(?s)^(0+[0-7]+){skip}:?$'.format(skip=SKIP_RE), 8),
|
||||
)
|
||||
|
||||
def fix_kv(m):
|
||||
v = m.group(0)
|
||||
if v in ('true', 'false', 'null'):
|
||||
return v
|
||||
elif v.startswith('/*') or v.startswith('//') or v.startswith('!') or v == ',':
|
||||
return ""
|
||||
|
||||
if v[0] in ("'", '"'):
|
||||
v = re.sub(r'(?s)\\.|"', lambda m: {
|
||||
'"': '\\"',
|
||||
"\\'": "'",
|
||||
'\\\n': '',
|
||||
'\\x': '\\u00',
|
||||
}.get(m.group(0), m.group(0)), v[1:-1])
|
||||
else:
|
||||
for regex, base in INTEGER_TABLE:
|
||||
im = re.match(regex, v)
|
||||
if im:
|
||||
i = int(im.group(1), base)
|
||||
return '"%d":' % i if v.endswith(':') else '%d' % i
|
||||
|
||||
return '"%s"' % v
|
||||
|
||||
return re.sub(r'''(?sx)
|
||||
"(?:[^"\\]*(?:\\\\|\\['"nurtbfx/\n]))*[^"\\]*"|
|
||||
'(?:[^'\\]*(?:\\\\|\\['"nurtbfx/\n]))*[^'\\]*'|
|
||||
{comment}|,(?={skip}[\]}}])|
|
||||
(?:(?<![0-9])[eE]|[a-df-zA-DF-Z_])[.a-zA-Z_0-9]*|
|
||||
\b(?:0[xX][0-9a-fA-F]+|0+[0-7]+)(?:{skip}:)?|
|
||||
[0-9]+(?={skip}:)|
|
||||
!+
|
||||
'''.format(comment=COMMENT_RE, skip=SKIP_RE), fix_kv, code)
|
||||
|
||||
|
||||
# from youtube-dl
|
||||
def hidden_inputs(html):
|
||||
html = re.sub(r'<!--(?:(?!<!--).)*-->', '', html)
|
||||
hidden_inputs = {}
|
||||
for input in re.findall(r'(?i)(<input[^>]+>)', html):
|
||||
attrs = extract_attributes(input)
|
||||
if not input:
|
||||
continue
|
||||
if attrs.get('type') not in ('hidden', 'submit'):
|
||||
continue
|
||||
name = attrs.get('name') or attrs.get('id')
|
||||
value = attrs.get('value')
|
||||
if name and value is not None:
|
||||
hidden_inputs[name] = value
|
||||
return hidden_inputs
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '2020.12.04'
|
|
@ -1,2 +0,0 @@
|
|||
nose
|
||||
wheel
|
|
@ -1,6 +0,0 @@
|
|||
[wheel]
|
||||
universal = True
|
||||
|
||||
[flake8]
|
||||
exclude = librefi/compat.py,setup.py
|
||||
ignore = E501
|
130
setup.py
130
setup.py
|
@ -1,130 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
from shutil import rmtree
|
||||
|
||||
try:
|
||||
from setuptools import setup, Command
|
||||
setuptools_available = True
|
||||
except ImportError:
|
||||
from distutils.core import setup, Command
|
||||
setuptools_available = False
|
||||
|
||||
|
||||
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.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4'
|
||||
|
||||
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
|
||||
|
||||
params = {}
|
||||
if setuptools_available:
|
||||
params['entry_points'] = {'console_scripts': ['librefi = librefi:main']}
|
||||
else:
|
||||
params['scripts'] = ['bin/librefi']
|
||||
|
||||
|
||||
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('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,
|
||||
packages=[
|
||||
'librefi',
|
||||
'librefi.connectors',
|
||||
'librefi.fxckers',
|
||||
],
|
||||
py_modules=['librefi'],
|
||||
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.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: Jython',
|
||||
],
|
||||
# $ setup.py publish support.
|
||||
cmdclass={
|
||||
'upload': UploadCommand,
|
||||
},
|
||||
**params
|
||||
)
|
|
@ -1,29 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from os import listdir, path
|
||||
import re
|
||||
|
||||
from librefi.compat import (
|
||||
compat_sys_platform,
|
||||
compat_str,
|
||||
)
|
||||
|
||||
|
||||
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))
|
||||
|
||||
|
||||
def test_compat_sys_platform():
|
||||
assert isinstance(compat_sys_platform, compat_str)
|
||||
assert 'java' not in compat_sys_platform
|
|
@ -1,8 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from librefi.utils import dump_qs
|
||||
from librefi.compat import compat_str
|
||||
from hashlib import sha512
|
||||
|
||||
|
||||
|
@ -16,7 +12,7 @@ def test_dump():
|
|||
{"przestań mi": ["kurwa", "rodzinę prześladować"]}],
|
||||
}
|
||||
result = dump_qs(obj)
|
||||
assert isinstance(result, compat_str)
|
||||
assert isinstance(result, str)
|
||||
assert sha512(result.encode("utf-8")).hexdigest(
|
||||
# flake8: noqa: E501
|
||||
) == "80cb0feb585e8a5969598797b74c6f7f2f314ee97dfd2d6f4aaf431b800f6c7a1dfe77efd550a1009d41ef2886b21b87ce1d9e4f11444af554a916987344aee1"
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
# -*- 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">
|
||||
|
@ -51,7 +47,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], compat_str)
|
||||
assert isinstance(results[i], str)
|
||||
assert results[i] == EXPECTED_RESULT_2[i]
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
# -*- 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, compat_str)
|
||||
assert isinstance(email, 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]+)+$",
|
||||
|
@ -18,5 +14,5 @@ def test_email_address():
|
|||
|
||||
def test_user_agent():
|
||||
ua = get_user_agent()
|
||||
assert isinstance(ua, compat_str)
|
||||
assert isinstance(ua, str)
|
||||
pass
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
# -*- 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"
|
||||
|
@ -13,7 +9,7 @@ NEW_URL_ABSOLUTE = "https://sakamoto.pl/DDD?test=yes"
|
|||
|
||||
def test_basic():
|
||||
abso = absolute_url(NEW_URL_RELATIVE, OLD_URL)
|
||||
assert isinstance(abso, (compat_str))
|
||||
assert isinstance(abso, (str))
|
||||
print(abso)
|
||||
assert abso == NEW_URL_ABSOLUTE
|
||||
pass
|
||||
|
|
Loading…
Reference in a new issue