diff --git a/README.md b/README.md index 199242f..67163bc 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,28 @@ # Notifier +[![Notifier](http://pkg.julialang.org/badges/Notifier_0.6.svg)](http://pkg.julialang.org/detail/Notifier) [![Build Status](https://travis-ci.org/goropikari/Notifier.jl.svg?branch=master)](https://travis-ci.org/goropikari/Notifier.jl) [![codecov.io](http://codecov.io/github/goropikari/Notifier.jl/coverage.svg?branch=master)](http://codecov.io/github/goropikari/Notifier.jl?branch=master) This package is notification tools for Julialang. + ## Features: + - Linux + - desktop notification + - sound notification + - email notification + - macOS + - desktop notification + - sound notification + - email notification + - say notification (Read given massage aloud) + - Windows (Experimental) + - desktop notification + - sound notification + ## Installation ```Julia Pkg.add("Notifier") +# Pkg.checkout("Notifier") # checkout master branch ``` # Linux OS @@ -20,7 +36,7 @@ Before using Notifier.jl, you need to install following softwares in your Linux $ sudo apt install libnotify-bin alsa-utils mailutils heirloom-mailx bsd-mailx ``` -This package uses `mail` linux command to notify by e-mail. Thus you need some settings in advance. +This package uses `mail` command to notify by e-mail. Thus you need some settings in advance. If following command works correctly, you don't need further setting. ```bash $ echo test | mail -s foo yourmail@example.com @@ -30,15 +46,15 @@ $ echo test | mail -s foo yourmail@example.com ### popup notification ```Julia using Notifier -notify("calculation done") +notify("Task completed") # defalut title is "Julia". # You can change the title by title option. -notify("calculation done", title="foofoo") -notify("calculation done", sound=true) # with sound -notify("calculation done", sound="./foo.wav") # specify a sound file -alarm() # only sound. You can specify a sound file, alarm(sound="./foo.wav") +notify("Task completed", title="foofoo") +notify("Task completed", sound=true) # with sound +notify("Task completed", sound="foo.wav") # specify a sound file +alarm() # only sound. You can specify a sound file, alarm(sound="foo.wav") ``` -![Screenshot of a Notification](./docs/popup.png?raw=true) +![Screenshot of a Notification](./docs/linuxpopup.png?raw=true) ### e-mail notification ```Julia @@ -65,14 +81,17 @@ email("message") # macOS ## Usage - +### popup notification ```julia using Notifier notify("Task completed") -notify("Notification with sound", sound=true) # you can also specify a sound file +notify("Change title", title="foofoo") +notify("Notification with sound", sound=true) +alarm() # only sound. You can specify a sound file, alarm(sound="foo.wav") +say("Finish calculation!") # Read aloud ``` -![Screenshot of a Notification](./docs/screenshot.png?raw=true) +![Screenshot of a Notification](./docs/macpopup.png?raw=true) Other supported parameters include `group` and `subtitle`. @@ -91,6 +110,28 @@ notify("Notification B", group="group2") Notifier.remove("group1") ``` +### e-mail notification +```Julia +email("message", To="foo@example.com") # default subject is set by date. +email("message", subject="result", To="foo@example.com") +``` + + +If you use "email" function frequently, I recommend you to register your email address by "register_email" function. +```Julia +julia> register_email() +Type your desired recipient e-mail address to receive a notification. +e-mail: foo@example.com + +Recipient e-mail address is saved at /path/to/.julia/v0.6/Notifier/email/address.txt. +If you want to change the address, modify /path/to/.julia/v0.6/Notifier/email/address.txt directly or run register_email() again +``` + +After you registered, you don't need to specify e-mail address. +```Julia +email("message") +``` + # Windows (Experimental) ## Usage ```Julia diff --git a/docs/linuxpopup.png b/docs/linuxpopup.png new file mode 100644 index 0000000..f4a4101 Binary files /dev/null and b/docs/linuxpopup.png differ diff --git a/docs/screenshot.png b/docs/macpopup.png similarity index 100% rename from docs/screenshot.png rename to docs/macpopup.png diff --git a/docs/popup.png b/docs/popup.png deleted file mode 100644 index ea0969e..0000000 Binary files a/docs/popup.png and /dev/null differ diff --git a/src/Notifier.jl b/src/Notifier.jl index 1f5a27e..5e20743 100644 --- a/src/Notifier.jl +++ b/src/Notifier.jl @@ -2,8 +2,8 @@ __precompile__() module Notifier -if is_linux() include("linux.jl") end -if is_apple() include("mac.jl") end -if is_windows() include("windows.jl") end +is_linux() && include("linux.jl") +is_apple() && include("mac.jl") +is_windows() && include("windows.jl") end # module diff --git a/src/email.jl b/src/email.jl new file mode 100644 index 0000000..ceff41c --- /dev/null +++ b/src/email.jl @@ -0,0 +1,55 @@ +export register_email, email + +""" + Notifier.register_email() + +Register a recipient e-mail address. +""" +function register_email() + emaildir = joinpath(@__DIR__, "..", "email") + mkpath(emaildir) + + if ispath(joinpath(emaildir, "address.txt")) + println("An e-mail address is already registered.") + print("Do you overwrite? [y/n]: ") + YesNo = lowercase(chomp(readline(STDIN))) + + if YesNo ∈ ["n", "no"] + return nothing + end + end + + println("\nType your desired recipient e-mail address to receive a notification.") + print("e-mail: ") + To = chomp(readline(STDIN)) + fp = open(joinpath(emaildir, "address.txt"), "w") + write(fp, To) + close(fp) + + println("\nRecipient e-mail address is saved at $(abspath((joinpath(emaildir, "address.txt")))).") + println("If you want to change the address, modify $(abspath((joinpath(emaildir, "address.txt")))) directly or run register_email() again.") +end + +""" + Notifier.email(message; subject, To) + +Send email to specific email address. + +# Arguments +- `To::AbstractString`: recipient email adress. +""" +function email(message; subject="$(round(now(), Dates.Second(1)))", To="") + emaildir = joinpath(@__DIR__, "..", "email") + if isempty(To) + if ispath(joinpath(emaildir, "address.txt")) + To = readline(joinpath(emaildir, "address.txt")) + else + error("""Email address is not specified. + In order to send an e-mail, you should register an e-mail address by + register_email() + or specify the address by using To option. + email(\"some messages\", To=\"foo@example.com\").""") + end + end + run(pipeline(`echo $message`, `mail -s $subject $To`)) +end diff --git a/src/linux.jl b/src/linux.jl index 656b018..92fcb92 100644 --- a/src/linux.jl +++ b/src/linux.jl @@ -1,15 +1,18 @@ import Base.notify export notify, alarm, register_email, email -@doc """ +include("email.jl") + +""" --- -Notifier.notify(message::AbstractString; title::AbstractString, sound, time) + Notifier.notify(message; title="Julia", sound=false, time=4) + +Notify by desktop notification. -defalut parameter\n - title = "Julia"\n - sound = false\n - time = 4 # display time (seconds) -""" notify +# Arguments +- `sound::Union{Bool, AbstractString}`: Play default sound or specific sound. +- `time::Real`: display time. +""" function notify(message::AbstractString; title="Julia", sound::Union{Bool, AbstractString}=false, @@ -26,67 +29,13 @@ function notify(message::AbstractString; return end -@doc """ -Notifier.alarm(;sound::AbstractString) -notify by sound +""" + Notifier.alarm(;sound="defalut.wav") -if you choose a specific sound WAV file, you can use it instead of the defalut sound. -""" alarm +Notify by sound. +If you choose a specific sound WAV file, you can play it instead of the defalut sound. +""" function alarm(;sound::AbstractString=joinpath(@__DIR__, "default.wav")) @async run(`aplay -q $sound`) return nothing end - -@doc """ -Notifier.register_email() - -register a recipient e-mail address -""" register_email -function register_email() - emaildir = joinpath(@__DIR__, "..", "email") - mkpath(emaildir) - - if ispath(joinpath(emaildir, "address.txt")) - println("An e-mail address is already registered.") - println("Do you overwrite? [y/n]") - YesNo = lowercase(chomp(readline(STDIN))) - - if YesNo ∈ ["n", "no"] - return - end - end - - println("\nType your desired recipient e-mail address to receive a notification.") - print("e-mail: ") - To = chomp(readline(STDIN)) - fp = open(joinpath(emaildir, "address.txt"), "w") - write(fp, To) - close(fp) - - println("\nRecipient e-mail address is saved at $(abspath((joinpath(emaildir, "address.txt")))).") - println("If you want to change the address, modify $(abspath((joinpath(emaildir, "address.txt")))) directly or run register_email() again.") -end - -@doc """ -Notifier.email(message; subject, To) - -defalut\n -subject="\$(round(now(), Dates.Second(1)))"\n -To="not-specified"\n -""" email -function email(message; subject="$(round(now(), Dates.Second(1)))", To="not-specified") - emaildir = joinpath(@__DIR__, "..", "email") - if To == "not-specified" - if ispath(joinpath(emaildir, "address.txt")) - To = readline(joinpath(emaildir, "address.txt")) - else - println("Email address is not specified.") - println("In order to send an e-mail, register an e-mail address by register_email() or") - println("specify it by To option like") - println(" email(\"some messages\", To=\"foo@example.com\").") - - return - end - end - run(pipeline(`echo $message`, `mail -s $subject $To`)) -end diff --git a/src/logo.svg b/src/logo.svg index 2a25660..df513c6 100644 --- a/src/logo.svg +++ b/src/logo.svg @@ -1,61 +1,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/src/mac.jl b/src/mac.jl index 8d3131a..614785c 100644 --- a/src/mac.jl +++ b/src/mac.jl @@ -1,14 +1,21 @@ import Base.notify -export notify +export notify, alarm, say + +include("email.jl") if ispath("/usr/local/bin/terminal-notifier") const terminalnotifier = "/usr/local/bin/terminal-notifier" elseif ispath(joinpath(Pkg.dir("Homebrew"), "deps", "usr", "bin", "terminal-notifier")) const terminalnotifier = joinpath(Pkg.dir("Homebrew"), "deps", "usr", "bin", "terminal-notifier") else - error("Notifier.jl not properly installed. Please run Pkg.build(\"Notifier\")") + error("Notifier.jl is not properly installed. Please run Pkg.build(\"Notifier\")") end +""" + Notifier.notify(message=""; title="Julia", subtitle="", group="", sound=false, sender="org.julialang.launcherapp") + +Notify by desktop notification. +""" function notify(message=""; title="Julia", subtitle="", group="", sound=false, sender="org.julialang.launcherapp") if group != "" && sound != "" && sound != false run(`$terminalnotifier -sender $sender -message $message -title $title -subtitle $subtitle -group $group -sound $sound`) @@ -25,12 +32,32 @@ function remove(group="ALL"; sender="org.julialang.launcherapp") run(`$terminalnotifier -remove $group -sender $sender`) end -#function list(group="ALL") -# lines = readall(`$terminalnotifier -list $group`) -# lines = split(lines, "\n") -# lines = map(line -> split(line, "\t"), lines) -# lines = map(line -> map(element -> convert(ASCIIString, element), line), lines) -# keys = lines[1] -# lines = lines[2:end-1] -# map(line -> Dict(zip(keys, line)), lines) -#end +""" + Notifier.alarm(;sound=joinpath(@__DIR__, "default.wav")) + +Notify by sound. +If you choose a specific sound WAV file, you can play it instead of the defalut sound. +```julia +alarm(sound="foo.wav") +``` +""" +function alarm(;sound::AbstractString=joinpath(@__DIR__, "default.wav")) + if sound == joinpath(@__DIR__, "default.wav") + @async run(`afplay $sound`) + elseif ispath(abspath(relpath(expanduser(sound)))) + @async run(`afplay $(expanduser(sound))`) + else + error("No such file or directory") + end + + return nothing +end + +""" + Notifier.say(message::AbstractString) + +Read given message aloud. +""" +function say(msg::AbstractString) + run(`say $msg`) +end diff --git a/src/windows.jl b/src/windows.jl index d646905..1a57761 100644 --- a/src/windows.jl +++ b/src/windows.jl @@ -1,17 +1,16 @@ import Base.notify export notify, alarm - -@doc """ +""" --- -Notifier.notify(message::AbstractString; - title::AbstractString, - sound::Union{Bool, AbstractString}, - time::Real) + Notifier.notify(message; title="Julia", sound=false, time=4) + +Notify by desktop notification. -default parameter\n - title = "Julia"\n - time = 4 # display time (seconds). If you set time=0, then the message box is displayed until you put botton. -""" notify +# Arguments +- `sound::Union{Bool, AbstractString}`: Play default sound or specific sound. +- `time::Real`: display time. If you set time=0, then the message box is displayed + until you put the botton. +""" function notify(message::AbstractString; title="Julia", sound::Union{Bool, AbstractString}=false, @@ -20,7 +19,6 @@ function notify(message::AbstractString; if sound == true @async run(`powershell -Command '('new-object System.Media.SoundPlayer $(joinpath(@__DIR__, "default.wav"))')'.PlaySync'('')'`) elseif ispath(sound) - #@async run(`aplay -q $sound`) @async run(`powershell -Command '('new-object System.Media.SoundPlayer $sound')'.PlaySync'('')'`) end end @@ -29,10 +27,15 @@ function notify(message::AbstractString; return end -@doc """ -Notifier.alarm(;sound::AbstractString) -notify by sound +""" + Notifier.alarm(;sound=joinpath(@__DIR__, "default.wav")) -if you choose a specific sound WAV file, you can use it instead of the default sound. -""" alarm -alarm(;sound::AbstractString=joinpath(@__DIR__, "default.wav")) = @async run(`powershell -Command '('new-object System.Media.SoundPlayer $sound')'.PlaySync'('')'`) +Notify by sound. +If you choose a specific sound WAV file, you can play it instead of the defalut sound. +```julia +alarm(sound="foo.wav") +``` +""" +function alarm(;sound::AbstractString=joinpath(@__DIR__, "default.wav")) + @async run(`powershell -Command '('new-object System.Media.SoundPlayer $sound')'.PlaySync'('')'`) +end diff --git a/test/linux_test.jl b/test/linux_test.jl index ca556d4..e69699d 100644 --- a/test/linux_test.jl +++ b/test/linux_test.jl @@ -22,3 +22,9 @@ end catch false end +@test try + alarm() + true +catch + false +end diff --git a/test/mac_test.jl b/test/mac_test.jl index 8ce74fe..e5c6b8b 100644 --- a/test/mac_test.jl +++ b/test/mac_test.jl @@ -34,3 +34,15 @@ end catch false end +@test try + alarm() + true +catch + false +end +isinteractive() && @test try + say("Hello") + true +catch + false +end