mirror of
https://github.com/RGBCube/nu_scripts
synced 2025-08-02 15:17:47 +00:00
added maths, defs and weather scripts (#217)
This commit is contained in:
parent
350cf53acf
commit
af2c1bea43
5 changed files with 748 additions and 0 deletions
|
@ -33,3 +33,147 @@ def fact [num: int] {
|
||||||
echo 'Error: can only calculate non-negative integers'
|
echo 'Error: can only calculate non-negative integers'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
### Added by kira
|
||||||
|
## constants
|
||||||
|
let pi = 3.1415926535897932
|
||||||
|
let e = 2.7182818284590452
|
||||||
|
|
||||||
|
#Calculate roots of the quadratic function: ax^2+bx+x
|
||||||
|
def q_roots [
|
||||||
|
a # x^2
|
||||||
|
b # x
|
||||||
|
c # independent term
|
||||||
|
] {
|
||||||
|
let d = $b ** 2 - 4 * $a * $c
|
||||||
|
if $d >= 0 {
|
||||||
|
let s = ($d | math sqrt)
|
||||||
|
let r1 = (($s - $b) / (2 * $a))
|
||||||
|
let r2 = (0 - (($s + $b) / (2 * $a)))
|
||||||
|
|
||||||
|
echo $"root #1: ($r1)"
|
||||||
|
echo $"root #2: ($r2)"
|
||||||
|
} else {
|
||||||
|
let s = ((0 - $d) | math sqrt)
|
||||||
|
let r = ((0 - $b) / (2 * $a))
|
||||||
|
let i = ($s / (2 * $a))
|
||||||
|
|
||||||
|
echo $"root #1: ($r) + ($i)*i"
|
||||||
|
echo $"root #2: ($r) - ($i)*i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Check if integer is prime
|
||||||
|
def isprime [n: int] {
|
||||||
|
let max = ($n | math sqrt | math ceil)
|
||||||
|
|
||||||
|
let flag = ([[isPrime];[true]] | update isPrime {if ($n mod 2) == 0 { false } else { seq 3 1 $max | each { |it| if ($n mod $it) == 0 { false }}}})
|
||||||
|
|
||||||
|
if ($flag.isPrime.0 | empty?) { echo 'prime' } else { echo 'not prime' }
|
||||||
|
}
|
||||||
|
|
||||||
|
#Prime list <= n
|
||||||
|
def primelist [n: int] {
|
||||||
|
let primes = [2 3]
|
||||||
|
|
||||||
|
let primes2 = (seq 5 2 $n | each {|it| if (isprime $it) == 'prime' {$it}})
|
||||||
|
|
||||||
|
$primes | append $primes2
|
||||||
|
}
|
||||||
|
|
||||||
|
#Multiplication table of n till max
|
||||||
|
def mtable [n: int, max: int] {
|
||||||
|
seq 1 $max | each {|it| echo $"($it)*($n) = ($n * $it)"}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Check if year is leap
|
||||||
|
def isleap [year: int] {
|
||||||
|
if ( (($year mod 4) == 0 && ($year mod 100) != 0) || ($year mod 400) == 0 ) { echo "It is a leap year." } else { echo "It is not a leap year."}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Greatest common divisior (gcd) between 2 integers
|
||||||
|
def gcd [a: int, b:int] {
|
||||||
|
if $a < $b {
|
||||||
|
gcd $b $a
|
||||||
|
} else if $b == 0 {
|
||||||
|
$a
|
||||||
|
} else {
|
||||||
|
gcd $b ($a mod $b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Least common multiple (lcm) between 2 integers
|
||||||
|
def lcm [a: int, b:int] {
|
||||||
|
if $a == $b && $b == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
$a * ($b / (gcd $a $b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Decimal number to custom base representation
|
||||||
|
def dec2base [
|
||||||
|
n: string #decimal number
|
||||||
|
b: string #base in [2,16]
|
||||||
|
] {
|
||||||
|
let base = if ( ($b | into int) < 2 || ($b | into int) > 16 ) {
|
||||||
|
echo "Wrong base, it must be an integer between 2 and 16"
|
||||||
|
10
|
||||||
|
} else {
|
||||||
|
$b | into int
|
||||||
|
}
|
||||||
|
|
||||||
|
let number = ($n | into int)
|
||||||
|
|
||||||
|
let chars = ['0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F']
|
||||||
|
|
||||||
|
if $number == 0 {
|
||||||
|
''
|
||||||
|
} else {
|
||||||
|
let newNumber = (($number - ($number mod $base)) / $base)
|
||||||
|
|
||||||
|
[(dec2base $newNumber $base) ($chars | get ($number mod $base))] | str collect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Scale list to [a,b] interval
|
||||||
|
def scale-minmax [a, b,input?] {
|
||||||
|
let x = if ($input | empty?) {$in} else {$input}
|
||||||
|
|
||||||
|
let min = ($x | math min)
|
||||||
|
let max = ($x | math max)
|
||||||
|
|
||||||
|
$x | each {|it| ((($it - $min) / ($max - $min)) * ($b - $a) + $a) }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Scale every column of a table (separately) to [a,b] interval
|
||||||
|
def scale-minmax-table [a, b,input?] {
|
||||||
|
let x = if ($input | empty?) {$in} else {$input}
|
||||||
|
let n_cols = ($x | transpose | length)
|
||||||
|
let name_cols = ($x | transpose | column2 0)
|
||||||
|
|
||||||
|
for $i in 0..($n_cols - 1) {
|
||||||
|
($x | column2 $i) | scale-minmax $a $b | wrap ($name_cols | get $i)
|
||||||
|
} | reduce {|it, acc| $acc | merge {$it}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#sin function
|
||||||
|
def "math sin" [ ] {
|
||||||
|
each {|x| "s(" + $"($x)" + ")\n" | bc -l | into decimal }
|
||||||
|
}
|
||||||
|
|
||||||
|
#cos function
|
||||||
|
def "math cos" [ ] {
|
||||||
|
each {|x| "c(" + $"($x)" + ")\n" | bc -l | into decimal }
|
||||||
|
}
|
||||||
|
|
||||||
|
#natural log function
|
||||||
|
def "math ln" [ ] {
|
||||||
|
each {|x| "l(" + $"($x)" + ")\n" | bc -l | into decimal }
|
||||||
|
}
|
||||||
|
|
||||||
|
#exp function
|
||||||
|
def "math exp" [ ] {
|
||||||
|
each {|x| "e(" + $"($x)" + ")\n" | bc -l | into decimal }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
4
miscelaneous/downup-plot
Executable file
4
miscelaneous/downup-plot
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#requieres fast-cli
|
||||||
|
fast --single-line --upload | stdbuf -o0 awk '{print $2 " " $6}' | ttyplot -2 -t "Download/Upload speed" -u Mbps
|
405
miscelaneous/nu_defs.nu
Normal file
405
miscelaneous/nu_defs.nu
Normal file
|
@ -0,0 +1,405 @@
|
||||||
|
#copy current dir
|
||||||
|
def cpwd [] {pwd | tr "\n" " " | sed "s/ //g" | xclip -sel clip}
|
||||||
|
|
||||||
|
#update-upgrade system (ubuntu)
|
||||||
|
def supgrade [] {
|
||||||
|
echo "updating..."
|
||||||
|
sudo aptitude update -y
|
||||||
|
echo "upgrading..."
|
||||||
|
sudo aptitude safe-upgrade -y
|
||||||
|
echo "autoremoving..."
|
||||||
|
sudo apt autoremove -y
|
||||||
|
}
|
||||||
|
|
||||||
|
#open mcomix
|
||||||
|
def mcx [file] {
|
||||||
|
bash -c $'mcomix "($file)" 2>/dev/null &'
|
||||||
|
}
|
||||||
|
|
||||||
|
#open file
|
||||||
|
def openf [file?] {
|
||||||
|
let file = if ($file | empty?) {$in} else {$file}
|
||||||
|
|
||||||
|
bash -c $'xdg-open "($file)" 2>/dev/null &'
|
||||||
|
}
|
||||||
|
|
||||||
|
#search for specific process
|
||||||
|
def psn [name: string] {
|
||||||
|
ps | find $name
|
||||||
|
}
|
||||||
|
|
||||||
|
#kill specified process in name
|
||||||
|
def killn [name: string] {
|
||||||
|
ps | find $name | each {kill -f $in.pid}
|
||||||
|
}
|
||||||
|
|
||||||
|
#jdownloader downloads info (requires a jdown python script)
|
||||||
|
def nujd [] {
|
||||||
|
jdown | lines | each { |line| $line | from nuon } | flatten | flatten
|
||||||
|
}
|
||||||
|
|
||||||
|
# Switch-case like instruction
|
||||||
|
def switch [
|
||||||
|
var #input var to test
|
||||||
|
cases: record #record with all cases
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# let x = 3
|
||||||
|
# switch $x {
|
||||||
|
# 1: { echo "you chose one" },
|
||||||
|
# 2: { echo "you chose two" },
|
||||||
|
# 3: { echo "you chose three" }
|
||||||
|
# }
|
||||||
|
] {
|
||||||
|
echo $cases | get $var | do $in
|
||||||
|
}
|
||||||
|
|
||||||
|
#post to discord
|
||||||
|
def post_to_discord [message] {
|
||||||
|
let content = $"{\"content\": \"($message)\"}"
|
||||||
|
|
||||||
|
let weburl = "webhook_url"
|
||||||
|
|
||||||
|
post $weburl $content --content-type "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
#select column of a table (to table)
|
||||||
|
def column [n] {
|
||||||
|
transpose | select $n | transpose | select column1 | headers
|
||||||
|
}
|
||||||
|
|
||||||
|
#get column of a table (to list)
|
||||||
|
def column2 [n] {
|
||||||
|
transpose | get $n | transpose | get column1 | skip 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#short pwd
|
||||||
|
def pwd-short [] {
|
||||||
|
$env.PWD | str replace $nu.home-path '~' -s
|
||||||
|
}
|
||||||
|
|
||||||
|
#string repeat
|
||||||
|
def "str repeat" [count: int] {
|
||||||
|
each {|it| let str = $it; echo 1..$count | each { echo $str } }
|
||||||
|
}
|
||||||
|
|
||||||
|
#join 2 lists
|
||||||
|
def union [a: list, b: list] {
|
||||||
|
$a | append $b | uniq
|
||||||
|
}
|
||||||
|
|
||||||
|
#nushell source files info
|
||||||
|
def 'nu-sloc' [] {
|
||||||
|
let stats = (
|
||||||
|
ls **/*.nu
|
||||||
|
| select name
|
||||||
|
| insert lines { |it| open $it.name | size | get lines }
|
||||||
|
| insert blank {|s| $s.lines - (open $s.name | lines | find --regex '\S' | length) }
|
||||||
|
| insert comments {|s| open $s.name | lines | find --regex '^\s*#' | length }
|
||||||
|
| sort-by lines -r
|
||||||
|
)
|
||||||
|
|
||||||
|
let lines = ($stats | reduce -f 0 {|it, acc| $it.lines + $acc })
|
||||||
|
let blank = ($stats | reduce -f 0 {|it, acc| $it.blank + $acc })
|
||||||
|
let comments = ($stats | reduce -f 0 {|it, acc| $it.comments + $acc })
|
||||||
|
let total = ($stats | length)
|
||||||
|
let avg = ($lines / $total | math round)
|
||||||
|
|
||||||
|
$'(char nl)(ansi pr) SLOC Summary for Nushell (ansi reset)(char nl)'
|
||||||
|
print { 'Total Lines': $lines, 'Blank Lines': $blank, Comments: $comments, 'Total Nu Scripts': $total, 'Avg Lines/Script': $avg }
|
||||||
|
$'(char nl)Source file stat detail:'
|
||||||
|
print $stats
|
||||||
|
}
|
||||||
|
|
||||||
|
#go to dir (via pipe)
|
||||||
|
def-env goto [] {
|
||||||
|
let input = $in
|
||||||
|
cd (
|
||||||
|
if ($input | path type) == file {
|
||||||
|
($input | path dirname)
|
||||||
|
} else {
|
||||||
|
$input
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#go to custom bash bin path, must be added last in config.nu
|
||||||
|
def-env goto-bash [] {
|
||||||
|
cd ($env.PATH | last)
|
||||||
|
}
|
||||||
|
|
||||||
|
#cd to the folder where a binary is located
|
||||||
|
def-env which-cd [program] {
|
||||||
|
let dir = (which $program | get path | path dirname | str trim)
|
||||||
|
cd $dir.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#push to git
|
||||||
|
def git-push [m: string] {
|
||||||
|
git add -A
|
||||||
|
git status
|
||||||
|
git commit -am $"($m)"
|
||||||
|
git push origin main
|
||||||
|
}
|
||||||
|
|
||||||
|
#get help for custom commands
|
||||||
|
def "help my-commands" [] {
|
||||||
|
help commands | where is_custom == true
|
||||||
|
}
|
||||||
|
|
||||||
|
#web search in terminal (requires ddgr)
|
||||||
|
def gg [...search: string] {
|
||||||
|
ddgr -n 5 ($search | str collect ' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
#habitipy dailies done all (requires habitipy)
|
||||||
|
def hab-dailies-done [] {
|
||||||
|
let to_do = (habitipy dailies | grep ✖ | awk {print $1} | tr '.\n' ' ' | split row ' ' | into int)
|
||||||
|
habitipy dailies done $to_do
|
||||||
|
}
|
||||||
|
|
||||||
|
#update aliases backup file from config.nu
|
||||||
|
def update-aliases [] {
|
||||||
|
let nlines = (open $nu.config-path | lines | length)
|
||||||
|
|
||||||
|
let from = ((grep "## aliases" $nu.config-path -n | split row ':').0 | into int)
|
||||||
|
|
||||||
|
open $nu.config-path | lines | last ($nlines - $from + 1) | save /path/to/backup/file.nu
|
||||||
|
}
|
||||||
|
|
||||||
|
#update config.nu from aliases backup
|
||||||
|
def update-config [] {
|
||||||
|
let from = ((grep "## aliases" $nu.config-path -n | split row ':').0 | into int)
|
||||||
|
let aliases = "/path/to/backup/file.nu"
|
||||||
|
|
||||||
|
open $nu.config-path | lines | first ($from - 1) | append (open $aliases | lines) | save temp.nu
|
||||||
|
mv temp.nu $nu.config-path
|
||||||
|
}
|
||||||
|
|
||||||
|
#countdown alarm (requires termdown y mpv)
|
||||||
|
def countdown [
|
||||||
|
n: int # time in seconds
|
||||||
|
] {
|
||||||
|
let BEEP = "/path/to/sound/file"
|
||||||
|
let muted = (pacmd list-sinks | awk '/muted/ { print $2 }' | tr '\n' ' ' | split row ' ' | last)
|
||||||
|
|
||||||
|
if $muted == 'no' {
|
||||||
|
termdown $n;mpv --no-terminal $BEEP
|
||||||
|
} else {
|
||||||
|
termdown $n
|
||||||
|
unmute
|
||||||
|
mpv --no-terminal $BEEP
|
||||||
|
mute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#get aliases
|
||||||
|
def get-aliases [] {
|
||||||
|
open $nu.config-path | lines | find alias | find -v aliases | split column '=' | select column1 column2 | rename Alias Command | update Alias {|f| $f.Alias | split row ' ' | last} | sort-by Alias
|
||||||
|
}
|
||||||
|
|
||||||
|
#compress every subfolder into separate files and delete them
|
||||||
|
def 7zfolders [] {
|
||||||
|
^find . -maxdepth 1 -mindepth 1 -type d -print0 | parallel -0 --eta 7z a -t7z -sdel -bso0 -bsp0 -m0=lzma2 -mx=9 -ms=on -mmt=on {}.7z {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#compress to 7z using max compression
|
||||||
|
def 7zmax [
|
||||||
|
filename: string #filename without extension
|
||||||
|
...rest: string #files to compress and extra flags for 7z (add flags between quotes)
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# compress all files in current directory and delete them
|
||||||
|
# 7zmax * "-sdel"
|
||||||
|
] {
|
||||||
|
|
||||||
|
if ($rest | empty?) {
|
||||||
|
echo "no files to compress specified"
|
||||||
|
} else {
|
||||||
|
7z a -t7z -m0=lzma2 -mx=9 -ms=on -mmt=on $"($filename).7z" $rest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#add event to google calendar, also usable without arguments (requires gcalcli)
|
||||||
|
def addtogcal [
|
||||||
|
calendar? #to which calendar add event
|
||||||
|
title? #event title
|
||||||
|
when? #date: yyyy.MM.dd hh:mm
|
||||||
|
where? #location
|
||||||
|
duration? #duration in minutes
|
||||||
|
] {
|
||||||
|
|
||||||
|
let calendar = if $calendar == null {echo $"calendar: ";input } else {$calendar}
|
||||||
|
let title = if $title == null {echo $"\ntitle: ";input } else {$title}
|
||||||
|
let when = if $when == null {echo $"\nwhen: ";input } else {$when}
|
||||||
|
let where = if $where == null {echo $"\nwhere: ";input } else {$where}
|
||||||
|
let duration = if $duration == null {echo $"\nduration: ";input } else {$duration}
|
||||||
|
|
||||||
|
gcalcli --calendar $"($calendar)" add --title $"($title)" --when $"($when)" --where $"($where)" --duration $"($duration)" --default-reminders
|
||||||
|
}
|
||||||
|
|
||||||
|
#show gcal agenda in selected calendars
|
||||||
|
def agenda [
|
||||||
|
--full: int #show all calendars (default: 0)
|
||||||
|
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
# agenda
|
||||||
|
# agenda --full true
|
||||||
|
# agenda "--details=all"
|
||||||
|
# agenda --full true "--details=all"
|
||||||
|
] {
|
||||||
|
let calendars = "your_selected_calendars"
|
||||||
|
let calendars_full = "most_calendars"
|
||||||
|
|
||||||
|
if ($full | empty?) || ($full == 0) {
|
||||||
|
gcalcli --calendar $"($calendars)" agenda --military $rest
|
||||||
|
} else {
|
||||||
|
gcalcli --calendar $"($calendars_full)" agenda --military $rest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#show gcal week in selected calendards
|
||||||
|
def semana [
|
||||||
|
--full: int #show all calendars (default: 0)
|
||||||
|
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
# semana
|
||||||
|
# semana --full true
|
||||||
|
# semana "--details=all"
|
||||||
|
# semana --full true "--details=all"
|
||||||
|
] {
|
||||||
|
let calendars = "your_selected_calendars"
|
||||||
|
let calendars_full = "most_calendars"
|
||||||
|
|
||||||
|
if ($full | empty?) || ($full == 0) {
|
||||||
|
gcalcli --calendar $"($calendars)" calw $rest --military --monday
|
||||||
|
} else {
|
||||||
|
gcalcli --calendar $"($calendars_full)" calw $rest --military --monday
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#show gcal month in selected calendards
|
||||||
|
def mes [
|
||||||
|
--full: int #show all calendars (default: 0)
|
||||||
|
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
# mes
|
||||||
|
# mes --full true
|
||||||
|
# mes "--details=all"
|
||||||
|
# mes --full true "--details=all"
|
||||||
|
] {
|
||||||
|
let calendars = "your_selected_calendars"
|
||||||
|
let calendars_full = "most_calendars"
|
||||||
|
|
||||||
|
if ($full | empty?) || ($full == 0) {
|
||||||
|
gcalcli --calendar $"($calendars)" calm $rest --military --monday
|
||||||
|
} else {
|
||||||
|
gcalcli --calendar $"($calendars_full)" calm $rest --military --monday
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#get bitly short link (requires xclip)
|
||||||
|
def mbitly [longurl] {
|
||||||
|
if ($longurl | empty?) {
|
||||||
|
echo "no url provided"
|
||||||
|
} else {
|
||||||
|
let Accesstoken = "Token"
|
||||||
|
let username = "user"
|
||||||
|
let url = $"https://api-ssl.bitly.com/v3/shorten?access_token=($Accesstoken)&login=($username)&longUrl=($longurl)"
|
||||||
|
|
||||||
|
let shorturl = (fetch $url | get data | get url)
|
||||||
|
|
||||||
|
$shorturl
|
||||||
|
$shorturl | xclip -sel clip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#translate text using mymemmory api
|
||||||
|
def trans [
|
||||||
|
...search:string #search query]
|
||||||
|
--from:string #from which language you are translating (default english)
|
||||||
|
--to:string #to which language you are translating (default spanish)
|
||||||
|
#
|
||||||
|
#Use ISO standar names for the languages, for example:
|
||||||
|
#english: en-US
|
||||||
|
#spanish: es-ES
|
||||||
|
#italian: it-IT
|
||||||
|
#swedish: sv-SV
|
||||||
|
#
|
||||||
|
#More in: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||||
|
] {
|
||||||
|
|
||||||
|
if ($search | empty?) {
|
||||||
|
echo "no search query provided"
|
||||||
|
} else {
|
||||||
|
let key = "api_kei"
|
||||||
|
let user = "user_email"
|
||||||
|
|
||||||
|
let from = if ($from | empty?) {"en-US"} else {$from}
|
||||||
|
let to = if ($to | empty?) {"es-ES"} else {$to}
|
||||||
|
|
||||||
|
let to_translate = ($search | str collect "%20")
|
||||||
|
|
||||||
|
let url = $"https://api.mymemory.translated.net/get?q=($to_translate)&langpair=($from)%7C($to)&of=json&key=($key)&de=($user)"
|
||||||
|
|
||||||
|
fetch $url | get responseData | get translatedText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#check if drive is mounted
|
||||||
|
def is-mounted [drive:string] {
|
||||||
|
let count = (ls "~/media" | find $"($drive)" | length)
|
||||||
|
|
||||||
|
if $count == 0 {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#get phone number from google contacts (requires goobook)
|
||||||
|
def get-phone-number [search:string] {
|
||||||
|
goobook dquery $search | from ssv | rename results | where results =~ '(?P<plus>\+)(?P<nums>\d+)'
|
||||||
|
}
|
||||||
|
|
||||||
|
#ping with plot (requires bash png-plot using ttyplot)
|
||||||
|
def nu-png-plot [] {
|
||||||
|
bash -c png-plot
|
||||||
|
}
|
||||||
|
|
||||||
|
#plot download-upload speed (requires bash downup-plot using ttyplot)
|
||||||
|
def nu-downup-plot [] {
|
||||||
|
bash -c downup-plot
|
||||||
|
}
|
||||||
|
|
||||||
|
#plot data table using gnuplot
|
||||||
|
def gnu-plot [
|
||||||
|
data? #1 or 2 column table
|
||||||
|
--title:string #title
|
||||||
|
#
|
||||||
|
#Example: If $x is a table with 2 columns
|
||||||
|
#$x | gnu-plot
|
||||||
|
#($x | column 0) | gnu-plot
|
||||||
|
#($x | column 1) | gnu-plot
|
||||||
|
#($x | column 0) | gnu-plot --title "My Title"
|
||||||
|
#gnu-plot $x --title "My Title"
|
||||||
|
] {
|
||||||
|
let x = if ($data | empty?) {$in} else {$data}
|
||||||
|
let n_cols = ($x | transpose | length)
|
||||||
|
let name_cols = ($x | transpose | column2 0)
|
||||||
|
|
||||||
|
let ylabel = if $n_cols == 1 {$name_cols | get 0} else {$name_cols | get 1}
|
||||||
|
let xlabel = if $n_cols == 1 {""} else {$name_cols | get 0}
|
||||||
|
|
||||||
|
let title = if ($title | empty?) {if $n_cols == 1 {$ylabel | str upcase} else {$"($ylabel) vs ($xlabel)"}} else {$title}
|
||||||
|
|
||||||
|
$x | to tsv | save data0.txt
|
||||||
|
sed 1d data0.txt | save data.txt
|
||||||
|
|
||||||
|
gnuplot -e $"set terminal dumb; unset key;set title '($title)';plot 'data.txt' w l lt 0;"
|
||||||
|
|
||||||
|
rm data*.txt | ignore
|
||||||
|
}
|
3
miscelaneous/png-plot
Executable file
3
miscelaneous/png-plot
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ping 1.1.1.1 | sed -u 's/^.*time=//g; s/ ms//g' | ttyplot -t \"ping to 1.1.1.1\" -u ms
|
192
weather/weatherdark.nu
Normal file
192
weather/weatherdark.nu
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
# Weather Script based on IP Address
|
||||||
|
# - Weather using dark weather api
|
||||||
|
# - Air polution condition using airvisual api
|
||||||
|
# - Street address using google maps api
|
||||||
|
# - Version 2.0
|
||||||
|
export def-env weatherds [] {
|
||||||
|
get_weather (get_location 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
# location functions thanks to https://github.com/nushell/nu_scripts/tree/main/weather
|
||||||
|
def locations [] {
|
||||||
|
[
|
||||||
|
[location city_column state_column country_column lat_column lon_column];
|
||||||
|
["http://ip-api.com/json/" city region countryCode lat lon]
|
||||||
|
["https://ipapi.co/json/" city region_code country_code latitude longitude]
|
||||||
|
["https://freegeoip.app/json/" city region_code country_code latitude longitude]
|
||||||
|
["https://ipwhois.app/json/" city region country_code latitude longitude]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_location [index: int] {
|
||||||
|
let wifi = (iwgetid -r)
|
||||||
|
let loc_json = (fetch (locations | select $index).0.location)
|
||||||
|
|
||||||
|
# if ip address in your home isn't precise, you can force a location
|
||||||
|
if $wifi =~ "my_wifi" { "your_lat,your_lon" } else { $"($loc_json.lat),($loc_json.lon)" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# dark sky
|
||||||
|
def fetch_api [loc] {
|
||||||
|
let apiKey = "ds_api_key"
|
||||||
|
let options = "?lang=en&units=si&exclude=minutely,hourly,flags"
|
||||||
|
|
||||||
|
let url = $"https://api.darksky.net/forecast/($apiKey)/($loc)($options)"
|
||||||
|
|
||||||
|
fetch $url
|
||||||
|
}
|
||||||
|
|
||||||
|
# street address
|
||||||
|
def get_address [loc] {
|
||||||
|
let mapsAPIkey = "maps_api_key"
|
||||||
|
let url = $"https://maps.googleapis.com/maps/api/geocode/json?latlng=($loc)&sensor=true&key=($mapsAPIkey)"
|
||||||
|
|
||||||
|
(fetch $url).results.0.formatted_address
|
||||||
|
}
|
||||||
|
|
||||||
|
# wind description (adjust to your liking)
|
||||||
|
def desc_wind [wind] {
|
||||||
|
if $wind < 30 { "Normal" } else if $wind < 50 { "Moderate" } else if $wind < 60 { "Strong" } else { "Very Strong" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# uv description (standard)
|
||||||
|
def uv_class [uvIndex] {
|
||||||
|
if $uvIndex < 2.9 { "Low" } else if $uvIndex < 5.9 { "Moderate" } else if $uvIndex < 7.9 { "High" } else if $uvIndex < 10.9 { "Very High" } else { "Extreme" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# air pollution
|
||||||
|
def get_airCond [loc] {
|
||||||
|
let apiKey = "airvisual_api_key"
|
||||||
|
let lat = (echo $loc | split row ",").0
|
||||||
|
let lon = (echo $loc | split row ",").1
|
||||||
|
let url = $"https://api.airvisual.com/v2/nearest_city?lat=($lat)&lon=($lon)&key=($apiKey)"
|
||||||
|
let aqius = (fetch $url).data.current.pollution.aqius
|
||||||
|
|
||||||
|
# clasification (standard)
|
||||||
|
if $aqius < 51 { "Good" } else if $aqius < 101 { "Moderate" } else if $aqius < 151 { "Unhealthy for some" } else if $aqius < 201 { "Unhealthy" } else if $aqius < 301 { "Very unhealthy" } else { "Hazardous" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse all the information
|
||||||
|
def get_weather [loc] {
|
||||||
|
|
||||||
|
let response = (fetch_api $loc)
|
||||||
|
let address = (get_address $loc)
|
||||||
|
let air_cond = (get_airCond $loc)
|
||||||
|
|
||||||
|
## Current conditions
|
||||||
|
let cond = $response.currently.summary
|
||||||
|
let temp = $response.currently.temperature
|
||||||
|
let wind = $response.currently.windSpeed * 3.6
|
||||||
|
let humi = $response.currently.humidity * 100
|
||||||
|
let uvIndex = $response.currently.uvIndex
|
||||||
|
let suntimes = ($response.daily.data | select sunriseTime sunsetTime | select 0 | update cells {|f| $f | into string | into datetime -o -4 | into string})
|
||||||
|
|
||||||
|
let sunrise = ($suntimes | get sunriseTime | get 0 | split row ' ' | get 3)
|
||||||
|
let sunset = ($suntimes | get sunsetTime | get 0 | split row ' ' | get 3)
|
||||||
|
let vientos = (desc_wind $wind)
|
||||||
|
let uvClass = (uv_class $uvIndex)
|
||||||
|
|
||||||
|
let Vientos = $"($vientos) \(($wind | into string -d 2) Km/h\)"
|
||||||
|
let humedad = $"($humi)%"
|
||||||
|
let temperature = $"($temp)°C"
|
||||||
|
|
||||||
|
let current = {
|
||||||
|
"Condition": ($cond)
|
||||||
|
Temperature: ($temperature)
|
||||||
|
Humidity: ($humedad)
|
||||||
|
Wind: ($Vientos)
|
||||||
|
"UV Index": ($uvClass)
|
||||||
|
"Air condition": ($air_cond)
|
||||||
|
Sunrise: ($sunrise)
|
||||||
|
Sunset: ($sunset)
|
||||||
|
}
|
||||||
|
|
||||||
|
## Forecast
|
||||||
|
let forecast = ($response.daily.data | select summary temperatureMin temperatureMax windSpeed humidity precipProbability precipIntensity uvIndex | update windSpeed {|f| $f.windSpeed * 3.6} | update precipIntensity {|f| $f.precipIntensity * 24} | update precipProbability {|f| $f.precipProbability * 100} | update humidity {|f| $f.humidity * 100} | update uvIndex {|f| uv_class $f.uvIndex} | update windSpeed {|f| $"(desc_wind $f.windSpeed) \(($f.windSpeed | into string -d 2)\)"} | rename Summary "T° min (°C)" "T° max (°C)" "Wind Speed (Km/h)" "Humidity (%)" "Precip. Prob. (%)" "Precip. Intensity (mm)")
|
||||||
|
|
||||||
|
## plots (require custom command gnu-plot)
|
||||||
|
($forecast | select "Humidity (%)") | gnu-plot
|
||||||
|
($forecast | select "Precip. Intensity (mm)") | gnu-plot
|
||||||
|
($forecast | select "Precip. Prob. (%)") | gnu-plot
|
||||||
|
($forecast | select "T° max (°C)") | gnu-plot
|
||||||
|
($forecast | select "T° min (°C)") | gnu-plot
|
||||||
|
|
||||||
|
## forecast
|
||||||
|
echo $"Forecast: ($response.daily.summary)"
|
||||||
|
echo $forecast
|
||||||
|
|
||||||
|
## current
|
||||||
|
echo $"Current conditions: ($address)"
|
||||||
|
echo $current
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Get weather for right command prompt (set in config.nu)
|
||||||
|
export def-env get_weather_by_interval [INTERVAL_WEATHER] {
|
||||||
|
let weather_runtime_file = (($env.HOME) | path join .weather_runtime_file.json)
|
||||||
|
|
||||||
|
if ($weather_runtime_file | path exists) {
|
||||||
|
let last_runtime_data = (open $weather_runtime_file)
|
||||||
|
|
||||||
|
let LAST_WEATHER_TIME = ($last_runtime_data | get last_weather_time)
|
||||||
|
|
||||||
|
if ($LAST_WEATHER_TIME | into datetime) + $INTERVAL_WEATHER < (date now) {
|
||||||
|
let WEATHER = (get_weather_for_prompt (get_location 0))
|
||||||
|
let NEW_WEATHER_TIME = (date now | date format '%Y-%m-%d %H:%M:%S %z')
|
||||||
|
|
||||||
|
$last_runtime_data | upsert weather $WEATHER | upsert last_weather_time $NEW_WEATHER_TIME | save $weather_runtime_file
|
||||||
|
|
||||||
|
$WEATHER
|
||||||
|
} else {
|
||||||
|
$last_runtime_data | get weather
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let WEATHER = (get_weather_for_prompt (get_location 0))
|
||||||
|
let LAST_WEATHER_TIME = (date now | date format '%Y-%m-%d %H:%M:%S %z')
|
||||||
|
|
||||||
|
let WEATHER_DATA = {
|
||||||
|
"weather": ($WEATHER)
|
||||||
|
"last_weather_time": ($LAST_WEATHER_TIME)
|
||||||
|
}
|
||||||
|
|
||||||
|
$WEATHER_DATA | save $weather_runtime_file
|
||||||
|
$WEATHER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_weather_for_prompt [loc] {
|
||||||
|
|
||||||
|
let response = (fetch_api $loc)
|
||||||
|
|
||||||
|
## current conditions
|
||||||
|
let cond = $response.currently.summary
|
||||||
|
let temp = $response.currently.temperature
|
||||||
|
let temperature = $"($temp)°C"
|
||||||
|
let icon = (get_weather_icon $response.currently.icon)
|
||||||
|
|
||||||
|
let current = {
|
||||||
|
Condition: ($cond)
|
||||||
|
Temperature: ($temperature)
|
||||||
|
Icon: ($icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $"($current.Icon) ($current.Temperature)"
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_weather_icon [icon: string] {
|
||||||
|
switch $icon {
|
||||||
|
"clear-day": {"☀️"},
|
||||||
|
"clear-night": {"🌑"},
|
||||||
|
"rain": {"🌧️"},
|
||||||
|
"snow": {"❄️"},
|
||||||
|
"sleet": {🌨️},
|
||||||
|
"wind": {"🌬️"},
|
||||||
|
"fog": {"🌫"},
|
||||||
|
"cloudy": {"☁️"},
|
||||||
|
"partly-cloudy-day": {"🌤️"},
|
||||||
|
"partly-cloudy-night": {"🌑☁️"},
|
||||||
|
"hail": {🌨},
|
||||||
|
"thunderstorm": {"🌩️"},
|
||||||
|
"tornado": {"🌪️"}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue