Big update, compatable with latest version of Conky
This commit is contained in:
parent
8bad18f047
commit
858154b5c4
8 changed files with 890 additions and 577 deletions
367
conf
367
conf
|
|
@ -1,229 +1,230 @@
|
||||||
###################################################################################################################################
|
-- ###################################################################################################################################
|
||||||
# This configuration file was created by Matt Grotke (mgrotke@gmail.com) for the "mgconky Conky Theme" project: https://github.com/mgrotke/mgconky
|
-- This configuration file was created by Matt Grotke (mgrotke@gmail.com) for the "mgconky Conky Theme" project: https://github.com/mgrotke/mgconky
|
||||||
# This file is in the public domain.
|
-- This file is in the public domain.
|
||||||
# ---------------------------------------------------------------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------------------------------------------------------------
|
||||||
# TO RUN THIS CONKY CONFIG, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
-- TO RUN THIS CONKY CONFIG, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
||||||
# conky -c ~/.conky/mgconky/conf
|
-- conky -c ~/.conky/mgconky/conf
|
||||||
#
|
--
|
||||||
# TO STOP CONKY, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
-- TO STOP CONKY, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
||||||
# killall conky
|
-- killall conky
|
||||||
#
|
--
|
||||||
# TO HAVE THIS CONKY RUN EVERY TIME AT BOOT, GO INTO "STARTUP SOFTWARE" APP AND ADD THE FOLLOWING COMMAND WITH A DELAY OF 10 SECONDS:
|
-- TO HAVE THIS CONKY RUN EVERY TIME AT BOOT, GO INTO "STARTUP SOFTWARE" APP AND ADD THE FOLLOWING COMMAND WITH A DELAY OF 10 SECONDS:
|
||||||
# conky -p 10 -c /home/<username>/.conky/mgconky/conf
|
-- conky -p 10 -c /home/<username>/.conky/mgconky/conf
|
||||||
# NOTE: It seems you must actually use the full path (/home/<username>) as the shortcut (~/) does not work.
|
-- NOTE: It seems you must actually use the full path (/home/<username>) as the shortcut (~/) does not work.
|
||||||
#
|
--
|
||||||
# !!!IMPORTANT!!! THE FOLLOWING ARE REQUIREMENTS FOR THIS SCRIPT TO WORK PROPERLY:
|
-- !!!IMPORTANT!!! THE FOLLOWING ARE REQUIREMENTS FOR THIS SCRIPT TO WORK PROPERLY:
|
||||||
# (1) Install software, if not already installed:
|
-- (1) DEPENDENCIES.
|
||||||
# "Conky" sudo apt-get install conky-all (or use software manager)
|
-- Install the following software, if not already installed:
|
||||||
# "Jq" sudo apt-get install jq (or use software manager)
|
-- "Conky" sudo apt-get install conky-all (or use software manager)
|
||||||
# "Curl" sudo apt-get install curl (or use software manager)
|
-- "Jq" sudo apt-get install jq (or use software manager)
|
||||||
# "Wget" sudo apt-get install wget (or use software manager)
|
-- "Curl" sudo apt-get install curl (or use software manager)
|
||||||
# "lm-sensors" sudo apt-get install lm-sensors (or use software manager)
|
-- "Wget" sudo apt-get install wget (or use software manager)
|
||||||
# (2) Install custom fonts:
|
-- "lm-sensors" sudo apt-get install lm-sensors (or use software manager)
|
||||||
# "Neuropolitical" Place .ttf file in ~/.fonts/ https://www.dafont.com/font-comment.php?file=neuropolitical
|
-- (2) FONTS.
|
||||||
# "StyleBats" Place .ttf file in ~/.fonts/ https://www.dafont.com/search.php?q=StyleBats
|
-- Install the following custom fonts:
|
||||||
# (3) Set the included bash script(s) as executable
|
-- "Neuropolitical" Place .ttf file in ~/.fonts/ https://www.dafont.com/font-comment.php?file=neuropolitical
|
||||||
# chmod +x ~/.conky/mgconky/weather/get_weather.sh
|
-- "StyleBats" Place .ttf file in ~/.fonts/ https://www.dafont.com/search.php?q=StyleBats
|
||||||
# chmod +x ~/.conky/mgconky/weather/parse_weather.sh
|
-- (3) SCRIPTS.
|
||||||
# chmod +x ~/.conky/mgconky/weather/parse_forecast.sh
|
-- Set the following included script(s) as executable:
|
||||||
# (4) Make a free account at https://openweathermap.org/
|
-- chmod +x ~/.conky/mgconky/weather/get_weather.sh
|
||||||
# (5) Write down your API key, which is found on the "API keys" tab after you log in. (https://home.openweathermap.org/api_keys)
|
-- chmod +x ~/.conky/mgconky/weather/parse_weather.sh
|
||||||
# (6) Find your city's location ID by entering your CITY NAME in the search box and select your city from the search results.
|
-- chmod +x ~/.conky/mgconky/weather/parse_forecast.sh
|
||||||
# Your location ID will be the number in the URL (for example: https://openweathermap.org/city/5128581)
|
-- chmod +x ~/.conky/mgconky/weather/parse_forecast.sh
|
||||||
# (7) In this conf file below, set the following variables:
|
-- chmod +x ~/.conky/mgconky/stocks/get_stocks.py (Requires python3, which is usually pre-installed on your OS)
|
||||||
# "template6" Set to your API key.
|
-- (4) WEATHER.
|
||||||
# "template7" Set to your location ID.
|
-- Make a free account at https://openweathermap.org/
|
||||||
# "template8" Set to either "imperial" (for Fahrenheit) or "metric" (for Celsius).
|
-- Write down your API key, which is found on the "API keys" tab after you log in. (https://home.openweathermap.org/api_key
|
||||||
# (8) Modify the drive names below with your device name(s), i.e. "/dev/sda", "/dev/sdb", "/dev/sdc", etc.
|
-- Find your city's location ID by entering your CITY NAME in the search box and select your city from the search results.
|
||||||
# (9) Modify the filesystems below with your mount name(s), i.e. "/" (root), "/mnt/MyData", "/media/<username>/MyUSBStick", etc.
|
-- Your location ID will be the number in the URL (for example: https://openweathermap.org/city/5128581)
|
||||||
# (10) Replace "enp34s0" below with name of your ethernet device. (Find name of ethernet device by typing "ip a" in terminal.)
|
-- In the config below, complete template0 through template3.
|
||||||
# (11) If you use Wi-Fi instead of ethernet, change the Network section. The following variables are available from Conky:
|
-- (5) STOCKS.
|
||||||
# ${wireless_ap <device>} Wireless access point MAC address
|
-- Unfortunately the days of using the Yahoo Finance API are over. It has been shut down. There are two APIs to choose from.
|
||||||
# ${wireless_bitrate <device>} Wireless bitrate (ie 11 Mb/s)
|
-- Alpha Vantage and Finnhub. You will need an API key to use either. Both offer FREE services, but with restrictions.
|
||||||
# ${wireless_essid <device>} Wireless access point ESSID
|
-- Alpha Vantage only allows 25 requests per day (!!!) for free. Finnhub allows 60 requests per minute for free!
|
||||||
# ${wireless_link_bar <h>,<w> <device>} Wireless link quality bar
|
-- Both services are available here. With Alpha Vantage, we must set the interval to 7200 seconds. That means your stock prices
|
||||||
# ${wireless_link_qual <device>} Wireless link quality
|
-- will only update every 2 hours. It makes 1 request per stock, so only include 1 or 2 stocks if you are using free Alpha
|
||||||
# ${wireless_link_qual_max <device>} Wireless link quality maximum value
|
-- Vantage. If you go With FinnHub, you cannot get historical prices at all, unless you have a paid plan, but you CAN add many
|
||||||
# ${wireless_link_qual_perc <device>} Wireless link quality in percents
|
-- stocks, and you can update your stocks much more frequently. Complete template4 through template7 in the config below.
|
||||||
# ${wireless_mode <device>} Wireless mode (Managed/Ad-Hoc/Master)
|
-- ###################################################################################################################################
|
||||||
###################################################################################################################################
|
|
||||||
|
|
||||||
#--------------------------
|
conky.config = {
|
||||||
# Window and drawing properties
|
|
||||||
#--------------------------
|
|
||||||
alignment top_right
|
|
||||||
minimum_size 225
|
|
||||||
maximum_width 225
|
|
||||||
gap_x 15
|
|
||||||
gap_y 15
|
|
||||||
background no
|
|
||||||
own_window yes
|
|
||||||
own_window_transparent yes
|
|
||||||
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
|
|
||||||
own_window_type normal
|
|
||||||
double_buffer yes
|
|
||||||
draw_shades no
|
|
||||||
draw_outline no
|
|
||||||
draw_borders no
|
|
||||||
draw_graph_borders yes
|
|
||||||
no_buffers yes
|
|
||||||
imlib_cache_size 0
|
|
||||||
cpu_avg_samples 2
|
|
||||||
update_interval 1.5
|
|
||||||
total_run_times 0
|
|
||||||
|
|
||||||
#--------------------------
|
-- Window and drawing properties
|
||||||
# Define fonts
|
alignment = "top_right",
|
||||||
#--------------------------
|
minimum_width = 225,
|
||||||
use_xft yes
|
maximum_width = 225,
|
||||||
xftalpha 0.9
|
gap_x = 15,
|
||||||
#xftfont DejaVu Sans:size=8
|
gap_y = 15,
|
||||||
xftfont Courier:size=9
|
background = false,
|
||||||
override_utf8_locale yes # Force UTF8? Requires XFT (see above)... will displays degree symbol, instead of °, etc.
|
own_window = true,
|
||||||
short_units yes
|
own_window_transparent = true,
|
||||||
uppercase no
|
own_window_hints = "undecorated,below,sticky,skip_taskbar,skip_pager",
|
||||||
|
own_window_type = "normal",
|
||||||
|
double_buffer = true,
|
||||||
|
draw_shades = false,
|
||||||
|
draw_outline = false,
|
||||||
|
draw_borders = false,
|
||||||
|
draw_graph_borders = true,
|
||||||
|
no_buffers = true,
|
||||||
|
imlib_cache_size = 0,
|
||||||
|
cpu_avg_samples = 2,
|
||||||
|
update_interval = 1.5,
|
||||||
|
total_run_times = 0,
|
||||||
|
|
||||||
#--------------------------
|
-- Define fonts
|
||||||
# Define Colors
|
use_xft = true,
|
||||||
#--------------------------
|
xftalpha = 0.9,
|
||||||
default_color white
|
override_utf8_locale = true, -- Force UTF8? Requires XFT (see above)... will display degree symbol, instead of °, etc.
|
||||||
default_shade_color black
|
short_units = true,
|
||||||
default_outline_color green
|
uppercase = false,
|
||||||
color0 orange # Titles
|
|
||||||
color1 slategrey # Horizonal lines
|
|
||||||
color2 white # Not used
|
|
||||||
color3 lime # Values
|
|
||||||
color4 yellow # Important
|
|
||||||
color5 lime # Bar graphs
|
|
||||||
|
|
||||||
#--------------------------
|
-- Define Colors
|
||||||
# Weather variables
|
default_color = "#FFFFFF", -- white
|
||||||
#--------------------------
|
default_shade_color = "#000000", -- black
|
||||||
template6 "<ENTER YOUR API KEY HERE>" # OpenWeatherMap API key (https://home.openweathermap.org/api_keys)
|
default_outline_color = "#00FF00", -- green
|
||||||
template7 "<ENTER YOUR CITY ID HERE>" # OpenWeatherMap City ID (the number in the URL of your city, for example: https://openweathermap.org/city/5128581)
|
color0 = "#FFA500", -- Titles (orange)
|
||||||
template8 "imperial" # Temp unit ("default" for Kelvin, "metric" for Celcius, "imperial" for Fahrenheit)
|
color1 = "#708090", -- Horizontal lines (slategrey)
|
||||||
template9 "" # Locale (e.g. "es_ES.UTF-8") # Leave empty for default
|
color2 = "#FFFFFF", -- Not used (white)
|
||||||
|
color3 = "#00FF00", -- Values (lime)
|
||||||
|
color4 = "#FFFF00", -- Important (yellow)
|
||||||
|
color5 = "#00FF00", -- Bar graphs (lime)
|
||||||
|
color6 = "#1E90FF", -- Good values (blue)
|
||||||
|
color7 = "#FF0000", -- Bad values (red)
|
||||||
|
|
||||||
#--------------------------
|
-- Weather variables
|
||||||
# Load Lua script(s) -- If multiple files, separate each path with a space. They should all be loaded on a single lua_load command.
|
template0 = "YOUR_OPENWEATHERMAP_API_KEY_HERE", -- OpenWeatherMap API key (https://home.openweathermap.org/api_keys)
|
||||||
#--------------------------
|
template1 = "YOUR_OPENWEATHERMAP_CITY_ID_HERE", -- OpenWeatherMap City ID (the number in the URL of your city, for example: https://openweathermap.org/city/5128581)
|
||||||
lua_load ~/.conky/mgconky/rounding.lua
|
template2 = "imperial", -- Temp unit ("default" for Kelvin, "metric" for Celsius, "imperial" for Fahrenheit)
|
||||||
|
template3 = "", -- Locale (e.g., "es_ES.UTF-8") # Leave empty for default
|
||||||
|
|
||||||
TEXT
|
-- Stock variables
|
||||||
|
template4 = "YOUR_FINNHUB_API_KEY_HERE", -- FinnHub API key (https://finnhub.io/)
|
||||||
|
template5 = "YOUR_ALPHAVANTAGE_API_KEY_HERE", -- Alpha Vantage API key (https://www.alphavantage.co/)
|
||||||
|
template6 = "goog,amzn,aapl,msft,meta,tsla,avgo,tsm,brk.a,pg,nvda", -- Stock symbols for FinnHub (comma separated, no spaces, i.e. goog,amzn,aapl)
|
||||||
|
template7 = "nvda", -- Stock symbols for Alpha Vantage (keep to a minimum unless you have a paid API key)
|
||||||
|
|
||||||
|
-- Load Lua script(s) -- If multiple files, separate each path with a space. They should all be loaded on a single lua_load command.
|
||||||
|
-- lua_load = "~/.conky/mgconky/script1.lua ~/.conky/mgconky/script2.lua",
|
||||||
|
lua_load = "~/.conky/mgconky/devices/get_device_info.lua",
|
||||||
|
}
|
||||||
|
|
||||||
|
conky.text = [[
|
||||||
#--------------------------
|
#--------------------------
|
||||||
# Linux Mint Logo and Text
|
# Computer Info
|
||||||
#--------------------------
|
#--------------------------
|
||||||
|
# ***** Linux Mint Logo and Version *****
|
||||||
${image ~/.conky/mgconky/mint_logo.png -s 35x35 -p 0,0}\
|
${image ~/.conky/mgconky/mint_logo.png -s 35x35 -p 0,0}\
|
||||||
${voffset 0}${goto 50}${font Neuropolitical:pixelsize=12}${color0}${execi 100000 lsb_release -sd || cat /etc/*release}${color}${font}
|
${voffset 0}${goto 50}${font Neuropolitical:pixelsize=12}${color0}${execi 100000 lsb_release -sd || cat /etc/*release}${color}${font Courier:size=9}
|
||||||
${voffset 0}${goto 50}${font Neuropolitical:size=10}${nodename}${font}
|
# ***** Computer Name *****
|
||||||
|
${voffset 0}${goto 50}${font Neuropolitical:size=10}${nodename}${font Courier:size=9}
|
||||||
|
# ***** Kernel Version *****
|
||||||
${voffset 8}Kernel: ${color3}${alignr}${sysname} ${kernel}${color}
|
${voffset 8}Kernel: ${color3}${alignr}${sysname} ${kernel}${color}
|
||||||
|
# ***** Up Time *****
|
||||||
${voffset 2}Uptime: ${color3}${alignr}${uptime_short}${color}
|
${voffset 2}Uptime: ${color3}${alignr}${uptime_short}${color}
|
||||||
${voffset 2}CPU:${goto 50}${color4}${execi 10 sensors | grep "Tdie" | cut -c16-17}°C${color}${goto 100}${alignr}GPU: ${color4}${nvidia temp}°C${color}
|
# ***** Temperatures *****
|
||||||
|
${voffset 2}CPU:${goto 50}${color4}${hwmon 0 temp 1}°C${color}${goto 100}${alignr}GPU: ${color4}${nvidia temp}°C${color}
|
||||||
|
#${voffset 2}CPU:${goto 50}${color4}${execi 10 sensors | grep "Tdie" | cut -c16-17}°C${color}${goto 100}${alignr}GPU: ${color4}${nvidia temp}°C${color}
|
||||||
|
# ***** CPU Make/Model *****
|
||||||
|
${voffset 6}${alignc}${color3}${lua_parse conky_get_cpu_info}
|
||||||
|
${voffset 0}${alignc}${color3}${lua_parse conky_get_gpu_info}
|
||||||
|
|
||||||
#--------------------------
|
#--------------------------
|
||||||
# Weather
|
# Weather
|
||||||
#--------------------------
|
#--------------------------
|
||||||
# ***** Download weather data and position icons *****
|
# ***** Download weather data and position icons *****
|
||||||
${execi 300 ~/.conky/mgconky/weather/get_weather.sh ${template6} ${template7} ${template8} ${template9}}\
|
${execi 300 ~/.conky/mgconky/weather/get_weather.sh ${template0} ${template1} ${template2} ${template3}}\
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime64/$(~/.conky/mgconky/weather/parse_weather.sh 'iconid').png ~/.cache/mgconky/weather0.png}${image ~/.cache/mgconky/weather0.png -p 40,135 -s 64x64}\
|
${execi 300 cp -f ~/.conky/mgconky/weather/lime64/$(~/.conky/mgconky/weather/parse_weather.sh 'iconid').png ~/.cache/mgconky/weather0.png}${image ~/.cache/mgconky/weather0.png -p 40,178 -s 64x64}\
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '1').png ~/.cache/mgconky/weather1.png}${image ~/.cache/mgconky/weather1.png -p 20,219 -s 32x32}\
|
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '1').png ~/.cache/mgconky/weather1.png}${image ~/.cache/mgconky/weather1.png -p 20,262 -s 32x32}\
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '2').png ~/.cache/mgconky/weather2.png}${image ~/.cache/mgconky/weather2.png -p 96,219 -s 32x32}\
|
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '2').png ~/.cache/mgconky/weather2.png}${image ~/.cache/mgconky/weather2.png -p 96,262 -s 32x32}\
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '3').png ~/.cache/mgconky/weather3.png}${image ~/.cache/mgconky/weather3.png -p 175,219 -s 32x32}
|
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '3').png ~/.cache/mgconky/weather3.png}${image ~/.cache/mgconky/weather3.png -p 175,262 -s 32x32}
|
||||||
# ***** Today's date *****
|
# ***** Today's date *****
|
||||||
${voffset -15}${color0}${alignc}${font Neuropolitical:size=10}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'location'}${font}${color}
|
${voffset -15}${color0}${alignc}${font Neuropolitical:size=15}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'location'}${font Courier:size=9}${color}
|
||||||
${voffset -4}${color0}${alignc}${font Neuropolitical:size=10}${execi 300 LANG=${template9} LC_TIME=${template9} date +'%^a, %e %^B'}${font}${color}
|
${voffset 0}${color0}${alignc}${font Neuropolitical:size=10}${execi 300 LANG=${template3} LC_TIME=${template3} date +'%^a, %e %^B'}${font Courier:size=9}${color}
|
||||||
# ***** Temperature right now *****
|
# ***** Temperature right now *****
|
||||||
${voffset 7}${alignc -40}${color3}${font Courier:size=20:bold}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'temperature'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${font}${color}
|
${voffset 7}${alignc -40}${color3}${font Courier:size=20:bold}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'temperature'}${if_match "${template2}" == "metric"}°C${else}${if_match "${template2}" == "imperial"}°F${else}${if_match "${template2}" == "default"}K${endif}${endif}${endif}${font Courier:size=9}${color}
|
||||||
# ***** Today's high/low temps *****
|
# ***** Today's high/low temps *****
|
||||||
${voffset 5}${alignc -40}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '0'}${color}\
|
${voffset 5}${alignc -40}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '0'}${color}\
|
||||||
/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '0'}\
|
/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '0'}\
|
||||||
${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
${if_match "${template2}" == "metric"}°C${else}${if_match "${template2}" == "imperial"}°F${else}${if_match "${template2}" == "default"}K${endif}${endif}${endif}${color}
|
||||||
# ***** Description of weather right now *****
|
# ***** Description of weather right now *****
|
||||||
#${voffset 0}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'description'}${color}
|
#${voffset 0}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'description'}${color}
|
||||||
# ***** Forecast day labels (MON, TUES, WED, etc) *****
|
# ***** Forecast day labels (MON, TUES, WED, etc) *****
|
||||||
${voffset 15}${color0}${font Neuropolitical:size=10}${alignc 77}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +1day +%^a}${font}${color}
|
${voffset 15}${color0}${font Neuropolitical:size=10}${alignc 77}${execi 300 LANG=${template3} LC_TIME=${template3} date -d +1day +%^a}${font Courier:size=9}${color}
|
||||||
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +2day +%^a}${font}${color}
|
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc}${execi 300 LANG=${template3} LC_TIME=${template3} date -d +2day +%^a}${font Courier:size=9}${color}
|
||||||
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc -77}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +3day +%^a}${font}${color}
|
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc -77}${execi 300 LANG=${template3} LC_TIME=${template3} date -d +3day +%^a}${font Courier:size=9}${color}
|
||||||
# ***** Forecast high/low temps *****
|
# ***** Forecast high/low temps *****
|
||||||
${voffset 32}${alignc 77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '1'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '1'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
${voffset 32}${alignc 77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '1'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '1'}${if_match "${template2}" == "metric"}°C${else}${if_match "${template2}" == "imperial"}°F${else}${if_match "${template2}" == "default"}K${endif}${endif}${endif}${color}
|
||||||
${voffset -13}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '2'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '2'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
${voffset -13}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '2'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '2'}${if_match "${template2}" == "metric"}°C${else}${if_match "${template2}" == "imperial"}°F${else}${if_match "${template2}" == "default"}K${endif}${endif}${endif}${color}
|
||||||
${voffset -13}${alignc -77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '3'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '3'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
${voffset -13}${alignc -77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '3'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '3'}${if_match "${template2}" == "metric"}°C${else}${if_match "${template2}" == "imperial"}°F${else}${if_match "${template2}" == "default"}K${endif}${endif}${endif}${color}
|
||||||
|
|
||||||
|
#--------------------------
|
||||||
|
# Stocks
|
||||||
|
#--------------------------
|
||||||
|
${voffset 6}${color0}${font Neuropolitical:size=8:bold}STOCKS ${color1}${hr 2}${color}${font Courier:size=9}
|
||||||
|
# ***** FinnHub API *****
|
||||||
|
${if_match "${template4}" != "YOUR_FINNHUB_API_KEY_HERE"}
|
||||||
|
${voffset -6}${execpi 60 $HOME/.conky/mgconky/stocks/get_stocks_finnhub.py --api_key ${template4} --symbols ${template6} --range_in_days 0 --price_dec_places 0 --percent_dec_places 1}
|
||||||
|
${endif}
|
||||||
|
# ***** Alpha Vantage API *****
|
||||||
|
${if_match "${template5}" != "YOUR_ALPHAVANTAGE_API_KEY_HERE"}
|
||||||
|
${voffset -12}${execpi 7200 $HOME/.conky/mgconky/stocks/get_stocks_alphavantage.py --api_key ${template5} --symbols ${template7} --range_in_days 30 --price_dec_places 0 --percent_dec_places 1}
|
||||||
|
${endif}
|
||||||
#
|
#
|
||||||
#--------------------------
|
#--------------------------
|
||||||
# Memory
|
# Memory
|
||||||
#--------------------------
|
#--------------------------
|
||||||
#${voffset -10}${color0}${font Neuropolitical:size=8:bold}MEMORY ${color1}${hr 2}${color}${font}
|
${voffset 0}${color0}${font Neuropolitical:size=8:bold}MEMORY ${color1}${hr 2}${color}${font Courier:size=9}
|
||||||
#${voffset 4}RAM:${alignr}${color3}${lua MyRound ${mem} 1 halfup G hideUnit}${color} of ${color3}${lua MyRound ${memmax} 0 ceil G addSpace}B${color}
|
# ***** System memory *****
|
||||||
#${voffset -2}${color5}${membar}${color}
|
${voffset 4}System:${alignr}${lua_parse conky_get_memory_usage sys}${color}
|
||||||
#${voffset 2}Swap:${alignr}${color3}${lua MyRound ${swap} 1 halfup G hideUnit}${color} of ${color3}${lua MyRound ${swapmax} 0 ceil G addSpace}B${color}
|
${voffset -2}${color5}${membar}${color}
|
||||||
#${voffset -2}${color5}${swapbar}${color}
|
# ***** Swap memory *****
|
||||||
|
${if_match "${lua conky_check_swap_status}" == "swapenabled"}\
|
||||||
|
${voffset 4}Swap:${alignr}${lua_parse conky_get_memory_usage swap}${color}
|
||||||
|
${voffset -2}${color5}${swapbar}${color}\
|
||||||
|
${endif}
|
||||||
#--------------------------
|
#--------------------------
|
||||||
# Drive #1
|
# Drives and Volumes
|
||||||
#--------------------------
|
#--------------------------
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/nvme0n1${color} ${color1}${hr 2}${color}
|
${voffset 6}${lua_parse conky_get_drives_and_volumes}
|
||||||
# ***** Read and write speeds for this device *****
|
#
|
||||||
#${voffset 4}Read: ${color3}${diskio_read nvme0n1}/s${color}${goto 120}Write: ${color3}${diskio_write nvme0n1}/s${color}
|
|
||||||
#${voffset -4}${color5}${diskiograph_read nvme0n1 14,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write nvme0n1 14,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 2}/:${alignr}${color3}${lua MyRound ${fs_used /} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar /}${color}
|
|
||||||
${voffset 2}/home:${alignr}${color3}${lua MyRound ${fs_used /home} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /home} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar /home}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Drive #2
|
|
||||||
#--------------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/sda${color} ${color1}${hr 2}${color}
|
|
||||||
# ***** Read and write speeds for this device *****
|
|
||||||
#${voffset 4}Read: ${color3}${diskio_read sda}/s${color}${goto 120}Write: ${color3}${diskio_write sda}/s${color}
|
|
||||||
#${voffset -4}${color5}${diskiograph_read sda 14,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write sda 14,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 2}/mnt/SSD120:${alignr}${color3}${lua MyRound ${fs_used /mnt/SSD120} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /mnt/SSD120} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar 6 /mnt/SSD120}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Drive #3
|
|
||||||
#--------------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/sdb${color} ${color1}${hr 2}${color}
|
|
||||||
# ***** Read and write speeds for this device *****
|
|
||||||
#${voffset 4}Read: ${color3}${diskio_read sdb}/s${color}${goto 120}Write: ${color3}${diskio_write sdb}/s${color}
|
|
||||||
#${voffset -4}${color5}${diskiograph_read sdb 14,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write sdb 14,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 2}/mnt/SSD180:${alignr}${color3}${lua MyRound ${fs_used /mnt/SSD180} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /mnt/SSD180} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar 6 /mnt/SSD180}${color}
|
|
||||||
|
|
||||||
#----------------------
|
#----------------------
|
||||||
# Top Processes
|
# Top Processes
|
||||||
#----------------------
|
#----------------------
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}TOP PROCESSES ${color1}${hr 2}${color}${font}
|
${voffset -6}${color0}${font Neuropolitical:size=8:bold}TOP PROCESSES ${color1}${hr 2}${color}${font Courier:size=9}
|
||||||
|
# ***** By memory usage *****
|
||||||
${voffset 6}By Memory Usage${goto 142}PID${alignr}RAM
|
${voffset 6}By Memory Usage${goto 142}PID${alignr}RAM
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 1}${goto 140}${top_mem pid 1}${alignr}${top_mem mem_res 1}${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top_mem name 1}${goto 140}${top_mem pid 1}${alignr}${top_mem mem_res 1}${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 2}${goto 140}${top_mem pid 2}${alignr}${top_mem mem_res 2}${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top_mem name 2}${goto 140}${top_mem pid 2}${alignr}${top_mem mem_res 2}${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 3}${goto 140}${top_mem pid 3}${alignr}${top_mem mem_res 3}${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top_mem name 3}${goto 140}${top_mem pid 3}${alignr}${top_mem mem_res 3}${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 4}${goto 140}${top_mem pid 4}${alignr}${top_mem mem_res 4}${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top_mem name 4}${goto 140}${top_mem pid 4}${alignr}${top_mem mem_res 4}${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 5}${goto 140}${top_mem pid 5}${alignr}${top_mem mem_res 5}${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top_mem name 5}${goto 140}${top_mem pid 5}${alignr}${top_mem mem_res 5}${color}
|
||||||
|
# ***** By CPU usage *****
|
||||||
${voffset 6}By CPU Usage${goto 142}PID${alignr}CPU
|
${voffset 6}By CPU Usage${goto 142}PID${alignr}CPU
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 1}${goto 140}${top pid 1}${alignr}${top cpu 1}%${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top name 1}${goto 140}${top pid 1}${alignr}${top cpu 1}%${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 2}${goto 140}${top pid 2}${alignr}${top cpu 2}%${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top name 2}${goto 140}${top pid 2}${alignr}${top cpu 2}%${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 3}${goto 140}${top pid 3}${alignr}${top cpu 3}%${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top name 3}${goto 140}${top pid 3}${alignr}${top cpu 3}%${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 4}${goto 140}${top pid 4}${alignr}${top cpu 4}%${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top name 4}${goto 140}${top pid 4}${alignr}${top cpu 4}%${color}
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 5}${goto 140}${top pid 5}${alignr}${top cpu 5}%${color}
|
${voffset 0}${font StyleBats:size=10}h${font Courier:size=9}${voffset -1}${color3}${offset 5}${top name 5}${goto 140}${top pid 5}${alignr}${top cpu 5}%${color}
|
||||||
|
|
||||||
#--------------------
|
#--------------------
|
||||||
# Network -- Replace "enp34s0" below with name of your ethernet device. (Find name of ethernet device by typing "ip a" in terminal.)
|
# Network -- Find name of ethernet device (e.g. "enp34s0") by typing "ip a" in terminal.
|
||||||
#--------------------
|
#--------------------
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}NETWORK ${color1}${hr 2}${color}${font}
|
${voffset 6}${color0}${font Neuropolitical:size=8:bold}NETWORK ${color1}${hr 2}${color}${font Courier:size=9}
|
||||||
${voffset 6}Ethernet Device:${goto 140}${color3}${gw_iface}${color}
|
# ***** IP addresses *****
|
||||||
${voffset 0}Internal IP:${goto 140}${color3}${addr enp34s0}${color}
|
${voffset 6}Interface Device:${goto 140}${color3}${gw_iface}${color}
|
||||||
|
${voffset 0}Internal IP:${goto 140}${color3}${addr ${gw_iface}}${color}
|
||||||
${voffset 0}External IP:${goto 140}${color3}${execi 1800 wget -q -O - checkip.dyndns.org | sed -e 's/[^[:digit:]\|.]//g'}${color}
|
${voffset 0}External IP:${goto 140}${color3}${execi 1800 wget -q -O - checkip.dyndns.org | sed -e 's/[^[:digit:]\|.]//g'}${color}
|
||||||
${voffset 6}DL: ${color3}${downspeed enp34s0}/s${color}${goto 140}UL:${color} ${color3}${upspeed enp34s0}/s${color}
|
# ***** VPN status *****
|
||||||
${voffset -2}${color5}${downspeedgraph enp34s0 25,90 000000 ff0000}${color}${alignr}${color5}${upspeedgraph enp34s0 25,90 000000 00ffff}${color}
|
${voffset 6}${alignc}${color4}VPN Status: ${lua_parse conky_get_vpn_status}
|
||||||
${voffset -6}Total: ${color3}${totaldown enp34s0}${color}${goto 140}Total:${color} ${color3}${totalup enp34s0}${color}
|
${voffset 6}DL: ${color3}${downspeed ${gw_iface}}/s${color}${goto 140}UL: ${color3}${upspeed ${gw_iface}}/s${color}
|
||||||
|
${voffset -2}${color5}${downspeedgraph ${gw_iface} 25,90 000000 ff0000}${color}${alignr}${color5}${upspeedgraph ${gw_iface} 25,90 000000 00ffff}${color}
|
||||||
|
${voffset -6}Total: ${color3}${totaldown ${gw_iface}}${color}${goto 140}Total: ${color3}${totalup ${gw_iface}}${color}
|
||||||
|
|
||||||
#--------------------
|
#--------------------
|
||||||
# Connections - netstat shows number of connections from your computer and application/PID making it. Kill spyware!
|
# Connections - netstat shows number of connections from your computer and application/PID making it. Kill spyware!
|
||||||
#--------------------
|
#--------------------
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}CONNECTIONS ${color1}${hr 2}${color}${font}
|
${voffset 6}${color0}${font Neuropolitical:size=8:bold}CONNECTIONS ${color1}${hr 2}${color}${font Courier:size=9}
|
||||||
${voffset 6}Num. connections / PID / Process
|
${voffset 6}Num. connections / PID / Process
|
||||||
${voffset 2}${color3}${execi 30 netstat -ept | grep ESTAB | awk '{print $9}' | cut -d: -f1 | sort | uniq -c | sort -nr}${color}
|
${voffset 2}${color3}${execi 30 netstat -ept | grep ESTAB | awk '{print $9}' | cut -d: -f1 | sort | uniq -c | sort -nr}${color}
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
|
||||||
248
conf_full
248
conf_full
|
|
@ -1,248 +0,0 @@
|
||||||
###################################################################################################################################
|
|
||||||
# This configuration file was created by Matt Grotke (mgrotke@gmail.com) for the "mgconky Conky Theme" project: https://github.com/mgrotke/mgconky
|
|
||||||
# This file is in the public domain.
|
|
||||||
# ---------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
# TO RUN THIS CONKY CONFIG, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
|
||||||
# conky -c ~/.conky/mgconky/conf
|
|
||||||
#
|
|
||||||
# TO STOP CONKY, YOU CAN TYPE THE FOLLOWING IN A TERMINAL:
|
|
||||||
# killall conky
|
|
||||||
#
|
|
||||||
# TO HAVE THIS CONKY RUN EVERY TIME AT BOOT, GO INTO "STARTUP SOFTWARE" APP AND ADD THE FOLLOWING COMMAND WITH A DELAY OF 10 SECONDS:
|
|
||||||
# conky -p 10 -c /home/<username>/.conky/mgconky/conf
|
|
||||||
# NOTE: It seems you must actually use the full path (/home/<username>) as the shortcut (~/) does not work.
|
|
||||||
#
|
|
||||||
# !!!IMPORTANT!!! THE FOLLOWING ARE REQUIREMENTS FOR THIS SCRIPT TO WORK PROPERLY:
|
|
||||||
# (1) Install software, if not already installed:
|
|
||||||
# "Conky" sudo apt-get install conky-all (or use software manager)
|
|
||||||
# "Jq" sudo apt-get install jq (or use software manager)
|
|
||||||
# "Curl" sudo apt-get install curl (or use software manager)
|
|
||||||
# "Wget" sudo apt-get install wget (or use software manager)
|
|
||||||
# "lm-sensors" sudo apt-get install lm-sensors (or use software manager)
|
|
||||||
# (2) Install custom fonts:
|
|
||||||
# "Neuropolitical" Place .ttf file in ~/.fonts/ https://www.dafont.com/font-comment.php?file=neuropolitical
|
|
||||||
# "StyleBats" Place .ttf file in ~/.fonts/ https://www.dafont.com/search.php?q=StyleBats
|
|
||||||
# (3) Set the included bash script(s) as executable
|
|
||||||
# chmod +x ~/.conky/mgconky/weather/get_weather.sh
|
|
||||||
# chmod +x ~/.conky/mgconky/weather/parse_weather.sh
|
|
||||||
# chmod +x ~/.conky/mgconky/weather/parse_forecast.sh
|
|
||||||
# (4) Make a free account at https://openweathermap.org/
|
|
||||||
# (5) Write down your API key, which is found on the "API keys" tab after you log in. (https://home.openweathermap.org/api_keys)
|
|
||||||
# (6) Find your city's location ID by entering your CITY NAME in the search box and select your city from the search results.
|
|
||||||
# Your location ID will be the number in the URL (for example: https://openweathermap.org/city/5128581)
|
|
||||||
# (7) In this conf file below, set the following variables:
|
|
||||||
# "template6" Set to your API key.
|
|
||||||
# "template7" Set to your location ID.
|
|
||||||
# "template8" Set to either "imperial" (for Fahrenheit) or "metric" (for Celsius).
|
|
||||||
# (8) Modify the drive names below with your device name(s), i.e. "/dev/sda", "/dev/sdb", "/dev/sdc", etc.
|
|
||||||
# (9) Modify the filesystems below with your mount name(s), i.e. "/" (root), "/mnt/MyData", "/media/<username>/MyUSBStick", etc.
|
|
||||||
# (10) Replace "enp34s0" below with name of your ethernet device. (Find name of ethernet device by typing "ip a" in terminal.)
|
|
||||||
# (11) If you use Wi-Fi instead of ethernet, change the Network section. The following variables are available from Conky:
|
|
||||||
# ${wireless_ap <device>} Wireless access point MAC address
|
|
||||||
# ${wireless_bitrate <device>} Wireless bitrate (ie 11 Mb/s)
|
|
||||||
# ${wireless_essid <device>} Wireless access point ESSID
|
|
||||||
# ${wireless_link_bar <h>,<w> <device>} Wireless link quality bar
|
|
||||||
# ${wireless_link_qual <device>} Wireless link quality
|
|
||||||
# ${wireless_link_qual_max <device>} Wireless link quality maximum value
|
|
||||||
# ${wireless_link_qual_perc <device>} Wireless link quality in percents
|
|
||||||
# ${wireless_mode <device>} Wireless mode (Managed/Ad-Hoc/Master)
|
|
||||||
###################################################################################################################################
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Window and drawing properties
|
|
||||||
#--------------------------
|
|
||||||
alignment top_right
|
|
||||||
minimum_size 225
|
|
||||||
maximum_width 225
|
|
||||||
gap_x 15
|
|
||||||
gap_y 15
|
|
||||||
background no
|
|
||||||
own_window yes
|
|
||||||
own_window_transparent yes
|
|
||||||
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
|
|
||||||
own_window_type normal
|
|
||||||
double_buffer yes
|
|
||||||
draw_shades no
|
|
||||||
draw_outline no
|
|
||||||
draw_borders no
|
|
||||||
draw_graph_borders yes
|
|
||||||
no_buffers yes
|
|
||||||
imlib_cache_size 0
|
|
||||||
cpu_avg_samples 2
|
|
||||||
update_interval 1.5
|
|
||||||
total_run_times 0
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Define fonts
|
|
||||||
#--------------------------
|
|
||||||
use_xft yes
|
|
||||||
xftalpha 0.9
|
|
||||||
#xftfont DejaVu Sans:size=8
|
|
||||||
xftfont Courier:size=9
|
|
||||||
override_utf8_locale yes # Force UTF8? Requires XFT (see above)... will displays degree symbol, instead of °, etc.
|
|
||||||
short_units yes
|
|
||||||
uppercase no
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Define Colors
|
|
||||||
#--------------------------
|
|
||||||
default_color white
|
|
||||||
default_shade_color black
|
|
||||||
default_outline_color green
|
|
||||||
color0 orange # Titles
|
|
||||||
color1 slategrey # Horizonal lines
|
|
||||||
color2 white # Not used
|
|
||||||
color3 lime # Values
|
|
||||||
color4 yellow # Important
|
|
||||||
color5 lime # Bar graphs
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Weather variables
|
|
||||||
#--------------------------
|
|
||||||
template6 "<ENTER YOUR API KEY HERE>" # OpenWeatherMap API key (https://home.openweathermap.org/api_keys)
|
|
||||||
template7 "<ENTER YOUR CITY ID HERE>" # OpenWeatherMap City ID (the number in the URL of your city, for example: https://openweathermap.org/city/5128581)
|
|
||||||
template8 "imperial" # Temp unit ("default" for Kelvin, "metric" for Celcius, "imperial" for Fahrenheit)
|
|
||||||
template9 "" # Locale (e.g. "es_ES.UTF-8") # Leave empty for default
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Load Lua script(s) -- If multiple files, separate each path with a space. They should all be loaded on a single lua_load command.
|
|
||||||
#--------------------------
|
|
||||||
lua_load ~/.conky/mgconky/rounding.lua
|
|
||||||
|
|
||||||
TEXT
|
|
||||||
#--------------------------
|
|
||||||
# Linux Mint Logo and Text
|
|
||||||
#--------------------------
|
|
||||||
${image ~/.conky/mgconky/mint_logo.png -s 35x35}${goto 50}${font Neuropolitical:pixelsize=12}${color0}${execi 100000 lsb_release -sd || cat /etc/*release}${color}${font}
|
|
||||||
${goto 50}${font Neuropolitical:size=10}${nodename}${font}
|
|
||||||
${voffset 8}Kernel: ${color3}${alignr}${sysname} ${kernel}${color}
|
|
||||||
${voffset 2}Uptime: ${color3}${alignr}${uptime_short}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Weather
|
|
||||||
#--------------------------
|
|
||||||
# ***** Download weather data and position icons *****
|
|
||||||
${execi 300 ~/.conky/mgconky/weather/get_weather.sh ${template6} ${template7} ${template8} ${template9}}\
|
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime64/$(~/.conky/mgconky/weather/parse_weather.sh 'iconid').png ~/.cache/mgconky/weather0.png}${image ~/.cache/mgconky/weather0.png -p 40,140 -s 64x64}\
|
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '1').png ~/.cache/mgconky/weather1.png}${image ~/.cache/mgconky/weather1.png -p 20,216 -s 32x32}\
|
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '2').png ~/.cache/mgconky/weather2.png}${image ~/.cache/mgconky/weather2.png -p 96,216 -s 32x32}\
|
|
||||||
${execi 300 cp -f ~/.conky/mgconky/weather/lime32/$(~/.conky/mgconky/weather/parse_forecast.sh 'first' '.weather[0].id' '3').png ~/.cache/mgconky/weather3.png}${image ~/.cache/mgconky/weather3.png -p 175,216 -s 32x32}
|
|
||||||
# ***** Today's date *****
|
|
||||||
${voffset -15}${color0}${alignc}${font Neuropolitical:size=10}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'location'}${font}${color}
|
|
||||||
${voffset -4}${color0}${alignc}${font Neuropolitical:size=10}${execi 300 LANG=${template9} LC_TIME=${template9} date +'%^a, %e %^B'}${font}${color}
|
|
||||||
${voffset 4}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'description'}${color}
|
|
||||||
# ***** Temperature right now *****
|
|
||||||
${voffset 8}${alignc -40}${color3}${font Courier:size=20:bold}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'temperature'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${font}${color}
|
|
||||||
# ***** Today's high/low temps *****
|
|
||||||
${voffset 3}${alignc -40}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '0'}${color}\
|
|
||||||
/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '0'}\
|
|
||||||
${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
|
||||||
# ***** Description of weather right now *****
|
|
||||||
#${voffset 0}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_weather.sh 'description'}${color}
|
|
||||||
# ***** Forecast day labels (MON, TUES, WED, etc) *****
|
|
||||||
${voffset 17}${color0}${font Neuropolitical:size=10}${alignc 77}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +1day +%^a}${font}${color}
|
|
||||||
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +2day +%^a}${font}${color}
|
|
||||||
${voffset -18}${color0}${font Neuropolitical:size=10}${alignc -77}${execi 300 LANG=${template9} LC_TIME=${template9} date -d +3day +%^a}${font}${color}
|
|
||||||
# ***** Forecast high/low temps *****
|
|
||||||
${voffset 32}${alignc 77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '1'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '1'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
|
||||||
${voffset -13}${alignc}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '2'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '2'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
|
||||||
${voffset -13}${alignc -77}${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'min' '.main.temp_min' '3'}${color}/${color3}${execi 300 ~/.conky/mgconky/weather/parse_forecast.sh 'max' '.main.temp_max' '3'}${if_match $template8 == "metric"}°C${else}${if_match $template8 == "imperial"}°F${else}${if_match $template8 == "default"}K${endif}${endif}${endif}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Processor
|
|
||||||
#--------------------------
|
|
||||||
${color0}${font Neuropolitical:size=8:bold}PROCESSOR ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 4}${color3}${font DejaVu Sans:size=8}${execi 100000 cat /proc/cpuinfo | grep 'model name' | cut -c 14-55 | uniq }${font}${color}
|
|
||||||
${voffset 2}Temp: ${color4}${execi 10 sensors | grep "Tdie" | cut -c16-19 }°C${color}${alignr}Freq: ${color3}${freq}MHz${color}
|
|
||||||
${voffset 0}${color5}${cpugraph 000000 00ffff}${color}
|
|
||||||
${voffset -4}Core 1:${goto 60}${color5}${cpubar cpu1 6,140}${color}${alignr}${color3}${cpu cpu1}%${color}
|
|
||||||
${voffset 0}Core 2:${goto 60}${color5}${cpubar cpu2 6,140}${color}${alignr}${color3}${cpu cpu2}%${color}
|
|
||||||
${voffset 0}Core 3:${goto 60}${color5}${cpubar cpu3 6,140}${color}${alignr}${color3}${cpu cpu3}%${color}
|
|
||||||
${voffset 0}Core 4:${goto 60}${color5}${cpubar cpu4 6,140}${color}${alignr}${color3}${cpu cpu4}%${color}
|
|
||||||
${voffset 0}Core 5:${goto 60}${color5}${cpubar cpu5 6,140}${color}${alignr}${color3}${cpu cpu5}%${color}
|
|
||||||
${voffset 0}Core 6:${goto 60}${color5}${cpubar cpu6 6,140}${color}${alignr}${color3}${cpu cpu6}%${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Graphics card
|
|
||||||
#--------------------------
|
|
||||||
${color0}${font Neuropolitical:size=8:bold}GRAPHICS CARD ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 4}Temp: ${color4}${nvidia temp}°C${color}${alignr}Threshold: ${color3}${nvidia threshold}°C${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Memory
|
|
||||||
#--------------------------
|
|
||||||
${color0}${font Neuropolitical:size=8:bold}MEMORY ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 4}RAM:${alignr}${color3}${lua MyRound ${mem} 1 halfup G hideUnit}${color} of ${color3}${lua MyRound ${memmax} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${membar}${color}
|
|
||||||
${voffset 2}Swap:${alignr}${color3}${lua MyRound ${swap} 1 halfup G hideUnit}${color} of ${color3}${lua MyRound ${swapmax} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${swapbar}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Drive #1
|
|
||||||
#--------------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/nvme0n1${color} ${color1}${hr 2}${color}
|
|
||||||
# ***** First we show the device *****
|
|
||||||
${voffset 4}Read:${color} ${color3}${diskio_read nvme0n1}/s${color}${goto 120}Write: ${color3}${diskio_write nvme0n1}/s${color}
|
|
||||||
${voffset -4}${color5}${diskiograph_read nvme0n1 25,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write nvme0n1 25,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 0}/ (root):${alignr}${color3}${lua MyRound ${fs_used /} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar /}${color}
|
|
||||||
${voffset 2}/home:${alignr}${color3}${lua MyRound ${fs_used /home} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /home} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar /home}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Drive #2
|
|
||||||
#--------------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/sda${color} ${color1}${hr 2}${color}
|
|
||||||
# ***** First we show the device *****
|
|
||||||
${voffset 4}Read: ${color3}${diskio_read sda}/s${color}${goto 120}Write: ${color3}${diskio_write sda}/s${color}
|
|
||||||
${voffset -4}${color5}${diskiograph_read sda 25,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write sda 25,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 0}/mnt/SSD120:${alignr}${color3}${lua MyRound ${fs_used /mnt/SSD120} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /mnt/SSD120} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar 6 /mnt/SSD120}${color}
|
|
||||||
|
|
||||||
#--------------------------
|
|
||||||
# Drive #3
|
|
||||||
#--------------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font} /dev/sdb${color} ${color1}${hr 2}${color}
|
|
||||||
# ***** First we show the device *****
|
|
||||||
${voffset 4}Read: ${color3}${diskio_read sdb}/s${color}${goto 120}Write: ${color3}${diskio_write sdb}/s${color}
|
|
||||||
${voffset -4}${color5}${diskiograph_read sdb 25,110 000000 ff0000}${color}${alignr}${color5}${diskiograph_write sdb 25,110 000000 00ffff}${color}
|
|
||||||
# ***** Now we show the mounts under this device *****
|
|
||||||
${voffset 0}/mnt/SSD180:${alignr}${color3}${lua MyRound ${fs_used /mnt/SSD180} 0 halfup G hideUnit}${color} of ${color3}${lua MyRound ${fs_size /mnt/SSD180} 0 ceil G addSpace}B${color}
|
|
||||||
${voffset -2}${color5}${fs_bar 6 /mnt/SSD180}${color}
|
|
||||||
|
|
||||||
#----------------------
|
|
||||||
# Top Processes
|
|
||||||
#----------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}TOP PROCESSES ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 6}By Memory Usage${goto 142}PID${alignr}RAM
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 1}${goto 140}${top_mem pid 1}${alignr}${top_mem mem_res 1}${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 2}${goto 140}${top_mem pid 2}${alignr}${top_mem mem_res 2}${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 3}${goto 140}${top_mem pid 3}${alignr}${top_mem mem_res 3}${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 4}${goto 140}${top_mem pid 4}${alignr}${top_mem mem_res 4}${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top_mem name 5}${goto 140}${top_mem pid 5}${alignr}${top_mem mem_res 5}${color}
|
|
||||||
${voffset 6}By CPU Usage${goto 142}PID${alignr}CPU
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 1}${goto 140}${top pid 1}${alignr}${top cpu 1}%${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 2}${goto 140}${top pid 2}${alignr}${top cpu 2}%${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 3}${goto 140}${top pid 3}${alignr}${top cpu 3}%${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 4}${goto 140}${top pid 4}${alignr}${top cpu 4}%${color}
|
|
||||||
${voffset 0}${font StyleBats:size=10}h${font}${voffset -1}${color3}${offset 5}${top name 5}${goto 140}${top pid 5}${alignr}${top cpu 5}%${color}
|
|
||||||
|
|
||||||
#--------------------
|
|
||||||
# Network -- Replace "enp34s0" below with name of your ethernet device. (Find name of ethernet device by typing "ip a" in terminal.)
|
|
||||||
#--------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}NETWORK ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 6}Ethernet Device:${goto 140}${color3}${gw_iface}${color}
|
|
||||||
${voffset 0}Internal IP:${goto 140}${color3}${addr enp34s0}${color}
|
|
||||||
${voffset 0}External IP:${goto 140}${color3}${execi 1800 wget -q -O - checkip.dyndns.org | sed -e 's/[^[:digit:]\|.]//g'}${color}
|
|
||||||
${voffset 6}DL: ${color3}${downspeed enp34s0}/s${color}${goto 140}UL:${color} ${color3}${upspeed enp34s0}/s${color}
|
|
||||||
${voffset -2}${color5}${downspeedgraph enp34s0 25,90 000000 ff0000}${color}${alignr}${color5}${upspeedgraph enp34s0 25,90 000000 00ffff}${color}
|
|
||||||
${voffset -6}Total: ${color3}${totaldown enp34s0}${color}${goto 140}Total:${color} ${color3}${totalup enp34s0}${color}
|
|
||||||
|
|
||||||
#--------------------
|
|
||||||
# Connections - netstat shows number of connections from your computer and application/PID making it. Kill spyware!
|
|
||||||
#--------------------
|
|
||||||
${voffset 0}${color0}${font Neuropolitical:size=8:bold}CONNECTIONS ${color1}${hr 2}${color}${font}
|
|
||||||
${voffset 6}Num. connections / PID / Process
|
|
||||||
${voffset 2}${color3}${execi 30 netstat -ept | grep ESTAB | awk '{print $9}' | cut -d: -f1 | sort | uniq -c | sort -nr}${color}
|
|
||||||
357
devices/get_device_info.lua
Normal file
357
devices/get_device_info.lua
Normal file
|
|
@ -0,0 +1,357 @@
|
||||||
|
--[[ ###########################################################################################################################################
|
||||||
|
# This script file was created by Matt Grotke (mgrotke@gmail.com) for the "mgconky Conky Theme" project: https://github.com/mgrotke/mgconky
|
||||||
|
# This file is in the public domain.
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------------------- ]]--
|
||||||
|
|
||||||
|
-- ########################################################## GET CPU MAKE AND MODEL ###########################################################
|
||||||
|
|
||||||
|
function conky_shorten_cpu_name(cpu_name)
|
||||||
|
-- Remove unnecessary parts like (R), (TM), "CPU", "@ XGHz", "Processor", and extra spaces
|
||||||
|
return (cpu_name
|
||||||
|
:gsub("%(R%)", "") -- Remove (R)
|
||||||
|
:gsub("%(TM%)", "") -- Remove (TM)
|
||||||
|
:gsub("CPU", "") -- Remove "CPU"
|
||||||
|
:gsub("Processor", "") -- Remove "Processor"
|
||||||
|
:gsub("@[%s%w%.]+", "") -- Remove "@ XGHz"
|
||||||
|
:gsub("%s%s+", " ") -- Remove extra spaces
|
||||||
|
:gsub("^%s+", "") -- Trim leading spaces
|
||||||
|
:gsub("%s+$", "") -- Trim trailing spaces
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache so we only run this once. The CPU will not change.
|
||||||
|
local conky_cpu_cached_output = nil
|
||||||
|
function conky_get_cpu_info()
|
||||||
|
if conky_cpu_cached_output then
|
||||||
|
return conky_cpu_cached_output
|
||||||
|
else
|
||||||
|
-- Open /proc/cpuinfo for reading
|
||||||
|
local file = io.open("/proc/cpuinfo", "r")
|
||||||
|
if not file then
|
||||||
|
conky_cpu_cached_output = "Failed to open /proc/cpuinfo"
|
||||||
|
return conky_cpu_cached_output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Read the contents of /proc/cpuinfo
|
||||||
|
local cpu_info = file:read("*all")
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
-- Find the 'model name' line
|
||||||
|
for line in cpu_info:gmatch("[^\r\n]+") do
|
||||||
|
local model_name = line:match("^model name%s*:%s*(.+)")
|
||||||
|
if model_name then
|
||||||
|
conky_cpu_cached_output = conky_shorten_cpu_name(model_name)
|
||||||
|
return conky_cpu_cached_output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return nil if no model name is found
|
||||||
|
conky_cpu_cached_output = "CPU model name not found"
|
||||||
|
return conky_cpu_cached_output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ########################################################## GET GU MAKE AND MODEL ###########################################################
|
||||||
|
|
||||||
|
function conky_shorten_gpu_name(gpu_name)
|
||||||
|
return (gpu_name
|
||||||
|
:gsub("NVIDIA Corporation", "NVIDIA")
|
||||||
|
:gsub("Advanced Micro Devices, Inc%.", "AMD")
|
||||||
|
:gsub("AMD Corporation", "AMD")
|
||||||
|
:gsub("Intel Corporation", "Intel")
|
||||||
|
:gsub("ATI Technologies Inc%.", "ATI")
|
||||||
|
:gsub("Qualcomm Technologies, Inc%.", "Qualcomm")
|
||||||
|
:gsub("ARM Holdings", "ARM")
|
||||||
|
:gsub("Apple Inc%.", "Apple")
|
||||||
|
:gsub("Matrox Graphics, Inc%.", "Matrox")
|
||||||
|
:gsub("S3 Graphics Co%., Ltd%.", "S3 Graphics")
|
||||||
|
:gsub("VIA Technologies, Inc%.", "VIA")
|
||||||
|
:gsub("Imagination Technologies Ltd%.", "Imagination")
|
||||||
|
:gsub("SiS %(Silicon Integrated Systems%)", "SiS")
|
||||||
|
:gsub("XGI Technology Inc%.", "XGI")
|
||||||
|
:gsub("3dfx Interactive, Inc%.", "3dfx")
|
||||||
|
:gsub("Raspberry Pi Foundation", "Raspberry Pi")
|
||||||
|
:gsub("Broadcom Inc%.", "Broadcom")
|
||||||
|
:gsub("Lite Hash Rate", "LHR")
|
||||||
|
:gsub("GA%d+%s%[", "") -- Remove chip identifier like "GA106 ["
|
||||||
|
:gsub("%].*", "") -- Remove everything after "]"
|
||||||
|
:gsub("%(.*%)", "") -- Remove revision info like "(rev a1)"
|
||||||
|
:gsub("%s+", " ") -- Normalize spaces
|
||||||
|
:match("^%s*(.-)%s*$") -- Trim leading/trailing spaces
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache so we only run this once. The GPU will not change.
|
||||||
|
local conky_gpu_cached_output = nil
|
||||||
|
function conky_get_gpu_info()
|
||||||
|
if conky_gpu_cached_output then
|
||||||
|
return conky_gpu_cached_output
|
||||||
|
else
|
||||||
|
local handle = io.popen("lspci -nn")
|
||||||
|
if not handle then
|
||||||
|
conky_gpu_cached_output = "Failed to run lspci"
|
||||||
|
return conky_gpu_cached_output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Read the output of the command
|
||||||
|
local output = handle:read("*all")
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Search for a VGA compatible controller or GPU entry
|
||||||
|
for line in output:gmatch("[^\r\n]+") do
|
||||||
|
if line:match("%[0300%]") then
|
||||||
|
-- Extract the relevant information after the colon
|
||||||
|
local gpu = line:match(": (.+)$")
|
||||||
|
if gpu then
|
||||||
|
conky_gpu_cached_output = conky_shorten_gpu_name(gpu)
|
||||||
|
return conky_gpu_cached_output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If no graphics card is found
|
||||||
|
conky_gpu_cached_output = "No graphics card found"
|
||||||
|
return conky_gpu_cached_output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- ########################################################## GET DRIVES AND VOLUMES ###########################################################
|
||||||
|
|
||||||
|
-- Cache so we don't spam this every conky tick
|
||||||
|
local conky_drives_cache_duration = 300 -- Cache output for 5 minutes
|
||||||
|
local conky_drives_last_update_time = 0
|
||||||
|
local conky_drives_cached_output = ""
|
||||||
|
|
||||||
|
function conky_get_drives_and_volumes()
|
||||||
|
local current_time = os.time()
|
||||||
|
|
||||||
|
-- Check if cache is still valid
|
||||||
|
if current_time - conky_drives_last_update_time < conky_drives_cache_duration then
|
||||||
|
return conky_drives_cached_output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Start fresh output
|
||||||
|
local output = ""
|
||||||
|
|
||||||
|
-- Use lsblk to get all devices and their mount points
|
||||||
|
local handle = io.popen("lsblk -ln -o NAME,TYPE,MOUNTPOINT,PKNAME")
|
||||||
|
if not handle then
|
||||||
|
return "Failed to execute lsblk command\n"
|
||||||
|
end
|
||||||
|
local result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Parse the lsblk output and group partitions by parent drive
|
||||||
|
local devices = {}
|
||||||
|
local parent_drive = nil
|
||||||
|
|
||||||
|
for line in (result or ""):gmatch("[^\r\n]+") do
|
||||||
|
local name, dtype, mount, pkname = line:match("^(%S+)%s+(%S+)%s*(%S*)%s*(%S*)$")
|
||||||
|
if dtype == "disk" then
|
||||||
|
parent_drive = name
|
||||||
|
devices[parent_drive] = { mountpoints = {} }
|
||||||
|
elseif dtype == "part" and parent_drive and mount and mount ~= "" then
|
||||||
|
table.insert(devices[parent_drive].mountpoints, mount)
|
||||||
|
elseif dtype == "dm" and pkname and mount and mount ~= "" then
|
||||||
|
-- Associate device-mapper (dm) devices with their parent physical disk
|
||||||
|
devices[pkname] = devices[pkname] or { mountpoints = {} }
|
||||||
|
table.insert(devices[pkname].mountpoints, mount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Generate the output, only including drives with active mount points
|
||||||
|
for drive, data in pairs(devices) do
|
||||||
|
if #data.mountpoints > 0 then
|
||||||
|
output = output .. '${voffset 0}${color0}${font Neuropolitical:size=8:bold}DRIVE${font Courier:size=9} /dev/' .. drive .. '${color} ${color1}${hr 2}${color}\n'
|
||||||
|
for _, mount in ipairs(data.mountpoints) do
|
||||||
|
-- Use df to get the size and used space for the mount
|
||||||
|
local handle = io.popen("df -h --output=target,size,used " .. mount .. " | tail -n 1")
|
||||||
|
local df_result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Parse df output
|
||||||
|
local target, size, used = df_result:match("(%S+)%s+(%S+)%s+(%S+)")
|
||||||
|
if target and size and used then
|
||||||
|
output = output .. '${voffset 2}' .. target .. ': ${alignr}${color3}' .. used .. 'B${color} of ${color3}' .. size .. 'B${color}\n'
|
||||||
|
output = output .. '${voffset -2}${color5}${fs_bar ' .. target .. '}${color}\n'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
output = output .. '\n' -- Add a blank line after the last mount point of the current drive
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache and return the output
|
||||||
|
conky_drives_cached_output = output
|
||||||
|
conky_drives_last_update_time = current_time
|
||||||
|
|
||||||
|
return conky_drives_cached_output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run and print the output (for standalone testing)
|
||||||
|
print(conky_get_drives_and_volumes())
|
||||||
|
|
||||||
|
|
||||||
|
-- ########################################################## GET VPN STATUS ###################################################################
|
||||||
|
|
||||||
|
-- Cache so we don't spam this every conky tick
|
||||||
|
local conky_vpn_cache = {
|
||||||
|
last_update_time = 0,
|
||||||
|
cache_duration = 15, -- Cache output for 15 seconds
|
||||||
|
cached_output = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function conky_get_vpn_status()
|
||||||
|
local current_time = os.time()
|
||||||
|
|
||||||
|
-- Update cache only if more than 30 seconds have passed
|
||||||
|
if current_time - conky_vpn_cache.last_update_time > conky_vpn_cache.cache_duration then
|
||||||
|
-- Run the `ip a` command and capture its output
|
||||||
|
local handle = io.popen("ip a")
|
||||||
|
if not handle then
|
||||||
|
return "${color7}Error: Failed to execute 'ip a'${color}"
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Check for active VPN
|
||||||
|
local vpn_status = "Off"
|
||||||
|
local vpn_color = "${color7}" -- Red for Off
|
||||||
|
|
||||||
|
for line in result:gmatch("[^\r\n]+") do
|
||||||
|
-- Look for active POINTOPOINT interfaces
|
||||||
|
if line:find("POINTOPOINT") and line:find("UP") then
|
||||||
|
local device_name = line:match("^%d+: ([^:]+):")
|
||||||
|
if device_name then
|
||||||
|
vpn_status = "On (" .. device_name .. ")"
|
||||||
|
vpn_color = "${color6}" -- Blue for On
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update cache
|
||||||
|
conky_vpn_cache.cached_output = vpn_color .. vpn_status .. "${color}"
|
||||||
|
conky_vpn_cache.last_update_time = current_time
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return cached status
|
||||||
|
return conky_vpn_cache.cached_output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test the function by printing the result
|
||||||
|
print(conky_get_vpn_status())
|
||||||
|
|
||||||
|
-- ########################################################## GET MEMORY USAGE #################################################################
|
||||||
|
|
||||||
|
-- Cache so we don't spam this every conky tick
|
||||||
|
local conky_memory_cache = {
|
||||||
|
last_update_time_swapstatus = 0,
|
||||||
|
last_update_time_memval = 0,
|
||||||
|
last_update_time_swapval = 0,
|
||||||
|
cache_duration = 15, -- Cache output for 1 minute
|
||||||
|
cached_output_swapstatus = "", -- Possible values: "swapenabled" | "swapdisabled"
|
||||||
|
cached_output_memval = "",
|
||||||
|
cached_output_swapval = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function conky_grep_memory(grep_filter)
|
||||||
|
|
||||||
|
-- Run the `free` command and capture its output
|
||||||
|
local handle = io.popen("free -h --si | grep " .. grep_filter)
|
||||||
|
if not handle then
|
||||||
|
return "Error: Failed to execute 'free'"
|
||||||
|
end
|
||||||
|
local result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function conky_get_memory_usage(grep_filter)
|
||||||
|
local current_time = os.time()
|
||||||
|
|
||||||
|
-- Is arg "sys" or "swap"
|
||||||
|
if grep_filter == "sys" then
|
||||||
|
|
||||||
|
-- Is cache stale?
|
||||||
|
if current_time - conky_memory_cache.last_update_time_memval > conky_memory_cache.cache_duration then
|
||||||
|
|
||||||
|
-- Extract memory usage details
|
||||||
|
local grep_result = conky_grep_memory("Mem")
|
||||||
|
local total, used = grep_result:match("Mem:%s+(%S+)%s+(%S+)")
|
||||||
|
if not total or not used then
|
||||||
|
conky_memory_cache.cached_output_memval = "Error: Failed to parse memory usage"
|
||||||
|
else
|
||||||
|
-- Format the output as "X of Y" with color formatting
|
||||||
|
conky_memory_cache.cached_output_memval = "${color3}" .. used .. "B${color} of ${color3}" .. total .. "B${color}"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update cache time
|
||||||
|
conky_memory_cache.last_update_time_memval = current_time
|
||||||
|
|
||||||
|
-- Debug
|
||||||
|
--print("DEBUG: UPDATED MEM VAL (" .. conky_memory_cache.cached_output_memval .. ")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return mem cache (the mem cache has been updated if the duration has passed)
|
||||||
|
return conky_memory_cache.cached_output_memval
|
||||||
|
|
||||||
|
else -- If arg is not "sys" we assume they are looking for swap
|
||||||
|
|
||||||
|
-- Is cache stale?
|
||||||
|
if current_time - conky_memory_cache.last_update_time_swapval > conky_memory_cache.cache_duration then
|
||||||
|
|
||||||
|
-- Extract swap usage details
|
||||||
|
local grep_result = conky_grep_memory("Swap")
|
||||||
|
local total, used = grep_result:match("Swap:%s+(%S+)%s+(%S+)")
|
||||||
|
if not total or not used then
|
||||||
|
conky_memory_cache.cached_output_swapval = "Error: Failed to parse swap usage"
|
||||||
|
else
|
||||||
|
-- Format the output as "X of Y" with color formatting
|
||||||
|
conky_memory_cache.cached_output_swapval = "${color3}" .. used .. "B${color} of ${color3}" .. total .. "B${color}"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update cache time
|
||||||
|
conky_memory_cache.last_update_time_swapval = current_time
|
||||||
|
|
||||||
|
-- Debug
|
||||||
|
--print("DEBUG: UPDATED SWAP VAL (" .. conky_memory_cache.cached_output_swapval .. ")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return swap cache (the swap cache has been updated if the duration has passed)
|
||||||
|
return conky_memory_cache.cached_output_swapval
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function conky_check_swap_status()
|
||||||
|
local current_time = os.time()
|
||||||
|
|
||||||
|
-- Is cache stale?
|
||||||
|
if current_time - conky_memory_cache.last_update_time_swapstatus > conky_memory_cache.cache_duration then
|
||||||
|
|
||||||
|
local grep_result = conky_grep_memory("Swap")
|
||||||
|
local total = grep_result:match("Swap:%s+(%S+)")
|
||||||
|
if not total or total == "0B" or total == "0" then
|
||||||
|
conky_memory_cache.cached_output_swapstatus = "swapdisabled"
|
||||||
|
else
|
||||||
|
conky_memory_cache.cached_output_swapstatus = "swapenabled"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update cache
|
||||||
|
conky_memory_cache.last_update_time_swapstatus = current_time
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug
|
||||||
|
--print("DEBUG: UPDATED SWAP STATUS (" .. conky_memory_cache.cached_output_swapstatus .. ")")
|
||||||
|
|
||||||
|
-- Return cached output
|
||||||
|
return conky_memory_cache.cached_output_swapstatus
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test the function by printing the result
|
||||||
|
print("Initial Memory Check Function Outputs:")
|
||||||
|
print(" CHECK SWAP STATUS = " .. conky_check_swap_status())
|
||||||
|
print(" GET MEMORY USAGE = " .. conky_get_memory_usage("mem"))
|
||||||
|
print(" GET SWAP USAGE = " .. conky_get_memory_usage("swap"))
|
||||||
|
|
||||||
146
rounding.lua
146
rounding.lua
|
|
@ -1,146 +0,0 @@
|
||||||
--[[ ##############################################################################################################################
|
|
||||||
# This script file was created by Matt Grotke (mgrotke@gmail.com) for the "mgconky Conky Theme" project: https://github.com/mgrotke/mgconky
|
|
||||||
# This file is in the public domain.
|
|
||||||
# ---------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
# The function below is intended to be called by a Conky config file in the following way:
|
|
||||||
# ${lua MyRound <value to round> <decimal places> <rounding type> <unit to use> <option>}
|
|
||||||
#
|
|
||||||
# Note that the function name in this file is "conky_MyRound" but it is called from Conky using "MyRound". This is normal.
|
|
||||||
#
|
|
||||||
# All arguments are mandatory:
|
|
||||||
# <value to round> Requires a numeric value, which may or may not contiain a trailing unit letter (it is expected that the Conky configuration variable "short_units" is set to "yes").
|
|
||||||
# <decimal places> Requires an integer, such as 0 (for no decimal places), 1, 2, etc.
|
|
||||||
# <rounding type> Requires one of the following (no quotes used): halfup, floor, ceil. Halfup is "standard" rounding where less than .5 goes down, and .5 and over goes up.
|
|
||||||
# <unit to use> Requires one of the following (no quotes used): auto, B, K, M, G, T. They will convert the number to Bytes, Kilobytes, Megabytes, Gigabytes, or Terabytes.
|
|
||||||
# <options> Requires one of the following (no quotes used): normal, hideUnit, addSpace.
|
|
||||||
# Examples:
|
|
||||||
# ${lua MyRound ${mem} 0 halfup auto normal} # Displays memory used, rounded to the nearest whole number, shown in whatever unit Conky determines is the most appropriate.
|
|
||||||
# ${lua MyRound ${mem} 0 halfup M normal} # Displays memory used, rounded to the nearest whole number, shown in Megabytes.
|
|
||||||
# ${lua MyRound ${mem} 0 ceil G hideUnit} # Displays memory used, rounded to the next whole number. The value WILL be in Megabytes, but a unit will not be displayed.
|
|
||||||
# ${lua MyRound ${mem} 1 halfup G addSpace} # Displays memory used, rounded to the nearest 1 decimal place, shown in Gigabytes. There will be a space before the G.
|
|
||||||
############################################################################################################################## ]]--
|
|
||||||
do
|
|
||||||
function conky_MyRound(arg, places, roundType, useUnit, modify)
|
|
||||||
|
|
||||||
-- Get args passed from Conky
|
|
||||||
local sArg = conky_parse(arg)
|
|
||||||
local sPlaces = conky_parse(places)
|
|
||||||
local sRoundType = conky_parse(roundType)
|
|
||||||
local sUseUnit = conky_parse(useUnit)
|
|
||||||
local sModify = conky_parse(modify)
|
|
||||||
|
|
||||||
-- Convert args into types
|
|
||||||
local nPlaces = tonumber(sPlaces)
|
|
||||||
local nValue = tonumber(sArg)
|
|
||||||
local sLastChar = ""
|
|
||||||
if nValue == nil then
|
|
||||||
-- It's not a number, because we assume it has a single char unit trailing
|
|
||||||
sLastChar = string.sub(sArg, -1) --select the last char
|
|
||||||
nValue = tonumber(string.sub(sArg, 0, string.len(sArg) - 1)) --select the first part of the string, except for the last char
|
|
||||||
if nValue == nil then return "Error, not number" end -- Still not a number
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Convert unit
|
|
||||||
local sUnitText = ""
|
|
||||||
if sUseUnit == "auto" then
|
|
||||||
sUnitText = sLastChar
|
|
||||||
elseif sUseUnit == sLastChar then
|
|
||||||
sUnitText = sLastChar
|
|
||||||
else
|
|
||||||
sUnitText = sUseUnit
|
|
||||||
if sLastChar == "B" then
|
|
||||||
if sUseUnit == "K" then
|
|
||||||
nValue = nValue / 1000
|
|
||||||
elseif sUseUnit == "M" then
|
|
||||||
nValue = nValue / 1000000
|
|
||||||
elseif sUseUnit == "G" then
|
|
||||||
nValue = nValue / 1000000000
|
|
||||||
elseif sUseUnit == "T" then
|
|
||||||
nValue = nValue / 1000000000000
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
elseif sLastChar == "K" then
|
|
||||||
if sUseUnit == "B" then
|
|
||||||
nValue = nValue * 1000
|
|
||||||
elseif sUseUnit == "M" then
|
|
||||||
nValue = nValue / 1000
|
|
||||||
elseif sUseUnit == "G" then
|
|
||||||
nValue = nValue / 1000000
|
|
||||||
elseif sUseUnit == "T" then
|
|
||||||
nValue = nValue / 1000000000
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
elseif sLastChar == "M" then
|
|
||||||
if sUseUnit == "B" then
|
|
||||||
nValue = nValue * 1000000
|
|
||||||
elseif sUseUnit == "K" then
|
|
||||||
nValue = nValue * 1000
|
|
||||||
elseif sUseUnit == "G" then
|
|
||||||
nValue = nValue / 1000
|
|
||||||
elseif sUseUnit == "T" then
|
|
||||||
nValue = nValue / 1000000
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
elseif sLastChar == "G" then
|
|
||||||
if sUseUnit == "B" then
|
|
||||||
nValue = nValue * 1000000000
|
|
||||||
elseif sUseUnit == "K" then
|
|
||||||
nValue = nValue * 1000000
|
|
||||||
elseif sUseUnit == "M" then
|
|
||||||
nValue = nValue * 1000
|
|
||||||
elseif sUseUnit == "T" then
|
|
||||||
nValue = nValue / 1000
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
elseif sLastChar == "T" then
|
|
||||||
if sUseUnit == "B" then
|
|
||||||
nValue = nValue * 1000000000000
|
|
||||||
elseif sUseUnit == "K" then
|
|
||||||
nValue = nValue * 1000000000
|
|
||||||
elseif sUseUnit == "M" then
|
|
||||||
nValue = nValue * 1000000
|
|
||||||
elseif sUseUnit == "G" then
|
|
||||||
nValue = nValue * 1000
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return "Error, invalid unit"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Modify unit?
|
|
||||||
if sModify == "normal" then
|
|
||||||
--do nothing (keep unit text how it is)
|
|
||||||
elseif sModify == "hideUnit" then
|
|
||||||
sUnitText = ""
|
|
||||||
elseif sModify == "addSpace" then
|
|
||||||
sUnitText = string.format(" %s", sUnitText)
|
|
||||||
else
|
|
||||||
return "Error, invalid modify"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Do the rounding
|
|
||||||
local nRounded = 0
|
|
||||||
if sRoundType == "halfup" then
|
|
||||||
local nPower = math.pow(10, nPlaces or 0)
|
|
||||||
nValue = nValue * nPower
|
|
||||||
if nValue >= 0 then nValue = math.floor(nValue + 0.5) else nValue = math.ceil(nValue - 0.5) end
|
|
||||||
nRounded = nValue / nPower
|
|
||||||
elseif sRoundType == "ceil" then
|
|
||||||
local nPower = math.pow(10, nPlaces or 0)
|
|
||||||
nRounded = math.ceil(nValue * nPower) / nPower
|
|
||||||
elseif sRoundType == "floor" then
|
|
||||||
local nPower = math.pow(10, nPlaces or 0)
|
|
||||||
nRounded = math.floor(nValue * nPower) / nPower
|
|
||||||
else
|
|
||||||
return "Error, invalid round type"
|
|
||||||
end
|
|
||||||
local sFormatter = string.format("%s%s%s", "%.", tostring(nPlaces), "f%s")
|
|
||||||
return string.format(sFormatter, nRounded, sUnitText)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 MiB |
156
stocks/get_stocks_alphavantage.py
Executable file
156
stocks/get_stocks_alphavantage.py
Executable file
|
|
@ -0,0 +1,156 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def fetch_intraday_data(api_key, symbol, interval="1min"):
|
||||||
|
"""Fetch current and historical intraday price using TIME_SERIES_INTRADAY."""
|
||||||
|
url = "https://www.alphavantage.co/query"
|
||||||
|
params = {
|
||||||
|
"function": "TIME_SERIES_INTRADAY",
|
||||||
|
"symbol": symbol,
|
||||||
|
"interval": interval,
|
||||||
|
"apikey": api_key
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
time_series = data.get(f"Time Series ({interval})")
|
||||||
|
|
||||||
|
# Debug: Log the raw response
|
||||||
|
#print(f"DEBUG: Response data for {symbol}: {data}")
|
||||||
|
|
||||||
|
if time_series:
|
||||||
|
# Sort the timestamps to get the first (open) and latest price
|
||||||
|
sorted_timestamps = sorted(time_series.keys())
|
||||||
|
open_time = sorted_timestamps[0] # Earliest timestamp of the day
|
||||||
|
latest_time = sorted_timestamps[-1] # Most recent timestamp
|
||||||
|
|
||||||
|
# Extract open price and latest price
|
||||||
|
open_price = float(time_series[open_time]["1. open"])
|
||||||
|
latest_price = float(time_series[latest_time]["4. close"])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"current_price": latest_price,
|
||||||
|
"compare_price": open_price
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
print(f"Error: No 'Time Series ({interval})' data found for {symbol}.")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"Error: Failed to fetch intraday data for {symbol} (HTTP {response.status_code})")
|
||||||
|
return None
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error: Failed to fetch intraday data for {symbol} - {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_historical_data(api_key, symbol, range_in_days):
|
||||||
|
"""Fetch current and historical price using TIME_SERIES_DAILY, allowing fallback to nearby dates."""
|
||||||
|
url = "https://www.alphavantage.co/query"
|
||||||
|
params = {
|
||||||
|
"function": "TIME_SERIES_DAILY",
|
||||||
|
"symbol": symbol,
|
||||||
|
"apikey": api_key
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
time_series = data.get("Time Series (Daily)")
|
||||||
|
|
||||||
|
# Debug: Log the raw response
|
||||||
|
#print(f"DEBUG: Response data for {symbol}: {data}")
|
||||||
|
|
||||||
|
if time_series:
|
||||||
|
# Current price is the latest closing price
|
||||||
|
latest_date = max(time_series.keys())
|
||||||
|
latest_data = time_series[latest_date]
|
||||||
|
current_price = float(latest_data["4. close"])
|
||||||
|
|
||||||
|
# Dates to check: exact, one day before, one day after
|
||||||
|
target_date = (datetime.now() - timedelta(days=range_in_days)).strftime("%Y-%m-%d")
|
||||||
|
fallback_dates = [
|
||||||
|
target_date,
|
||||||
|
(datetime.now() - timedelta(days=range_in_days + 1)).strftime("%Y-%m-%d"),
|
||||||
|
(datetime.now() - timedelta(days=range_in_days - 1)).strftime("%Y-%m-%d")
|
||||||
|
]
|
||||||
|
|
||||||
|
# Find the first available date in the fallback list
|
||||||
|
historical_price = None
|
||||||
|
for date in fallback_dates:
|
||||||
|
if date in time_series:
|
||||||
|
historical_price = float(time_series[date]["4. close"])
|
||||||
|
break
|
||||||
|
|
||||||
|
return {
|
||||||
|
"current_price": current_price,
|
||||||
|
"compare_price": historical_price
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
print(f"Error: No 'Time Series (Daily)' data found for {symbol}.")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"Error: Failed to fetch historical data for {symbol} (HTTP {response.status_code})")
|
||||||
|
return None
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error: Failed to fetch historical data for {symbol} - {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Parse command-line arguments
|
||||||
|
parser = argparse.ArgumentParser(description="Fetch stock data from Alpha Vantage.")
|
||||||
|
parser.add_argument("--api_key", required=True, help="Your Alpha Vantage API key")
|
||||||
|
parser.add_argument("--symbols", required=True, help="Comma-separated list of stock symbols")
|
||||||
|
parser.add_argument("--range_in_days", type=int, default=0, help="Number of days for historical comparison (0 for none)")
|
||||||
|
parser.add_argument("--price_dec_places", type=int, default=0, help="Decimal places for prices")
|
||||||
|
parser.add_argument("--percent_dec_places", type=int, default=1, help="Decimal places for percentages")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Split symbols
|
||||||
|
symbols = args.symbols.strip().upper().split(",")
|
||||||
|
|
||||||
|
# Use a list to build the final output string
|
||||||
|
output = []
|
||||||
|
|
||||||
|
# Prepare for printing output
|
||||||
|
color_header = "${color}"
|
||||||
|
color_label = "${color3}"
|
||||||
|
color_value = "${color3}"
|
||||||
|
color_good = "${color6}"
|
||||||
|
color_bad = "${color7}"
|
||||||
|
line_tab1_offset = "${goto 25}"
|
||||||
|
line_tab2_offset = "${goto 90}"
|
||||||
|
line_tab3_offset = "${alignr}" # Could also replace this with goto 120 if you don't like the right alignment
|
||||||
|
|
||||||
|
# Iterate symbols
|
||||||
|
for symbol in symbols:
|
||||||
|
fetched_data = fetch_intraday_data(args.api_key, symbol) if args.range_in_days < 1 else fetch_historical_data(args.api_key, symbol, args.range_in_days)
|
||||||
|
if fetched_data:
|
||||||
|
current_price = fetched_data["current_price"]
|
||||||
|
compare_price = fetched_data["compare_price"]
|
||||||
|
price_difference = current_price - compare_price
|
||||||
|
percent_change = (price_difference / current_price) * 100
|
||||||
|
color_dynamic = (
|
||||||
|
color_good if round(price_difference, args.price_dec_places) > 0
|
||||||
|
else color_bad if round(price_difference, args.price_dec_places) < 0
|
||||||
|
else color_value
|
||||||
|
)
|
||||||
|
output.append(
|
||||||
|
f"{line_tab1_offset}{color_label}{symbol}: {line_tab2_offset}{color_value}{round(current_price, args.price_dec_places):.{args.price_dec_places}f} "
|
||||||
|
f"{line_tab3_offset}{color_dynamic}{round(price_difference, args.price_dec_places):+.{args.price_dec_places}f} "
|
||||||
|
f"({round(percent_change, args.percent_dec_places):+.{args.percent_dec_places}f}%)"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output.append(f"{symbol}: Error fetching data")
|
||||||
|
|
||||||
|
# Join all parts of the output and print it
|
||||||
|
header_label = f"Intraday" if args.range_in_days < 1 else f"{args.range_in_days} Day"
|
||||||
|
header_line = f"{line_tab1_offset}{color_header}Ticker{line_tab2_offset}Price ($$){line_tab3_offset}{header_label}{color_label}"
|
||||||
|
return header_line + "\n" + f"{line_tab1_offset}{color_header}${{voffset -5}}${{hr 1}}" + "\n" + "\n".join(output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(main())
|
||||||
|
|
||||||
193
stocks/get_stocks_finnhub.py
Executable file
193
stocks/get_stocks_finnhub.py
Executable file
|
|
@ -0,0 +1,193 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_current_stock_data(api_key, symbol):
|
||||||
|
url = "https://finnhub.io/api/v1/quote"
|
||||||
|
params = {
|
||||||
|
'symbol': symbol,
|
||||||
|
'token': api_key
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
return {
|
||||||
|
"symbol": symbol,
|
||||||
|
"current_price": data.get("c"),
|
||||||
|
"open_price": data.get("o")
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
print(f"Error: Failed to fetch current data for {symbol} (HTTP {response.status_code})")
|
||||||
|
return None
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error: Failed to get current stock data for {symbol} - {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_current_crypto_data(api_key, symbol):
|
||||||
|
url = "https://finnhub.io/api/v1/crypto/candle"
|
||||||
|
current_time = int(datetime.now().timestamp())
|
||||||
|
params = {
|
||||||
|
'symbol': symbol,
|
||||||
|
'resolution': '1', # 1-minute resolution
|
||||||
|
'from': current_time - 60, # Last minute
|
||||||
|
'to': current_time,
|
||||||
|
'token': api_key
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
if data.get("s") == "ok" and "c" in data:
|
||||||
|
return {
|
||||||
|
"symbol": symbol,
|
||||||
|
"current_price": data["c"][-1], # Last closing price
|
||||||
|
"open_price": data["o"][-1] # Last opening price
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
print(f"Error: Crypto data not OK for {symbol}")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"Error: Failed to fetch crypto data for {symbol} (HTTP {response.status_code})")
|
||||||
|
return None
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error: Failed to get crypto data for {symbol} - {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_historical_data(api_key, symbol, range_in_days):
|
||||||
|
url = "https://finnhub.io/api/v1/stock/candle" if ':' in symbol else "https://finnhub.io/api/v1/crypto/candle"
|
||||||
|
end_time = int(datetime.now().timestamp())
|
||||||
|
start_time = int((datetime.now() - timedelta(days=range_in_days)).timestamp())
|
||||||
|
params = {
|
||||||
|
'symbol': symbol,
|
||||||
|
'resolution': 'D', # Daily candles
|
||||||
|
'from': start_time,
|
||||||
|
'to': end_time,
|
||||||
|
'token': api_key
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
if data.get("s") == "ok":
|
||||||
|
return {
|
||||||
|
"symbol": symbol,
|
||||||
|
"timestamps": data["t"],
|
||||||
|
"close_prices": data["c"]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
print(f"Error: Historical data not ok for {symbol}")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"Error: Failed to fetch historical data for {symbol} (HTTP {response.status_code})")
|
||||||
|
return None
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error: Failed to get historical stock data for {symbol} - {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Parse command-line arguments
|
||||||
|
parser = argparse.ArgumentParser(description="Fetch stock data from FinnHub.")
|
||||||
|
parser.add_argument("--api_key", required=True, help="Your personal FinnHub API key")
|
||||||
|
parser.add_argument("--symbols", required=True, help="Stock symbols (comma separated) to fetch")
|
||||||
|
parser.add_argument("--range_in_days", default=0, type=int, help="Number of days to compare against (optional, default is 0)")
|
||||||
|
parser.add_argument("--price_dec_places", default=0, type=int, help="Number of decimal places for prices (default is 0)")
|
||||||
|
parser.add_argument("--percent_dec_places", default=1, type=int, help="Number of decimal places for percentages (default is 1)")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Split symbols
|
||||||
|
symbols = args.symbols.strip().upper().split(",")
|
||||||
|
|
||||||
|
# Use a list to build the final output string
|
||||||
|
output = []
|
||||||
|
|
||||||
|
# Prepare for printing output
|
||||||
|
color_header = "${color}"
|
||||||
|
color_label = "${color3}"
|
||||||
|
color_value = "${color3}"
|
||||||
|
color_good = "${color6}"
|
||||||
|
color_bad = "${color7}"
|
||||||
|
line_tab1_offset = "${goto 25}"
|
||||||
|
line_tab2_offset = "${goto 90}"
|
||||||
|
line_tab3_offset = "${alignr}" # Could also replace this with goto 120 if you don't like the right alignment
|
||||||
|
historical_data_exists = False
|
||||||
|
|
||||||
|
# Iterate symbols (crypto symbols have a colon in them, i.e. BINANCE:BTCUSDT; COINBASE:BTCUSD)
|
||||||
|
for symbol in symbols:
|
||||||
|
current_data = fetch_current_crypto_data(args.api_key, symbol) if ':' in symbol else fetch_current_stock_data(args.api_key, symbol)
|
||||||
|
if current_data:
|
||||||
|
current_price = current_data['current_price']
|
||||||
|
if args.range_in_days > 0:
|
||||||
|
# Fetch historical data if range_in_days > 0
|
||||||
|
historical_data = fetch_historical_data(args.api_key, symbol, args.range_in_days)
|
||||||
|
if historical_data:
|
||||||
|
historical_data_exists = True
|
||||||
|
# Find the closing price for exactly X days ago
|
||||||
|
target_date = (datetime.now() - timedelta(days=args.range_in_days)).strftime("%Y-%m-%d")
|
||||||
|
timestamps = historical_data["timestamps"]
|
||||||
|
close_prices = historical_data["close_prices"]
|
||||||
|
|
||||||
|
# Convert timestamps to dates and find the target date's index
|
||||||
|
date_to_close_price = {
|
||||||
|
datetime.fromtimestamp(ts).strftime("%Y-%m-%d"): price
|
||||||
|
for ts, price in zip(timestamps, close_prices)
|
||||||
|
}
|
||||||
|
|
||||||
|
historical_closing_price = date_to_close_price.get(target_date, None)
|
||||||
|
if historical_closing_price is not None:
|
||||||
|
# Calculate difference in value from current price to historical close
|
||||||
|
price_difference = current_price - historical_closing_price
|
||||||
|
percent_change = (price_difference / historical_closing_price) * 100
|
||||||
|
color_dynamic = (
|
||||||
|
color_good if round(price_difference, args.price_dec_places) > 0
|
||||||
|
else color_bad if round(price_difference, args.price_dec_places) < 0
|
||||||
|
else color_value
|
||||||
|
)
|
||||||
|
output.append(
|
||||||
|
f"{line_tab1_offset}{color_label}{symbol}: {line_tab2_offset}{color_value}{round(current_price, args.price_dec_places):.{args.price_dec_places}f} "
|
||||||
|
f"{line_tab3_offset}{color_dynamic}{round(price_difference, args.price_dec_places):+.{args.price_dec_places}f} "
|
||||||
|
f"({round(percent_change, args.percent_dec_places):+.{args.percent_dec_places}f}%)"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output.append(
|
||||||
|
f"{symbol}: {round(current_price, args.price_dec_places):.{args.price_dec_places}f} "
|
||||||
|
f"| {args.range_in_days} days: No historical data"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output.append(f"{symbol}: Error fetching historical data")
|
||||||
|
else:
|
||||||
|
# Only include intraday change if no historical data is requested
|
||||||
|
open_price = current_data['open_price']
|
||||||
|
if open_price is not None and current_price is not None:
|
||||||
|
intraday_change = current_price - open_price
|
||||||
|
intraday_percent_change = (intraday_change / open_price) * 100
|
||||||
|
color_dynamic = (
|
||||||
|
color_good if round(intraday_change, args.price_dec_places) > 0
|
||||||
|
else color_bad if round(intraday_change, args.price_dec_places) < 0
|
||||||
|
else color_value
|
||||||
|
)
|
||||||
|
output.append(
|
||||||
|
f"{line_tab1_offset}{color_label}{symbol}: {line_tab2_offset}{color_value}{round(current_price, args.price_dec_places):.{args.price_dec_places}f} "
|
||||||
|
f"{line_tab3_offset}{color_dynamic}{round(intraday_change, args.price_dec_places):+.{args.price_dec_places}f} "
|
||||||
|
f"({round(intraday_percent_change, args.percent_dec_places):+.{args.percent_dec_places}f}%)"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output.append(
|
||||||
|
f"{symbol}: {round(current_price, args.price_dec_places):.{args.price_dec_places}f} | Intraday: N/A"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output.append(f"{symbol}: Error fetching current data")
|
||||||
|
|
||||||
|
# Join all parts of the output and print it
|
||||||
|
header_label = f"{args.range_in_days} Day" if historical_data_exists else "Intraday"
|
||||||
|
header_line = f"{line_tab1_offset}{color_header}Ticker{line_tab2_offset}Price ($$){line_tab3_offset}{header_label}{color_label}"
|
||||||
|
return header_line + "\n" + f"{line_tab1_offset}{color_header}${{voffset -5}}${{hr 1}}" + "\n" + "\n".join(output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(main())
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue