#[cfg(feature = "pyo3")]
use pyo3::prelude::*;
use std::env;
use std::path::PathBuf;
use sysinfo::System;
use super::error::{Error, Result};
pub fn app_dir() -> Result<PathBuf> {
#[cfg(target_os = "macos")]
{
match env::var_os("HOME") {
Some(h) if !h.is_empty() => {
let home = PathBuf::from(h);
Ok(home.join("Library").join("Application Support"))
}
_ => Err(Error::EnvionmentNotFound("$HOME".into())),
}
}
#[cfg(target_os = "windows")]
{
match env::var_os("APPDATA") {
Some(p) if !p.is_empty() => Ok(PathBuf::from(p)),
_ => Err(Error::EnvionmentNotFound("%APPDATA%".into())),
}
}
#[cfg(target_os = "linux")]
{
match env::var_os("XDG_DATA_HOME") {
Some(p) if !p.is_empty() => Ok(PathBuf::from(p)),
_ => {
match env::var_os("HOME") {
Some(h) if !h.is_empty() => {
let home = PathBuf::from(h);
Ok(home.join(".local").join("share"))
}
_ => Err(Error::EnvionmentNotFound("$XDG_DATA_HOME or $HOME".into())),
}
}
}
}
}
#[cfg(target_os = "macos")]
pub fn library_dir() -> Result<PathBuf> {
match env::var_os("HOME") {
Some(h) if !h.is_empty() => {
let home = PathBuf::from(h);
Ok(home.join("Library"))
}
_ => Err(Error::EnvionmentNotFound("$HOME".into())),
}
}
pub fn rekordbox_agent_app_dir() -> Result<PathBuf> {
let app_dir = app_dir()?;
let path = app_dir.join("Pioneer").join("rekordboxAgent");
if !path.exists() {
Err(Error::FileNotFound(path.display().to_string()))
} else {
Ok(path)
}
}
pub fn rekordbox_app_dir() -> Result<PathBuf> {
let app_dir = app_dir()?;
let path = app_dir.join("Pioneer").join("rekordbox");
if !path.exists() {
Err(Error::FileNotFound(path.display().to_string()))
} else {
Ok(path)
}
}
pub fn options_json_path() -> Result<PathBuf> {
let app_dir = rekordbox_agent_app_dir()?;
let path = app_dir.join("storage").join("options.json");
if !path.exists() {
Err(Error::FileNotFound(path.display().to_string()))
} else {
Ok(path)
}
}
pub fn default_master_db_path() -> Result<PathBuf> {
#[cfg(target_os = "macos")]
{
let lib_dir = library_dir()?;
let path = lib_dir.join("Pioneer").join("rekordbox").join("master.db");
if !path.exists() {
let path = lib_dir
.join("Application Support")
.join("Pioneer")
.join("rekordbox")
.join("master.db");
if !path.exists() {
Err(Error::FileNotFound(path.display().to_string()))
} else {
Ok(path)
}
} else {
Ok(path)
}
}
#[cfg(not(target_os = "macos"))]
{
let app_dir = rekordbox_app_dir()?;
let path = app_dir.join("master.db");
if !path.exists() {
Err(Error::FileNotFound(path.display().to_string()))
} else {
Ok(path)
}
}
}
#[deprecated(since = "0.1.5", note = "use the `RekordboxOptions` handler instead!")]
pub fn get_rekordbox_share_path() -> Result<PathBuf> {
let app_dir = rekordbox_app_dir()?;
let path = app_dir.join("share");
if !path.exists() {
return Err(Error::FileNotFound(path.display().to_string()));
};
Ok(path)
}
#[deprecated(since = "0.1.5", note = "use the `RekordboxOptions` handler instead!")]
pub fn get_master_playlist_xml_path() -> Result<PathBuf> {
let app_dir = rekordbox_app_dir()?;
let path = app_dir.join("masterPlaylists6.xml");
if !path.exists() {
return Err(Error::FileNotFound(path.display().to_string()));
};
Ok(path)
}
#[deprecated(
since = "0.1.5",
note = "use `RekordboxOptions` or `default_master_db_path` instead"
)]
pub fn get_master_db_path() -> Result<PathBuf> {
let app_dir = rekordbox_app_dir()?;
let path = app_dir.join("master.db");
if !path.exists() {
return Err(Error::FileNotFound(path.display().to_string()));
};
Ok(path)
}
#[derive(Debug, Eq, PartialEq)]
pub struct Process {
pub pid: u32,
pub name: String,
}
pub fn get_rekordbox_processes() -> Vec<Process> {
let s = System::new_all();
let mut processes: Vec<Process> = Vec::new();
for (pid, process) in s.processes() {
if let Some(name) = process.name().to_str() {
let name: &str = name.trim_end_matches(".exe");
if name.contains::<&str>("rekordbox".as_ref()) {
let proc = Process {
pid: pid.as_u32(),
name: name.to_string(),
};
processes.push(proc);
}
}
}
processes
}
pub fn get_rekordbox_pid() -> Option<i32> {
let s = System::new_all();
for (pid, process) in s.processes() {
if let Some(name) = process.name().to_str() {
let name: &str = name.trim_end_matches(".exe");
if name.to_lowercase() == "rekordbox" {
return Some(pid.as_u32() as i32);
}
}
}
None
}
pub fn is_rekordbox_running() -> bool {
get_rekordbox_pid().is_some()
}
#[cfg(feature = "pyo3")]
#[pyclass]
pub struct PyStrIter {
pub inner: std::vec::IntoIter<String>,
}
#[cfg(feature = "pyo3")]
impl PyStrIter {
pub fn new(items: Vec<String>) -> Self {
Self {
inner: items.into_iter(),
}
}
}
#[cfg(feature = "pyo3")]
#[pymethods]
impl PyStrIter {
pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
pub fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<String> {
slf.inner.next()
}
}
#[cfg(feature = "pyo3")]
#[pyclass]
pub struct PyObjectIter {
pub inner: std::vec::IntoIter<Py<PyAny>>,
}
#[cfg(feature = "pyo3")]
impl PyObjectIter {
pub fn new(items: Vec<Py<PyAny>>) -> Self {
Self {
inner: items.into_iter(),
}
}
}
#[cfg(feature = "pyo3")]
#[pymethods]
impl PyObjectIter {
pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
pub fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<Py<PyAny>> {
slf.inner.next()
}
}
#[cfg(feature = "pyo3")]
#[pyclass]
pub struct PyItemsIter {
pub inner: std::vec::IntoIter<(String, Py<PyAny>)>,
}
#[cfg(feature = "pyo3")]
impl PyItemsIter {
pub fn new(items: Vec<(String, Py<PyAny>)>) -> Self {
Self {
inner: items.into_iter(),
}
}
}
#[cfg(feature = "pyo3")]
#[pymethods]
impl PyItemsIter {
pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
pub fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<(String, Py<PyAny>)> {
slf.inner.next()
}
}