roezio: migrate poezio/xdg.py
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
5fdcb95e8a
commit
5dcccad90b
11 changed files with 94 additions and 55 deletions
|
@ -17,6 +17,7 @@ ncurses = "5"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
enum-set = "0.0"
|
enum-set = "0.0"
|
||||||
clap = { version = "3.2.17", features = ["derive"] }
|
clap = { version = "3.2.17", features = ["derive"] }
|
||||||
|
directories = "4.0.1"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
|
@ -19,7 +19,7 @@ from configparser import RawConfigParser, NoOptionError, NoSectionError
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Union, Tuple, cast, Any
|
from typing import Dict, List, Optional, Union, Tuple, cast, Any
|
||||||
|
|
||||||
from poezio import xdg
|
from poezio.libpoezio import XDG
|
||||||
from slixmpp import JID, InvalidJID
|
from slixmpp import JID, InvalidJID
|
||||||
|
|
||||||
log = logging.getLogger(__name__) # type: logging.Logger
|
log = logging.getLogger(__name__) # type: logging.Logger
|
||||||
|
@ -603,7 +603,7 @@ def get_image_cache() -> Optional[Path]:
|
||||||
tmp_dir = config.getstr('tmp_image_dir')
|
tmp_dir = config.getstr('tmp_image_dir')
|
||||||
if tmp_dir:
|
if tmp_dir:
|
||||||
return Path(tmp_dir)
|
return Path(tmp_dir)
|
||||||
return xdg.CACHE_HOME / 'images'
|
return XDG.cache_dir / 'images'
|
||||||
|
|
||||||
|
|
||||||
def check_config():
|
def check_config():
|
||||||
|
@ -656,7 +656,7 @@ def setup_logging(debug_file=''):
|
||||||
"Change the logging config according to the cmdline options and config"
|
"Change the logging config according to the cmdline options and config"
|
||||||
global LOG_DIR
|
global LOG_DIR
|
||||||
LOG_DIR = config.get('log_dir')
|
LOG_DIR = config.get('log_dir')
|
||||||
LOG_DIR = Path(LOG_DIR).expanduser() if LOG_DIR else xdg.DATA_HOME / 'logs'
|
LOG_DIR = Path(LOG_DIR).expanduser() if LOG_DIR else XDG.data_dir / 'logs'
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
logging_config = deepcopy(LOGGING_CONFIG)
|
logging_config = deepcopy(LOGGING_CONFIG)
|
||||||
if config.get('log_errors'):
|
if config.get('log_errors'):
|
||||||
|
|
|
@ -27,7 +27,7 @@ from slixmpp.util import FileSystemCache
|
||||||
|
|
||||||
from poezio import common
|
from poezio import common
|
||||||
from poezio import fixes
|
from poezio import fixes
|
||||||
from poezio import xdg
|
from poezio.libpoezio import XDG
|
||||||
from poezio.config import config
|
from poezio.config import config
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class Connection(slixmpp.ClientXMPP):
|
||||||
'https://poez.io',
|
'https://poez.io',
|
||||||
'cache':
|
'cache':
|
||||||
FileSystemCache(
|
FileSystemCache(
|
||||||
str(xdg.CACHE_HOME),
|
str(XDG.cache_dir),
|
||||||
'caps',
|
'caps',
|
||||||
encode=str,
|
encode=str,
|
||||||
decode=lambda x: DiscoInfo(ET.fromstring(x))),
|
decode=lambda x: DiscoInfo(ET.fromstring(x))),
|
||||||
|
|
|
@ -11,7 +11,7 @@ from slixmpp import JID, InvalidJID
|
||||||
|
|
||||||
from poezio import common
|
from poezio import common
|
||||||
from poezio import tabs
|
from poezio import tabs
|
||||||
from poezio import xdg
|
from poezio.libpoezio import XDG
|
||||||
from poezio.config import config
|
from poezio.config import config
|
||||||
from poezio.roster import roster
|
from poezio.roster import roster
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ class CompletionCore:
|
||||||
""" Completion for /theme"""
|
""" Completion for /theme"""
|
||||||
themes_dir = config.getstr('themes_dir')
|
themes_dir = config.getstr('themes_dir')
|
||||||
themes_dir = Path(themes_dir).expanduser(
|
themes_dir = Path(themes_dir).expanduser(
|
||||||
) if themes_dir else xdg.DATA_HOME / 'themes'
|
) if themes_dir else XDG.data_dir / 'themes'
|
||||||
try:
|
try:
|
||||||
theme_files = [
|
theme_files = [
|
||||||
name.stem for name in themes_dir.iterdir()
|
name.stem for name in themes_dir.iterdir()
|
||||||
|
|
|
@ -66,7 +66,8 @@ from poezio.size_manager import SizeManager
|
||||||
from poezio.user import User
|
from poezio.user import User
|
||||||
from poezio.text_buffer import TextBuffer
|
from poezio.text_buffer import TextBuffer
|
||||||
from poezio.timed_events import DelayedEvent
|
from poezio.timed_events import DelayedEvent
|
||||||
from poezio import keyboard, xdg
|
from poezio import keyboard
|
||||||
|
from poezio.libpoezio import XDG
|
||||||
|
|
||||||
from poezio.core.completions import CompletionCore
|
from poezio.core.completions import CompletionCore
|
||||||
from poezio.core.tabs import Tabs
|
from poezio.core.tabs import Tabs
|
||||||
|
@ -154,7 +155,7 @@ class Core:
|
||||||
self.bookmarks = BookmarkList()
|
self.bookmarks = BookmarkList()
|
||||||
self.remote_fifo = None
|
self.remote_fifo = None
|
||||||
self.avatar_cache = FileSystemPerJidCache(
|
self.avatar_cache = FileSystemPerJidCache(
|
||||||
str(xdg.CACHE_HOME), 'avatars', binary=True)
|
str(XDG.cache_dir), 'avatars', binary=True)
|
||||||
# a unique buffer used to store global information
|
# a unique buffer used to store global information
|
||||||
# that are displayed in almost all tabs, in an
|
# that are displayed in almost all tabs, in an
|
||||||
# information window.
|
# information window.
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
def to_curses_attr(fg: int, bg: int, attrs: str) -> int: ...
|
def to_curses_attr(fg: int, bg: int, attrs: str) -> int: ...
|
||||||
def run_cmdline_args(argv: List[str]) -> Tuple[Dict[Any, Any], bool]: ...
|
def run_cmdline_args(argv: List[str]) -> Tuple[Dict[Any, Any], bool]: ...
|
||||||
|
|
||||||
|
class XDG:
|
||||||
|
cache_dir: Path
|
||||||
|
config_dir: Path
|
||||||
|
data_dir: Path
|
||||||
|
|
|
@ -13,7 +13,8 @@ from pathlib import Path
|
||||||
from os import path
|
from os import path
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
from poezio import tabs, xdg
|
from poezio import tabs
|
||||||
|
from poezio.libpoezio import XDG
|
||||||
from poezio.core.structs import Command, Completion
|
from poezio.core.structs import Command, Completion
|
||||||
from poezio.plugin import PluginAPI
|
from poezio.plugin import PluginAPI
|
||||||
from poezio.config import config
|
from poezio.config import config
|
||||||
|
@ -395,7 +396,7 @@ class PluginManager:
|
||||||
"""
|
"""
|
||||||
plugins_conf_dir = config.getstr('plugins_conf_dir')
|
plugins_conf_dir = config.getstr('plugins_conf_dir')
|
||||||
self.plugins_conf_dir = Path(plugins_conf_dir).expanduser(
|
self.plugins_conf_dir = Path(plugins_conf_dir).expanduser(
|
||||||
) if plugins_conf_dir else xdg.CONFIG_HOME / 'plugins'
|
) if plugins_conf_dir else XDG.config_dir / 'plugins'
|
||||||
self.check_create_plugins_conf_dir()
|
self.check_create_plugins_conf_dir()
|
||||||
|
|
||||||
def check_create_plugins_conf_dir(self):
|
def check_create_plugins_conf_dir(self):
|
||||||
|
@ -420,7 +421,7 @@ class PluginManager:
|
||||||
"""
|
"""
|
||||||
plugins_dir = config.getstr('plugins_dir')
|
plugins_dir = config.getstr('plugins_dir')
|
||||||
self.plugins_dir = Path(plugins_dir).expanduser(
|
self.plugins_dir = Path(plugins_dir).expanduser(
|
||||||
) if plugins_dir else xdg.DATA_HOME / 'plugins'
|
) if plugins_dir else XDG.data_dir / 'plugins'
|
||||||
self.check_create_plugins_dir()
|
self.check_create_plugins_dir()
|
||||||
|
|
||||||
def check_create_plugins_dir(self):
|
def check_create_plugins_dir(self):
|
||||||
|
|
|
@ -77,7 +77,7 @@ from typing import Dict, List, Union, Tuple, Optional, cast
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from os import path
|
from os import path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from poezio import colors, xdg, libpoezio
|
from poezio import colors, libpoezio
|
||||||
|
|
||||||
from importlib import machinery
|
from importlib import machinery
|
||||||
finder = machinery.PathFinder()
|
finder = machinery.PathFinder()
|
||||||
|
@ -450,7 +450,7 @@ def update_themes_dir(option: Optional[str] = None,
|
||||||
# import from the user-defined prefs
|
# import from the user-defined prefs
|
||||||
themes_dir_str = config.getstr('themes_dir')
|
themes_dir_str = config.getstr('themes_dir')
|
||||||
themes_dir = Path(themes_dir_str).expanduser(
|
themes_dir = Path(themes_dir_str).expanduser(
|
||||||
) if themes_dir_str else xdg.DATA_HOME / 'themes'
|
) if themes_dir_str else libpoezio.XDG.data_dir / 'themes'
|
||||||
try:
|
try:
|
||||||
themes_dir.mkdir(parents=True, exist_ok=True)
|
themes_dir.mkdir(parents=True, exist_ok=True)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
# Copyright 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
|
||||||
#
|
|
||||||
# This file is part of Poezio.
|
|
||||||
#
|
|
||||||
# Poezio is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GPL-3.0+ license. See the COPYING file.
|
|
||||||
"""
|
|
||||||
Implements the XDG base directory specification.
|
|
||||||
|
|
||||||
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from os import environ
|
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
# $HOME has already been checked to not be None in test_env().
|
|
||||||
DEFAULT_PATHS: Dict[str, Path] = {
|
|
||||||
'XDG_CONFIG_HOME': Path.home() / '.config',
|
|
||||||
'XDG_DATA_HOME': Path.home() / '.local' / 'share',
|
|
||||||
'XDG_CACHE_HOME': Path.home() / '.cache',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _get_directory(variable: str) -> Path:
|
|
||||||
"""
|
|
||||||
returns the default configuration directory path
|
|
||||||
"""
|
|
||||||
if variable not in DEFAULT_PATHS:
|
|
||||||
raise ValueError('Invalid XDG basedir variable')
|
|
||||||
xdg = environ.get(variable)
|
|
||||||
if xdg is not None:
|
|
||||||
xdg_path = Path(xdg)
|
|
||||||
if xdg_path.is_absolute():
|
|
||||||
return xdg_path / 'poezio'
|
|
||||||
return DEFAULT_PATHS[variable] / 'poezio'
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_HOME = _get_directory('XDG_CONFIG_HOME')
|
|
||||||
DATA_HOME = _get_directory('XDG_DATA_HOME')
|
|
||||||
CACHE_HOME = _get_directory('XDG_CACHE_HOME')
|
|
|
@ -4,6 +4,7 @@ mod args;
|
||||||
mod error;
|
mod error;
|
||||||
mod logger;
|
mod logger;
|
||||||
mod theming;
|
mod theming;
|
||||||
|
mod xdg;
|
||||||
|
|
||||||
use crate::args::parse_args;
|
use crate::args::parse_args;
|
||||||
use crate::logger::LogItem;
|
use crate::logger::LogItem;
|
||||||
|
@ -27,6 +28,7 @@ fn libpoezio(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
m.add_function(wrap_pyfunction!(to_curses_attr, m)?)?;
|
m.add_function(wrap_pyfunction!(to_curses_attr, m)?)?;
|
||||||
m.add_function(wrap_pyfunction!(parse_logs, m)?)?;
|
m.add_function(wrap_pyfunction!(parse_logs, m)?)?;
|
||||||
m.add_function(wrap_pyfunction!(run_cmdline_args, m)?)?;
|
m.add_function(wrap_pyfunction!(run_cmdline_args, m)?)?;
|
||||||
|
m.add("XDG", xdg::PyProject::new(xdg::PROJECT.clone()))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
69
src/xdg.rs
Normal file
69
src/xdg.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (C) 2018-2099 The crate authors.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
// option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::cell::LazyCell;
|
||||||
|
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
use pyo3::{
|
||||||
|
marker::Python,
|
||||||
|
prelude::{pyclass, pymethods, PyObject, PyResult},
|
||||||
|
IntoPy,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Project qualifier
|
||||||
|
pub const QUALIFIER: &'static str = "io";
|
||||||
|
/// Project organization
|
||||||
|
pub const ORGANIZATION: &'static str = "poez";
|
||||||
|
/// Project appname
|
||||||
|
pub const APPNAME: &'static str = "Poezio";
|
||||||
|
|
||||||
|
/// Project directories
|
||||||
|
pub const PROJECT: LazyCell<ProjectDirs> = LazyCell::new(|| {
|
||||||
|
ProjectDirs::from(QUALIFIER, ORGANIZATION, APPNAME).expect("HOME dir should be available.")
|
||||||
|
});
|
||||||
|
|
||||||
|
#[pyclass(name = "XDG")]
|
||||||
|
pub struct PyProject(ProjectDirs);
|
||||||
|
|
||||||
|
fn get_path(py: Python<'_>) -> PyResult<PyObject> {
|
||||||
|
// TODO: Stop importing pathlib all the time
|
||||||
|
let pathlib = py.import("pathlib")?;
|
||||||
|
let path = pathlib.getattr("Path")?;
|
||||||
|
Ok(path.into_py(py))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PyProject {
|
||||||
|
pub fn new(dirs: ProjectDirs) -> Self {
|
||||||
|
PyProject(dirs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl PyProject {
|
||||||
|
#[getter]
|
||||||
|
pub fn cache_dir(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||||
|
Ok(get_path(py)?.call1(py, (self.0.cache_dir(),))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
pub fn config_dir(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||||
|
Ok(get_path(py)?.call1(py, (self.0.config_dir(),))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
pub fn data_dir(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||||
|
Ok(get_path(py)?.call1(py, (self.0.data_dir(),))?)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue