Merge branch 'main' into main

This commit is contained in:
Damien Elmes 2025-08-20 01:17:43 +10:00 committed by GitHub
commit b5e7c7c6f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 2644 additions and 3225 deletions

5
Cargo.lock generated
View file

@ -3959,6 +3959,7 @@ dependencies = [
"anki_process", "anki_process",
"anyhow", "anyhow",
"camino", "camino",
"serde_json",
"walkdir", "walkdir",
"which", "which",
] ]
@ -5974,9 +5975,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.10" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]] [[package]]
name = "slotmap" name = "slotmap"

View file

@ -169,7 +169,7 @@ fn build_rsbridge(build: &mut Build) -> Result<()> {
pub fn check_rust(build: &mut Build) -> Result<()> { pub fn check_rust(build: &mut Build) -> Result<()> {
let inputs = inputs![ let inputs = inputs![
glob!("{rslib/**,pylib/rsbridge/**,ftl/**,build/**,qt/launcher/**}"), glob!("{rslib/**,pylib/rsbridge/**,ftl/**,build/**,qt/launcher/**,tools/minilints/**}"),
"Cargo.lock", "Cargo.lock",
"Cargo.toml", "Cargo.toml",
"rust-toolchain.toml", "rust-toolchain.toml",

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,12 @@ class _MacOSHelper:
"On completion, file should be saved if no error has arrived." "On completion, file should be saved if no error has arrived."
self._dll.end_wav_record() self._dll.end_wav_record()
def disable_appnap(self) -> None:
self._dll.disable_appnap()
def enable_appnap(self) -> None:
self._dll.enable_appnap()
# this must not be overwritten or deallocated # this must not be overwritten or deallocated
@CFUNCTYPE(None, c_char_p) # type: ignore @CFUNCTYPE(None, c_char_p) # type: ignore

25
qt/mac/appnap.swift Normal file
View file

@ -0,0 +1,25 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Foundation
private var currentActivity: NSObjectProtocol?
@_cdecl("disable_appnap")
public func disableAppNap() {
// No-op if already assigned
guard currentActivity == nil else { return }
currentActivity = ProcessInfo.processInfo.beginActivity(
options: .userInitiatedAllowingIdleSystemSleep,
reason: "AppNap is disabled"
)
}
@_cdecl("enable_appnap")
public func enableAppNap() {
guard let activity = currentActivity else { return }
ProcessInfo.processInfo.endActivity(activity)
currentActivity = nil
}

View file

@ -15,6 +15,7 @@ echo "Building macOS helper dylib..."
# Create the wheel using uv # Create the wheel using uv
echo "Creating wheel..." echo "Creating wheel..."
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
rm -rf dist
"$PROJ_ROOT/out/extracted/uv/uv" build --wheel "$PROJ_ROOT/out/extracted/uv/uv" build --wheel
echo "Build complete!" echo "Build complete!"

View file

@ -1,8 +1,6 @@
# Copyright: Ankitects Pty Ltd and contributors # Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import os
import platform
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "anki-mac-helper" name = "anki-mac-helper"
version = "0.1.0" version = "0.1.1"
description = "Small support library for Anki on Macs" description = "Small support library for Anki on Macs"
requires-python = ">=3.9" requires-python = ">=3.9"
license = { text = "AGPL-3.0-or-later" } license = { text = "AGPL-3.0-or-later" }

14
qt/mac/update-launcher-env Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
#
# Build and install into the launcher venv
set -e
./build.sh
if [[ "$OSTYPE" == "darwin"* ]]; then
export VIRTUAL_ENV=$HOME/Library/Application\ Support/AnkiProgramFiles/.venv
else
export VIRTUAL_ENV=$HOME/.local/share/AnkiProgramFiles/.venv
fi
../../out/extracted/uv/uv pip install dist/*.whl

View file

@ -12,7 +12,7 @@ dependencies = [
"send2trash", "send2trash",
"waitress>=2.0.0", "waitress>=2.0.0",
"pywin32; sys.platform == 'win32'", "pywin32; sys.platform == 'win32'",
"anki-mac-helper; sys.platform == 'darwin'", "anki-mac-helper>=0.1.1; sys.platform == 'darwin'",
"pip-system-certs!=5.1", "pip-system-certs!=5.1",
"pyqt6>=6.2", "pyqt6>=6.2",
"pyqt6-webengine>=6.2", "pyqt6-webengine>=6.2",

View file

@ -99,8 +99,6 @@ impl Collection {
historical_retention.unwrap_or(0.9), historical_retention.unwrap_or(0.9),
ignore_before, ignore_before,
)?; )?;
let preset_desired_retention =
req.as_ref().map(|w| w.preset_desired_retention).unwrap();
let mut progress = self.new_progress_handler::<ComputeMemoryProgress>(); let mut progress = self.new_progress_handler::<ComputeMemoryProgress>();
progress.update(false, |s| s.total_cards = items.len() as u32)?; progress.update(false, |s| s.total_cards = items.len() as u32)?;
for (idx, (card_id, item)) in items.into_iter().enumerate() { for (idx, (card_id, item)) in items.into_iter().enumerate() {
@ -108,6 +106,7 @@ impl Collection {
let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?; let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
let original = card.clone(); let original = card.clone();
if let Some(req) = &req { if let Some(req) = &req {
let preset_desired_retention = req.preset_desired_retention;
// Store decay and desired retention in the card so that add-ons, card info, // Store decay and desired retention in the card so that add-ons, card info,
// stats and browser search/sorts don't need to access the deck config. // stats and browser search/sorts don't need to access the deck config.
// Unlike memory states, scheduler doesn't use decay and dr stored in the card. // Unlike memory states, scheduler doesn't use decay and dr stored in the card.

View file

@ -12,5 +12,6 @@ anki_io.workspace = true
anki_process.workspace = true anki_process.workspace = true
anyhow.workspace = true anyhow.workspace = true
camino.workspace = true camino.workspace = true
serde_json.workspace = true
walkdir.workspace = true walkdir.workspace = true
which.workspace = true which.workspace = true

View file

@ -2,6 +2,7 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use std::cell::LazyCell; use std::cell::LazyCell;
use std::collections::BTreeMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::env; use std::env;
use std::fs; use std::fs;
@ -148,7 +149,7 @@ impl LintContext {
if last_author == "49699333+dependabot[bot]@users.noreply.github.com" { if last_author == "49699333+dependabot[bot]@users.noreply.github.com" {
println!("Dependabot whitelisted."); println!("Dependabot whitelisted.");
return Ok(()); std::process::exit(0);
} else if all_contributors.contains(last_author.as_str()) { } else if all_contributors.contains(last_author.as_str()) {
return Ok(()); return Ok(());
} }
@ -267,5 +268,16 @@ fn generate_licences() -> Result<String> {
"--manifest-path", "--manifest-path",
"rslib/Cargo.toml", "rslib/Cargo.toml",
])?; ])?;
Ok(output.stdout)
let licenses: Vec<BTreeMap<String, serde_json::Value>> = serde_json::from_str(&output.stdout)?;
let filtered: Vec<BTreeMap<String, serde_json::Value>> = licenses
.into_iter()
.map(|mut entry| {
entry.remove("version");
entry
})
.collect();
Ok(serde_json::to_string_pretty(&filtered)?)
} }

View file

@ -147,10 +147,10 @@ dev = [
[[package]] [[package]]
name = "anki-mac-helper" name = "anki-mac-helper"
version = "0.1.0" version = "0.1.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/9f/c4d3e635ddbd2c6c24ff5454e96900fd2061b9abbb0198b9283446780d08/anki_mac_helper-0.1.0-py3-none-any.whl", hash = "sha256:ed449aba27ea3bc7999054afa10dacf08ef856ed7af46526d9c8599d8179a618", size = 40637, upload-time = "2025-06-19T14:38:07.672Z" }, { url = "https://files.pythonhosted.org/packages/40/82/edb6194704defec181dddce8bc6a53c4afc72fa1f2bb4d68ffe244567767/anki_mac_helper-0.1.1-py3-none-any.whl", hash = "sha256:774a69cf9f0fe6d4b54949e2d6588a54a76ff51e78cbfc26b527d1ed3c5b34e3", size = 41812, upload-time = "2025-08-19T09:43:50.345Z" },
] ]
[[package]] [[package]]
@ -214,7 +214,7 @@ qt68 = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "anki-audio", marker = "(sys_platform == 'darwin' and extra == 'audio') or (sys_platform == 'win32' and extra == 'audio')", specifier = "==0.1.0" }, { name = "anki-audio", marker = "(sys_platform == 'darwin' and extra == 'audio') or (sys_platform == 'win32' and extra == 'audio')", specifier = "==0.1.0" },
{ name = "anki-mac-helper", marker = "sys_platform == 'darwin'" }, { name = "anki-mac-helper", marker = "sys_platform == 'darwin'", specifier = ">=0.1.1" },
{ name = "beautifulsoup4" }, { name = "beautifulsoup4" },
{ name = "flask" }, { name = "flask" },
{ name = "flask-cors" }, { name = "flask-cors" },