Merge 'image-cache: use sha256 hash of url for key'
Link: https://github.com/damus-io/notedeck/pull/631
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2505,6 +2505,7 @@ dependencies = [
|
|||||||
"security-framework",
|
"security-framework",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ url = "2.5.2"
|
|||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.3"
|
||||||
uuid = { version = "1.10.0", features = ["v4"] }
|
uuid = { version = "1.10.0", features = ["v4"] }
|
||||||
security-framework = "2.11.0"
|
security-framework = "2.11.0"
|
||||||
|
sha2 = "0.10.8"
|
||||||
|
|
||||||
[profile.small]
|
[profile.small]
|
||||||
inherits = 'release'
|
inherits = 'release'
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ serde = { workspace = true }
|
|||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
puffin = { workspace = true, optional = true }
|
puffin = { workspace = true, optional = true }
|
||||||
|
sha2 = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
|||||||
@@ -5,9 +5,13 @@ use poll_promise::Promise;
|
|||||||
use egui::ColorImage;
|
use egui::ColorImage;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::{create_dir_all, File};
|
||||||
|
|
||||||
|
use hex::ToHex;
|
||||||
|
use sha2::Digest;
|
||||||
use std::path;
|
use std::path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use tracing::warn;
|
||||||
|
|
||||||
pub type ImageCacheValue = Promise<Result<TextureHandle>>;
|
pub type ImageCacheValue = Promise<Result<TextureHandle>>;
|
||||||
pub type ImageCacheMap = HashMap<String, ImageCacheValue>;
|
pub type ImageCacheMap = HashMap<String, ImageCacheValue>;
|
||||||
@@ -46,6 +50,9 @@ impl ImageCache {
|
|||||||
|
|
||||||
pub fn write(cache_dir: &path::Path, url: &str, data: ColorImage) -> Result<()> {
|
pub fn write(cache_dir: &path::Path, url: &str, data: ColorImage) -> Result<()> {
|
||||||
let file_path = cache_dir.join(Self::key(url));
|
let file_path = cache_dir.join(Self::key(url));
|
||||||
|
if let Some(p) = file_path.parent() {
|
||||||
|
create_dir_all(p)?;
|
||||||
|
}
|
||||||
let file = File::options()
|
let file = File::options()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
@@ -64,7 +71,51 @@ impl ImageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn key(url: &str) -> String {
|
pub fn key(url: &str) -> String {
|
||||||
base32::encode(base32::Alphabet::Crockford, url.as_bytes())
|
let k: String = sha2::Sha256::digest(url.as_bytes()).encode_hex();
|
||||||
|
PathBuf::from(&k[0..2])
|
||||||
|
.join(&k[2..4])
|
||||||
|
.join(k)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Migrate from base32 encoded url to sha256 url + sub-dir structure
|
||||||
|
pub fn migrate_v0(&self) -> Result<()> {
|
||||||
|
for file in std::fs::read_dir(&self.cache_dir)? {
|
||||||
|
let file = if let Ok(f) = file {
|
||||||
|
f
|
||||||
|
} else {
|
||||||
|
// not sure how this could fail, skip entry
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if !file.path().is_file() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let old_filename = file.file_name().to_string_lossy().to_string();
|
||||||
|
let old_url = if let Some(u) =
|
||||||
|
base32::decode(base32::Alphabet::Crockford, &old_filename)
|
||||||
|
.and_then(|s| String::from_utf8(s).ok())
|
||||||
|
{
|
||||||
|
u
|
||||||
|
} else {
|
||||||
|
warn!("Invalid base32 filename: {}", &old_filename);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let new_path = self.cache_dir.join(Self::key(&old_url));
|
||||||
|
if let Some(p) = new_path.parent() {
|
||||||
|
create_dir_all(p)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = std::fs::rename(file.path(), &new_path) {
|
||||||
|
warn!(
|
||||||
|
"Failed to migrate file from {} to {}: {:?}",
|
||||||
|
file.path().display(),
|
||||||
|
new_path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map(&self) -> &ImageCacheMap {
|
pub fn map(&self) -> &ImageCacheMap {
|
||||||
|
|||||||
@@ -207,6 +207,11 @@ impl Notedeck {
|
|||||||
let tabs = Tabs::new(None);
|
let tabs = Tabs::new(None);
|
||||||
let app_rect_handler = AppSizeHandler::new(&path);
|
let app_rect_handler = AppSizeHandler::new(&path);
|
||||||
|
|
||||||
|
// migrate
|
||||||
|
if let Err(e) = img_cache.migrate_v0() {
|
||||||
|
error!("error migrating image cache: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ndb,
|
ndb,
|
||||||
img_cache,
|
img_cache,
|
||||||
|
|||||||
Reference in New Issue
Block a user