Compare commits
1 commit
roezio
...
roezio-sta
Author | SHA1 | Date | |
---|---|---|---|
aca6983bef |
3 changed files with 133 additions and 1 deletions
|
@ -10,7 +10,7 @@ authors = [
|
|||
description = "A console XMPP client"
|
||||
|
||||
[dependencies]
|
||||
pyo3 = { version = "0.17", features = ["extension-module"] }
|
||||
pyo3 = { version = "0.17", features = ["auto-initialize", "nightly"] }
|
||||
nom = "7.1"
|
||||
chrono = "0.4"
|
||||
ncurses = "5"
|
||||
|
@ -20,6 +20,9 @@ clap = { version = "3.2.17", features = ["derive"] }
|
|||
directories = "4.0.1"
|
||||
configparser = "3.0.1"
|
||||
jid = "0.9.4"
|
||||
libc = "0.2.132"
|
||||
log = "0.4.17"
|
||||
simplelog = "0.12.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
|
12
src/error.rs
12
src/error.rs
|
@ -21,10 +21,14 @@ use std::io;
|
|||
use std::num::TryFromIntError;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use pyo3::PyErr;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Error {
|
||||
IOError(io::Error),
|
||||
IntError(TryFromIntError),
|
||||
PyError(PyErr),
|
||||
StartupCheck(String),
|
||||
UnableToCreateConfigDir,
|
||||
InvalidConfigValueType(ConfigValue),
|
||||
InvalidValueType(String),
|
||||
|
@ -36,6 +40,8 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Error::IOError(e) => write!(f, "io error: {}", e),
|
||||
Error::IntError(e) => write!(f, "int error: {}", e),
|
||||
Error::PyError(e) => write!(f, "python error: {}", e),
|
||||
Error::StartupCheck(e) => write!(f, "Startup check error: {}", e),
|
||||
Error::UnableToCreateConfigDir => write!(f, "Unable to create config dir"),
|
||||
Error::InvalidConfigValueType(err) => write!(f, "Invalid ConfigValue type: {}", err),
|
||||
Error::InvalidValueType(err) => write!(f, "Invalid value type: {}", err),
|
||||
|
@ -59,3 +65,9 @@ impl From<TryFromIntError> for Error {
|
|||
Error::IntError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PyErr> for Error {
|
||||
fn from(err: PyErr) -> Error {
|
||||
Error::PyError(err)
|
||||
}
|
||||
}
|
||||
|
|
117
src/main.rs
Normal file
117
src/main.rs
Normal file
|
@ -0,0 +1,117 @@
|
|||
// 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/>.
|
||||
|
||||
#![feature(once_cell)]
|
||||
|
||||
mod args;
|
||||
mod config;
|
||||
mod error;
|
||||
mod xdg;
|
||||
|
||||
use crate::args::Args;
|
||||
use crate::config::Config;
|
||||
use crate::error::Error;
|
||||
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use clap::Parser;
|
||||
use libc;
|
||||
use log;
|
||||
use simplelog::WriteLogger;
|
||||
use pyo3::{Python, PyResult, py_run};
|
||||
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
if unsafe { libc::getuid() == 0 } {
|
||||
return Err(Error::StartupCheck(String::from("Do not run as root")));
|
||||
}
|
||||
|
||||
io::stdout().write_all(b"\x1b]0;poezio\x07")?;
|
||||
io::stdout().flush()?;
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
let firstrun = !args.filename.exists();
|
||||
if firstrun {
|
||||
let parent = args
|
||||
.filename
|
||||
.parent()
|
||||
.ok_or(Error::UnableToCreateConfigDir)?;
|
||||
fs::create_dir_all(parent).map_err(|_| Error::UnableToCreateConfigDir)?;
|
||||
let default = include_bytes!("../data/default_config.cfg");
|
||||
let mut file = fs::File::create::<&Path>(args.filename.as_ref())?;
|
||||
file.write_all(default)?;
|
||||
};
|
||||
|
||||
let config: Config = Config::builder::<&Path>(args.filename.as_ref()).build()?;
|
||||
// println!("Config: {:?}", config);
|
||||
config.setup_logging(None::<PathBuf>)?;
|
||||
|
||||
if args.check_config {
|
||||
config.check_config();
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let custom_version = args.custom_version;
|
||||
|
||||
update_themes_dir()?;
|
||||
|
||||
Python::with_gil(|py| -> PyResult<()> {
|
||||
let pathlib = py.import("pathlib")?;
|
||||
let path = pathlib.getattr("Path")?;
|
||||
let configfile = path.call1((args.filename.clone(),))?;
|
||||
|
||||
py_run!(py, configfile firstrun custom_version, r#"
|
||||
import signal
|
||||
|
||||
from poezio import config
|
||||
from poezio.core.core import Core
|
||||
|
||||
config.config = config.Config(configfile) # XXX: doesn't work.
|
||||
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
cocore = Core(custom_version, firstrun)
|
||||
signal.signal(signal.SIGUSR1, cocore.sigusr_handler) # reload the config
|
||||
signal.signal(signal.SIGHUP, cocore.exit_from_signal)
|
||||
signal.signal(signal.SIGTERM, cocore.exit_from_signal)
|
||||
cocore.start()
|
||||
|
||||
from slixmpp.exceptions import IqError, IqTimeout
|
||||
|
||||
# Warning: asyncio must always be imported after the config. Otherwise
|
||||
# the asyncio logger will not follow our configuration and won't write
|
||||
# the tracebacks in the correct file, etc
|
||||
import asyncio
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.set_exception_handler(cocore.loop_exception_handler)
|
||||
|
||||
loop.add_reader(sys.stdin, cocore.on_input_readable)
|
||||
loop.add_signal_handler(signal.SIGWINCH, cocore.sigwinch_handler)
|
||||
cocore.xmpp.start()
|
||||
loop.run_forever()
|
||||
# We reach this point only when loop.stop() is called
|
||||
try:
|
||||
cocore.reset_curses()
|
||||
except:
|
||||
pass
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue