Merge pull request #7709 from AppFlowy-IO/refactor_path_name

chore: rename data path
This commit is contained in:
Nathan.fooo 2025-04-08 21:19:07 +08:00 committed by GitHub
commit eae4e42dcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 71 additions and 27 deletions

View File

@ -73,10 +73,10 @@ Future<Directory> appFlowyApplicationDataDirectory() async {
case IntegrationMode.develop:
final Directory documentsDir = await getApplicationSupportDirectory()
.then((directory) => directory.create());
return Directory(path.join(documentsDir.path, 'data_dev')).create();
return Directory(path.join(documentsDir.path, 'data_dev'));
case IntegrationMode.release:
final Directory documentsDir = await getApplicationSupportDirectory();
return Directory(path.join(documentsDir.path, 'data')).create();
return Directory(path.join(documentsDir.path, 'data'));
case IntegrationMode.unitTest:
case IntegrationMode.integrationTest:
return Directory(path.join(Directory.current.path, '.sandbox'));

View File

@ -8,7 +8,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
show SignInPayloadPB, SignUpPayloadPB, UserProfilePB;
import 'package:appflowy_result/appflowy_result.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/uuid.dart';
import '../../../generated/locale_keys.g.dart';
import 'device_id.dart';
@ -65,8 +64,7 @@ class BackendAuthService implements AuthService {
Map<String, String> params = const {},
}) async {
const password = "Guest!@123456";
final uid = uuid();
final userEmail = "$uid@appflowy.io";
final userEmail = "anon@appflowy.io";
final request = SignUpPayloadPB.create()
..name = LocaleKeys.defaultUsername.tr()

View File

@ -2604,6 +2604,7 @@ dependencies = [
"tokio",
"tokio-stream",
"tracing",
"url",
"uuid",
]
@ -3049,7 +3050,6 @@ dependencies = [
"collab-user",
"dashmap 6.0.1",
"diesel",
"diesel_derives",
"fake",
"fancy-regex 0.11.0",
"flowy-codegen",
@ -3064,7 +3064,6 @@ dependencies = [
"lib-dispatch",
"lib-infra",
"nanoid",
"once_cell",
"protobuf",
"quickcheck",
"quickcheck_macros",
@ -3074,7 +3073,6 @@ dependencies = [
"semver",
"serde",
"serde_json",
"serde_repr",
"strum",
"strum_macros 0.25.2",
"tokio",

View File

@ -58,6 +58,7 @@ serde_repr.workspace = true
uuid.workspace = true
sysinfo = "0.30.5"
semver = { version = "1.0.22", features = ["serde"] }
url = "2.5.0"
[features]
profiling = ["console-subscriber", "tokio/tracing"]

View File

@ -1,9 +1,10 @@
use std::fmt;
use std::path::Path;
use std::path::{Path, PathBuf};
use base64::Engine;
use semver::Version;
use tracing::{error, info};
use url::Url;
use crate::log_filter::create_log_filter;
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
@ -28,7 +29,25 @@ pub struct AppFlowyCoreConfig {
pub(crate) log_filter: String,
pub cloud_config: Option<AFCloudConfiguration>,
}
impl AppFlowyCoreConfig {
pub fn ensure_path(&self) {
let create_if_needed = |path_str: &str, label: &str| {
let dir = std::path::Path::new(path_str);
if !dir.exists() {
match std::fs::create_dir_all(dir) {
Ok(_) => info!("Created {} path: {}", label, path_str),
Err(err) => error!(
"Failed to create {} path: {}. Error: {}",
label, path_str, err
),
}
}
};
create_if_needed(&self.storage_path, "storage");
create_if_needed(&self.application_path, "application");
}
}
impl fmt::Debug for AppFlowyCoreConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug = f.debug_struct("AppFlowy Configuration");
@ -46,30 +65,60 @@ impl fmt::Debug for AppFlowyCoreConfig {
}
fn make_user_data_folder(root: &str, url: &str) -> String {
// Isolate the user data folder by using the base url of AppFlowy cloud. This is to avoid
// the user data folder being shared by different AppFlowy cloud.
let storage_path = if !url.is_empty() {
let server_base64 = URL_SAFE_ENGINE.encode(url);
format!("{}_{}", root, server_base64)
// If a URL is provided, try to parse it and extract the domain name.
// This isolates the user data folder by the domain, which prevents data sharing
// between different AppFlowy cloud instances.
print!("Creating user data folder for URL: {}, root:{}", url, root);
let mut storage_path = if url.is_empty() {
PathBuf::from(root)
} else {
root.to_string()
let server_base64 = URL_SAFE_ENGINE.encode(url);
PathBuf::from(format!("{}_{}", root, server_base64))
};
// Only use new storage path if the old one doesn't exist
if !storage_path.exists() {
let anon_path = format!("{}_anonymous", root);
// We use domain name as suffix to isolate the user data folder since version 0.8.9
let new_storage_path = if url.is_empty() {
// if the url is empty, then it's anonymous mode
anon_path
} else {
match Url::parse(url) {
Ok(parsed_url) => {
if let Some(domain) = parsed_url.host_str() {
format!("{}_{}", root, domain)
} else {
anon_path
}
},
Err(_) => anon_path,
}
};
storage_path = PathBuf::from(new_storage_path);
}
// Copy the user data folder from the root path to the isolated path
// The root path without any suffix is the created by the local version AppFlowy
if !Path::new(&storage_path).exists() && Path::new(root).exists() {
info!("Copy dir from {} to {}", root, storage_path);
if !storage_path.exists() && Path::new(root).exists() {
info!("Copy dir from {} to {:?}", root, storage_path);
let src = Path::new(root);
match copy_dir_recursive(src, Path::new(&storage_path)) {
Ok(_) => storage_path,
match copy_dir_recursive(src, &storage_path) {
Ok(_) => storage_path
.into_os_string()
.into_string()
.unwrap_or_else(|_| root.to_string()),
Err(err) => {
// when the copy dir failed, use the root path as the storage path
error!("Copy dir failed: {}", err);
root.to_string()
},
}
} else {
storage_path
.into_os_string()
.into_string()
.unwrap_or_else(|_| root.to_string())
}
}

View File

@ -105,6 +105,8 @@ impl AppFlowyCore {
#[instrument(skip(config, runtime))]
async fn init(config: AppFlowyCoreConfig, runtime: Arc<AFPluginRuntime>) -> Self {
config.ensure_path();
// Init the key value database
let store_preference = Arc::new(KVStorePreferences::new(&config.storage_path).unwrap());
info!("🔥{:?}", &config);

View File

@ -31,12 +31,9 @@ tracing.workspace = true
bytes.workspace = true
serde = { workspace = true, features = ["rc"] }
serde_json.workspace = true
serde_repr.workspace = true
protobuf.workspace = true
lazy_static = "1.4.0"
diesel.workspace = true
diesel_derives = { version = "2.1.0", features = ["sqlite", "r2d2"] }
once_cell = "1.17.1"
strum = "0.25"
strum_macros = "0.25.2"
tokio = { workspace = true, features = ["rt"] }

View File

@ -76,14 +76,14 @@ pub async fn sign_up(
let params: SignUpParams = data.into_inner().try_into()?;
let authenticator = params.auth_type.clone();
let old_authenticator = manager.cloud_services.get_user_authenticator();
let prev_authenticator = manager.cloud_services.get_user_authenticator();
match manager.sign_up(authenticator, BoxAny::new(params)).await {
Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
Err(err) => {
manager
.cloud_services
.set_user_authenticator(&old_authenticator);
return Err(err);
.set_user_authenticator(&prev_authenticator);
Err(err)
},
}
}

View File

@ -403,7 +403,6 @@ impl UserManager {
) -> Result<UserProfile, FlowyError> {
// sign out the current user if there is one
let migration_user = self.get_migration_user(&authenticator).await;
self.cloud_services.set_user_authenticator(&authenticator);
let auth_service = self.cloud_services.get_user_service()?;
let response: AuthResponse = auth_service.sign_up(params).await?;