~azzamsa/bilal.rs

397f8dec4d9dfdcffe53bb4a467dc06596171617 — azzamsa 6 months ago d3b33eb
refactor: refactor
M README.md => README.md +45 -9
@@ 30,6 30,14 @@

## Usage

## Usage Examples

``` bash
bilal all                            Show all salahs time
bilal current                        ... current salah time
bilal current --json                  .... with JSON format
```

Create a file named `bilal.toml` in `~/.config/bilal/`. If you are on `Windows`, put it under `\AppData\Bilal\`. Then add your configuration:

``` toml


@@ 40,29 48,55 @@ madhab = "Shafi"
method = "Egyptian"
```

You can get latitude and longitude value from [mapcoordinates](https://www.mapcoordinates.net/en).
Other [madhab](https://docs.rs/islam/0.1.1/islam/pray/madhab/enum.Madhab.html#variants)
and [method](https://docs.rs/islam/0.1.1/islam/pray/method/enum.Method.html#variants) options are available.
To see more options, please read the [wiki](docs/wiki.md)

## Usage with other tools
### Command-line options

You can use Bilal with `i3status-rs` to show salah time in your status.
``` bash
USAGE:
    bilal [FLAGS] [OPTIONS] [salah]

ARGS:
    <salah>    A Salah to show [default: all]

![i3status-bilal](docs/i3rs.png)
FLAGS:
    -h, --help       Prints help information
    -J, --json       Display Salah in JSON formatted string
    -V, --version    Prints version information

OPTIONS:
        --color <WHEN>    Display Salah in colored output [default: always]
```

![i3status-bilal-urgent](docs/i3rs-urgent.png)
### Usage with other tools

`i3status-rs` configuration Example:
You can use Bilal with `i3status-rust` to show salah time in your status.

![i3status-rust-bilal](docs/i3status-rust.png)

![i3status-rust-bilal-urgent](docs/i3status-rust-urgent.png)

`i3status-rurts` configuration Example:

``` bash
[[block]]
block = "custom"
cycle = ["bilal -c -J", "bilal -n -J"]
cycle = [
        "bilal current -J",
        "bilal next -J",
        ]
on_click = "<command>"
interval = 300
json = true

```

See [more examples](examples/) to learn other variations.

If you like `bilal` to support your favourite status-bar, please hit me in
the [mailing-list][mailing-list] with the valid input of your status-bar. In i3status-rust
the valid input it would be `{"icon": "ICON", "state": "STATE", "text": "YOURTEXT"}`.

## Installation

### From binaries


@@ 98,6 132,8 @@ For reporting issues, visit the tracker here: https://todo.sr.ht/~azzamsa/Bilal

Please send patches to `~azzamsa/public-inbox@lists.sr.ht`

To learn more read [contributing.md](docs/dev/contributing.md)

## Origin of the name

The name Bilal was chosen in reference to the Bilal bin Rabah. The first

M docs/demo.gif => docs/demo.gif +0 -0
M docs/demo.sh => docs/demo.sh +6 -8
@@ 1,11 1,9 @@
#doitlive prompt: >
#doitlive shell: /bin/fish
#doitlive speed: 3
bilal -h
c
bilal --all
c
bilal --current
bilal --next
bilal --current --json
bilal --next --json
bilal all
clear
bilal current
bilal next
bilal current --json
bilal next --json

A docs/dev/contributing.md => docs/dev/contributing.md +32 -0
@@ 0,0 1,32 @@
## Contributing

### Unsure how to contribute?

- [How to send patches](https://git-send-email.io/#step-3)

### Running The Demo

The demo is shown using [doitlive](https://github.com/sloria/doitlive).
Set the window dimension to `x: 638 y: 230 w: 780 h: 557`, then run:

``` shell
doitlive play docs/demo.sh
```


### Release

After the release has been pushed, run the code below to produce
pre-compiled binaries. Then upload them to the release page.

``` bash
$ rm -rf target
$ source docs/dev/relase.sh
```

or if you use `fish`

``` fish
❯ rm -rf target
❯ bash -c "source docs/dev/release.sh"
```

M docs/dev/releasing.md => docs/dev/releasing.md +4 -3
@@ 8,6 8,7 @@ $ find . | grep "\.rs" | xargs touch ; cargo clippy --all-features -- --deny war

- Run `cargo update` and review dependency updates.
- Update the CHANGELOG.
- Update version numbers in `Cargo.toml` and `README.md`, Run `cargo update -p bilal` so that the Cargo.lock is updated.
- Create new branch (master branch is protected), commit with a message format: `v[0-9]+.[0-9]+.[0-9]+`, and push.
- Wait for a checks to pass, merge the branch to master, then tag a release with a copy of the relevant section of the CHANGELOG.
- Update version numbers in `Cargo.toml`, then run `cargo update -p bilal` so that the Cargo.lock is updated.
- Create a commit with a message format: `v[0-9]+.[0-9]+.[0-9]+`, and push.
- Wait for a checks to pass, tag a commit with a release tag, then push the tag. 
- Run the `docs/release.sh` to produce pre-compiled binaries.

D docs/i3rs-urgent.png => docs/i3rs-urgent.png +0 -0
D docs/i3rs.png => docs/i3rs.png +0 -0
A docs/i3status-rust-urgent.png => docs/i3status-rust-urgent.png +0 -0
A docs/i3status-rust.png => docs/i3status-rust.png +0 -0
M docs/wiki.md => docs/wiki.md +20 -28
@@ 7,40 7,32 @@ You can get latitude and longitude value from online services, such as

### Method

The methods in subsection are the similar methods.
Available methods are:

| Value | Description |
| ----- | ----------- |
| `MuslimWorldLeague` | Muslim World League. Fajr angle: 18, Isha angle: 17 |
| `Egyptian` | Egyptian General Authority of Survey. Fajr angle: 19.5, Isha angle: 17.5 |
| `Karachi` | University of Islamic Sciences, Karachi. Fajr angle: 18, Isha angle: 18 |
| `UmmAlQura` | Umm al-Qura University, Makkah. Fajr angle: 18.5, Isha interval: 90.  |
| `Dubai` | Method used in UAE. Fajr angle: 18.2, Isha angle: 18.2. |
| `Qatar` | Modified version of Umm al-Qura used in Qatar. Fajr angle: 18, Isha interval: 90. |
| `Kuwait` | Method used by the country of Kuwait. Fajr angle: 18, Isha angle: 17.5 |
| `MoonsightingCommittee` | Moonsighting Committee. Fajr angle: 18, Isha angle: 18. |
| `Singapore` | Method used by Singapore. Fajr angle: 20, Isha angle: 18. |
| `NorthAmerica` | Referred to as the ISNA method. Fajr angle: 15, Isha angle: 15 |
| `Other` | Fajr angle: 0, Isha angle: 0. |

This docs is adapted from [insha/salah](https://github.com/insha/salah/).
- `Karachi`: University of Islamic Sciences, Karachi (UISK). Fajr angle: 18.0, Isha angle: 18.0
  - Ministry of Religious Affaires, Tunisia
  - France - Angle 18°
- `MuslimWorldLeague`: Muslim World League (MWL). Fajr angle: 18.0, Isha angle: 17.0
  - Ministry of Religious Affaires and Awqaf, Algeria
  - Presidency of Religious Affairs, Turkey
- `Egyptian`: Egyptian General Authority of Survey (EGAS): 19.5, Isha angle: 17.5 
- `UmmAlQura`:  Umm al-Qura University, Makkah (UMU). Fajr angle: 18.5, Isha interval: 90
- `NorthAmerica`: Islamic Society of North America (ISNA). Fajr angle: 15.0, Isha angle: 15.0 
  - France - Angle 15°
- `French`: French Muslims (ex-UOIF). Fajr angle: 12.0, Isha angle: 12.0
- `Singapore`: Islamic Religious Council of Signapore (MUIS). Fajr angle: 20.0, Isha angle: 18.0
  - Department of Islamic Advancements of Malaysia (JAKIM)
  - Ministry of Religious Affairs of Indonesia (KEMENAG)
- `Russia`: Spiritual Administration of Muslims of Russia. Fajr angle: 16.0, Isha angle: 15.0
- `FixedInterval`: Fixed Ishaa Time Interval, 90min. Fajr angle: 19.5, Isha interval: 90 (ramdan: 120)


### Madhab

This settings corresponds to Asr prayer time.
For Hanafi madhab, the Asr is bit later than that of the Shafi madhab.

| Value | Description |
| ----- | ----------- |
| `Shafi` | Earlier Asr time |
| `Hanafi` | Later Asr time |

## Contribution

### Release

To make a release. Change the `version` in `Cargo.toml` then run:
- `Shafi`:  Earlier Asr time
- `Hanafi`: Later Asr time

``` bash
$ source scripts/relase.sh
```

A examples/i3status-rust.toml => examples/i3status-rust.toml +17 -0
@@ 0,0 1,17 @@
# tested against
# i3status-rs 0.14.3 (commit b98c99e 2020-12-10)

[icons]
name = "awesome5"
[icons.overrides]
bilal = "  "

[[block]]
block = "custom"
cycle = [
        "bilal current -J",
        "bilal next -J",
        ]
on_click = "<command>"
interval = 300
json = true

M src/app.rs => src/app.rs +3 -1
@@ 10,6 10,7 @@ pub fn build() -> App<'static> {
            Arg::new("salah")
                .possible_values(&["all", "next", "current"])
                .default_value("all")
                .hide_possible_values(true)
                .takes_value(true)
                .about("A Salah to show"),
        )


@@ 22,10 23,11 @@ pub fn build() -> App<'static> {
        .arg(
            Arg::new("color")
                .long("color")
                .takes_value(true)
                .value_name("WHEN")
                .possible_values(&["always", "auto", "never"])
                .default_value("always")
                .hide_possible_values(true)
                .takes_value(true)
                .about("Display Salah in colored output"),
        );
    app

M src/output.rs => src/output.rs +34 -30
@@ 24,27 24,25 @@ impl Printer {
    pub fn all(&self) -> Result<(), BilalError> {
        let prayers = self.prayers;

        let print_output = |name: &str, prayer: DateTime<Local>| {
            writeln!(
                io::stdout(),
                "{}: {}:{}:{}",
                name,
                prayer.hour(),
                prayer.minute(),
                prayer.second()
            )
            .ok();
        let fmt_output = |name: &str, prayer: DateTime<Local>| {
            format!("{}: {}:{}", name, prayer.hour(), prayer.minute())
        };

        print_output("Fajr", prayers.fajr);
        print_output("Sherook", prayers.sherook);
        print_output("Dohr", prayers.dohr);
        print_output("Asr", prayers.asr);
        print_output("Mghreb", prayers.maghreb);
        print_output("Ishaa", prayers.ishaa);
        print_output("Fist third of night", prayers.first_third_of_night);
        print_output("Midnight", prayers.midnight);
        print_output("Last third of night", prayers.last_third_of_night);
        Self::print(fmt_output("Fajr", prayers.fajr));
        Self::print(fmt_output("Sherook", prayers.sherook));
        Self::print(fmt_output("Dohr", prayers.dohr));
        Self::print(fmt_output("Asr", prayers.asr));
        Self::print(fmt_output("Mghreb", prayers.maghreb));
        Self::print(fmt_output("Ishaa", prayers.ishaa));
        Self::print(fmt_output(
            "Fist third of night",
            prayers.first_third_of_night,
        ));
        Self::print(fmt_output("Midnight", prayers.midnight));
        Self::print(fmt_output(
            "Last third of night",
            prayers.last_third_of_night,
        ));

        Ok(())
    }


@@ 63,7 61,7 @@ impl Printer {
        };

        // default
        let mut prayer_fmt = format!("\u{23fa} {} {}", prayer.name(), remaining_fmt);
        let mut prayer_fmt = format!("{} {}", prayer.name(), remaining_fmt);
        let state = {
            if minute < 30 {
                "Critical"


@@ 74,15 72,16 @@ impl Printer {

        // JSON
        if self.json_format {
            prayer_fmt = format!(r#"{{"state":"{}", "text": "{}"}}"#, state, prayer_fmt)
            prayer_fmt = format!(
                r#"{{"icon": "{}", "state": "{}", "text": "{} {}"}}"#,
                "bilal", state, "\u{23fa} ", prayer_fmt
            )
        }
        // color
        if self.show_color && state == "Critical" {
        if self.show_color && state == "Critical" && !self.json_format {
            prayer_fmt = format!("{}", prayer_fmt.red());
        }

        writeln!(io::stdout(), "{}", prayer_fmt).ok();

        Self::print(prayer_fmt);
        Ok(())
    }
    /// Show next prayer info


@@ 91,17 90,22 @@ impl Printer {
        let prayer = prayers.next();
        let time = prayers.time(prayer);

        let time_fmt = format!("({}:{}:{})", time.hour(), time.minute(), time.second());
        let time_fmt = format!("({}:{})", time.hour(), time.minute());

        // default
        let mut prayer_fmt = format!("\u{25b6} {} {}", prayer.name(), time_fmt);
        let mut prayer_fmt = format!("{} {}", prayer.name(), time_fmt);
        // JSON
        let state = "Info";
        if self.json_format {
            prayer_fmt = format!(r#"{{"state":"{}", "text": "{}"}}"#, state, prayer_fmt)
            prayer_fmt = format!(
                r#"{{"icon": "{}", "state": "{}", "text": "{} {}"}}"#,
                "bilal", state, "\u{25b6}", prayer_fmt
            )
        }
        writeln!(io::stdout(), "{}", prayer_fmt).ok();

        Self::print(prayer_fmt);
        Ok(())
    }
    fn print(prayer_fmt: String) {
        writeln!(io::stdout(), "{}", prayer_fmt).ok();
    }
}

M tests/integration.rs => tests/integration.rs +2 -2
@@ 23,7 23,7 @@ fn all() {
#[test]
fn current() {
    let mut cmd = Command::cargo_bin("bilal").unwrap();
    cmd.arg("current");
    cmd.arg("current").arg("--json");
    // \u{23fa} : ⏺
    cmd.assert()
        .success()


@@ 33,7 33,7 @@ fn current() {
#[test]
fn next() {
    let mut cmd = Command::cargo_bin("bilal").unwrap();
    cmd.arg("next");
    cmd.arg("next").arg("--json");
    // \u{25b6} : ▶
    cmd.assert()
        .success()