Add a backend method to extract static media references (#2716)
* Add a backend method to extract static media references * Extract into Notetype.gather_media_names()
This commit is contained in:
parent
7b84348771
commit
c052be9e25
@ -8,6 +8,7 @@ option java_multiple_files = true;
|
|||||||
package anki.media;
|
package anki.media;
|
||||||
|
|
||||||
import "anki/generic.proto";
|
import "anki/generic.proto";
|
||||||
|
import "anki/notetypes.proto";
|
||||||
|
|
||||||
service MediaService {
|
service MediaService {
|
||||||
rpc CheckMedia(generic.Empty) returns (CheckMediaResponse);
|
rpc CheckMedia(generic.Empty) returns (CheckMediaResponse);
|
||||||
@ -15,6 +16,8 @@ service MediaService {
|
|||||||
rpc TrashMediaFiles(TrashMediaFilesRequest) returns (generic.Empty);
|
rpc TrashMediaFiles(TrashMediaFilesRequest) returns (generic.Empty);
|
||||||
rpc EmptyTrash(generic.Empty) returns (generic.Empty);
|
rpc EmptyTrash(generic.Empty) returns (generic.Empty);
|
||||||
rpc RestoreTrash(generic.Empty) returns (generic.Empty);
|
rpc RestoreTrash(generic.Empty) returns (generic.Empty);
|
||||||
|
rpc ExtractStaticMediaFiles(notetypes.NotetypeId)
|
||||||
|
returns (generic.StringList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implicitly includes any of the above methods that are not listed in the
|
// Implicitly includes any of the above methods that are not listed in the
|
||||||
|
@ -8,7 +8,7 @@ import pprint
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from typing import Callable
|
from typing import Callable, Sequence
|
||||||
|
|
||||||
from anki import media_pb2
|
from anki import media_pb2
|
||||||
from anki._legacy import DeprecatedNamesMixin, deprecated_keywords
|
from anki._legacy import DeprecatedNamesMixin, deprecated_keywords
|
||||||
@ -149,6 +149,9 @@ class MediaManager(DeprecatedNamesMixin):
|
|||||||
files.append(fname)
|
files.append(fname)
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
def extract_static_media_files(self, mid: NotetypeId) -> Sequence[str]:
|
||||||
|
return self.col._backend.extract_static_media_files(mid)
|
||||||
|
|
||||||
def transform_names(self, txt: str, func: Callable) -> str:
|
def transform_names(self, txt: str, func: Callable) -> str:
|
||||||
for reg in self.regexps:
|
for reg in self.regexps:
|
||||||
txt = re.sub(reg, func, txt)
|
txt = re.sub(reg, func, txt)
|
||||||
|
@ -16,8 +16,6 @@ use crate::revlog::RevlogEntry;
|
|||||||
use crate::search::CardTableGuard;
|
use crate::search::CardTableGuard;
|
||||||
use crate::search::NoteTableGuard;
|
use crate::search::NoteTableGuard;
|
||||||
use crate::text::extract_media_refs;
|
use crate::text::extract_media_refs;
|
||||||
use crate::text::extract_underscored_css_imports;
|
|
||||||
use crate::text::extract_underscored_references;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(super) struct ExchangeData {
|
pub(super) struct ExchangeData {
|
||||||
@ -75,7 +73,7 @@ impl ExchangeData {
|
|||||||
gather_media_names_from_note(note, &mut inserter, &svg_getter);
|
gather_media_names_from_note(note, &mut inserter, &svg_getter);
|
||||||
}
|
}
|
||||||
for notetype in self.notetypes.iter() {
|
for notetype in self.notetypes.iter() {
|
||||||
gather_media_names_from_notetype(notetype, &mut inserter);
|
notetype.gather_media_names(&mut inserter);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -158,19 +156,6 @@ fn gather_media_names_from_note(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_media_names_from_notetype(notetype: &Notetype, inserter: &mut impl FnMut(String)) {
|
|
||||||
for name in extract_underscored_css_imports(¬etype.config.css) {
|
|
||||||
inserter(name.to_string());
|
|
||||||
}
|
|
||||||
for template in ¬etype.templates {
|
|
||||||
for template_side in [&template.config.q_format, &template.config.a_format] {
|
|
||||||
for name in extract_underscored_references(template_side) {
|
|
||||||
inserter(name.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn svg_getter(notetypes: &[Notetype]) -> impl Fn(NotetypeId) -> bool {
|
fn svg_getter(notetypes: &[Notetype]) -> impl Fn(NotetypeId) -> bool {
|
||||||
let svg_map: HashMap<NotetypeId, bool> = notetypes
|
let svg_map: HashMap<NotetypeId, bool> = notetypes
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
// 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
|
||||||
use anki_proto::generic;
|
use anki_proto::generic;
|
||||||
@ -7,7 +9,9 @@ use anki_proto::media::TrashMediaFilesRequest;
|
|||||||
|
|
||||||
use crate::collection::Collection;
|
use crate::collection::Collection;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
|
use crate::error::OrNotFound;
|
||||||
use crate::notes::service::to_i64s;
|
use crate::notes::service::to_i64s;
|
||||||
|
use crate::notetype::NotetypeId;
|
||||||
|
|
||||||
impl crate::services::MediaService for Collection {
|
impl crate::services::MediaService for Collection {
|
||||||
fn check_media(&mut self) -> error::Result<CheckMediaResponse> {
|
fn check_media(&mut self) -> error::Result<CheckMediaResponse> {
|
||||||
@ -47,4 +51,19 @@ impl crate::services::MediaService for Collection {
|
|||||||
fn restore_trash(&mut self) -> error::Result<()> {
|
fn restore_trash(&mut self) -> error::Result<()> {
|
||||||
self.media_checker()?.restore_trash()
|
self.media_checker()?.restore_trash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_static_media_files(
|
||||||
|
&mut self,
|
||||||
|
ntid: anki_proto::notetypes::NotetypeId,
|
||||||
|
) -> error::Result<generic::StringList> {
|
||||||
|
let ntid = NotetypeId::from(ntid);
|
||||||
|
let notetype = self.storage.get_notetype(ntid)?.or_not_found(ntid)?;
|
||||||
|
let mut files: HashSet<String> = HashSet::new();
|
||||||
|
let mut inserter = |name: String| {
|
||||||
|
files.insert(name);
|
||||||
|
};
|
||||||
|
notetype.gather_media_names(&mut inserter);
|
||||||
|
|
||||||
|
Ok(files.into_iter().collect::<Vec<_>>().into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,8 @@ use crate::storage::comma_separated_ids;
|
|||||||
use crate::template::FieldRequirements;
|
use crate::template::FieldRequirements;
|
||||||
use crate::template::ParsedTemplate;
|
use crate::template::ParsedTemplate;
|
||||||
use crate::text::ensure_string_in_nfc;
|
use crate::text::ensure_string_in_nfc;
|
||||||
|
use crate::text::extract_underscored_css_imports;
|
||||||
|
use crate::text::extract_underscored_references;
|
||||||
|
|
||||||
define_newtype!(NotetypeId, i64);
|
define_newtype!(NotetypeId, i64);
|
||||||
|
|
||||||
@ -624,6 +626,19 @@ impl Notetype {
|
|||||||
HashSet::new()
|
HashSet::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn gather_media_names(&self, inserter: &mut impl FnMut(String)) {
|
||||||
|
for name in extract_underscored_css_imports(&self.config.css) {
|
||||||
|
inserter(name.to_string());
|
||||||
|
}
|
||||||
|
for template in &self.templates {
|
||||||
|
for template_side in [&template.config.q_format, &template.config.a_format] {
|
||||||
|
for name in extract_underscored_references(template_side) {
|
||||||
|
inserter(name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// True if the slice is empty or either template of the first tuple doesn't
|
/// True if the slice is empty or either template of the first tuple doesn't
|
||||||
|
Loading…
Reference in New Issue
Block a user