Skip to content

Commit

Permalink
refactor: removed unused code and print statements. Put code for Imag…
Browse files Browse the repository at this point in the history
…es in own module
  • Loading branch information
maximizzar committed Mar 26, 2024
1 parent cff68fa commit 7749a84
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 125 deletions.
137 changes: 137 additions & 0 deletions src/image.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use regex::Regex;

#[derive(Debug, serde::Deserialize, PartialEq, serde::Serialize)]
struct Image {
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
galleries: Option<Vec<Gallery>>,
#[serde(skip_serializing_if = "Option::is_none")]
performers: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
tags: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
files: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
updated_at: Option<String>,
}

#[derive(Debug, serde::Deserialize, PartialEq, serde::Serialize)]
struct Gallery {
title: String,
}

pub(crate) fn process_entry(entry: std::fs::DirEntry, dry_run: bool) {
let json_file_path = entry.path();
let json_string: String = std::fs::read_to_string(&json_file_path).expect("Json File not Readable!");
let mut image: Image = serde_json::from_str(&json_string.to_string().as_str()).expect("Json Config not valid!");

if image.title.is_none() {
image.title = get_file_name(&image);
}
if image.date.is_none() {
image.date = get_date(&image);
}

update_json(&image, &json_file_path.to_str().unwrap().to_string(), dry_run);
}

fn get_file_name(image: &Image) -> Option<String> {
let path_str: String = image.files.to_owned().unwrap().get(0).unwrap().as_str().to_string();
let file_name = std::path::Path::new(&path_str).file_stem().unwrap().to_str().unwrap();
Some(file_name.to_string())
}

fn get_file_mtime(image: &Image) -> Option<String> {
let file_path: String = image.files.to_owned().unwrap().get(0).unwrap().as_str().to_string();

match std::fs::metadata(file_path) {
Ok(metadata) => {
if let Ok(modified_time) = metadata.modified() {
let datetime: chrono::DateTime<chrono::Utc> = chrono::DateTime::from(modified_time);
let formatted_date = datetime.format("%Y-%m-%d").to_string();
return Some(formatted_date);
} else {
eprintln!("Failed to get modified time")
}
}
Err(e) => eprintln!("Error: {}", e),
}
None
}

fn get_date(image: &Image) -> Option<String> {
//get_date_from_filename
let mut date = get_date_from_string(get_file_name(&image));
if let Some(date) = date {
return Option::from(date);
}
//get_date_from_title
date = get_date_from_string(Some(image.title.clone().unwrap()));
if let Some(date) = date {
println!("get_date_from_title: {}", date);
return Option::from(date);
}
//get_file_metadata
date = get_file_mtime(&image);
if let Some(date) = date {
println!("get_file_metadata: {}", date);
return Option::from(date);
}
fn get_date_from_string(date_string: Option<String>) -> Option<String> {
fn convert_date(input_date: &str) -> Option<String> {
let date_formats = &["%Y%m%d", "%Y-%m-%d", "%d%m%Y", "%d-%m-%Y"];
let output_format = "%Y-%m-%d";

for date_format in date_formats {
match chrono::NaiveDate::parse_from_str(input_date, date_format) {
Ok(date_obj) => {
return Some(date_obj.format(output_format).to_string());
}
Err(_) => continue,
}
}

None
}

if date_string.is_none() {
return None;
}

let date_formats = vec![
r"\d{4}\d{2}\d{2}", // YYYYMMDD
r"\d{4}-\d{2}-\d{2}", // YYYY-MM-DD
r"\d{2}\d{2}\d{4}", // DDMMYYYY
r"\d{2}-\d{2}-\d{4}", // DD-MM-YYYY
];

for format in date_formats {
let re = Regex::new(format).unwrap();
if let Some(captures) = re.captures(date_string.clone().unwrap().to_string().as_str()) {
if let Some(date) = captures.get(0) {
if let Some(converted_date) = convert_date(date.as_str()) {
return Some(converted_date);
}
}
}
}
None
}
None
}


fn update_json(json_data: &Image, json_file_path: &String, dry_run: bool) {
if dry_run {
let json_string = serde_json::to_string(&json_data).unwrap();
println!("{json_string}");
return;
}
let json_string = serde_json::to_string_pretty(&json_data).unwrap();
std::fs::write(json_file_path, json_string).expect("Json File not Writeable!");
}
184 changes: 59 additions & 125 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,161 +1,95 @@
use std::ops::Deref;
use regex::Regex;

mod image;

#[derive(Debug, serde::Deserialize, PartialEq, serde::Serialize)]
struct JsonData {
struct Performer {
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
twitter: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
instagram: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
birthdate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
death_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
ethnicity: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>,
country: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
date: Option<String>,
hair_color: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
galleries: Option<Vec<Gallery>>,
eye_color: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
performers: Option<Vec<String>>,
height: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
tags: Option<Vec<String>>,
weight: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
files: Option<Vec<String>>,
measurements: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
fake_tits: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
career_length: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
tattoos: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
piercings: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
image: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
updated_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
rating: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
details: Option<String>,
}

#[derive(Debug, serde::Deserialize, PartialEq, serde::Serialize)]
struct Gallery {
title: String,
struct Studio {
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
image: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
updated_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
rating: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
details: Option<String>,
}

// Any value that is present is considered Some value, including null.
fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where T: serde::Deserialize<'de>, D: serde::Deserializer<'de> {
serde::Deserialize::deserialize(deserializer).map(Some)
}

fn main() {
let arguments: Vec<String> = std::env::args().collect();
if arguments.len() > 4 {
if arguments.len() > 4 {
eprintln!("Too many Arguments!");
std::process::exit(1);
}
if let Some(index) = &arguments.iter().position(|arg| arg == "--directory_path") {
let directory_path = arguments.get(index + 1).unwrap().deref();
let dry_run = arguments.clone().iter().any(|arg| arg == "--dry-run");

if let Ok(entries) = std::fs::read_dir(directory_path) {
let images = directory_path.to_string() + "/images";
let _scenes = directory_path.to_string() + "/scenes";

if let Ok(entries) = std::fs::read_dir(images) {
for entry in entries {
if let Ok(entry) = entry {
process_entry(entry, dry_run);
image::process_entry(entry, dry_run);
}
}
}
} else {
eprintln!("Please Provide a valid Path (Stash-exported json files");
}
}
fn process_entry(entry: std::fs::DirEntry, dry_run: bool) {
let json_file_path = entry.path();
let json_string: String = std::fs::read_to_string(&json_file_path).expect("Json File not Readable!");
let mut image: JsonData = serde_json::from_str(&json_string.to_string().as_str()).expect("Json Config not valid!");

if image.title.is_none() {
image.title = get_file_name(&image);
}
if image.date.is_none() {
image.date = get_date(&image);
}
update_json(&image, &json_file_path.to_str().unwrap().to_string(), dry_run);
}

fn get_file_name(image: &JsonData) -> Option<String> {
let path_str: String = image.files.to_owned().unwrap().get(0).unwrap().as_str().to_string();
let file_name = std::path::Path::new(&path_str).file_stem().unwrap().to_str().unwrap();
Some(file_name.to_string())
}
fn get_file_metadata(image: &JsonData) -> Option<String> {
let file_path: String = image.files.to_owned().unwrap().get(0).unwrap().as_str().to_string();

match std::fs::metadata(file_path) {
Ok(metadata) => {
if let Ok(modified_time) = metadata.modified() {
let datetime: chrono::DateTime<chrono::Utc> = chrono::DateTime::from(modified_time);
let formatted_date = datetime.format("%Y-%m-%d").to_string();
return Some(formatted_date)
} else {
eprintln!("Failed to get modified time")
}
},
Err(e) => eprintln!("Error: {}", e),
}
None
}

fn get_date(image: &JsonData) -> Option<String> {
//get_date_from_filename
let mut date = get_date_from_string(get_file_name(&image));
if let Some(date) = date {
return Option::from(date);
}
//get_date_from_title
date = get_date_from_string(Some(image.title.clone().unwrap()));
if let Some(date) = date {
println!("get_date_from_title: {}", date);
return Option::from(date);
}
//get_file_metadata
date = get_file_metadata(&image);
if let Some(date) = date {
println!("get_file_metadata: {}", date);
return Option::from(date);
}
fn get_date_from_string(date_string: Option<String>) -> Option<String> {
fn convert_date(input_date: &str) -> Option<String> {
let date_formats = &["%Y%m%d", "%Y-%m-%d", "%d%m%Y", "%d-%m-%Y"];
let output_format = "%Y-%m-%d";

for date_format in date_formats {
match chrono::NaiveDate::parse_from_str(input_date, date_format) {
Ok(date_obj) => {
return Some(date_obj.format(output_format).to_string());
},
Err(_) => continue,
}
}

None
}

if date_string.is_none() {
return None;
}

let date_formats = vec![
r"\d{4}\d{2}\d{2}", // YYYYMMDD
r"\d{4}-\d{2}-\d{2}", // YYYY-MM-DD
r"\d{2}\d{2}\d{4}", // DDMMYYYY
r"\d{2}-\d{2}-\d{4}", // DD-MM-YYYY
];

for format in date_formats {
let re = Regex::new(format).unwrap();
if let Some(captures) = re.captures(date_string.clone().unwrap().to_string().as_str()) {
if let Some(date) = captures.get(0) {
if let Some(converted_date) = convert_date(date.as_str()) {
return Some(converted_date);
}
}
}
}
None
}
None
}

fn update_json(json_data: &JsonData, json_file_path: &String, dry_run: bool) {
if dry_run {
let json_string = serde_json::to_string(&json_data).unwrap();
println!("{json_string}");
return;
}
let json_string = serde_json::to_string_pretty(&json_data).unwrap();
std::fs::write(json_file_path, json_string).expect("Json File not Writeable!");
}

0 comments on commit 7749a84

Please sign in to comment.