SongRec/Internal formats/song history.csv: Difference between revisions
Appearance
| (2 intermediate revisions by the same user not shown) | |||
| Line 10: | Line 10: | ||
Relevant code: | Relevant code: | ||
== | <syntaxhighlight lang="rust"> | ||
use app_dirs::{get_app_root, AppDataType::*, AppInfo}; | |||
use directories::ProjectDirs; | |||
use std::error::Error; | |||
use std::fs::create_dir_all; | |||
#[cfg(not(windows))] | |||
use std::os::unix::fs::symlink; | |||
#[cfg(windows)] | |||
use std::os::windows::fs::symlink_dir; | |||
use std::path::PathBuf; | |||
use std::sync::LazyLock; | |||
const QUALIFIER: &str = ""; | |||
const ORGANIZATION: &str = "SongRec"; | |||
const APPLICATION: &str = "SongRec"; | |||
static PROJECT_DIRS: LazyLock<ProjectDirs> = | |||
LazyLock::new(|| ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION).unwrap()); | |||
pub fn obtain_recognition_history_csv_path() -> Result<PathBuf, Box<dyn Error>> { | |||
let mut csv_path = obtain_data_directory()?; | |||
csv_path.push("song_history.csv"); | |||
Ok(csv_path) | |||
} | |||
fn obtain_data_directory() -> Result<PathBuf, Box<dyn Error>> { | |||
let data_dir = PROJECT_DIRS.data_dir(); | |||
if !data_dir.exists() { | |||
let old_dir = get_old_data_dir_path()?; | |||
if old_dir.exists() { | |||
#[cfg(not(windows))] | |||
symlink(old_dir, data_dir)?; | |||
#[cfg(windows)] | |||
symlink_dir(old_dir, data_dir)?; | |||
} else { | |||
create_dir_all(data_dir)?; | |||
} | |||
} | |||
Ok(data_dir.to_path_buf()) | |||
} | |||
// Backwards compatibility | |||
fn get_old_data_dir_path() -> Result<PathBuf, Box<dyn Error>> { | |||
let app_info = AppInfo { | |||
name: "SongRec", | |||
author: "SongRec", | |||
}; | |||
Ok(get_app_root(UserData, &app_info)?) | |||
} | |||
</syntaxhighlight> | |||
== Columns == | |||
(WIP 2026-05-06) | (WIP 2026-05-06) | ||
The [https://github.com/marin-m/SongRec/blob/b738934/src/utils/csv_song_history.rs#L11 <code>SongHistoryRecord</code> structure defined in <code>src/utils/csv_song_history.rs</code>] holds a list of the columns/fields that can be serialized through the serde CSV crate, using the [https://github.com/marin-m/SongRec/blob/b738934/src/gui/song_history_interface.rs#L46 <code>RecognitionHistoryInterface</code> struct from <code>src/gui/song_history_interface.rs</code>] which implements trait [https://github.com/marin-m/SongRec/blob/b738934/src/gui/song_history_interface.rs#L57 <code>SongRecordInterface</code> from the same file]: | |||
<syntaxhighlight lang="rust"> | |||
use serde::{Deserialize, Serialize}; | |||
#[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)] | |||
pub struct SongHistoryRecord { | |||
pub song_name: String, | |||
#[serde(default)] | |||
pub album: Option<String>, | |||
// The following fields have been added in version 0.3.0 | |||
#[serde(default)] | |||
pub track_key: Option<String>, | |||
#[serde(default)] | |||
pub release_year: Option<String>, | |||
#[serde(default)] | |||
pub genre: Option<String>, | |||
pub recognition_date: String, | |||
} | |||
</syntaxhighlight> | |||
Latest revision as of 08:11, 6 May 2026
The song_history.csv file of SongRec is saved, under Linux, at the ~/.local/share/songrec/song_history.csv path by default, when using an unsandboxed environment.
It uses the CSV format.
Save location
(WIP 2026-05-06)
The location for the song_history.csv file is calculated through the obtain_recognition_history_csv_path function of src/utils/filesystem_operations.rs.
Relevant code:
use app_dirs::{get_app_root, AppDataType::*, AppInfo};
use directories::ProjectDirs;
use std::error::Error;
use std::fs::create_dir_all;
#[cfg(not(windows))]
use std::os::unix::fs::symlink;
#[cfg(windows)]
use std::os::windows::fs::symlink_dir;
use std::path::PathBuf;
use std::sync::LazyLock;
const QUALIFIER: &str = "";
const ORGANIZATION: &str = "SongRec";
const APPLICATION: &str = "SongRec";
static PROJECT_DIRS: LazyLock<ProjectDirs> =
LazyLock::new(|| ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION).unwrap());
pub fn obtain_recognition_history_csv_path() -> Result<PathBuf, Box<dyn Error>> {
let mut csv_path = obtain_data_directory()?;
csv_path.push("song_history.csv");
Ok(csv_path)
}
fn obtain_data_directory() -> Result<PathBuf, Box<dyn Error>> {
let data_dir = PROJECT_DIRS.data_dir();
if !data_dir.exists() {
let old_dir = get_old_data_dir_path()?;
if old_dir.exists() {
#[cfg(not(windows))]
symlink(old_dir, data_dir)?;
#[cfg(windows)]
symlink_dir(old_dir, data_dir)?;
} else {
create_dir_all(data_dir)?;
}
}
Ok(data_dir.to_path_buf())
}
// Backwards compatibility
fn get_old_data_dir_path() -> Result<PathBuf, Box<dyn Error>> {
let app_info = AppInfo {
name: "SongRec",
author: "SongRec",
};
Ok(get_app_root(UserData, &app_info)?)
}
Columns
(WIP 2026-05-06)
The SongHistoryRecord structure defined in src/utils/csv_song_history.rs holds a list of the columns/fields that can be serialized through the serde CSV crate, using the RecognitionHistoryInterface struct from src/gui/song_history_interface.rs which implements trait SongRecordInterface from the same file:
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)]
pub struct SongHistoryRecord {
pub song_name: String,
#[serde(default)]
pub album: Option<String>,
// The following fields have been added in version 0.3.0
#[serde(default)]
pub track_key: Option<String>,
#[serde(default)]
pub release_year: Option<String>,
#[serde(default)]
pub genre: Option<String>,
pub recognition_date: String,
}