|
1 | 1 | use anyhow::Result; |
2 | 2 | use clap::{Parser, Subcommand}; |
| 3 | +use regex::Regex; |
3 | 4 | use serde::Serialize; |
4 | 5 |
|
5 | 6 | use crate::api::DantaClient; |
@@ -140,6 +141,10 @@ pub enum Commands { |
140 | 141 | }, |
141 | 142 | /// List all tags |
142 | 143 | Tags, |
| 144 | + /// Extract image URLs from all floors of a hole |
| 145 | + Images { |
| 146 | + hole_id: i64, |
| 147 | + }, |
143 | 148 | /// List your own holes |
144 | 149 | MyHoles { |
145 | 150 | #[arg(short, long, default_value = "10")] |
@@ -658,6 +663,46 @@ pub async fn run_cli(cmd: Commands, json: bool) -> Result<()> { |
658 | 663 | } |
659 | 664 | } |
660 | 665 | } |
| 666 | + Commands::Images { hole_id } => { |
| 667 | + let client = get_client().await?; |
| 668 | + let hole = client.get_hole(hole_id).await?; |
| 669 | + let total = hole.reply as u32 + 1; |
| 670 | + let floors = client.get_floors(hole_id, 0, total.max(100), None).await?; |
| 671 | + |
| 672 | + let md_img = Regex::new(r"!\[[^\]]*\]\((https?://[^)]+)\)").unwrap(); |
| 673 | + let bare_url = |
| 674 | + Regex::new(r"https?://\S+\.(?:jpg|jpeg|png|gif|webp)(?:\?\S*)?").unwrap(); |
| 675 | + |
| 676 | + let urls: Vec<String> = floors |
| 677 | + .iter() |
| 678 | + .flat_map(|f| { |
| 679 | + let mut found: Vec<String> = Vec::new(); |
| 680 | + for cap in md_img.captures_iter(&f.content) { |
| 681 | + found.push(cap[1].to_string()); |
| 682 | + } |
| 683 | + for cap in bare_url.captures_iter(&f.content) { |
| 684 | + let url = cap[0].to_string(); |
| 685 | + if !found.contains(&url) { |
| 686 | + found.push(url); |
| 687 | + } |
| 688 | + } |
| 689 | + found |
| 690 | + }) |
| 691 | + .filter(|url| { |
| 692 | + let filename = url.rsplit('/').next().unwrap_or(""); |
| 693 | + let filename = filename.split('?').next().unwrap_or(filename); |
| 694 | + !filename.starts_with("dx_") |
| 695 | + }) |
| 696 | + .collect(); |
| 697 | + |
| 698 | + if json { |
| 699 | + json_out(&urls); |
| 700 | + } else { |
| 701 | + for url in &urls { |
| 702 | + println!("{}", url); |
| 703 | + } |
| 704 | + } |
| 705 | + } |
661 | 706 | Commands::Tui | Commands::Serve { .. } => unreachable!(), |
662 | 707 | } |
663 | 708 | Ok(()) |
|
0 commit comments