Compare commits

..

1 commit

Author SHA1 Message Date
selfisekai
a2e50a0c18 netiawifi (costa coffee pl) fxcker 2020-09-20 18:25:04 +02:00
36 changed files with 135 additions and 3931 deletions

1
.gitignore vendored
View file

@ -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

View file

@ -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

View file

@ -1 +0,0 @@
include README.md LICENSE

View file

@ -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>

View file

@ -1,6 +0,0 @@
#!/usr/bin/env python
import librefi
if __name__ == '__main__':
librefi.main()

View file

@ -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"

View file

@ -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',
]

View file

@ -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()

File diff suppressed because it is too large Load diff

View file

@ -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')

View file

@ -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)

View file

@ -0,0 +1 @@
nose

View file

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._map import fxckers_map
__all__ = ['fxckers_map']

View file

@ -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

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._common import BaseFxcker

View file

@ -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']

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._common import BaseFxcker
from ..utils import regex_search_string, dump_qs

View file

@ -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="([^"]+)"',

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._common import BaseFxcker
from ..utils import regex_search_string

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._common import BaseFxcker

View 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

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from ._common import BaseFxcker
from ..utils import regex_search_string, dump_qs

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
__version__ = '2020.12.04'

View file

@ -1,2 +0,0 @@
nose
wheel

View file

@ -1,6 +0,0 @@
[wheel]
universal = True
[flake8]
exclude = librefi/compat.py,setup.py
ignore = E501

130
setup.py
View file

@ -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
)

View file

@ -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

View file

@ -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"

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -1,5 +0,0 @@
[tox]
envlist = py27,py38,py39
[testenv]
deps = nose