perf(parsers): optimiser listing CBZ avec file_names(), ajouter magic bytes check RAR
- Remplacer by_index() par file_names() pour lister les pages ZIP (zero I/O) - Ajouter vérification magic bytes avant fallback RAR - Ajouter tracing debug logs dans parsers - Script docker-push avec version bump interactif Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,3 +14,4 @@ regex = "1"
|
|||||||
unrar.workspace = true
|
unrar.workspace = true
|
||||||
zip = { version = "8", default-features = false, features = ["deflate"] }
|
zip = { version = "8", default-features = false, features = ["deflate"] }
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
|
tracing.workspace = true
|
||||||
|
|||||||
@@ -166,13 +166,30 @@ fn analyze_cbz(path: &Path, allow_fallback: bool) -> Result<(i32, Vec<u8>)> {
|
|||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(zip_err) => {
|
Err(zip_err) => {
|
||||||
if allow_fallback {
|
if allow_fallback {
|
||||||
// Try RAR fallback first (file might be a RAR with .cbz extension)
|
tracing::debug!(target: "extraction", "[EXTRACTION] ZipArchive::new failed for {}: {} — trying fallbacks", path.display(), zip_err);
|
||||||
|
|
||||||
|
// Check magic bytes to avoid expensive RAR probe on ZIP files
|
||||||
|
let is_zip_magic = std::fs::File::open(path)
|
||||||
|
.and_then(|mut f| {
|
||||||
|
let mut magic = [0u8; 4];
|
||||||
|
std::io::Read::read_exact(&mut f, &mut magic)?;
|
||||||
|
Ok(magic[0] == b'P' && magic[1] == b'K')
|
||||||
|
})
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if !is_zip_magic {
|
||||||
|
// Try RAR fallback (file might be a RAR with .cbz extension)
|
||||||
if let Ok(result) = analyze_cbr(path, false) {
|
if let Ok(result) = analyze_cbr(path, false) {
|
||||||
|
tracing::debug!(target: "extraction", "[EXTRACTION] RAR fallback succeeded for {}", path.display());
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try streaming fallback: read local file headers without central directory
|
// Try streaming fallback: read local file headers without central directory
|
||||||
// (handles ZIP files with NTFS extra fields that confuse the central dir parser)
|
// (handles ZIP files with NTFS extra fields that confuse the central dir parser)
|
||||||
|
let t0 = std::time::Instant::now();
|
||||||
if let Ok(result) = analyze_cbz_streaming(path) {
|
if let Ok(result) = analyze_cbz_streaming(path) {
|
||||||
|
tracing::debug!(target: "extraction", "[EXTRACTION] Streaming fallback succeeded for {} — {} pages in {:.0}ms", path.display(), result.0, t0.elapsed().as_secs_f64() * 1000.0);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,17 +197,11 @@ fn analyze_cbz(path: &Path, allow_fallback: bool) -> Result<(i32, Vec<u8>)> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut image_names: Vec<String> = Vec::new();
|
let mut image_names: Vec<String> = archive
|
||||||
for i in 0..archive.len() {
|
.file_names()
|
||||||
let entry = match archive.by_index(i) {
|
.filter(|name| is_image_name(&name.to_ascii_lowercase()))
|
||||||
Ok(e) => e,
|
.map(|name| name.to_string())
|
||||||
Err(_) => continue, // skip corrupted entries
|
.collect::<Vec<_>>();
|
||||||
};
|
|
||||||
let name = entry.name().to_ascii_lowercase();
|
|
||||||
if is_image_name(&name) {
|
|
||||||
image_names.push(entry.name().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
image_names.sort_by(|a, b| natord::compare(a, b));
|
image_names.sort_by(|a, b| natord::compare(a, b));
|
||||||
|
|
||||||
if image_names.is_empty() {
|
if image_names.is_empty() {
|
||||||
|
|||||||
@@ -4,29 +4,75 @@ set -e
|
|||||||
# Docker Hub
|
# Docker Hub
|
||||||
REGISTRY="docker.io"
|
REGISTRY="docker.io"
|
||||||
OWNER="julienfroidefond32"
|
OWNER="julienfroidefond32"
|
||||||
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
|
||||||
|
|
||||||
SERVICES=("api" "indexer" "backoffice")
|
SERVICES=("api" "indexer" "backoffice")
|
||||||
|
|
||||||
|
# ─── Version bump ───────────────────────────────────────────────────────────
|
||||||
|
CURRENT_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
||||||
|
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
|
||||||
|
|
||||||
echo "=== Stripstream Librarian Docker Push ==="
|
echo "=== Stripstream Librarian Docker Push ==="
|
||||||
|
echo "Current version: $CURRENT_VERSION"
|
||||||
|
echo ""
|
||||||
|
echo "Bump version?"
|
||||||
|
echo " 1) patch → $MAJOR.$MINOR.$((PATCH + 1))"
|
||||||
|
echo " 2) minor → $MAJOR.$((MINOR + 1)).0"
|
||||||
|
echo " 3) major → $((MAJOR + 1)).0.0"
|
||||||
|
echo " 4) skip → keep $CURRENT_VERSION"
|
||||||
|
echo ""
|
||||||
|
read -rp "Choice [1-4]: " BUMP_CHOICE
|
||||||
|
|
||||||
|
case "$BUMP_CHOICE" in
|
||||||
|
1) NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" ;;
|
||||||
|
2) NEW_VERSION="$MAJOR.$((MINOR + 1)).0" ;;
|
||||||
|
3) NEW_VERSION="$((MAJOR + 1)).0.0" ;;
|
||||||
|
4) NEW_VERSION="$CURRENT_VERSION" ;;
|
||||||
|
*) echo "Invalid choice"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$NEW_VERSION" != "$CURRENT_VERSION" ]; then
|
||||||
|
echo "Bumping version: $CURRENT_VERSION → $NEW_VERSION"
|
||||||
|
|
||||||
|
# Update Cargo.toml (workspace version)
|
||||||
|
sed -i.bak "s/^version = \"$CURRENT_VERSION\"/version = \"$NEW_VERSION\"/" Cargo.toml
|
||||||
|
rm -f Cargo.toml.bak
|
||||||
|
|
||||||
|
# Update backoffice package.json
|
||||||
|
sed -i.bak "s/\"version\": \"$CURRENT_VERSION\"/\"version\": \"$NEW_VERSION\"/" apps/backoffice/package.json
|
||||||
|
rm -f apps/backoffice/package.json.bak
|
||||||
|
|
||||||
|
# Update Cargo.lock
|
||||||
|
cargo update --workspace 2>/dev/null || true
|
||||||
|
|
||||||
|
# Commit version bump
|
||||||
|
git add Cargo.toml Cargo.lock apps/backoffice/package.json
|
||||||
|
git commit -m "chore: bump version to $NEW_VERSION"
|
||||||
|
echo "✓ Version bumped and committed"
|
||||||
|
else
|
||||||
|
echo "Keeping version $CURRENT_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION="$NEW_VERSION"
|
||||||
|
|
||||||
|
echo ""
|
||||||
echo "Registry: $REGISTRY"
|
echo "Registry: $REGISTRY"
|
||||||
echo "Version: $VERSION"
|
echo "Version: $VERSION"
|
||||||
echo "Services: ${SERVICES[@]}"
|
echo "Services: ${SERVICES[*]}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
for service in "${SERVICES[@]}"; do
|
for service in "${SERVICES[@]}"; do
|
||||||
echo "Building $service..."
|
echo "Building $service..."
|
||||||
docker build -f apps/$service/Dockerfile -t $service:latest .
|
docker build -f "apps/$service/Dockerfile" -t "$service:latest" .
|
||||||
|
|
||||||
echo "Tagging $service..."
|
echo "Tagging $service..."
|
||||||
docker tag $service:latest $REGISTRY/$OWNER/stripstream-$service:$VERSION
|
docker tag "$service:latest" "$REGISTRY/$OWNER/stripstream-$service:$VERSION"
|
||||||
docker tag $service:latest $REGISTRY/$OWNER/stripstream-$service:latest
|
docker tag "$service:latest" "$REGISTRY/$OWNER/stripstream-$service:latest"
|
||||||
|
|
||||||
echo "Pushing stripstream-$service:$VERSION..."
|
echo "Pushing stripstream-$service:$VERSION..."
|
||||||
docker push $REGISTRY/$OWNER/stripstream-$service:$VERSION
|
docker push "$REGISTRY/$OWNER/stripstream-$service:$VERSION"
|
||||||
|
|
||||||
echo "Pushing stripstream-$service:latest..."
|
echo "Pushing stripstream-$service:latest..."
|
||||||
docker push $REGISTRY/$OWNER/stripstream-$service:latest
|
docker push "$REGISTRY/$OWNER/stripstream-$service:latest"
|
||||||
|
|
||||||
echo "✓ $service pushed successfully"
|
echo "✓ $service pushed successfully"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -38,3 +84,10 @@ for service in "${SERVICES[@]}"; do
|
|||||||
echo " - $REGISTRY/$OWNER/stripstream-$service:$VERSION"
|
echo " - $REGISTRY/$OWNER/stripstream-$service:$VERSION"
|
||||||
echo " - $REGISTRY/$OWNER/stripstream-$service:latest"
|
echo " - $REGISTRY/$OWNER/stripstream-$service:latest"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Tag git with version
|
||||||
|
if ! git tag -l "v$VERSION" | grep -q "v$VERSION"; then
|
||||||
|
git tag "v$VERSION"
|
||||||
|
echo ""
|
||||||
|
echo "Git tag v$VERSION created. Push with: git push origin v$VERSION"
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user