diff --git a/Makefile b/Makefile index 9ca48bf..9697ecb 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ CARGO_VERSION := stable CARGO_OPTIONS := CARGO_SUB_OPTIONS := CARGO_COMMAND := cargo +$(CARGO_VERSION) $(CARGO_OPTIONS) -APP_ARGS := launcher hain +APP_ARGS := launcher albert # Environment #=============================================================== diff --git a/README.md b/README.md index 689a996..6794d72 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ If the cargo project is a binary crates, this tool can register the binary in th - Register as workflow - [Hain](https://hainproject.github.io/hain/docs/) - Register as devplugin +- [Albert](https://albertlauncher.github.io/docs/extensions/python/) + - Register as Python extension + ## TODO - [ ] cargo workspace(Only single binary crates) @@ -15,9 +18,11 @@ If the cargo project is a binary crates, this tool can register the binary in th ## Usage -### Alfred workflow +### Common -``` +- Install CLI binary + +``` shell $ cd {your binary crates project} # Install to local, or manually install @@ -26,8 +31,13 @@ $ cd {your binary crates project} $ cargo install --path . ... Installing /Users/watawuwu/.cargo/bin/{your-binary} +``` + +### Alfred workflow -# Export to Alfred +- Generate Alfredworkflow file + +``` $ cargo launcher alfred ``` @@ -39,19 +49,23 @@ $ cargo launcher alfred ### Hain plugin -``` -$ cd {your binary crates project} - -# Install to local, or manually install -# The script path is set as follows -# PATH=$HOME/.cargo/bin:$HOME/.local/bin:/usr/local/bin:$PATH -$ cargo install --path . -... - Installing /Users/watawuwu/.cargo/bin/{your-binary} +- Export to hain devplugin directory -# Export to hain devplugin +``` $ cargo launcher hain ``` - Restart Hain + +### Albert plugin + +- Export to albert module directory + +``` +$ cargo launcher albert +``` + +- Check the checkbox of the python extension list and activate the setting + + diff --git a/albert.png b/albert.png new file mode 100644 index 0000000..c2b1d0b Binary files /dev/null and b/albert.png differ diff --git a/src/albert.rs b/src/albert.rs new file mode 100644 index 0000000..3037274 --- /dev/null +++ b/src/albert.rs @@ -0,0 +1,106 @@ +#[cfg(target_os = "linux")] +use failure::*; +#[cfg(target_os = "linux")] +use log::*; +#[cfg(target_os = "linux")] +use std::fs; +#[cfg(target_os = "linux")] +use std::path::PathBuf; + +use crate::cargo::CargoConfig; +use crate::error::Result; +#[cfg(target_os = "linux")] +use crate::fs::write_file; +use crate::launcher::LauncherConfig; +#[cfg(target_os = "linux")] +use crate::tpl::{self, Param}; +#[cfg(target_os = "linux")] +const MODULE_TEMPLATE: &[u8] = include_bytes!("asset/albert/__init__.py"); + +#[cfg(target_os = "linux")] +pub fn install(cargo_conf: &CargoConfig, launcher_conf: &LauncherConfig) -> Result<()> { + let workflow_path = make(cargo_conf, launcher_conf)?; + copy(cargo_conf, workflow_path)?; + Ok(()) +} + +#[cfg(target_os = "linux")] +fn make(cargo_conf: &CargoConfig, launcher_conf: &LauncherConfig) -> Result> { + let module = module_path(&launcher_conf.work_dir)?; + write_file(&module, module_bin(cargo_conf)?.as_bytes())?; + + let icon = icon_path(&launcher_conf.work_dir)?; + write_file(&icon, &launcher_conf.icon(cargo_conf)?[..])?; + + Ok(vec![module, icon]) +} + +#[cfg(target_os = "linux")] +fn module_bin(config: &CargoConfig) -> Result { + let mut params = Param::new(); + params.insert("prettyname", config.name()); + params.insert("version", config.version()); + params.insert("trigger", config.name()); + params.insert("author", &config.author()); + + let tpl = String::from_utf8_lossy(MODULE_TEMPLATE).into_owned(); + let contents = tpl::render(&tpl, ¶ms)?; + + Ok(contents) +} + +#[cfg(target_os = "linux")] +fn copy(conf: &CargoConfig, paths: Vec) -> Result<()> { + let sink_dir = application_config(conf)?; + fs::create_dir_all(&sink_dir)?; + for path in paths { + debug!("path: {:?}", &path); + debug!("sink: {:?}", &sink_dir); + let name = path.file_name().ok_or_else(|| err_msg("Not file type"))?; + let mut sink = sink_dir.clone(); + sink.push(name); + fs::copy(&path, sink)?; + } + + show_help(&sink_dir); + Ok(()) +} + +#[cfg(target_os = "linux")] +fn show_help(path: &PathBuf) { + let msg = r#" +Install completed!! +Please check the checkbox of the python extension list and activate the setting. + +Installed path: "#; + println!("{}{}", msg, path.to_string_lossy()); +} + +#[cfg(target_os = "linux")] +fn application_config(cargo_conf: &CargoConfig) -> Result { + let mut path = dirs::home_dir().ok_or_else(|| err_msg("Notfound home dir"))?; + path.push(".local/share/albert/org.albert.extension.python/modules"); + path.push(cargo_conf.name()); + Ok(path) +} + +#[cfg(target_os = "linux")] +fn module_path(dir: &PathBuf) -> Result { + path(dir, "__init__.py") +} + +#[cfg(target_os = "linux")] +fn icon_path(dir: &PathBuf) -> Result { + path(dir, "icon.png") +} + +#[cfg(target_os = "linux")] +fn path(dir: &PathBuf, name: &str) -> Result { + let dir_s = dir.to_str().ok_or_else(|| err_msg("NotFound dir path"))?; + Ok(PathBuf::from(format!("{}/{}", dir_s, name))) +} + +#[cfg(not(target_os = "linux"))] +pub fn install(_cargo_conf: &CargoConfig, _launcher_conf: &LauncherConfig) -> Result<()> { + failure::bail!("Albert supported only linux") +} diff --git a/src/asset/albert/__init__.py b/src/asset/albert/__init__.py new file mode 100644 index 0000000..3a5f7a0 --- /dev/null +++ b/src/asset/albert/__init__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +import os +import subprocess + +from albertv0 import * + +__iid__ = "PythonInterface/v0.2" +__prettyname__ = "{{prettyname}}" +__version__ = "{{version}}" +__trigger__ = "{{trigger}}" +__author__ = "{{author}}" +__dependencies__ = [] + +iconPath = os.path.join(os.path.dirname(__file__), 'icon.png') +pathlist = ["/usr/local/bin", "~/.local/bin", "~/.cargo/bin"] + +def handleQuery(query): + if not query.isTriggered: + return None + + if len(query.string) <= 1: + return None + + os.environ["PATH"] += os.pathsep + os.pathsep.join(pathlist) + cmd = ["url"] + query.string.split() + pipes = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + items = [] + if pipes.returncode != 0: + err_msg = "%s. exit code: %s" % (pipes.stderr.strip().decode("utf-8"), pipes.returncode) + items.append(Item( + id = __prettyname__, + icon = iconPath, + text = err_msg, + subtext = "Failed", + actions = [] + )) + else: + out = pipes.stdout.decode("utf-8") + items.append(Item( + id = __prettyname__, + icon = iconPath, + text = out, + subtext = "Success", + actions = [ + ClipAction("Added to Clipboard", out) + ] + )) + return items + diff --git a/src/hain.rs b/src/hain.rs index 483ac48..f1dec99 100644 --- a/src/hain.rs +++ b/src/hain.rs @@ -62,8 +62,10 @@ Installed path: "#; #[cfg(target_os = "macos")] fn application_config(cargo_conf: &CargoConfig) -> Result { let mut path = dirs::home_dir().ok_or_else(|| err_msg("Notfound home dir"))?; - path.push("Library/Application Support"); - path.push("hain-user/devplugins"); + path.push("Library"); + path.push("Application Support"); + path.push("hain-user"); + path.push("devplugins"); path.push(plugin_name(cargo_conf.name())); Ok(path) } diff --git a/src/launcher.rs b/src/launcher.rs index 7c1d578..75481d5 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -2,6 +2,7 @@ use pretty_env_logger; use std::path::PathBuf; use structopt::clap::*; +use crate::albert; use crate::alfred; use crate::args::Args; use crate::cargo::CargoConfig; @@ -18,6 +19,7 @@ arg_enum! { pub enum Launcher { Alfred, Hain, + Albert, } } @@ -50,6 +52,7 @@ pub fn launch(args: &Args, cargo_config: &CargoConfig) -> Result<()> { match args.launcher { Launcher::Alfred => alfred::install(&cargo_config, &launcher_config)?, Launcher::Hain => hain::install(&cargo_config, &launcher_config)?, + Launcher::Albert => albert::install(&cargo_config, &launcher_config)?, } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 5f55b89..b706fa9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod albert; mod alfred; mod args; mod cargo;