Skip to content

Commit

Permalink
Update force_download behavior
Browse files Browse the repository at this point in the history
Because of the changes, the previous behavior of merging database has
been removed and can only accept one.
  • Loading branch information
foo-dogsquared committed Oct 1, 2021
1 parent 0745b3e commit bfc4015
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 34 deletions.
24 changes: 22 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,27 @@ and this project adheres to link:https://semver.org/spec/v2.0.0.html[Semantic Ve



== v1.1.0 - 2021-09-30
== 1.2.0 - 2021-10-01

I don't think this is a good application of "Release early, release often" but there are minor behavior changes for the plugin.
Which means a new version of the plugin.


=== Changed

* The plugin can now only accept one bangs database file at a time.
* `force_download` default value from `true` to `false` due to fixed behavior.


=== Fixed

* `force_download` now forces to download the database and use the local plugin path (e.g., `$HOME/.local/share/pop-launcher/plugins`).
This is considered a fix because I didn't realize `force_download` is essentially useless. ;p




== 1.1.0 - 2021-09-30

Main highlight of this release is the addition of plugin-specific configuration.
It should be located in `$POP_PLUGIN_PATH/bangs/config.json`.
Expand All @@ -33,7 +53,7 @@ footnote:[Turns out the launcher service sorts the results by default unless `no



== v1.0.0 - 2021-09-26
== 1.0.0 - 2021-09-26

The initial release.

Expand Down
13 changes: 8 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ The plugin has a certain format to follow to do its thing.
! ${SEARCH_QUERY}...
----

The search query should have at least one bang for it to work (unless you've set `default_bangs` from the <<Plugin-specific configuration>>).

You can search bangs within the search query by prepending it with `{bangs_search_query_prefix}`.
The plugin will only give search results if a bang is the last part of the search query.

Expand Down Expand Up @@ -113,8 +115,11 @@ It is a simple JSON object with the possible keys and their values.
| 8

| `force_download`
| Indicates whether or not the fallback database should be downloaded if no database has been found.
| `true`
| Indicates whether or not the fallback database should be downloaded forcibly.
This will override the database to be downloaded in the home directory.
Be careful as this will override already existing database files and will download each time the plugin is invoked.
Don't enable this unless you have good and unlimited internet connection.
| `false`

| `default_bangs`
| A list of bangs to be used when no bangs from the search query was found.
Expand All @@ -128,7 +133,7 @@ This is the equivalent JSON for the default configuration.
{
"db_url": "https://duckduckgo.com/bang.js",
"max_limit": 8,
"force_download": true
"force_download": false
}
----

Expand Down Expand Up @@ -179,8 +184,6 @@ It'll be more useful once this project continues to be develop which you can fre

== Future considerations

* Remove the database merging from different plugin paths.

* Make a consistent interface similar to the built-in plugins.
The way how a user can interact with the plugin is slightly different compared to them — e.g., you have to press 'Enter' to open the URLs instead of adding them.
If possible, it should be moved into some other keybindings to finalize and open the query.
Expand Down
57 changes: 30 additions & 27 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use crate::utils::{find, local_plugin_dir};

use serde::{Deserialize, Serialize};

pub static BANG_FILENAME: &str = "db.json";
pub static PLUGIN_CONFIG_FILENAME: &str = "config.json";

/// The bangs database.
/// It's based from how [Duckduckgo's own database](https://duckduckgo.com/bang.js) is structured.
pub type Database = HashMap<String, Bang>;
Expand Down Expand Up @@ -59,60 +62,59 @@ impl Bang {
}

/// Loads the database (`db.json`) from the plugin paths.
/// Please take note it merges the database from each plugin path.
/// It will only accept one database at a time.
/// If it has no database or forcing the download, it will use the database from the home directory
/// instead.
///
/// It will also take care of automatically downloading the default database in the local plugin
/// path if there's no database found in the plugin paths.
pub fn load(app_config: &AppConfig) -> Database {
let mut db = Database::default();

// Finding all `db.json` files and merging the databases together.
// I'm not sure if this is ideal so expect this will change in the future.
// It'll most likely change to override the top-level plugin path (e.g., the user plugins
// directory over the distribution plugin path).
let mut paths: Vec<PathBuf> = find("bangs", "db.json").collect();
// Finding all `db.json` files, taking only the local (as much as possible) plugin path.
let mut db_path: PathBuf = match find("bangs", BANG_FILENAME).take(1).next() {
Some(p) => p,
None => {
let mut p = local_plugin_dir("bangs");
p.push(BANG_FILENAME);

p
}
};

// Download Duckduckgo's bang database when there's no such database anywhere.
// Download Duckduckgo's bang database when there's no such database anywhere or if the app is
// configured to force the download.
// We'll download it in the home directory (since that is just the safest location for it).
// Specifically at `LOCAL` variable given from the `pop_launcher` crate.
// Being synchronous makes it a bit harder to handle this well.
//
// We also use `curl` from the command line instead of using an HTTP client because I just want
// to save some bytes lel.
if paths.is_empty() && app_config.force_download {
eprintln!("[bangs] no found database files, downloading the default database");
if app_config.force_download || !db_path.is_file() {
eprintln!("[bangs] forced download, downloading the configured database");
match Command::new("curl")
.arg("--silent")
.arg(&app_config.db_url)
.output()
{
Ok(process) => {
let mut db_path = local_plugin_dir("bangs");
db_path.push("db.json");
// We'll force the download to the home directory since it is the safest
// location.
db_path = local_plugin_dir("bangs");
db_path.push(BANG_FILENAME);

if let Ok(mut file) = File::create(&db_path) {
match file.write(&process.stdout) {
Ok(_) => eprintln!("[bangs] default database file successfully downloaded"),
Err(e) => eprintln!("[bangs] not able to write in to file: {}", e),
}
}

paths.push(db_path);
}
Err(err) => eprintln!("[bangs] default database download failed: {}", err),
}
}

// Merge all databases.
for path in find("bangs", "db.json") {
let string = match std::fs::read_to_string(&path) {
Ok(string) => string,
Err(why) => {
eprintln!("[bangs] failed to read config: {}", why);
continue;
}
};

if let Ok(string) = std::fs::read_to_string(&db_path) {
match serde_json::from_str::<Vec<Bang>>(&string) {
Ok(config) => {
for bang in config {
Expand Down Expand Up @@ -147,7 +149,6 @@ pub struct AppConfig {
}

/// Plugin-specific configuration.
/// It should come from `config.json` from one of the plugin paths.
impl Default for AppConfig {
fn default() -> Self {
Self {
Expand All @@ -166,8 +167,10 @@ impl AppConfig {
pub fn load() -> Self {
let mut config = Self::default();

// We'll only take one of them to not let the configuration confusion happen.
if let Some(config_file) = find("bangs", "config.json").take(1).next() {
// We'll also take only one.
// Keep in mind the list of plugin paths from `pop_launcher` crate are sorted from local to
// system-wide locations.
if let Some(config_file) = find("bangs", PLUGIN_CONFIG_FILENAME).take(1).next() {
if let Ok(content) = std::fs::read_to_string(config_file) {
match serde_json::from_str::<Self>(&content) {
Ok(new_config) => config = new_config,
Expand All @@ -189,6 +192,6 @@ impl AppConfig {
}

fn force_download() -> bool {
true
false
}
}

0 comments on commit bfc4015

Please sign in to comment.