fiqhboard 0.0.1__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,99 @@
1
+ # One release, everywhere at once. A tag v* → check → build → PyPI → GitHub Release.
2
+ # Nothing is published unless the check and the build succeed, so GitHub and PyPI never differ.
3
+ # The file name (publish.yml) and the "pypi" environment are what PyPI's trusted publishing is tied to: keep them.
4
+ # (The desktop applications — portable exe, AppImage, macOS — join this pipeline in P1.)
5
+ name: Release
6
+
7
+ on:
8
+ push:
9
+ tags:
10
+ - "v*"
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ check:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v7
20
+ - uses: actions/setup-python@v7
21
+ with:
22
+ python-version: "3.12"
23
+ - name: One version everywhere, and its CHANGELOG section
24
+ run: |
25
+ python - "${GITHUB_REF_NAME}" <<'EOF'
26
+ import json, re, sys, pathlib
27
+ tag = sys.argv[1]
28
+ want = tag[1:] if tag.startswith("v") else tag
29
+ found = {
30
+ "src/fiqhboard/__init__.py": re.search(r'__version__ = "([^"]+)"', pathlib.Path("src/fiqhboard/__init__.py").read_text()).group(1),
31
+ "js/package.json": json.loads(pathlib.Path("js/package.json").read_text())["version"],
32
+ "js/index.js": re.search(r'export const version = "([^"]+)"', pathlib.Path("js/index.js").read_text()).group(1),
33
+ }
34
+ bad = {k: v for k, v in found.items() if v != want}
35
+ if bad:
36
+ sys.exit(f"tag {tag} but: {bad}")
37
+ text = pathlib.Path("CHANGELOG.md").read_text(encoding="utf-8")
38
+ m = re.search(r"^## \[" + re.escape(want) + r"\][^\n]*\n(.*?)(?=^## \[|\Z)", text, re.S | re.M)
39
+ if not m:
40
+ sys.exit(f"CHANGELOG.md has no section ## [{want}]")
41
+ pathlib.Path("release-notes.md").write_text(m.group(1).strip() + "\n", encoding="utf-8")
42
+ print(f"one version everywhere: {want}; CHANGELOG.md has the {want} section")
43
+ EOF
44
+ - uses: actions/upload-artifact@v7
45
+ with:
46
+ name: release-notes
47
+ path: release-notes.md
48
+
49
+ python:
50
+ needs: check
51
+ runs-on: ubuntu-latest
52
+ steps:
53
+ - uses: actions/checkout@v7
54
+ - uses: actions/setup-python@v7
55
+ with:
56
+ python-version: "3.12"
57
+ - run: python -m pip install --upgrade build twine
58
+ - run: python -m build
59
+ - run: python -m twine check dist/*
60
+ - uses: actions/upload-artifact@v7
61
+ with:
62
+ name: dist
63
+ path: dist/
64
+
65
+ publish:
66
+ needs: python
67
+ runs-on: ubuntu-latest
68
+ environment: pypi
69
+ permissions:
70
+ id-token: write
71
+ steps:
72
+ - uses: actions/download-artifact@v8
73
+ with:
74
+ name: dist
75
+ path: dist/
76
+ - uses: pypa/gh-action-pypi-publish@release/v1
77
+
78
+ github-release:
79
+ needs: publish
80
+ runs-on: ubuntu-latest
81
+ permissions:
82
+ contents: write
83
+ steps:
84
+ - uses: actions/download-artifact@v8
85
+ with:
86
+ path: artifacts/
87
+ - name: Gather the files and their checksums
88
+ run: |
89
+ mkdir release
90
+ find artifacts -type f \( -name '*.whl' -o -name '*.tar.gz' \) -exec cp {} release/ \;
91
+ cd release && sha256sum * > SHA256SUMS.txt && cat SHA256SUMS.txt
92
+ - name: Create the GitHub Release
93
+ env:
94
+ GH_TOKEN: ${{ github.token }}
95
+ run: |
96
+ gh release create "${GITHUB_REF_NAME}" release/* \
97
+ --repo "${GITHUB_REPOSITORY}" \
98
+ --title "fiqhboard ${GITHUB_REF_NAME#v}" \
99
+ --notes-file artifacts/release-notes/release-notes.md
@@ -0,0 +1,31 @@
1
+ # Local-only project notes — never pushed
2
+ FiqhBoard_Handoff.md
3
+ FIQHBOARD_TODO.md
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *.egg-info/
9
+ build/
10
+ dist/
11
+ .venv/
12
+ venv/
13
+
14
+ # Data built locally (shipped separately, never committed raw)
15
+ *.sqlite
16
+ *.sqlite3
17
+ *.db
18
+
19
+ # Node / npm
20
+ node_modules/
21
+ *.tgz
22
+ package-lock.json
23
+
24
+ # Editors / OS
25
+ .vscode/
26
+ .idea/
27
+ .DS_Store
28
+ Thumbs.db
29
+
30
+ # desktop builds
31
+ dist-app/
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ Every release of fiqhboard, newest first. The same version number is published on PyPI, npm and GitHub.
4
+
5
+ ## [0.0.1] — 2026-10-19
6
+
7
+ The first release: it reserves the name.
8
+
9
+ - The `fiqhboard` package with the commands `fiqhboard` and `fqb` (no arguments: the window; with arguments: the command line) and `fiqhboard-gui` (the window, without a console on Windows).
10
+ - A welcome window that says what fiqhboard is and what comes next.
11
+ - `fqb -V` / `--version` / `version`, and `fqb -h`.
12
+ - The README: why fiqhboard, how a comparison is built (one question per row, each school in its own terms, nothing without a source), and the roadmap.
13
+ - The npm package `fiqhboard` 0.0.1, a placeholder that reserves the name.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bayram Kotan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.5
2
+ Name: fiqhboard
3
+ Version: 0.0.1
4
+ Summary: Comparative fiqh of the four Sunni schools: side-by-side matrices, every ruling with its source and evidence, a glossary and decision diagrams
5
+ Project-URL: Homepage, https://github.com/bayramkotan/fiqhboard
6
+ Project-URL: Repository, https://github.com/bayramkotan/fiqhboard
7
+ Project-URL: Issues, https://github.com/bayramkotan/fiqhboard/issues
8
+ Author: Bayram Kotan
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: fiqh,hanafi,hanbali,islamic law,islamic studies,madhhab,maliki,shafii
12
+ Classifier: Development Status :: 1 - Planning
13
+ Classifier: Environment :: X11 Applications :: Qt
14
+ Classifier: Intended Audience :: Education
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Natural Language :: Arabic
17
+ Classifier: Natural Language :: English
18
+ Classifier: Natural Language :: Turkish
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Topic :: Education
22
+ Classifier: Topic :: Religion
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: pyside6>=6.6
25
+ Description-Content-Type: text/markdown
26
+
27
+ <h1 align="center">⚖️ fiqhboard &nbsp;<sub>الفقه المقارن</sub></h1>
28
+
29
+ <p align="center">
30
+ <strong>Comparative fiqh of the four Sunni schools</strong><br>
31
+ <sub>Hanafi, Maliki, Shafi'i and Hanbali side by side — every ruling in its school's own words, with its source and its evidence</sub>
32
+ </p>
33
+
34
+ <p align="center">
35
+ <a href="https://pypi.org/project/fiqhboard/">
36
+ <img src="https://img.shields.io/badge/PyPI-v0.0.1-1D4777?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
37
+ </a>
38
+ <img src="https://img.shields.io/badge/Python-3.10%2B-A47E24?style=for-the-badge&logo=python&logoColor=white" alt="Python">
39
+ <img src="https://img.shields.io/badge/Platform-Windows%20%7C%20Linux%20%7C%20macOS-5B6878?style=for-the-badge" alt="Platform">
40
+ <a href="https://www.npmjs.com/package/fiqhboard">
41
+ <img src="https://img.shields.io/badge/npm-v0.0.1-14304F?style=for-the-badge&logo=npm" alt="npm">
42
+ </a>
43
+ <img src="https://img.shields.io/badge/License-MIT-D6B25E?style=for-the-badge" alt="License">
44
+ </p>
45
+
46
+ <p align="center">
47
+ <a href="#-why-fiqhboard">Why</a> •
48
+ <a href="#-how-a-comparison-is-built">How</a> •
49
+ <a href="#-install">Install</a> •
50
+ <a href="#%EF%B8%8F-command-line">Command line</a> •
51
+ <a href="#-roadmap">Roadmap</a> •
52
+ <a href="#-license">License</a>
53
+ </p>
54
+
55
+ > **Planning (0.0.1).** This first release reserves the name and opens a welcome window. The comparison matrices, the evidence drawer, the glossary and the diagrams follow, release by release.
56
+
57
+ ---
58
+
59
+ ## 💡 Why fiqhboard
60
+
61
+ Comparing the four schools usually means reading four books, each in its own vocabulary. fiqhboard puts them in one table — without flattening them into one vocabulary:
62
+
63
+ - **One question per row.** A row does not ask "is it fard?"; it asks something every school can answer, such as *"Is wudu valid without an intention?"* The colours and the agree/disagree filter come from that answer.
64
+ - **Each school in its own terms.** The Hanafi *wajib* is not the Shafi'i *wajib*; a Hanbali *shart* is not a *fard*. Every cell shows the school's own term, in Arabic and in transliteration, and no term is mapped onto another school's.
65
+ - **The relied-upon view, and the others.** A cell shows the school's relied-upon position (*mu'tamad*, *mufta bihi*, *mashhur*, *asahh*) and says so; other views within the school stay one click away.
66
+ - **Nothing without a source.** Every position names the book, volume and page it comes from; every piece of evidence — verse, hadith, principle — is cited.
67
+ - **Agreement of the four is not ijma'.** When the four schools agree, fiqhboard says *the four schools agree*. Ijma' is shown only where a source claims it, attributed to that source.
68
+ - **For learning, not fatwa.** The decision diagrams teach how each school reasons; for your own situation, ask a qualified scholar.
69
+
70
+ ## 🧩 How a comparison is built
71
+
72
+ ```text
73
+ topic wudu › its obligatory acts
74
+ question Is wudu valid without an intention?
75
+ answers valid · invalid
76
+ ┌──────────────┬──────────────┬──────────────┬──────────────┐
77
+ │ Hanafi │ Maliki │ Shafi'i │ Hanbali │
78
+ ├──────────────┼──────────────┼──────────────┼──────────────┤
79
+ answer │ valid │ invalid │ invalid │ invalid │
80
+ own term │ sunna سنة │ fard فرض │ fard فرض │ shart شرط │
81
+ source │ book, vol, p │ book, vol, p │ book, vol, p │ book, vol, p │
82
+ └──────────────┴──────────────┴──────────────┴──────────────┘
83
+ evidence hadith bukhari:1 · Qur'an 5:6
84
+ ```
85
+
86
+ The data lives as JSON in a separate repository, is checked by a validator (no source, no publication), and is read into SQLite so the application works offline. Hadith evidence uses the same references as [isnady](https://github.com/bayramkotan/isnady) and its data.
87
+
88
+ ## 📦 Install
89
+
90
+ ```bash
91
+ pip install fiqhboard
92
+ ```
93
+
94
+ On Linux distributions that protect the system Python (Arch, CachyOS, Debian, Ubuntu), use `pipx install fiqhboard`, a virtual environment, or add `--break-system-packages`.
95
+
96
+ Portable applications (Windows exe, Linux AppImage, macOS) join the GitHub Releases in a coming version.
97
+
98
+ ## ⌨️ Command line
99
+
100
+ | Short | Full | What it does |
101
+ |---|---|---|
102
+ | `fqb` | `fiqhboard` | Opens the window |
103
+ | `fqb -V` | `fiqhboard --version` | Prints the version (`-v`, `-V`, `--version`, `version`) |
104
+ | `fqb -h` | `fiqhboard -h` | Help |
105
+ | | `fiqhboard-gui` | The window, without a console on Windows |
106
+
107
+ The command line never loads Qt, so it runs over SSH and in scripts. Every feature of the window will also be on the command line.
108
+
109
+ ## 🗺️ Roadmap
110
+
111
+ - [x] **0.0.1** — the name, the package, a welcome window
112
+ - [ ] The application skeleton: settings, themes, interface languages (English, Turkish, Arabic first), portable applications
113
+ - [ ] The data format and its validator; the data repository
114
+ - [ ] The first topic end to end: the obligatory acts of wudu, every cell sourced
115
+ - [ ] The comparison matrix and the evidence drawer
116
+ - [ ] The glossary, with a definition under every term
117
+ - [ ] Decision diagrams, one per school (the prostration of forgetfulness first)
118
+ - [ ] Export to PDF, PNG and Markdown
119
+ - [ ] Purity (*taharah*) and prayer (*salat*) in full
120
+
121
+ ## 📄 License
122
+
123
+ The application is released under the [MIT License](LICENSE). Quoted works keep their own licences; modern works under copyright are cited, never reproduced.
@@ -0,0 +1,97 @@
1
+ <h1 align="center">⚖️ fiqhboard &nbsp;<sub>الفقه المقارن</sub></h1>
2
+
3
+ <p align="center">
4
+ <strong>Comparative fiqh of the four Sunni schools</strong><br>
5
+ <sub>Hanafi, Maliki, Shafi'i and Hanbali side by side — every ruling in its school's own words, with its source and its evidence</sub>
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://pypi.org/project/fiqhboard/">
10
+ <img src="https://img.shields.io/badge/PyPI-v0.0.1-1D4777?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
11
+ </a>
12
+ <img src="https://img.shields.io/badge/Python-3.10%2B-A47E24?style=for-the-badge&logo=python&logoColor=white" alt="Python">
13
+ <img src="https://img.shields.io/badge/Platform-Windows%20%7C%20Linux%20%7C%20macOS-5B6878?style=for-the-badge" alt="Platform">
14
+ <a href="https://www.npmjs.com/package/fiqhboard">
15
+ <img src="https://img.shields.io/badge/npm-v0.0.1-14304F?style=for-the-badge&logo=npm" alt="npm">
16
+ </a>
17
+ <img src="https://img.shields.io/badge/License-MIT-D6B25E?style=for-the-badge" alt="License">
18
+ </p>
19
+
20
+ <p align="center">
21
+ <a href="#-why-fiqhboard">Why</a> •
22
+ <a href="#-how-a-comparison-is-built">How</a> •
23
+ <a href="#-install">Install</a> •
24
+ <a href="#%EF%B8%8F-command-line">Command line</a> •
25
+ <a href="#-roadmap">Roadmap</a> •
26
+ <a href="#-license">License</a>
27
+ </p>
28
+
29
+ > **Planning (0.0.1).** This first release reserves the name and opens a welcome window. The comparison matrices, the evidence drawer, the glossary and the diagrams follow, release by release.
30
+
31
+ ---
32
+
33
+ ## 💡 Why fiqhboard
34
+
35
+ Comparing the four schools usually means reading four books, each in its own vocabulary. fiqhboard puts them in one table — without flattening them into one vocabulary:
36
+
37
+ - **One question per row.** A row does not ask "is it fard?"; it asks something every school can answer, such as *"Is wudu valid without an intention?"* The colours and the agree/disagree filter come from that answer.
38
+ - **Each school in its own terms.** The Hanafi *wajib* is not the Shafi'i *wajib*; a Hanbali *shart* is not a *fard*. Every cell shows the school's own term, in Arabic and in transliteration, and no term is mapped onto another school's.
39
+ - **The relied-upon view, and the others.** A cell shows the school's relied-upon position (*mu'tamad*, *mufta bihi*, *mashhur*, *asahh*) and says so; other views within the school stay one click away.
40
+ - **Nothing without a source.** Every position names the book, volume and page it comes from; every piece of evidence — verse, hadith, principle — is cited.
41
+ - **Agreement of the four is not ijma'.** When the four schools agree, fiqhboard says *the four schools agree*. Ijma' is shown only where a source claims it, attributed to that source.
42
+ - **For learning, not fatwa.** The decision diagrams teach how each school reasons; for your own situation, ask a qualified scholar.
43
+
44
+ ## 🧩 How a comparison is built
45
+
46
+ ```text
47
+ topic wudu › its obligatory acts
48
+ question Is wudu valid without an intention?
49
+ answers valid · invalid
50
+ ┌──────────────┬──────────────┬──────────────┬──────────────┐
51
+ │ Hanafi │ Maliki │ Shafi'i │ Hanbali │
52
+ ├──────────────┼──────────────┼──────────────┼──────────────┤
53
+ answer │ valid │ invalid │ invalid │ invalid │
54
+ own term │ sunna سنة │ fard فرض │ fard فرض │ shart شرط │
55
+ source │ book, vol, p │ book, vol, p │ book, vol, p │ book, vol, p │
56
+ └──────────────┴──────────────┴──────────────┴──────────────┘
57
+ evidence hadith bukhari:1 · Qur'an 5:6
58
+ ```
59
+
60
+ The data lives as JSON in a separate repository, is checked by a validator (no source, no publication), and is read into SQLite so the application works offline. Hadith evidence uses the same references as [isnady](https://github.com/bayramkotan/isnady) and its data.
61
+
62
+ ## 📦 Install
63
+
64
+ ```bash
65
+ pip install fiqhboard
66
+ ```
67
+
68
+ On Linux distributions that protect the system Python (Arch, CachyOS, Debian, Ubuntu), use `pipx install fiqhboard`, a virtual environment, or add `--break-system-packages`.
69
+
70
+ Portable applications (Windows exe, Linux AppImage, macOS) join the GitHub Releases in a coming version.
71
+
72
+ ## ⌨️ Command line
73
+
74
+ | Short | Full | What it does |
75
+ |---|---|---|
76
+ | `fqb` | `fiqhboard` | Opens the window |
77
+ | `fqb -V` | `fiqhboard --version` | Prints the version (`-v`, `-V`, `--version`, `version`) |
78
+ | `fqb -h` | `fiqhboard -h` | Help |
79
+ | | `fiqhboard-gui` | The window, without a console on Windows |
80
+
81
+ The command line never loads Qt, so it runs over SSH and in scripts. Every feature of the window will also be on the command line.
82
+
83
+ ## 🗺️ Roadmap
84
+
85
+ - [x] **0.0.1** — the name, the package, a welcome window
86
+ - [ ] The application skeleton: settings, themes, interface languages (English, Turkish, Arabic first), portable applications
87
+ - [ ] The data format and its validator; the data repository
88
+ - [ ] The first topic end to end: the obligatory acts of wudu, every cell sourced
89
+ - [ ] The comparison matrix and the evidence drawer
90
+ - [ ] The glossary, with a definition under every term
91
+ - [ ] Decision diagrams, one per school (the prostration of forgetfulness first)
92
+ - [ ] Export to PDF, PNG and Markdown
93
+ - [ ] Purity (*taharah*) and prayer (*salat*) in full
94
+
95
+ ## 📄 License
96
+
97
+ The application is released under the [MIT License](LICENSE). Quoted works keep their own licences; modern works under copyright are cited, never reproduced.
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "fiqhboard"
7
+ dynamic = ["version"]
8
+ description = "Comparative fiqh of the four Sunni schools: side-by-side matrices, every ruling with its source and evidence, a glossary and decision diagrams"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Bayram Kotan" }]
13
+ requires-python = ">=3.10"
14
+ dependencies = ["PySide6>=6.6"]
15
+
16
+ keywords = ["fiqh", "islamic law", "madhhab", "hanafi", "maliki", "shafii", "hanbali", "islamic studies"]
17
+ classifiers = [
18
+ "Development Status :: 1 - Planning",
19
+ "Environment :: X11 Applications :: Qt",
20
+ "Intended Audience :: Education",
21
+ "Intended Audience :: Science/Research",
22
+ "Natural Language :: English",
23
+ "Natural Language :: Arabic",
24
+ "Natural Language :: Turkish",
25
+ "Operating System :: OS Independent",
26
+ "Programming Language :: Python :: 3",
27
+ "Topic :: Education",
28
+ "Topic :: Religion",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/bayramkotan/fiqhboard"
33
+ Repository = "https://github.com/bayramkotan/fiqhboard"
34
+ Issues = "https://github.com/bayramkotan/fiqhboard/issues"
35
+
36
+ [project.scripts]
37
+ fiqhboard = "fiqhboard.main:main"
38
+ fqb = "fiqhboard.main:main"
39
+
40
+ [project.gui-scripts]
41
+ fiqhboard-gui = "fiqhboard.main:gui_main"
42
+
43
+ [tool.hatch.version]
44
+ path = "src/fiqhboard/__init__.py"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/fiqhboard"]
48
+
49
+ [tool.hatch.build.targets.sdist]
50
+ exclude = ["FiqhBoard_Handoff.md", "FIQHBOARD_TODO.md", "js/"]
@@ -0,0 +1,4 @@
1
+ """fiqhboard — comparative fiqh of the four Sunni schools."""
2
+
3
+ APP_NAME = "fiqhboard"
4
+ __version__ = "0.0.1"
@@ -0,0 +1,3 @@
1
+ from fiqhboard.main import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,67 @@
1
+ """The command line. It never imports Qt.
2
+
3
+ Every feature of the window will also be here (fiqhboard's rule: the window
4
+ and the command line give the same answer, both from fiqhboard.core).
5
+ """
6
+
7
+ import argparse
8
+ import os
9
+ import sys
10
+
11
+ from fiqhboard import APP_NAME, __version__
12
+
13
+ VERSION_WORDS = {"-v", "-V", "--version", "--v", "--V", "version"}
14
+
15
+
16
+ def _prog() -> str:
17
+ name = os.path.basename(sys.argv[0] or "") if sys.argv else ""
18
+ name = os.path.splitext(name)[0]
19
+ return name if name in ("fiqhboard", "fqb") else "fiqhboard"
20
+
21
+
22
+ def build_parser() -> argparse.ArgumentParser:
23
+ prog = _prog()
24
+ parser = argparse.ArgumentParser(
25
+ prog=prog,
26
+ description="fiqhboard: comparative fiqh of the four Sunni schools (Hanafi, Maliki, Shafi'i, Hanbali).",
27
+ epilog=(
28
+ "Without arguments the window opens.\n"
29
+ "\n"
30
+ "commands:\n"
31
+ f" {prog} version the version (also -v, -V, --version)\n"
32
+ "\n"
33
+ "This is the first release: it reserves the name. The comparison matrices,\n"
34
+ "the evidence drawer, the glossary and the diagrams follow."
35
+ ),
36
+ formatter_class=argparse.RawDescriptionHelpFormatter,
37
+ )
38
+ parser.add_argument("command", nargs="?", choices=["version"], help=argparse.SUPPRESS)
39
+ return parser
40
+
41
+
42
+ def _utf8_output() -> None:
43
+ """Windows writes redirected output in an old code page; Arabic would fail."""
44
+ for stream in (sys.stdout, sys.stderr):
45
+ try:
46
+ stream.reconfigure(encoding="utf-8", errors="replace")
47
+ except (AttributeError, ValueError):
48
+ pass
49
+
50
+
51
+ def main(argv=None) -> int:
52
+ _utf8_output()
53
+ argv = list(sys.argv[1:] if argv is None else argv)
54
+ if argv and argv[0] in VERSION_WORDS:
55
+ print(f"{APP_NAME} {__version__}")
56
+ return 0
57
+ parser = build_parser()
58
+ args = parser.parse_args(argv)
59
+ if args.command == "version":
60
+ print(f"{APP_NAME} {__version__}")
61
+ return 0
62
+ parser.print_help()
63
+ return 0
64
+
65
+
66
+ if __name__ == "__main__":
67
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ """The PySide6 window. Only this package imports Qt."""
@@ -0,0 +1,98 @@
1
+ """The main window.
2
+
3
+ The first release shows a single welcome page: only working pages are added to
4
+ the window (the matrix, the glossary and the diagrams arrive with their data).
5
+ """
6
+
7
+ from PySide6.QtCore import Qt
8
+ from PySide6.QtWidgets import (
9
+ QFrame,
10
+ QHBoxLayout,
11
+ QLabel,
12
+ QMainWindow,
13
+ QVBoxLayout,
14
+ QWidget,
15
+ )
16
+
17
+ from fiqhboard import APP_NAME, __version__
18
+
19
+ LAPIS = "#1D4777"
20
+ GOLD = "#A47E24"
21
+
22
+ SCHOOLS = [
23
+ ("Hanafi", "الحنفي"),
24
+ ("Maliki", "المالكي"),
25
+ ("Shafi'i", "الشافعي"),
26
+ ("Hanbali", "الحنبلي"),
27
+ ]
28
+
29
+ NEXT = [
30
+ "Side-by-side matrices: one question per row, the four schools in the columns",
31
+ "Every position in each school's own terms, with the book, volume and page it comes from",
32
+ "The evidence drawer: the verse, the hadith (from isnady-data) and the principle behind each ruling",
33
+ "A glossary of fiqh terms in English, Turkish and Arabic",
34
+ "Decision diagrams, one per school, for learning — not as a fatwa",
35
+ ]
36
+
37
+
38
+ class MainWindow(QMainWindow):
39
+ def __init__(self) -> None:
40
+ super().__init__()
41
+ self.setWindowTitle(f"{APP_NAME} {__version__}")
42
+ self.resize(960, 640)
43
+
44
+ page = QWidget()
45
+ outer = QVBoxLayout(page)
46
+ outer.setContentsMargins(48, 40, 48, 40)
47
+ outer.setSpacing(18)
48
+
49
+ title_row = QHBoxLayout()
50
+ title = QLabel(APP_NAME)
51
+ title.setStyleSheet(f"font-size: 34px; font-weight: 600; color: {LAPIS};")
52
+ arabic = QLabel("الفقه المقارن")
53
+ arabic.setStyleSheet(f"font-size: 28px; color: {GOLD};")
54
+ arabic.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignAbsolute | Qt.AlignmentFlag.AlignVCenter)
55
+ title_row.addWidget(title)
56
+ title_row.addStretch(1)
57
+ title_row.addWidget(arabic)
58
+ outer.addLayout(title_row)
59
+
60
+ line = QFrame()
61
+ line.setFixedHeight(2)
62
+ line.setStyleSheet(f"background: {GOLD};")
63
+ outer.addWidget(line)
64
+
65
+ lead = QLabel("Comparative fiqh of the four Sunni schools — each ruling in its school's own words, "
66
+ "with its source and its evidence.")
67
+ lead.setWordWrap(True)
68
+ lead.setStyleSheet("font-size: 17px;")
69
+ outer.addWidget(lead)
70
+
71
+ chips = QHBoxLayout()
72
+ chips.setSpacing(10)
73
+ for name, ar in SCHOOLS:
74
+ chip = QLabel(f"{name} · {ar}")
75
+ chip.setStyleSheet(
76
+ f"border: 1px solid {LAPIS}; border-radius: 12px; padding: 4px 12px; font-size: 14px;")
77
+ chips.addWidget(chip)
78
+ chips.addStretch(1)
79
+ outer.addLayout(chips)
80
+
81
+ heading = QLabel("Coming next")
82
+ heading.setStyleSheet(f"font-size: 15px; font-weight: 600; color: {GOLD}; margin-top: 12px;")
83
+ outer.addWidget(heading)
84
+ for item in NEXT:
85
+ row = QLabel(f"• {item}")
86
+ row.setWordWrap(True)
87
+ row.setStyleSheet("font-size: 14px;")
88
+ outer.addWidget(row)
89
+
90
+ outer.addStretch(1)
91
+ footer = QLabel(
92
+ f'Version {__version__} · first release, reserving the name · '
93
+ f'<a href="https://github.com/bayramkotan/fiqhboard">github.com/bayramkotan/fiqhboard</a>')
94
+ footer.setOpenExternalLinks(True)
95
+ footer.setStyleSheet("font-size: 12px;")
96
+ outer.addWidget(footer)
97
+
98
+ self.setCentralWidget(page)
@@ -0,0 +1,59 @@
1
+ """Entry points.
2
+
3
+ The same program answers to several names:
4
+ fiqhboard, fqb no arguments: open the window; with arguments: the command line
5
+ fiqhboard-gui always the window, without a console on Windows
6
+
7
+ The command line never imports Qt, so it works on a server, over SSH and in
8
+ scripts, and starts quickly.
9
+ """
10
+
11
+ import os
12
+ import sys
13
+
14
+ from fiqhboard import APP_NAME, __version__
15
+
16
+
17
+ def gui_main() -> int:
18
+ try:
19
+ from PySide6.QtCore import QLoggingCategory
20
+ from PySide6.QtWidgets import QApplication
21
+ except ImportError:
22
+ print("The fiqhboard window needs PySide6: pip install PySide6\n"
23
+ "The command line works without it; see: fqb -h", file=sys.stderr)
24
+ return 1
25
+
26
+ from fiqhboard.gui.main_window import MainWindow
27
+
28
+ if not os.environ.get("QT_LOGGING_RULES"):
29
+ # Qt reports, for every installed font, that it cannot shape a script none of them covers:
30
+ # hundreds of harmless lines. Only that category is silenced; a user's own QT_LOGGING_RULES wins.
31
+ QLoggingCategory.setFilterRules("qt.text.font.db=false")
32
+ if sys.platform == "win32":
33
+ # without its own id, Windows groups the window under python(w).exe and shows Python's icon
34
+ try:
35
+ import ctypes
36
+
37
+ ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("bayramkotan.fiqhboard")
38
+ except (AttributeError, OSError):
39
+ pass
40
+
41
+ app = QApplication(sys.argv[:1])
42
+ app.setApplicationName(APP_NAME)
43
+ app.setApplicationVersion(__version__)
44
+ app.setDesktopFileName("fiqhboard")
45
+ window = MainWindow()
46
+ window.show()
47
+ return app.exec()
48
+
49
+
50
+ def main() -> int:
51
+ if len(sys.argv) > 1:
52
+ from fiqhboard.cli import main as cli_main
53
+
54
+ return cli_main(sys.argv[1:])
55
+ return gui_main()
56
+
57
+
58
+ if __name__ == "__main__":
59
+ raise SystemExit(main())