mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-17 06:01:33 -06:00
Compare commits
2 Commits
5edaf2cf10
...
c075097acd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c075097acd | ||
|
|
b0148ef36c |
43
.github/workflows/ci_python.yaml
vendored
43
.github/workflows/ci_python.yaml
vendored
@@ -59,44 +59,25 @@ jobs:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install tools (search engine)
|
||||
run: pip install bandit isort mypy pycodestyle pyflakes pyright
|
||||
|
||||
- name: Gather files (search engine)
|
||||
working-directory: src/searchengine/nova3
|
||||
run: |
|
||||
export "PY_FILES=$(find . -type f -name '*.py' -path '*searchengine*' ! -name 'socks.py' -printf '%p ')"
|
||||
echo $PY_FILES
|
||||
echo "PY_FILES=$PY_FILES" >> "$GITHUB_ENV"
|
||||
pip install uv
|
||||
uv sync
|
||||
|
||||
- name: Check typings (search engine)
|
||||
run: |
|
||||
curl \
|
||||
-L \
|
||||
-o src/searchengine/nova3/socks.pyi "https://github.com/python/typeshed/raw/refs/heads/main/stubs/PySocks/socks.pyi"
|
||||
MYPYPATH="src/searchengine/nova3" \
|
||||
mypy \
|
||||
--explicit-package-bases \
|
||||
--strict \
|
||||
$PY_FILES
|
||||
pyright \
|
||||
$PY_FILES
|
||||
working-directory: src/searchengine/nova3
|
||||
run: uv run just check
|
||||
|
||||
- name: Lint code (search engine)
|
||||
run: |
|
||||
pyflakes $PY_FILES
|
||||
bandit --skip B110,B310,B314,B405 $PY_FILES
|
||||
working-directory: src/searchengine/nova3
|
||||
run: uv run just lint
|
||||
|
||||
- name: Format code (search engine)
|
||||
working-directory: src/searchengine/nova3
|
||||
run: |
|
||||
pycodestyle \
|
||||
--ignore=E265,E402 \
|
||||
--max-line-length=1000 \
|
||||
--statistics \
|
||||
$PY_FILES
|
||||
isort \
|
||||
--check \
|
||||
--diff \
|
||||
$PY_FILES
|
||||
uv run just format
|
||||
git diff --exit-code
|
||||
|
||||
- name: Build code (search engine)
|
||||
run: |
|
||||
python -m compileall $PY_FILES
|
||||
working-directory: src/searchengine/nova3
|
||||
run: uv run just build
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
.vscode/
|
||||
|
||||
src/gui/geoip/GeoIP.dat
|
||||
src/gui/geoip/GeoIP.dat.gz
|
||||
src/qbittorrent
|
||||
@@ -10,7 +11,6 @@ CMakeLists.txt.user*
|
||||
qbittorrent.pro.user*
|
||||
conf.pri
|
||||
Makefile*
|
||||
*.pyc
|
||||
*.log
|
||||
|
||||
# Compiled object files
|
||||
|
||||
4
src/searchengine/.gitignore
vendored
Normal file
4
src/searchengine/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.egg-info
|
||||
*.lock
|
||||
*.pyc
|
||||
*.pyi
|
||||
46
src/searchengine/nova3/README.md
Normal file
46
src/searchengine/nova3/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
nova3 Engine
|
||||
===
|
||||
|
||||
## Development Workflow
|
||||
|
||||
0. Prerequisite
|
||||
|
||||
* A Linux-like environment
|
||||
* [Python](https://www.python.org/) installed
|
||||
* [uv](https://docs.astral.sh/uv/) installed
|
||||
|
||||
1. Setup development environment
|
||||
|
||||
1. Setup virtual environment and dependencies
|
||||
```shell
|
||||
uv sync
|
||||
```
|
||||
|
||||
2. Activate virtual environment
|
||||
```shell
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
2. Run type check
|
||||
|
||||
```shell
|
||||
just check
|
||||
```
|
||||
|
||||
3. Run static analyzer
|
||||
|
||||
```shell
|
||||
just lint
|
||||
```
|
||||
|
||||
4. Apply formatting
|
||||
|
||||
```shell
|
||||
just format
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [How to write a search plugin](https://github.com/qbittorrent/search-plugins/wiki/How-to-write-a-search-plugin)
|
||||
* [just - Command runner](https://just.systems/man/en/)
|
||||
* [uv - Python package and project manager](https://docs.astral.sh/uv/)
|
||||
54
src/searchengine/nova3/justfile
Normal file
54
src/searchengine/nova3/justfile
Normal file
@@ -0,0 +1,54 @@
|
||||
PY_FILES := `find . -maxdepth 1 -type f -name '*.py' ! -name 'socks.py' -printf '%P '`
|
||||
|
||||
# Show available recipes to run
|
||||
default:
|
||||
just --list
|
||||
|
||||
# Run type check
|
||||
check files=PY_FILES: fetch_aux
|
||||
mypy \
|
||||
{{ files }}
|
||||
pyright \
|
||||
{{ files }}
|
||||
|
||||
# Byte-compile files
|
||||
build files=PY_FILES:
|
||||
python \
|
||||
-m compileall \
|
||||
{{ files }}
|
||||
|
||||
# Fetch auxiliary files
|
||||
[private]
|
||||
fetch_aux:
|
||||
#!/usr/bin/sh
|
||||
if [ ! -f 'socks.pyi' ]; then
|
||||
curl -L -o socks.pyi "https://github.com/python/typeshed/raw/refs/heads/main/stubs/PySocks/socks.pyi"
|
||||
fi
|
||||
|
||||
# Apply formatting
|
||||
format files=PY_FILES:
|
||||
pycodestyle \
|
||||
--ignore=E265,E402 \
|
||||
--max-line-length=1000 \
|
||||
--statistics \
|
||||
{{ files }}
|
||||
isort \
|
||||
--line-length 1000 \
|
||||
{{ files }}
|
||||
just \
|
||||
--fmt \
|
||||
--unstable
|
||||
|
||||
# Run static analyzer
|
||||
lint files=PY_FILES:
|
||||
pyflakes \
|
||||
{{ files }}
|
||||
bandit \
|
||||
--skip B110,B310,B314,B405 \
|
||||
{{ files }}
|
||||
|
||||
# Run tests
|
||||
test files='tests/*.py': fetch_aux
|
||||
pytest \
|
||||
--showlocals \
|
||||
{{ files }}
|
||||
25
src/searchengine/nova3/pyproject.toml
Normal file
25
src/searchengine/nova3/pyproject.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[project]
|
||||
name = "qBittorrent-search-engine"
|
||||
description = "Search engine for qBittorrent search feature"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
dynamic = ["version"]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"bandit",
|
||||
"isort",
|
||||
"mypy",
|
||||
"pycodestyle",
|
||||
"pyflakes",
|
||||
"pyright",
|
||||
"pytest",
|
||||
"rust-just",
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
explicit_package_bases = true
|
||||
strict = true
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["./"]
|
||||
@@ -36,6 +36,7 @@ export default [
|
||||
"curly": ["error", "multi-or-nest", "consistent"],
|
||||
"eqeqeq": "error",
|
||||
"guard-for-in": "error",
|
||||
"no-implicit-coercion": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-var": "error",
|
||||
@@ -73,7 +74,10 @@ export default [
|
||||
"Unicorn/no-array-for-each": "error",
|
||||
"Unicorn/no-for-loop": "error",
|
||||
"Unicorn/no-zero-fractions": "error",
|
||||
"Unicorn/prefer-classlist-toggle": "error",
|
||||
"Unicorn/prefer-native-coercion-functions": "error",
|
||||
"Unicorn/prefer-number-properties": "error",
|
||||
"Unicorn/prefer-single-call": "error",
|
||||
"Unicorn/switch-case-braces": ["error", "avoid"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,10 +710,8 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
colElem.classList.toggle("reverse", isReverse);
|
||||
}
|
||||
const oldColElem = getCol(this.dynamicTableFixedHeaderDivId, oldColumn);
|
||||
if (oldColElem !== null) {
|
||||
oldColElem.classList.remove("sorted");
|
||||
oldColElem.classList.remove("reverse");
|
||||
}
|
||||
if (oldColElem !== null)
|
||||
oldColElem.classList.remove("sorted", "reverse");
|
||||
}
|
||||
|
||||
getSelectedRowId() {
|
||||
|
||||
@@ -730,9 +730,7 @@ window.qBittorrent.Search ??= (() => {
|
||||
for (const plugin of responseJSON)
|
||||
searchPlugins.push(plugin);
|
||||
|
||||
const pluginOptions = [];
|
||||
pluginOptions.push(createOption("QBT_TR(Only enabled)QBT_TR[CONTEXT=SearchEngineWidget]", "enabled"));
|
||||
pluginOptions.push(createOption("QBT_TR(All plugins)QBT_TR[CONTEXT=SearchEngineWidget]", "all"));
|
||||
const pluginOptions = [createOption("QBT_TR(Only enabled)QBT_TR[CONTEXT=SearchEngineWidget]", "enabled"), createOption("QBT_TR(All plugins)QBT_TR[CONTEXT=SearchEngineWidget]", "all")];
|
||||
|
||||
const searchPluginsEmpty = (searchPlugins.length === 0);
|
||||
if (!searchPluginsEmpty) {
|
||||
|
||||
@@ -17,12 +17,8 @@
|
||||
MochaUI.initializeTabs("aboutTabs");
|
||||
|
||||
const showContent = (element) => {
|
||||
for (const content of document.querySelectorAll(".aboutTabContent")) {
|
||||
if (content === element)
|
||||
content.classList.remove("invisible");
|
||||
else
|
||||
content.classList.add("invisible");
|
||||
}
|
||||
for (const content of document.querySelectorAll(".aboutTabContent"))
|
||||
content.classList.toggle("invisible", (content !== element));
|
||||
};
|
||||
|
||||
document.getElementById("aboutAboutLink").addEventListener("click", (event) => {
|
||||
|
||||
@@ -36,12 +36,8 @@
|
||||
MochaUI.initializeTabs("preferencesTabs");
|
||||
|
||||
const showTab = (element) => {
|
||||
for (const tab of document.querySelectorAll(".PrefTab")) {
|
||||
if (tab === element)
|
||||
tab.classList.remove("invisible");
|
||||
else
|
||||
tab.classList.add("invisible");
|
||||
}
|
||||
for (const tab of document.querySelectorAll(".PrefTab"))
|
||||
tab.classList.toggle("invisible", (tab !== element));
|
||||
};
|
||||
|
||||
document.getElementById("PrefBehaviorLink").addEventListener("click", (e) => {
|
||||
|
||||
@@ -620,8 +620,8 @@
|
||||
|
||||
if (articlesDiffer) {
|
||||
// update unread count
|
||||
const oldUnread = feedData[r.uid].map((art) => !art.isRead).filter((v) => v).length;
|
||||
const newUnread = r.articles.map((art) => !art.isRead).filter((v) => v).length;
|
||||
const oldUnread = feedData[r.uid].map((art) => !art.isRead).filter(Boolean).length;
|
||||
const newUnread = r.articles.map((art) => !art.isRead).filter(Boolean).length;
|
||||
const unreadDifference = newUnread - oldUnread;
|
||||
|
||||
// find all parents (and self) and add unread difference
|
||||
@@ -733,7 +733,7 @@
|
||||
});
|
||||
|
||||
// calculate number of unread
|
||||
const numberOfUnread = dataEntry.articles.map((art) => !art.isRead).filter((v) => v).length;
|
||||
const numberOfUnread = dataEntry.articles.map((art) => !art.isRead).filter(Boolean).length;
|
||||
// find all items that contain this rss feed and add unread count
|
||||
for (const row of rssFeedTable.getRowValues()) {
|
||||
if (dataEntry.fullName.slice(0, row.full_data.dataPath.length) === row.full_data.dataPath)
|
||||
|
||||
Reference in New Issue
Block a user