mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Remove server synchronization code
This commit (tries to) remove all code for synchronyzing to a music metadata server. Because the intended use cases of the application have shifted over time, this isn't a central feature anymore. However, it may well be decided to reintroduce the functionality at some point in the future.
This commit is contained in:
parent
384ca255f3
commit
f165c6cae8
48 changed files with 96 additions and 2633 deletions
|
|
@ -10,7 +10,6 @@ glib = "0.14.0"
|
|||
gstreamer = "0.17.0"
|
||||
gstreamer-player = "0.17.0"
|
||||
log = { version = "0.4.14", features = ["std"] }
|
||||
musicus_client = { version = "0.1.0", path = "../client" }
|
||||
musicus_database = { version = "0.1.0", path = "../database" }
|
||||
musicus_import = { version = "0.1.0", path = "../import" }
|
||||
thiserror = "1.0.23"
|
||||
|
|
@ -18,4 +17,3 @@ tokio = { version = "1.4.0", features = ["sync"] }
|
|||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
mpris-player = "0.6.0"
|
||||
secret-service = "2.0.1"
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
/// An error that can happened within the backend.
|
||||
/// An error that happened within the backend.
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
ClientError(#[from] musicus_client::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
DatabaseError(#[from] musicus_database::Error),
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[error("An error happened using the SecretService.")]
|
||||
SecretServiceError(#[from] secret_service::Error),
|
||||
|
||||
#[error("An error happened while decoding to UTF-8.")]
|
||||
Utf8Error(#[from] std::str::Utf8Error),
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
use gio::prelude::*;
|
||||
use log::warn;
|
||||
use musicus_client::{Client, LoginData};
|
||||
use musicus_database::DbThread;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::RefCell;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use tokio::sync::{broadcast, broadcast::Sender};
|
||||
|
||||
pub use musicus_client as client;
|
||||
pub use musicus_database as db;
|
||||
pub use musicus_import as import;
|
||||
|
||||
|
|
@ -22,9 +18,6 @@ mod logger;
|
|||
pub mod player;
|
||||
pub use player::*;
|
||||
|
||||
#[cfg(all(feature = "dbus"))]
|
||||
mod secure;
|
||||
|
||||
/// General states the application can be in.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BackendState {
|
||||
|
|
@ -49,9 +42,6 @@ pub struct Backend {
|
|||
/// Access to GSettings.
|
||||
settings: gio::Settings,
|
||||
|
||||
/// Whether the server should be used by default when searching for or changing items.
|
||||
use_server: Cell<bool>,
|
||||
|
||||
/// The current path to the music library, which is used by the player and the database. This
|
||||
/// is guaranteed to be Some, when the state is set to BackendState::Ready.
|
||||
music_library_path: RefCell<Option<PathBuf>>,
|
||||
|
|
@ -65,9 +55,6 @@ pub struct Backend {
|
|||
/// The player handling playlist and playback. This can be assumed to exist, when the state is
|
||||
/// set to BackendState::Ready.
|
||||
player: RefCell<Option<Rc<Player>>>,
|
||||
|
||||
/// A client for the Wolfgang server.
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
|
|
@ -83,12 +70,10 @@ impl Backend {
|
|||
Backend {
|
||||
state_sender,
|
||||
settings: gio::Settings::new("de.johrpan.musicus"),
|
||||
use_server: Cell::new(true),
|
||||
music_library_path: RefCell::new(None),
|
||||
library_updated_sender,
|
||||
database: RefCell::new(None),
|
||||
player: RefCell::new(None),
|
||||
client: Client::new(),
|
||||
player: RefCell::new(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,24 +87,6 @@ impl Backend {
|
|||
pub async fn init(&self) -> Result<()> {
|
||||
self.init_library().await?;
|
||||
|
||||
let url = self.settings.string("server-url");
|
||||
if !url.is_empty() {
|
||||
self.client.set_server_url(&url);
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "dbus"))]
|
||||
match Self::load_login_data().await {
|
||||
Ok(Some(data)) => self.client.set_login_data(Some(data)),
|
||||
Err(err) => warn!(
|
||||
"The login data could not be loaded from SecretService. It will not \
|
||||
be available. Error message: {}",
|
||||
err
|
||||
),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
self.use_server.set(self.settings.boolean("use-server"));
|
||||
|
||||
if self.get_music_library_path().is_none() {
|
||||
self.set_state(BackendState::NoMusicLibrary);
|
||||
} else {
|
||||
|
|
@ -129,80 +96,6 @@ impl Backend {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Whether the server should be used by default.
|
||||
///
|
||||
/// This will return `false` if no server URL is set up. Otherwise, the
|
||||
/// value is based on the users "use-server" preference.
|
||||
pub fn use_server(&self) -> bool {
|
||||
self.client.get_server_url().is_some() && self.use_server.get()
|
||||
}
|
||||
|
||||
/// Set whether the server should be used by default.
|
||||
pub fn set_use_server(&self, enabled: bool) {
|
||||
self.use_server.set(enabled);
|
||||
|
||||
if let Err(err) = self.settings.set_boolean("use-server", enabled) {
|
||||
warn!(
|
||||
"An error happened whilte trying to save the \"use-server\" setting to GSettings. \
|
||||
Error message: {}",
|
||||
err
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the URL of the Musicus server to connect to.
|
||||
pub fn set_server_url(&self, url: &str) {
|
||||
if let Err(err) = self.settings.set_string("server-url", url) {
|
||||
warn!(
|
||||
"An error happened while trying to save the server URL to GSettings. Most \
|
||||
likely it will not be available at the next startup. Error message: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
self.client.set_server_url(url);
|
||||
}
|
||||
|
||||
/// Get the currently set server URL.
|
||||
pub fn get_server_url(&self) -> Option<String> {
|
||||
self.client.get_server_url()
|
||||
}
|
||||
|
||||
/// Set the user credentials to use.
|
||||
pub async fn set_login_data(&self, data: Option<LoginData>) {
|
||||
#[cfg(all(feature = "dbus"))]
|
||||
if let Some(data) = &data {
|
||||
if let Err(err) = Self::store_login_data(data.clone()).await {
|
||||
warn!(
|
||||
"An error happened while trying to store the login data using SecretService. \
|
||||
This means, that they will not be available at the next startup most likely. \
|
||||
Error message: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if let Err(err) = Self::delete_secrets().await {
|
||||
warn!(
|
||||
"An error happened while trying to delete the login data from SecretService. \
|
||||
This may result in the login data being reloaded at the next startup. Error \
|
||||
message: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.client.set_login_data(data);
|
||||
}
|
||||
|
||||
pub fn cl(&self) -> &Client {
|
||||
&self.client
|
||||
}
|
||||
|
||||
/// Get the currently stored login credentials.
|
||||
pub fn get_login_data(&self) -> Option<LoginData> {
|
||||
self.client.get_login_data()
|
||||
}
|
||||
|
||||
/// Set the current state and notify the user interface.
|
||||
fn set_state(&self, state: BackendState) {
|
||||
self.state_sender.send(state).unwrap();
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
use crate::{Backend, Error, Result};
|
||||
use futures_channel::oneshot;
|
||||
use musicus_client::LoginData;
|
||||
use secret_service::{Collection, EncryptionType, SecretService};
|
||||
use std::collections::HashMap;
|
||||
use std::thread;
|
||||
|
||||
impl Backend {
|
||||
/// Get the login credentials from secret storage.
|
||||
pub(super) async fn load_login_data() -> Result<Option<LoginData>> {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
thread::spawn(move || sender.send(Self::load_login_data_priv()).unwrap());
|
||||
receiver.await?
|
||||
}
|
||||
|
||||
/// Savely store the user's current login credentials.
|
||||
pub(super) async fn store_login_data(data: LoginData) -> Result<()> {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
thread::spawn(move || sender.send(Self::store_login_data_priv(data)).unwrap());
|
||||
receiver.await?
|
||||
}
|
||||
|
||||
/// Delete all stored secrets.
|
||||
pub(super) async fn delete_secrets() -> Result<()> {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
thread::spawn(move || sender.send(Self::delete_secrets_priv()).unwrap());
|
||||
receiver.await?
|
||||
}
|
||||
|
||||
/// Get the login credentials from secret storage.
|
||||
fn load_login_data_priv() -> Result<Option<LoginData>> {
|
||||
let ss = SecretService::new(EncryptionType::Dh)?;
|
||||
let collection = Self::get_collection(&ss)?;
|
||||
|
||||
let items = collection.get_all_items()?;
|
||||
|
||||
let key = "musicus-login-data";
|
||||
let item = items
|
||||
.iter()
|
||||
.find(|item| item.get_label().unwrap_or_default() == key);
|
||||
|
||||
Ok(match item {
|
||||
Some(item) => {
|
||||
let username = item
|
||||
.get_attributes()?
|
||||
.get("username")
|
||||
.ok_or(Error::Other(
|
||||
"Missing username in SecretService attributes.",
|
||||
))?
|
||||
.to_owned();
|
||||
|
||||
let password = std::str::from_utf8(&item.get_secret()?)?.to_owned();
|
||||
|
||||
Some(LoginData { username, password })
|
||||
}
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Savely store the user's current login credentials.
|
||||
fn store_login_data_priv(data: LoginData) -> Result<()> {
|
||||
let ss = SecretService::new(EncryptionType::Dh)?;
|
||||
let collection = Self::get_collection(&ss)?;
|
||||
|
||||
let key = "musicus-login-data";
|
||||
Self::delete_secrets_for_key(&collection, key)?;
|
||||
|
||||
let mut attributes = HashMap::new();
|
||||
attributes.insert("username", data.username.as_str());
|
||||
collection.create_item(
|
||||
key,
|
||||
attributes,
|
||||
data.password.as_bytes(),
|
||||
true,
|
||||
"text/plain",
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete all stored secrets.
|
||||
fn delete_secrets_priv() -> Result<()> {
|
||||
let ss = SecretService::new(EncryptionType::Dh)?;
|
||||
let collection = Self::get_collection(&ss)?;
|
||||
|
||||
let key = "musicus-login-data";
|
||||
Self::delete_secrets_for_key(&collection, key)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete all stored secrets for the provided key.
|
||||
fn delete_secrets_for_key(collection: &Collection, key: &str) -> Result<()> {
|
||||
let items = collection.get_all_items()?;
|
||||
|
||||
for item in items {
|
||||
if item.get_label().unwrap_or_default() == key {
|
||||
item.delete()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the default SecretService collection and unlock it.
|
||||
fn get_collection<'a>(ss: &'a SecretService) -> Result<Collection<'a>> {
|
||||
let collection = ss.get_default_collection()?;
|
||||
collection.unlock()?;
|
||||
|
||||
Ok(collection)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue