linux-browser 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: linux-browser
3
+ Version: 0.1.0
4
+ Summary: A small Chromium-powered graphical web browser for Linux
5
+ Author: linux-browser contributors
6
+ License: MIT
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: PySide6>=6.6
10
+ Requires-Dist: PySide6-WebEngine>=6.6
11
+
12
+ # Linux Browser
13
+
14
+ A small graphical browser for Linux, packaged as a normal Python application. It uses Qt WebEngine, which embeds Chromium, so pages are rendered with their real HTML, CSS, JavaScript, images, and network behavior rather than being converted to terminal text.
15
+
16
+ ## Debian 12
17
+
18
+ Install a display server (a desktop session is fine) and the runtime libraries used by Qt:
19
+
20
+ ```bash
21
+ sudo apt update
22
+ sudo apt install libegl1 libgl1 libnss3 libxkbcommon-x11-0 libxcb-cursor0 \
23
+ libxcomposite1 libxdamage1 libxrandr2 libasound2 xdg-utils
24
+ ```
25
+
26
+ The PyPI wheels provide the Qt and Chromium components. A working graphical session and graphics driver are still required to show the window. On a headless machine, run it inside a desktop container or an X server such as Xvfb.
27
+
28
+ ## Install and run
29
+
30
+ ```bash
31
+ python3 -m venv .venv
32
+ .venv/bin/python -m pip install linux-browser
33
+ .venv/bin/linux-browser
34
+ ```
35
+
36
+ Open a specific page directly:
37
+
38
+ ```bash
39
+ linux-browser https://example.com
40
+ ```
41
+
42
+ The address bar accepts URLs and search terms. Back, forward, reload, and common keyboard shortcuts are available in the toolbar.
43
+
44
+ ## Development
45
+
46
+ ```bash
47
+ python3 -m venv .venv
48
+ .venv/bin/python -m pip install -e . pytest build
49
+ .venv/bin/python -m pytest
50
+ ```
51
+
52
+ The WebEngine test loads an in-memory page and checks that CSS and JavaScript execute. It is skipped when PySide6 is not installed, which keeps package metadata checks usable in minimal build environments.
53
+
54
+ ## Build and publish
55
+
56
+ ```bash
57
+ .venv/bin/python -m build
58
+ .venv/bin/python -m pip install twine
59
+ .venv/bin/twine check dist/*
60
+ .venv/bin/twine upload dist/*
61
+ ```
62
+
63
+ Publishing requires a PyPI account and credentials configured for `twine`.
@@ -0,0 +1,52 @@
1
+ # Linux Browser
2
+
3
+ A small graphical browser for Linux, packaged as a normal Python application. It uses Qt WebEngine, which embeds Chromium, so pages are rendered with their real HTML, CSS, JavaScript, images, and network behavior rather than being converted to terminal text.
4
+
5
+ ## Debian 12
6
+
7
+ Install a display server (a desktop session is fine) and the runtime libraries used by Qt:
8
+
9
+ ```bash
10
+ sudo apt update
11
+ sudo apt install libegl1 libgl1 libnss3 libxkbcommon-x11-0 libxcb-cursor0 \
12
+ libxcomposite1 libxdamage1 libxrandr2 libasound2 xdg-utils
13
+ ```
14
+
15
+ The PyPI wheels provide the Qt and Chromium components. A working graphical session and graphics driver are still required to show the window. On a headless machine, run it inside a desktop container or an X server such as Xvfb.
16
+
17
+ ## Install and run
18
+
19
+ ```bash
20
+ python3 -m venv .venv
21
+ .venv/bin/python -m pip install linux-browser
22
+ .venv/bin/linux-browser
23
+ ```
24
+
25
+ Open a specific page directly:
26
+
27
+ ```bash
28
+ linux-browser https://example.com
29
+ ```
30
+
31
+ The address bar accepts URLs and search terms. Back, forward, reload, and common keyboard shortcuts are available in the toolbar.
32
+
33
+ ## Development
34
+
35
+ ```bash
36
+ python3 -m venv .venv
37
+ .venv/bin/python -m pip install -e . pytest build
38
+ .venv/bin/python -m pytest
39
+ ```
40
+
41
+ The WebEngine test loads an in-memory page and checks that CSS and JavaScript execute. It is skipped when PySide6 is not installed, which keeps package metadata checks usable in minimal build environments.
42
+
43
+ ## Build and publish
44
+
45
+ ```bash
46
+ .venv/bin/python -m build
47
+ .venv/bin/python -m pip install twine
48
+ .venv/bin/twine check dist/*
49
+ .venv/bin/twine upload dist/*
50
+ ```
51
+
52
+ Publishing requires a PyPI account and credentials configured for `twine`.
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "linux-browser"
7
+ version = "0.1.0"
8
+ description = "A small Chromium-powered graphical web browser for Linux"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "linux-browser contributors" }]
13
+ dependencies = [
14
+ "PySide6>=6.6",
15
+ "PySide6-WebEngine>=6.6",
16
+ ]
17
+
18
+ [project.scripts]
19
+ linux-browser = "linux_browser.app:main"
20
+
21
+ [tool.setuptools]
22
+ package-dir = {"" = "src"}
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["src"]
26
+
27
+ [tool.pytest.ini_options]
28
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """A lightweight graphical browser for Linux."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,81 @@
1
+ """Graphical browser application powered by Qt WebEngine."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from urllib.parse import quote
7
+
8
+ from PySide6.QtCore import QUrl
9
+ from PySide6.QtGui import QAction, QKeySequence
10
+ from PySide6.QtWidgets import QApplication, QLineEdit, QMainWindow, QToolBar
11
+ from PySide6.QtWebEngineWidgets import QWebEngineView
12
+
13
+
14
+ class BrowserWindow(QMainWindow):
15
+ """A minimal browser window with real Chromium page rendering."""
16
+
17
+ def __init__(self, start_url: str = "https://duckduckgo.com") -> None:
18
+ super().__init__()
19
+ self.setWindowTitle("Linux Browser")
20
+ self.resize(1280, 800)
21
+
22
+ toolbar = QToolBar("Navigation")
23
+ toolbar.setMovable(False)
24
+ self.addToolBar(toolbar)
25
+
26
+ back_action = QAction("Back", self)
27
+ back_action.setShortcut(QKeySequence("Alt+Left"))
28
+ back_action.triggered.connect(lambda: self.web_view.back())
29
+ toolbar.addAction(back_action)
30
+
31
+ forward_action = QAction("Forward", self)
32
+ forward_action.setShortcut(QKeySequence("Alt+Right"))
33
+ forward_action.triggered.connect(lambda: self.web_view.forward())
34
+ toolbar.addAction(forward_action)
35
+
36
+ reload_action = QAction("Reload", self)
37
+ reload_action.setShortcut(QKeySequence("Ctrl+R"))
38
+ reload_action.triggered.connect(lambda: self.web_view.reload())
39
+ toolbar.addAction(reload_action)
40
+
41
+ self.address_bar = QLineEdit()
42
+ self.address_bar.setPlaceholderText("Enter a web address or search term")
43
+ self.address_bar.setClearButtonEnabled(True)
44
+ self.address_bar.returnPressed.connect(self.navigate)
45
+ toolbar.addWidget(self.address_bar)
46
+
47
+ self.web_view = QWebEngineView()
48
+ self.web_view.urlChanged.connect(self.update_address)
49
+ self.web_view.titleChanged.connect(self.update_title)
50
+ self.setCentralWidget(self.web_view)
51
+ self.navigate(start_url)
52
+
53
+ def navigate(self, text: str | None = None) -> None:
54
+ address = (text if text is not None else self.address_bar.text()).strip()
55
+ if not address:
56
+ return
57
+ if " " in address or "." not in address and not address.startswith(("http://", "https://", "file:", "data:")):
58
+ address = f"https://duckduckgo.com/?q={quote(address)}"
59
+ elif not address.startswith(("http://", "https://", "file:", "data:")):
60
+ address = f"https://{address}"
61
+ self.web_view.setUrl(QUrl(address))
62
+
63
+ def update_address(self, url: QUrl) -> None:
64
+ self.address_bar.setText(url.toString())
65
+ self.address_bar.setCursorPosition(0)
66
+
67
+ def update_title(self, title: str) -> None:
68
+ self.setWindowTitle(f"{title} - Linux Browser" if title else "Linux Browser")
69
+
70
+
71
+ def main(argv: list[str] | None = None) -> int:
72
+ args = sys.argv[1:] if argv is None else argv
73
+ app = QApplication([sys.argv[0], *args])
74
+ app.setApplicationName("Linux Browser")
75
+ window = BrowserWindow(args[0] if args else "https://duckduckgo.com")
76
+ window.show()
77
+ return app.exec()
78
+
79
+
80
+ if __name__ == "__main__":
81
+ raise SystemExit(main())
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: linux-browser
3
+ Version: 0.1.0
4
+ Summary: A small Chromium-powered graphical web browser for Linux
5
+ Author: linux-browser contributors
6
+ License: MIT
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: PySide6>=6.6
10
+ Requires-Dist: PySide6-WebEngine>=6.6
11
+
12
+ # Linux Browser
13
+
14
+ A small graphical browser for Linux, packaged as a normal Python application. It uses Qt WebEngine, which embeds Chromium, so pages are rendered with their real HTML, CSS, JavaScript, images, and network behavior rather than being converted to terminal text.
15
+
16
+ ## Debian 12
17
+
18
+ Install a display server (a desktop session is fine) and the runtime libraries used by Qt:
19
+
20
+ ```bash
21
+ sudo apt update
22
+ sudo apt install libegl1 libgl1 libnss3 libxkbcommon-x11-0 libxcb-cursor0 \
23
+ libxcomposite1 libxdamage1 libxrandr2 libasound2 xdg-utils
24
+ ```
25
+
26
+ The PyPI wheels provide the Qt and Chromium components. A working graphical session and graphics driver are still required to show the window. On a headless machine, run it inside a desktop container or an X server such as Xvfb.
27
+
28
+ ## Install and run
29
+
30
+ ```bash
31
+ python3 -m venv .venv
32
+ .venv/bin/python -m pip install linux-browser
33
+ .venv/bin/linux-browser
34
+ ```
35
+
36
+ Open a specific page directly:
37
+
38
+ ```bash
39
+ linux-browser https://example.com
40
+ ```
41
+
42
+ The address bar accepts URLs and search terms. Back, forward, reload, and common keyboard shortcuts are available in the toolbar.
43
+
44
+ ## Development
45
+
46
+ ```bash
47
+ python3 -m venv .venv
48
+ .venv/bin/python -m pip install -e . pytest build
49
+ .venv/bin/python -m pytest
50
+ ```
51
+
52
+ The WebEngine test loads an in-memory page and checks that CSS and JavaScript execute. It is skipped when PySide6 is not installed, which keeps package metadata checks usable in minimal build environments.
53
+
54
+ ## Build and publish
55
+
56
+ ```bash
57
+ .venv/bin/python -m build
58
+ .venv/bin/python -m pip install twine
59
+ .venv/bin/twine check dist/*
60
+ .venv/bin/twine upload dist/*
61
+ ```
62
+
63
+ Publishing requires a PyPI account and credentials configured for `twine`.
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/linux_browser/__init__.py
4
+ src/linux_browser/app.py
5
+ src/linux_browser.egg-info/PKG-INFO
6
+ src/linux_browser.egg-info/SOURCES.txt
7
+ src/linux_browser.egg-info/dependency_links.txt
8
+ src/linux_browser.egg-info/entry_points.txt
9
+ src/linux_browser.egg-info/requires.txt
10
+ src/linux_browser.egg-info/top_level.txt
11
+ tests/test_package.py
12
+ tests/test_webengine.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ linux-browser = linux_browser.app:main
@@ -0,0 +1,2 @@
1
+ PySide6>=6.6
2
+ PySide6-WebEngine>=6.6
@@ -0,0 +1 @@
1
+ linux_browser
@@ -0,0 +1,8 @@
1
+ import unittest
2
+
3
+ from linux_browser import __version__
4
+
5
+
6
+ class PackageTest(unittest.TestCase):
7
+ def test_package_has_version(self) -> None:
8
+ self.assertEqual(__version__, "0.1.0")
@@ -0,0 +1,46 @@
1
+ import sys
2
+ import unittest
3
+
4
+
5
+ try:
6
+ from PySide6.QtCore import QEventLoop, QTimer
7
+ from PySide6.QtWidgets import QApplication
8
+ from PySide6.QtWebEngineWidgets import QWebEngineView
9
+ except ImportError:
10
+ QWebEngineView = None
11
+
12
+
13
+ @unittest.skipUnless(QWebEngineView, "PySide6-WebEngine is not installed")
14
+ class WebEngineSmokeTest(unittest.TestCase):
15
+ @classmethod
16
+ def setUpClass(cls) -> None:
17
+ cls.application = QApplication.instance() or QApplication(sys.argv)
18
+
19
+ def test_renders_css_and_runs_javascript(self) -> None:
20
+ view = QWebEngineView()
21
+ loaded = []
22
+ view.loadFinished.connect(loaded.append)
23
+ view.setHtml(
24
+ "<html><head><style>body { color: rgb(1, 2, 3); }</style></head>"
25
+ "<body><main id='content'>initial</main>"
26
+ "<script>document.title = 'Rendered';"
27
+ "document.querySelector('#content').textContent = 'JavaScript ran';</script>"
28
+ "</body></html>"
29
+ )
30
+
31
+ loop = QEventLoop()
32
+ view.loadFinished.connect(loop.quit)
33
+ QTimer.singleShot(5000, loop.quit)
34
+ loop.exec()
35
+ self.assertTrue(loaded and loaded[-1])
36
+
37
+ result = []
38
+ view.page().runJavaScript(
39
+ "[document.title, document.querySelector('#content').textContent, "
40
+ "getComputedStyle(document.body).color]",
41
+ result.append,
42
+ )
43
+ QTimer.singleShot(1000, loop.quit)
44
+ loop.exec()
45
+ self.assertEqual(result, [["Rendered", "JavaScript ran", "rgb(1, 2, 3)"]])
46
+ view.deleteLater()