diff --git a/crates/parsers/Cargo.toml b/crates/parsers/Cargo.toml index 0be7ac8..fb4930e 100644 --- a/crates/parsers/Cargo.toml +++ b/crates/parsers/Cargo.toml @@ -14,3 +14,4 @@ regex = "1" unrar.workspace = true zip = { version = "8", default-features = false, features = ["deflate"] } flate2 = "1" +tracing.workspace = true diff --git a/crates/parsers/src/lib.rs b/crates/parsers/src/lib.rs index cd32f21..1703609 100644 --- a/crates/parsers/src/lib.rs +++ b/crates/parsers/src/lib.rs @@ -166,13 +166,30 @@ fn analyze_cbz(path: &Path, allow_fallback: bool) -> Result<(i32, Vec)> { Ok(a) => a, Err(zip_err) => { if allow_fallback { - // Try RAR fallback first (file might be a RAR with .cbz extension) - if let Ok(result) = analyze_cbr(path, false) { - return Ok(result); + 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) { + tracing::debug!(target: "extraction", "[EXTRACTION] RAR fallback succeeded for {}", path.display()); + return Ok(result); + } } + // Try streaming fallback: read local file headers without central directory // (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) { + 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); } } @@ -180,17 +197,11 @@ fn analyze_cbz(path: &Path, allow_fallback: bool) -> Result<(i32, Vec)> { } }; - let mut image_names: Vec = Vec::new(); - for i in 0..archive.len() { - let entry = match archive.by_index(i) { - Ok(e) => e, - Err(_) => continue, // skip corrupted entries - }; - let name = entry.name().to_ascii_lowercase(); - if is_image_name(&name) { - image_names.push(entry.name().to_string()); - } - } + let mut image_names: Vec = archive + .file_names() + .filter(|name| is_image_name(&name.to_ascii_lowercase())) + .map(|name| name.to_string()) + .collect::>(); image_names.sort_by(|a, b| natord::compare(a, b)); if image_names.is_empty() { diff --git a/scripts/docker-push.sh b/scripts/docker-push.sh index f9aadf7..352ae7b 100755 --- a/scripts/docker-push.sh +++ b/scripts/docker-push.sh @@ -4,29 +4,75 @@ set -e # Docker Hub REGISTRY="docker.io" OWNER="julienfroidefond32" -VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') 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 "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 "Version: $VERSION" -echo "Services: ${SERVICES[@]}" +echo "Services: ${SERVICES[*]}" echo "" for service in "${SERVICES[@]}"; do echo "Building $service..." - docker build -f apps/$service/Dockerfile -t $service:latest . + docker build -f "apps/$service/Dockerfile" -t "$service:latest" . echo "Tagging $service..." - 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:$VERSION" + docker tag "$service:latest" "$REGISTRY/$OWNER/stripstream-$service:latest" echo "Pushing stripstream-$service:$VERSION..." - docker push $REGISTRY/$OWNER/stripstream-$service:$VERSION + docker push "$REGISTRY/$OWNER/stripstream-$service:$VERSION" echo "Pushing stripstream-$service:latest..." - docker push $REGISTRY/$OWNER/stripstream-$service:latest + docker push "$REGISTRY/$OWNER/stripstream-$service:latest" echo "✓ $service pushed successfully" echo "" @@ -38,3 +84,10 @@ for service in "${SERVICES[@]}"; do echo " - $REGISTRY/$OWNER/stripstream-$service:$VERSION" echo " - $REGISTRY/$OWNER/stripstream-$service:latest" 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