Compare commits

..

5 Commits

5 changed files with 266 additions and 134 deletions

View File

@ -1,13 +1,13 @@
# PrayTime # PrayTime
PrayTime is a small vala program which find timings of Islamic Prayer PrayTime is a small program written in vala which find timings of Islamic Prayer
and play the adhan at the given time. and play the adhan at the given time.
PrayTime use the api on aladhan.com to retriew timings. PrayTime use the api on aladhan.com to retriew timings.
## Prerequisites ## Prerequisites
valac curl meson ninja glib gobject json-glib gstreamer valac curl meson ninja glib gobject json-glib gstreamer pluie-echo
see meson.build see meson.build
@ -17,12 +17,22 @@ gobject_dep = dependency('gobject-2.0')
gio_dep = dependency('gio-2.0') gio_dep = dependency('gio-2.0')
json_dep = dependency('json-glib-1.0') json_dep = dependency('json-glib-1.0')
gstreamer_dep = dependency('gstreamer-1.0') gstreamer_dep = dependency('gstreamer-1.0')
echo_dep = dependency('pluie-echo-0.2')
``` ```
on debian or debian like you can do : on debian or debian like you can do :
``` ```
$ sudo apt-get install valac libjson-glib-dev libgstreamer1.0-dev meson ninja-build $ sudo apt-get install valac libjson-glib-dev libgstreamer1.0-dev libgstreamer0.10-dev meson ninja-build
``` ```
there is not yet a package for pluie-echo dependency, but you can install it with :
```
cd /tmp/
git clone https://github.com/pluie-org/libpluie-echo.git --branch latest --single-branch
cd libpluie-echo
meson --prefix=/usr ./ build
sudo ninja install -C build
```
## Install ## Install
@ -67,35 +77,28 @@ isha =
[Cron] [Cron]
# timings updating time # timings updating time
time = 00:00 time = 02:22
# cron file
path = /etc/cron.d/praytime
``` ```
## Usage ## Usage
![praytime usage](https://www.meta-tech.academy/img/praytime-usage.png?tmp=2)
First step is to edit configuration file First step is to edit configuration file
``` ```
/usr/share/praytime.praytime.ini /usr/share/praytime.praytime.ini
``` ```
and set your city & location, then add some adhan file. Set your city & location, then add some adhan file
After that you can initialise the cron installation with After that you can initialise the cron installation with
``` ```
$ sudo praytime cron $ praytime cron
updating /etc/cron.d/praytime : ok
----------------------------------------------------------
Paris FR - +0200 Thursday 19 October 2017 02:17:12
----------------------------------------------------------
Fajr : 06:32
Dhuhr : 13:36
Asr : 16:23
Maghrib : 18:53
Isha : 20:32
``` ```
![praytime cron](https://www.meta-tech.academy/img/praytime-cron.png?tmp=1)
you can test adhan with : you can test adhan with :
@ -103,18 +106,14 @@ you can test adhan with :
# Fajr or other prayer # Fajr or other prayer
praytime play Fajr praytime play Fajr
``` ```
![praytime play adhan](https://www.meta-tech.academy/img/praytime-play.png?tmp=1)
to see current timings simply do : to see current timings simply do :
``` ```
$ praytime $ praytime
----------------------------------------------------------
Paris FR - +0200 Thursday 19 October 2017 02:20:26
----------------------------------------------------------
Fajr : 06:32
Dhuhr : 13:36
Asr : 16:23
Maghrib : 18:53
Isha : 20:32
``` ```
![praytime timings](https://www.meta-tech.academy/img/praytime-timings.png?tmp=1)
the red star indicates coming prayers

View File

@ -29,6 +29,4 @@ isha =
[Cron] [Cron]
# timings updating time # timings updating time
time = 00:00 time = 02:22
# cron file
path = /etc/cron.d/praytime

View File

@ -3,34 +3,55 @@ using Pluie;
int main (string[] argv) int main (string[] argv)
{ {
int done = 0;
var nostate = false;
Echo.init (bool.parse("@DEBUG@"));
Dbg.in (Log.METHOD);
var p = new PrayTime ("@DATA_PATH@", "@INSTALL_PATH@", "@VERSION@"); var p = new PrayTime ("@DATA_PATH@", "@INSTALL_PATH@", "@VERSION@");
if (argv.length > 1) { if (argv.length > 1) {
switch (argv[1]) { if (argv[1] == "version") {
stdout.printf (p.version);
nostate = true;
}
else {
case "cron" : of.title ("PrayTime", p.version, "a-sansara");
p.init_cron ();
break;
case "timings" : switch (argv[1]) {
break; case "cron" :
p.init_cron ();
break;
case "play" : case "play" :
if (argv.length > 2) { if (argv.length > 2) {
p.play_adhan (argv[2]); done = p.play_adhan (argv[2]);
} }
else { else {
stderr.printf ("missing pray parameter\n"); of.error ("missing pray parameter");
return 1; done = 1;
} }
break; break;
default :
of.warn ("invalid command %s".printf (argv[1]));
p.usage();
done = 1;
break;
}
} }
} }
else { else {
p.infos (); p.infos ();
} }
stdout.printf ("\n"); of.echo ();
return 0; if (!nostate) {
of.rs (done == 0);
of.echo ();
}
Dbg.out (Log.METHOD);
return done;
} }

View File

@ -1,12 +1,13 @@
project('PrayTime', 'vala', 'c') project('PrayTime', 'vala', 'c')
glib_dep = dependency('glib-2.0') glib_dep = dependency('glib-2.0')
gobject_dep = dependency('gobject-2.0') gobject_dep = dependency('gobject-2.0')
gio_dep = dependency('gio-2.0') gio_dep = dependency('gio-2.0')
json_dep = dependency('json-glib-1.0') json_dep = dependency('json-glib-1.0')
gstreamer_dep = dependency('gstreamer-1.0') gstreamer_dep = dependency('gstreamer-1.0')
echo_dep = dependency('pluie-echo-0.2')
version = '0.2.2' version = '0.2.6'
bindir = join_paths(get_option('prefix'), get_option('bindir')) bindir = join_paths(get_option('prefix'), get_option('bindir'))
datadir = join_paths(get_option('prefix'), get_option('datadir'), 'praytime') datadir = join_paths(get_option('prefix'), get_option('datadir'), 'praytime')
@ -14,6 +15,7 @@ conf = configuration_data()
conf.set('VERSION' , version) conf.set('VERSION' , version)
conf.set('INSTALL_PATH', bindir) conf.set('INSTALL_PATH', bindir)
conf.set('DATA_PATH' , datadir) conf.set('DATA_PATH' , datadir)
conf.set('DEBUG' , 'false')
sources = [ sources = [
'src/Pluie.PrayTime.vala', 'src/Pluie.PrayTime.vala',
@ -29,5 +31,5 @@ configure_file(
install_data('config/praytime.ini', install_dir : datadir) install_data('config/praytime.ini', install_dir : datadir)
executable('praytime', sources, install : true, install_dir : bindir, executable('praytime', sources, install : true, install_dir : bindir,
dependencies : [glib_dep, gobject_dep, gio_dep, json_dep, gstreamer_dep]) dependencies : [glib_dep, gobject_dep, gio_dep, json_dep, gstreamer_dep, echo_dep])

View File

@ -3,68 +3,89 @@ using Gst;
class Pluie.PrayTime : GLib.Object class Pluie.PrayTime : GLib.Object
{ {
const bool DEBUG = false;
const string SEP = "----------------------------------------------------------";
const string[] PRAYLIST = { "Fajr", "Dhuhr", "Asr", "Maghrib", "Isha" };
const string protocol = "http";
const string hostname = "api.aladhan.com";
const string uri = "timingsByCity?";
private string path; private const string[] PRAYLIST = { "Fajr", "Dhuhr", "Asr", "Maghrib", "Isha" };
private string version; private const string protocol = "http";
private string bin; private const string hostname = "api.aladhan.com";
private GLib.KeyFile kf; private const string uri = "timingsByCity?";
private GLib.MainLoop loop;
private Gst.Element playbin; private Sys.Cmd cmd;
private string path;
public string version;
private string bin;
private GLib.KeyFile kf;
private GLib.MainLoop loop;
private Gst.Element playbin;
public PrayTime (string path, string bin, string version) public PrayTime (string path, string bin, string version)
{ {
Dbg.in (Log.METHOD, "path:'%s':bin:'%s':version:'%s'".printf (path, bin, version), Log.LINE, Log.FILE);
this.path = path; this.path = path;
this.version = version; this.version = version;
this.bin = bin; this.bin = bin;
this.kf = this.load_config ("praytime.ini"); this.kf = this.load_config ("praytime.ini");
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
} }
public void play_adhan (string pray) public int play_adhan (string pray)
{ {
Dbg.in (Log.METHOD, "pray:'%s'".printf (pray), Log.LINE, Log.FILE);
var done = 0;
if (pray in PrayTime.PRAYLIST) { if (pray in PrayTime.PRAYLIST) {
double volume = this.get_volume (pray.down ()); double volume = this.get_volume (pray.down ());
string mp3 = this.get_mp3 (pray.down ()); string mp3 = this.get_mp3 (pray.down ());
of.action ("Playing Adhan", "%s time".printf (pray));
this.play (mp3, volume); this.play (mp3, volume);
} }
else { else {
this.on_error(@"invalid pray parameter '$pray'"); of.error (@"invalid pray parameter '$pray'");
done = 1;
} }
Dbg.out (Log.METHOD, "done ? %d".printf (done), Log.LINE, Log.FILE);
return done;
} }
public void infos() public void infos (bool bypass_title = false)
{ {
KeyFile k = this.load_config ("praytime.daily.ini"); Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
bool done = true;
var date = new GLib.DateTime.now_local (); var date = new GLib.DateTime.now_local ();
stdout.printf ( KeyFile k = this.load_config ("praytime.daily.ini", true);
"%s\n %s %s - %s\n%s\n", if (!bypass_title) {
PrayTime.SEP, of.title ("PrayTime", this.version, "a-sansara");
this.get_config ("city"), }
this.get_config ("country"), of.action (
date.format ("%z %A %d %B %Y %T"), "Retriew timings for",
PrayTime.SEP "%s %s\n".printf (this.get_config ("city"), this.get_config ("country"))
); );
of.echo (date.format ("%z %A %d %B %Y"), false);
of.echo (date.format ("%T"), true, false, ECHO.OPTION_SEP);
of.echo ();
int t = int.parse(date.format ("%H%M"));
var s = "";
var p = "";
foreach (string pray in PrayTime.PRAYLIST) { foreach (string pray in PrayTime.PRAYLIST) {
try { try {
stdout.printf (" %10s : %s\n", pray, k.get_string ("Praytime", pray.down ())); p = k.get_string ("Praytime", pray.down ());
s = (int.parse(p.substring (0, 2) + p.substring (3, 2))) > t ? "*" : " ";
of.keyval(pray, "%s %s".printf( p, of.c (ECHO.MICROTIME).s (s)));
} }
catch (GLib.KeyFileError e) { catch (GLib.KeyFileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
done = false;
} }
} }
of.state (done);
Dbg.out (Log.METHOD, "done:%d".printf ((int)done), Log.LINE, Log.FILE);
} }
public void init_cron () public void init_cron ()
{ {
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
try { try {
var parser = new Json.Parser (); var parser = new Json.Parser ();
parser.load_from_data (this.get_timings ()); parser.load_from_data (this.get_timings ());
@ -75,81 +96,94 @@ class Pluie.PrayTime : GLib.Object
var results = node.get_object_member ("timings"); var results = node.get_object_member ("timings");
this.write_timings (results, time); this.write_timings (results, time);
this.set_cron (time); this.set_cron (time);
this.infos (); this.infos (true);
} }
catch (Error e) { catch (Error e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
} }
private void on_error (string msg) private string get_config_file (string basename, bool tmp)
{ {
if (PrayTime.DEBUG) { return Path.build_filename (!tmp ? this.path : Environment.get_tmp_dir (), basename);
message (msg);
}
stderr.printf (" Error : %s\n", msg);
} }
private string get_config_file (string basename) private KeyFile load_config (string basename, bool tmp = false)
{
return Path.build_filename (this.path, basename);
}
private KeyFile load_config (string basename)
{ {
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
KeyFile f = new KeyFile (); KeyFile f = new KeyFile ();
f.set_list_separator (','); f.set_list_separator (',');
try { try {
f.load_from_file (this.get_config_file (basename), KeyFileFlags.NONE); f.load_from_file (this.get_config_file (basename, tmp), KeyFileFlags.NONE);
} }
catch (KeyFileError e) { catch (KeyFileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
catch (FileError e) { catch (FileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return f; return f;
} }
private string get_mp3 (string key = "default") private string get_mp3 (string key = "default")
{ {
Dbg.in (Log.METHOD, "key:'%s'".printf (key), Log.LINE, Log.FILE);
string mp3 = this.get_config (key, "Adhan"); string mp3 = this.get_config (key, "Adhan");
if (mp3 == "" && key != "default") { if (mp3 == "" && key != "default") {
mp3 = this.get_config ("default", "Adhan"); mp3 = this.get_config ("default", "Adhan");
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return mp3; return mp3;
} }
private double get_volume (string key = "default") private double get_volume (string key = "default")
{ {
Dbg.in (Log.METHOD, "key:'%s'".printf (key), Log.LINE, Log.FILE);
string volume = this.get_config (key, "Volumes"); string volume = this.get_config (key, "Volumes");
if (volume == "" && key != "default") { if (volume == "" && key != "default") {
volume = this.get_config ("default", "Volumes"); volume = this.get_config ("default", "Volumes");
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return double.parse (volume); return double.parse (volume);
} }
private string get_config (string key, string group = "Params") private string get_config (string key, string group = "Params")
{ {
Dbg.in (Log.METHOD, "key:'%s':group:'%s'".printf (key, group), Log.LINE, Log.FILE);
string v = ""; string v = "";
try { try {
v = this.kf.get_string (group, key); v = this.kf.get_string (group, key);
} }
catch (GLib.KeyFileError e) { catch (GLib.KeyFileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return v; return v;
} }
private int spawn_cmd (string cmd, out string response)
{
Dbg.in (Log.METHOD, "cmd:'%s'".printf (cmd), Log.LINE, Log.FILE);
if (this.cmd == null) this.cmd = new Sys.Cmd();
this.cmd.run (false, cmd);
response = this.cmd.output;
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return this.cmd.status;
}
private string get_timings () private string get_timings ()
{ {
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
of.action ("Loading timings");
string url = "%s://%s/%scity=%s&country=%s&method=%s&latitudeAdjustmentMethod=%s".printf( string url = "%s://%s/%scity=%s&country=%s&method=%s&latitudeAdjustmentMethod=%s".printf(
PrayTime.protocol, PrayTime.protocol,
PrayTime.hostname, PrayTime.hostname,
@ -159,87 +193,151 @@ class Pluie.PrayTime : GLib.Object
this.get_config ("method"), this.get_config ("method"),
this.get_config ("latitudeAdjustmentMethod") this.get_config ("latitudeAdjustmentMethod")
); );
of.echo (url, true, false, ECHO.OPTION_SEP);
var f = File.new_for_uri (url); var f = File.new_for_uri (url);
var response = ""; var response = "";
try { try {
// root user experience problem with that
// don't know why, use curl as alternative
// in get_alt_timings
FileInputStream fs = f.read (); FileInputStream fs = f.read ();
var dis = new DataInputStream (fs); var dis = new DataInputStream (fs);
string line; string line;
while ((line = dis.read_line (null)) != null) { while ((line = dis.read_line (null)) != null) {
response += line + "\n"; response += line + "\n";
} }
of.state (true);
} }
catch (GLib.Error e) { catch (GLib.Error e) {
this.on_error (e.message); of.state (false);
Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
response = this.get_alt_timings (url); response = this.get_alt_timings (url);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return response; return response;
} }
private string get_alt_timings (string url) private string get_alt_timings (string url)
{ {
stdout.printf(" trying alternate method to get timings\n"); Dbg.in (Log.METHOD, "url:'%s'".printf (url), Log.LINE, Log.FILE);
string response = ""; of.action ("Trying alternate method to load timings");
string std_error; string response;
int status; var status = this.spawn_cmd ("curl %s".printf (url), out response);
try { of.state (status == 0);
Process.spawn_command_line_sync ( Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
"curl "+url,
out response,
out std_error,
out status
);
} catch (SpawnError e) {
stderr.printf ("%s\n", e.message);
}
return response; return response;
} }
private int get_user_crontab_content (string user, out string response)
{
return this.spawn_cmd ("crontab -l -u %s".printf (user), out response);
}
private int install_user_crontab (string user, string path)
{
string response;
return this.spawn_cmd ("crontab %s -u %s".printf (path, user), out response);
}
private string? get_user_crontab (ref string user, ref string content)
{
Dbg.in (Log.METHOD, "user:'%s'".printf (user), Log.LINE, Log.FILE);
string data = "";
string udata;
try {
if (this.get_user_crontab_content (user, out udata) == 0) {
var regex = new Regex (Path.build_filename (this.bin, "praytime").escape (null));
foreach (string line in udata.split ("\n")) {
if (!regex.match (line) && line != "") {
data += line + "\n";
}
}
data += "\n" + content + "\n";
}
}
catch (RegexError e) {
data = null;
Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
}
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return data;
}
private string get_user ()
{
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
string? user = Environment.get_variable ("SUDO_USER");
if (user == null) {
user = Environment.get_variable ("USER");
}
if (user == null) {
user = Environment.get_variable ("LOGNAME");
}
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
return user;
}
private void set_cron (GLib.DateTime date) private void set_cron (GLib.DateTime date)
{ {
Dbg.in (Log.METHOD, "date:'%s'".printf (date.format ("%F %Hh%Mm%S")), Log.LINE, Log.FILE);
try { try {
string bin = "root "+Path.build_filename(this.bin, "praytime"); string user = this.get_user();
string cron_path = this.get_config ("path", "Cron"); of.action ("Setting crontab for user", user);
KeyFile k = this.load_config ("praytime.daily.ini", true);
string[] update = this.get_config ("time", "Cron").split (":", 2); string[] update = this.get_config ("time", "Cron").split (":", 2);
string content = "# %s\n%d %d * * * %s %s\n".printf (date.format ("%c"), int.parse (update[1]), int.parse(update[0]) , bin, "cron"); string[] time = null;
KeyFile k = this.load_config ("praytime.daily.ini"); string bin = Path.build_filename (this.bin, "praytime");
string cron_path = Path.build_filename (Environment.get_tmp_dir (), "praytime.crontab");
string content = "# > autogenerated by %s %s\n".printf (bin, date.format ("%c")) +
"%02d %02d * * * %s cron\n".printf (int.parse (update[1]), int.parse (update[0]) , bin);
foreach (string pray in PrayTime.PRAYLIST) { foreach (string pray in PrayTime.PRAYLIST) {
string[] time = k.get_string ("Praytime", pray.down ()).split (":", 2); time = k.get_string ("Praytime", pray.down ()).split (":", 2);
content += "%s %s * * * %s %s %s\n".printf (time[1], time[0] , bin, "play", pray); content += "%s %s * * * sh -c \"DISPLAY=:0 %s play %s\"\n".printf (time[1], time[0] , bin, pray);
}
content += "# < autogenerated by %s\n".printf(bin);
content = this.get_user_crontab (ref user, ref content);
if (content != null) {
if (FileUtils.set_contents (cron_path, content)) {
int status = this.install_user_crontab (user, cron_path);
of.state (status == 0);
}
} }
bool done = FileUtils.set_contents (cron_path, content);
stdout.printf ("\n updating %s : %s\n", cron_path, done ? "ok" : "ko");
} }
catch (GLib.KeyFileError e) { catch (GLib.KeyFileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
catch(GLib.FileError e) { catch(GLib.FileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
} }
private void write_timings (Json.Object results, GLib.DateTime date) private void write_timings (Json.Object results, GLib.DateTime date)
{ {
Dbg.in (Log.METHOD, "results:...:date:'%s'".printf (date.format ("%F %Hh%Mm%S")), Log.LINE, Log.FILE);
of.action ("Saving timings");
string data = "[Praytime]\n# %s\n%-10s = %s\n".printf (date.format ("%c"), "timestamp", date.to_unix ().to_string ()); string data = "[Praytime]\n# %s\n%-10s = %s\n".printf (date.format ("%c"), "timestamp", date.to_unix ().to_string ());
foreach (string pray in PrayTime.PRAYLIST) { foreach (string pray in PrayTime.PRAYLIST) {
data += "%-10s = %s\n".printf (pray.down(), results.get_string_member (pray)); data += "%-10s = %s\n".printf (pray.down(), results.get_string_member (pray));
} }
try { try {
FileUtils.set_contents (this.get_config_file ("praytime.daily.ini"), data); var done = FileUtils.set_contents (this.get_config_file ("praytime.daily.ini", true), data);
of.state (done);
} }
catch (GLib.FileError e) { catch (GLib.FileError e) {
stderr.printf ("%s\n", e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
} }
private void play (string f, double volume = 1.0, string[]? params = null) private void play (string f, double volume = 1.0, string[]? params = null)
{ {
Dbg.in (Log.METHOD, "f:'%s':volume:%0.1f".printf (f, volume), Log.LINE, Log.FILE);
try { try {
Gst.init (ref params); Gst.init (ref params);
this.loop = new GLib.MainLoop (); this.loop = new GLib.MainLoop ();
@ -251,11 +349,12 @@ class Pluie.PrayTime : GLib.Object
this.loop.run (); this.loop.run ();
} }
catch (FileError e) { catch (FileError e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
catch (Error e) { catch (Error e) {
this.on_error (e.message); Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
} }
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
} }
@ -267,12 +366,12 @@ class Pluie.PrayTime : GLib.Object
GLib.Error err; GLib.Error err;
string debug; string debug;
message.parse_error (out err, out debug); message.parse_error (out err, out debug);
stdout.printf ("Error: %s\n", err.message); of.error (err.message);
loop.quit (); loop.quit ();
break; break;
case MessageType.EOS: case MessageType.EOS:
stdout.printf ("end of stream\n"); of.echo ("end of stream");
this.playbin.set_state (State.NULL); this.playbin.set_state (State.NULL);
loop.quit (); loop.quit ();
break; break;
@ -283,4 +382,17 @@ class Pluie.PrayTime : GLib.Object
return true; return true;
} }
public void usage ()
{
of.echo ("\nUsage :", true, true, ECHO.VAL);
of.usage_command("praytime", "cron" , "" , "%s\n%s\n%s".printf (
"# update user crontab",
"# before installing please check config file ",
"# %s/praytime.ini".printf (this.path)
));
of.usage_command("praytime", "version", "" , "# display program version");
of.usage_command("praytime", "play" , "PRAYER_NAME", "# play adhan (Fajr, Dhuhr, Asr, Maghrib, Isha)");
of.usage_command("praytime", "" , "" , "# display prayer timings");
}
} }