--- /dev/null
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# OSX useful to ignore
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.dist-info/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# IntelliJ Idea family of suites
+.idea
+*.iml
+## File-based project format:
+*.ipr
+*.iws
+## mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# Briefcase log files
+logs/
--- /dev/null
+# FedorDPI Release Notes
+
+## 0.0.1 (06 Feb 2025)
+
+* Initial release
--- /dev/null
+FedorDPI: FedorDPI
+Copyright (C) 2025 Fedor Sevrugin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+Текущая версия основана на FedorDPI V1.0.2
+
+Собранные пакеты текущей версии находятся в директории current-build
+
+
+FedorDPI
+========
+
+**This cross-platform app was generated by** `Briefcase`_ **- part of**
+`The BeeWare Project`_. **If you want to see more tools like Briefcase, please
+consider** `becoming a financial member of BeeWare`_.
+
+FedorDPI
+
+.. _`Briefcase`: https://briefcase.readthedocs.io/
+.. _`The BeeWare Project`: https://beeware.org/
+.. _`becoming a financial member of BeeWare`: https://beeware.org/contributing/membership
--- /dev/null
+# This project was generated with 0.3.21 using template: https://github.com/beeware/briefcase-template@v0.3.21
+[tool.briefcase]
+project_name = "fedordpi"
+bundle = "fedor.sevrugin.ru"
+version = "0.0.1"
+url = "https://fedor.sevrugin.ru"
+license.file = "LICENSE"
+author = "Fedor Sevrugin"
+author_email = "fedor.sevrugin@gmail.com"
+
+[tool.briefcase.app.fedordpi]
+formal_name = "FedorDPI"
+description = "FedorDPI"
+long_description = """More details about the app should go here.
+"""
+sources = [
+ "src/fedordpi",
+]
+test_sources = [
+ "tests",
+]
+
+requires = [
+]
+test_requires = [
+ "pytest",
+]
+
+[tool.briefcase.app.fedordpi.macOS]
+universal_build = true
+requires = [
+ "toga-cocoa~=0.4.7",
+ "std-nslog~=1.0.3",
+]
+
+[tool.briefcase.app.fedordpi.linux]
+requires = [
+ "toga-gtk~=0.4.7",
+]
+
+[tool.briefcase.app.fedordpi.linux.system.debian]
+system_requires = [
+ # Needed to compile pycairo wheel
+ "libcairo2-dev",
+ # Needed to compile PyGObject wheel
+ "libgirepository1.0-dev",
+]
+
+system_runtime_requires = [
+ # Needed to provide GTK and its GI bindings
+ "gir1.2-gtk-3.0",
+ "libgirepository-1.0-1",
+ # Dependencies that GTK looks for at runtime
+ "libcanberra-gtk3-module",
+ # Needed to provide WebKit2 at runtime
+ # Note: Debian 11 and Ubuntu 20.04 require gir1.2-webkit2-4.0 instead
+ # "gir1.2-webkit2-4.1",
+]
+
+[tool.briefcase.app.fedordpi.linux.system.rhel]
+system_requires = [
+ # Needed to compile pycairo wheel
+ "cairo-gobject-devel",
+ # Needed to compile PyGObject wheel
+ "gobject-introspection-devel",
+]
+
+system_runtime_requires = [
+ # Needed to support Python bindings to GTK
+ "gobject-introspection",
+ # Needed to provide GTK
+ "gtk3",
+ # Dependencies that GTK looks for at runtime
+ "libcanberra-gtk3",
+ # Needed to provide WebKit2 at runtime
+ # "webkit2gtk3",
+]
+
+[tool.briefcase.app.fedordpi.linux.system.suse]
+system_requires = [
+ # Needed to compile pycairo wheel
+ "cairo-devel",
+ # Needed to compile PyGObject wheel
+ "gobject-introspection-devel",
+]
+
+system_runtime_requires = [
+ # Needed to provide GTK
+ "gtk3",
+ # Needed to support Python bindings to GTK
+ "gobject-introspection", "typelib(Gtk) = 3.0",
+ # Dependencies that GTK looks for at runtime
+ "libcanberra-gtk3-module",
+ # Needed to provide WebKit2 at runtime
+ # "libwebkit2gtk3", "typelib(WebKit2)",
+]
+
+[tool.briefcase.app.fedordpi.linux.system.arch]
+system_requires = [
+ # Needed to compile pycairo wheel
+ "cairo",
+ # Needed to compile PyGObject wheel
+ "gobject-introspection",
+ # Runtime dependencies that need to exist so that the
+ # Arch package passes final validation.
+ # Needed to provide GTK
+ "gtk3",
+ # Dependencies that GTK looks for at runtime
+ "libcanberra",
+ # Needed to provide WebKit2
+ # "webkit2gtk",
+]
+
+system_runtime_requires = [
+ # Needed to provide GTK
+ "gtk3",
+ # Needed to provide PyGObject bindings
+ "gobject-introspection-runtime",
+ # Dependencies that GTK looks for at runtime
+ "libcanberra",
+ # Needed to provide WebKit2 at runtime
+ # "webkit2gtk",
+]
+
+[tool.briefcase.app.fedordpi.linux.appimage]
+manylinux = "manylinux_2_28"
+
+system_requires = [
+ # Needed to compile pycairo wheel
+ "cairo-gobject-devel",
+ # Needed to compile PyGObject wheel
+ "gobject-introspection-devel",
+ # Needed to provide GTK
+ "gtk3-devel",
+ # Dependencies that GTK looks for at runtime, that need to be
+ # in the build environment to be picked up by linuxdeploy
+ "libcanberra-gtk3",
+ "PackageKit-gtk3-module",
+ "gvfs-client",
+]
+
+linuxdeploy_plugins = [
+ "DEPLOY_GTK_VERSION=3 gtk",
+]
+
+[tool.briefcase.app.fedordpi.linux.flatpak]
+flatpak_runtime = "org.gnome.Platform"
+flatpak_runtime_version = "47"
+flatpak_sdk = "org.gnome.Sdk"
+
+[tool.briefcase.app.fedordpi.windows]
+requires = [
+ "toga-winforms~=0.4.7",
+]
+
+# Mobile deployments
+[tool.briefcase.app.fedordpi.iOS]
+requires = [
+ "toga-iOS~=0.4.7",
+ "std-nslog~=1.0.3",
+]
+
+[tool.briefcase.app.fedordpi.android]
+requires = [
+ "toga-android~=0.4.7",
+]
+
+base_theme = "Theme.MaterialComponents.Light.DarkActionBar"
+
+build_gradle_dependencies = [
+ "com.google.android.material:material:1.12.0",
+ # Needed for DetailedList
+ # "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0",
+ # Needed for MapView
+ # "org.osmdroid:osmdroid-android:6.1.20",
+]
+
+# Web deployments
+[tool.briefcase.app.fedordpi.web]
+requires = [
+ "toga-web~=0.4.7",
+]
+style_framework = "Shoelace v2.3"
+
--- /dev/null
+from fedordpi.app import main
+
+if __name__ == "__main__":
+ main().main_loop()
--- /dev/null
+"""
+FedorDPI
+"""
+
+import toga
+from toga.style import Pack
+from toga.style.pack import COLUMN, ROW
+import random
+import asyncio
+import sys
+
+
+class FedorDPI(toga.App):
+ BLOCKED = [b'youtube.com', b'youtu.be', b'yt.be', b'googlevideo.com', b'ytimg.com', b'ggpht.com', b'gvt1.com', b'youtube-nocookie.com', b'youtube-ui.l.google.com', b'youtubeembeddedplayer.googleapis.com', b'youtube.googleapis.com', b'youtubei.googleapis.com', b'yt-video-upload.l.google.com', b'wide-youtube.l.google.com']
+ TASKS = []
+
+ async def main(self, host, port):
+
+ server = await asyncio.start_server(self.new_conn, host, port)
+ await server.serve_forever()
+
+
+ async def pipe(self, reader, writer):
+
+ while not reader.at_eof() and not writer.is_closing():
+ try:
+ writer.write(await reader.read(1500))
+ await writer.drain()
+ except:
+ break
+
+ writer.close()
+
+
+ async def new_conn(self, local_reader, local_writer):
+
+ http_data = await local_reader.read(1500)
+
+ try:
+ type, target = http_data.split(b"\r\n")[0].split(b" ")[0:2]
+ host, port = target.split(b":")
+ except:
+ local_writer.close()
+ return
+
+ if (type != b"CONNECT"):
+ local_writer.close()
+ return
+
+ local_writer.write(b'HTTP/1.1 200 OK\n\n')
+ await local_writer.drain()
+
+ try:
+ remote_reader, remote_writer = await asyncio.open_connection(host, port)
+ except:
+ local_writer.close()
+ return
+
+ if (port == b'443'):
+ await self.fragemtn_data(local_reader, remote_writer)
+
+ self.TASKS.append(asyncio.create_task(self.pipe(local_reader, remote_writer)))
+ self.TASKS.append(asyncio.create_task(self.pipe(remote_reader, local_writer)))
+
+
+ async def fragemtn_data(self, local_reader, remote_writer):
+
+ head = await local_reader.read(5)
+ data = await local_reader.read(1500)
+ parts = []
+
+ if all([data.find(site) == -1 for site in self.BLOCKED]):
+ remote_writer.write(head + data)
+ await remote_writer.drain()
+
+ return
+
+ while data:
+ part_len = random.randint(1, len(data))
+ parts.append(bytes.fromhex("1603") + bytes([random.randint(0, 255)]) + int(
+ part_len).to_bytes(2, byteorder='big') + data[0:part_len])
+
+ data = data[part_len:]
+
+ remote_writer.write(b''.join(parts))
+ await remote_writer.drain()
+
+
+ def startup(self):
+ main_box = toga.Box(style=Pack(direction=COLUMN))
+
+ button1 = toga.Button(
+ "Start proxy server",
+ on_press=self.start_proxy,
+ style=Pack(padding=50),
+ )
+
+ button2 = toga.Button(
+ "Stop proxy server and quit",
+ on_press=self.quit,
+ style=Pack(padding=50),
+ )
+
+
+ main_box.add(button1, button2)
+
+ self.main_window = toga.MainWindow(title=self.formal_name)
+ self.main_window.content = main_box
+ self.main_window.show()
+
+ async def start_proxy(self, widget):
+ host = '127.0.0.1'
+ port = 8881
+ print(f'proxy: {host}:{str(port)}')
+ await self.main(host=host, port=port)
+
+ def quit(self, widget):
+ sys.exit()
+
+def main():
+ return FedorDPI()
--- /dev/null
+Put any application resources (e.g., icons and resources) here;
+they can be referenced in code as "resources/filename".