Skip to content

@dru8274 /README secret
Last active

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
[#!][FVWM] - Flexget with Vertical Titlebars.
Information
===========
System Debian "testing" nee Crunchbang Waldorf
Window Manager FVWM
Compositor Compton
Notification Daemon xfce4-notifyd
Status Bar dzen
Torrent Client transmission-remote-cli
Torrent Autodownload flexget http://flexget.com/
Music Player ncmpcpp
MPD Visualizer spectrum https://bbs.archlinux.org/viewtopic.php?id=173102
Flexget is a more powerful tool to automatically download torrents to collect information. My concept
here is for flexget to inform me about newly available tv premieres and movies, rather than having
to trawl through torrent websites instead. The aim being to improve the signal to noise ratio
of the results.
The terms here are all urxvt. The font used is mostly gohufont, except for "sar-rx" and
"spectrum" which use "fixed" font.
-gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1
-misc-fixed-medium-r-normal--6-60-75-75-c-40-iso8859-1
The pixmap tile used as background for terms and menus was cropped and altered
from "thached" wallpaper :- http://hotiron.deviantart.com/art/Thatched-148517108
The status bar, coverart changer, and most of the urxvt run with perl scripts.
dzen status bar dzen-status.pl
coverart changer ncmpcpp-helper.pl
download speed histogram "sar-rx" sar-rx.pl
System Information "System" system-info.pl
"Disks" disk-usage.pl
"Processes" top-processes.pl
Flexget Information "Flexget" flexget-torrents-added.pl
"Television" flexget-premieres+docos.pl
"Movies" flexget-movies.pl
Lastly, the fvwm configs are unfinished, and a bit rough. Even so, the curious are welcome
to look. I've cut and pasted the fvwm configs into two files - config & fvwm-menus.
#### FLEXGET CONFIG
## ~/.flexget/config.yml
schedules:
- tasks: [ettv_and_eztv, colbert, tvteam_and_afg, mvgroups]
interval:
minutes: 10
- tasks: [tv_premieres, movies]
interval:
minutes: 60
templates:
global:
verify_ssl_certificates: no
cookies: ~/.flexget/cookies.sqlite
use_transmission:
transmission:
host: localhost
port: 9091
username: nostromo
password: '{b3ac1f4a8d7e9198df116a9b2b6xxxxxxxxx9e4eu8IQfZA'
ratio: 2
addpaused: no
maxupspeed: 300
maxdownspeed: 300
tasks:
ettv_and_eztv:
template:
- global
- use_transmission
inputs:
- rss: 'http://ezrss.it/feed/'
- rss: 'http://rss.thepiratebay.se/user/0e3b2f46e5892dc5b2aac6dbe548bc27'
- rss: 'http://rss.thepiratebay.se/user/d17c6a45441ce0bc0c057f19057f95e1'
- rss: 'https://kickass.to/bookmarks/rss/users/xxxxxxxxxxxxxxxxxxxxxxx/'
include: series.yml
quality: hdtv|webdl|webrip <720p
exec: ~/.flexget/bin/add_torrent.pl "{{series_season}}::{{series_episode}}::{{series_name}}"
priority: 1
colbert:
template:
- global
- use_transmission
inputs:
- rss: 'http://ezrss.it/search/index.php?show_name=the+colbert+report&show_name_exact=true&date=&quality=HDTV&quality_exact=true&release_group=&mode=rss'
# - rss: 'http://ezrss.it/feed/'
# - rss: 'http://rss.thepiratebay.se/user/d17c6a45441ce0bc0c057f19057f95e1'
quality: hdtv|webdl|webrip <720p
seen: local
series:
- The Colbert Report:
identified_by: date
exec: ~/.flexget/bin/add_colbert.pl "{{title}}"
priority: 1
tvteam_and_afg:
template:
- global
- use_transmission
inputs:
- rss: 'http://torrentz.eu/feedA?q=afg+added+%3C+7d'
- rss: 'http://rss.thepiratebay.se/user/7e434ea6455f089db7f0291b3bd1d4db'
include: series.yml
quality: hdtv|webdl|webrip <720p
exec: ~/.flexget/bin/add_torrent.pl "{{series_season}}::{{series_episode}}::{{series_name}}"
priority: 2
## Premieres to be improved with plugins for thetvdb.com. See notes below.
tv_premieres:
template:
- global
inputs:
# TvTeam, ettv, eztv, eztv, torrentz (afg,fov,tla,river),
- rss: 'http://rss.thepiratebay.se/user/7e434ea6455f089db7f0291b3bd1d4db'
- rss: 'http://rss.thepiratebay.se/user/0e3b2f46e5892dc5b2aac6dbe548bc27'
- rss: 'http://rss.thepiratebay.se/user/d17c6a45441ce0bc0c057f19057f95e1'
- rss: 'http://ezrss.it/feed/'
- rss: 'http://torrentz.eu/feedA?q=afg+added+%3C+7d'
- rss: 'http://torrentz.eu/feedA?q=fov%7Ctla%7Criver+added+%3C+7d'
regexp:
reject:
- MVGROUP
series_premiere: yes
seen: local
exec: echo "{{series_name}}" >> ~/.flexget/lists/x-premieres.txt
priority: 3
mvgroups:
template: global
inputs:
- rss: 'https://zzzzzzzzzzzzz:xxxxxxxxxxxxxxxxxxxxxx@forums.mvgroup.org/rss.php?torrentsonly=1'
regexp:
## For series, reject all but the first title.
accept_excluding:
- '[2-9]of[0-9]'
from: title
seen: local
exec: echo "{{title}}" >> ~/.flexget/lists/x-mvgroups.txt
priority: 3
movies:
inputs:
- rss: 'http://torrentz.ch/feedA?q=dvdrip|brrip+2013|2014+movies+-xxx+-french+-dutch+-polish+added+%3C14d+MiLLENiUM|santi|MAXSPEED|AQOS|ETRG|juggs|LEGi0N'
- rss: 'http://kickass.to/other-movies/?rss=1'
- rss: 'http://yts.re/rss'
- rss: 'http://feeds.feedburner.com/TorrentbitnlLatestMoviesTorrents50'
- rss: 'http://extratorrent.cc/rss.xml?type=hot&cat=H264+X26'
regexp:
reject:
## TV episodes sometimes get mixed into the movies feeds. Awful.
- '[Ss][0-9][0-9][Ee][0-9][0-9]'
## Not into bollywood flicks.
- hindi
## Discard ancient movies. Regexp works much faster than imdb queries do.
- '19[0-9][0-9]'
- '200[0-9]'
- '201[0-2]'
quality:
- hdrip
- webrip+
- 480p+
seen_movies: strict
imdb_required: yes
imdb_lookup: yes
imdb:
min_score: 4.0
min_votes: 900
min_year: 2013
reject_languages:
- Hindi
- Japanese
- Hebrew
reject_genres:
- animation
- musical
- horror
- comedy
exec: echo "{{imdb_name}}::{{imdb_score}}::{{imdb_genres}}::{{imdb_languages}}::{{title}}" >> ~/.flexget/lists/x-movies.txt ;
priority: 4
## Premieres http://flexget.com/wiki/Plugins/thetvdb_lookup
## http://flexget.com/wiki/Cookbook/Series/PremieresGenres
## http://flexget.com/wiki/Plugins/require_field
# thetvdb_lookup: yes
# require_field: series_genres
# regexp:
# reject:
# - documentary: {from: series_genres}
# - talk show: {from: series_genres}
# - game show: {from: series_genres}
# series_premiere: yes
##################################
## FVWM config - ~/.fvwm/config ##
##################################
## The default fvwm functions are kept in /usr/share/fvwm/ConfigFvwmDefaults
## The StartFunction should be empty anyways.
DestroyFunc StartFunction
AddToFunc StartFunction I Echo "START-FUNCTION - Top of List"
## ╔═════════════════════════════╗
## ║ GLOBAL SETTINGS + STYLES ║
## ╚═════════════════════════════╝
## ┌─────────┐
## │ PATHS │
## └─────────┘
## ImagePath sets the path to all subfolders that contain images
SetEnv fvwm_wallpapers $[FVWM_USERDIR]/images/wallpapers
ImagePath $[FVWM_USERDIR]:+images:+icons:+mini:$[fvwm_wallpapers]:$[FVWM_USERDIR]/tiles
SetEnv fvwm_term_tile "$[FVWM_USERDIR]/images/term-tile.png"
## LocalePath path
## ModulePath path p7741
## ┌─────────────────┐
## │ FONT SETTINGS │
## └─────────────────┘
SetEnv fvwm_bitmap_normal_font -gohu-gohufont-medium-r-normal--14-*-iso8859-1
SetEnv fvwm_bitmap_bold_font -gohu-gohufont-bold-r-normal--14-*-iso8859-1
DefaultFont "xft:Sans Bold:pixelsize=14"
## Fonts for text in window titlebars.
Style * Font "xft:Sans Bold:pixelsize=14"
Style URxvt Font $[fvwm_bitmap_bold_font]
Style FvwmConsole Font $[fvwm_bitmap_bold_font]
#-gohu-gohufont-medium-r-normal--14-*-iso8859-1
## Fonts for text in menus.
#MenuStyle * Font -gohu-gohufont-medium-r-normal--14-*-iso8859-1
#MenuStyle * TitleFont -gohu-gohufont-bold-r-normal--14-*-iso8859-1
MenuStyle * Font $[fvwm_bitmap_bold_font]
MenuStyle * TitleFont $[fvwm_bitmap_bold_font]
MenuStyle WindowList Font "xft:DejaVu Sans Mono:style=Book:pixelsize=16"
## Fonts for icon titles, if they exist.
#Style * IconFont "xft:monospace:pixelsize=$[infostore.fontsize]:Medium"
#Style * IconFont -gohu-gohufont-medium-r-normal--11-*-iso8859-1
Style * IconFont $[fvwm_bitmap_normal_font]
## ┌────────────┐
## │ Desktops │
## └────────────┘
## Set the range of desktop index numbers.
InfoStoreAdd desk_min 1
InfoStoreAdd desk_max 7
## Just one page per desktop for me - WYSIWYG.
DesktopSize 1x1
## Define a usable workspace with a 3 pixel margin on the right-hand margin.
EwmhBaseStruts 0 3 0 0
## ┌──────────────────┐
## │ Edge Scrolling │
## └──────────────────┘
## Specify no scrolling when the cursor hits the edge of a page.
EdgeScroll 0 0
## Disables mouse edge scrolling, even when a window is dragged.
EdgeThickness 0
## Defines the ease with which the desktop is changed by moving the mouse over the
## edge of the screen. A value of -1 completely disables the scrolling.
EdgeResistance -1
## ┌─────────────────────────┐
## │ MOUSE + KEYS + CURSOR │
## └─────────────────────────┘
## The maximum delay in milliseconds for a single mouse button click when used in a Function.
ClickTime 300
## When a mouse is clicked and held, MoveThreshold is the smallest movement (in pixels)
## before fvwm can recognize the mouse action as a drag rather than a click.
## MoveThreshold 3
## Prevent the cursor from being changed by the execution of certain commands
BusyCursor * False
## Ignore the Numlock key. FAQ #5.5
IgnoreModifiers L25
## Mouse cursor styles
CursorStyle ROOT left_ptr
CursorStyle TITLE left_ptr
CursorStyle DEFAULT left_ptr
CursorStyle SYS left_ptr
CursorStyle MENU left_ptr
## ┌───────────────────┐
## │ WINDOW MOVEMENT │
## └───────────────────┘
## The maximum size window with which to use opaque movement.
OpaqueMoveSize unlimited
## Instruct fvwm to resize windows with their contents still visible.
Style * ResizeOpaque
## SnapAttraction affects interactive window movement. It lets nearby windows snap together,
## or snap to edges so that they are easier to align on your desktop.
#Style * SnapAttraction 3 Windows ScreenWindows
## Never hide the position/size of window that is being interactively moved or resized.
HideGeometryWindow
## The number of steps of animation for when a window is shaded.
Style * WindowShadeSteps 30
# SetAnimation
## ┌────────────────────────┐
## │ FOCUS + RAISE POLICY │
## └────────────────────────┘
## Similar focus behavior to xfce and openbox.
Style * ClickToFocus, FPSortWindowlistByFocus
## When a window is raised/lowered, all its transients are raised/lowered too.
Style * RaiseTransient, LowerTransient, StackTransientParent
## Use EWMH hints and respect EWMH hints which change the window layer.
Style * EWMHUseStackingOrderHints
## Prevent new windows from stealing focus away from the current desktop.
## From : http://fvwmwiki.xteddy.org/Tips/FocusStealing/
Style * SkipMapping
DestroyFunc EWMHActivateWindowFunc
AddToFunc EWMHActivateWindowFunc I nop
## Instruct fvwm to ignore urgency hints.
DestroyFunc UrgencyFunc
AddToFunc UrgencyFunc I nop
## DefaultLayers (bottom|put|top)
## ┌────────────────────┐
## │ PLACEMENT POLICY │
## └────────────────────┘
## Sometimes affects window placement (fvwm manpage, p2920).
Emulate Fvwm
## The default placement method.
Style * MinOverlapPercentPlacement
## Instruct fvwm to ignore program specified PPosition hints.
## This works well with most programs (man fvwm, p5565).
Style * !UsePPosition
## Icons are positioned by fvwm, not the program.
Style * !UseIconPosition
## ┌───────────────────────────┐
## │ ICON STYLES + COLORSETS │
## └───────────────────────────┘
## Icons are displayed without titles.
Style * !IconTitle
## Each icon has a border relief of thickness 1.
Style * IconBackgroundRelief +1, IconBackgroundPadding 0, IconBackgroundColorset 25
## Colorset for the icon border.
Colorset 25 fg #606F6A, bg #606F6A, hi #606F6A, sh #606F6A
## The icon placement method.
Style * IconBox 990x100+19+500, IconSize 80 80, IconGrid 120 80
## ┌────────────────┐
## │ DECOR STYLES │
## └────────────────┘
## No extra window decorations.
Style * NoDecorHint, NoFuncHint, NoOLDecor, GNOMEIgnoreHints
## Transient windows get title bar and decorations by default.
Style * DecorateTransient
## ┌──────────────────────────┐
## │ BORDER + HANDLE STYLES │
## └──────────────────────────┘
Style * BorderWidth 4, HandleWidth 4
Style URxvt* BorderWidth 2, HandleWidth 2
Style * BorderColorset 18, HilightBorderColorset 19
BorderStyle -- Flat
## Border colors - on this setup, only the bg value colors the border.
Colorset 18 fg #ffffff, bg #36403D, sh #ffffff, hi #ffffff
Colorset 19 fg #ffffff, bg #566661, sh #ffffff, hi #ffffff
## ┌──────────────────┐
## │ TITLEBAR STYLES │
## └──────────────────┘
Style * Title, TitleAtTop
#Style FvwmButtons !Title
Style URxvt TitleAtLeft
Style feh TitleAtLeft
## The titlebar height sizes itself to fit the current titlefont. Text is left-justified
TitleStyle Centered Height 0
TitleStyle Inactive (Colorset 20 -- Flat )
TitleStyle Active (Colorset 21 -- Flat )
## Colorsets for text within the titlebar.
Style * Colorset 10, HilightColorset 10
## Styling for the titlebar buttons.
## ButtonStyle All -- UseTitleStyle
## ButtonStyle All -- Flat
## Button 2, used to access the WindowsOpsMenu.
## AddButtonStyle 2 Vector 5 40x40@1 60x40@1 60x60@0 40x60@0 40x40@1
## Titlebar background color :-
## - the bg value sets the color.
## - option RootTransparent also acts on the titlebar
Colorset 20 fg #ffffff, bg #302F2C, sh #ffffff, hi #ffffff
Colorset 21 fg #ffffff, bg #302F2C, sh #ffffff, hi #ffffff
## #36312A, #26231F, #302D28, #302E2A, #302F2C
## Titlebar text + buttons - the fg value colors text within the titlebar
## - the sh and hi values colors vector buttons
#Colorset 10 fg grey55, bg #ffffff, sh grey55, hi grey55
Colorset 10 fg #808079, bg #ffffff, sh #808079, hi #808079
## ┌──────────────┐
## │ MENU STYLES │
## └──────────────┘
## The Help and F1 keys invoke a built-in menu that fvwm creates. Unwanted.
DestroyMenu MenuFvwmRoot
## The menu colorset.
## fg & bg set the colors for text and background. hi sets color for the triangle.
## sh & hi set the colors for border and separators. TiledPixmap sets the bg pixmap.
MenuStyle * MenuColorset 3
##Colorset 3 fg grey80, bg #2E3436, sh grey60, hi grey60, TiledPixmap "dark-thached--40--20--1024x600.xpm"
#Colorset 3 fg grey80, bg #2E3436, sh grey60, hi grey60, TiledPixmap "term-tile.png"
## Remove bg - unused in this setup. Keep hi and sh equal for this setup
Colorset 3 fg #75756F, sh #52615C, hi #52615C, TiledPixmap "dark-thached--40--20--1024x600.xpm"
## The menu colorset for items that are active (selected).
## fg & bg set colors for active text and background. hi sets the active triangle color.
## sh has no known affect.
MenuStyle * ActiveColorset 7
#Colorset 7 fg #2E3436, bg grey80, hi #2E3436
Colorset 7 fg #17191A, bg #999991, hi #2E3436
## Enable a hilighted foreground and background for selected menu items.
MenuStyle * ActiveFore
MenuStyle * HilightBack
## Warp the pointer to the menu title when a sub menu is opened.
MenuStyle * !TitleWarp
## Use short menu separators.
MenuStyle * SeparatorsShort
## Use solid triangles to indicate sub-menus.
MenuStyle * TrianglesSolid
## Set the offset of sub-menus relative to their parent.
MenuStyle * PopupOffset 6 100
## When a submenu item has been selected, only open up its popup menu after a short delay.
MenuStyle * PopupDelay 500
## The maximum delay (mS) allowed for fvwm to recognize two mouse clicks as a "double click".
MenuStyle * DoubleClickTime 500
## other styles
MenuStyle * PopupAsSubmenu, RemoveSubmenus, SubmenusRight, Hilight3DOff, !Animation
MenuStyle * BorderWidth 2
## Reiterate the same MenuStyles as above, but now with the "WindowList" menu.
MenuStyle WindowList MenuColorset 3
MenuStyle WindowList ActiveColorset 7
MenuStyle WindowList ActiveFore
MenuStyle WindowList HilightBack
MenuStyle WindowList SeparatorsShort
MenuStyle WindowList Hilight3DOff
MenuStyle WindowList !Animation
MenuStyle WindowList BorderWidth 1
MenuStyle WindowList SelectOnRelease Meta_L
## ┌───────────────────────────────────────────────────────────────────────────────────────┐
## │ QUICK INFO REFERENCE │
## ├─────────────────────────────────────┬─────────────────────────────────────────────────┤
## │ * Numbering of the mouse-buttons... │ * Numbering of the window-buttons... │
## │ ┌────────────┐ │ ┌───────────────────────────────┐ │
## │ │ || || || │ │ │ 1 3 5 7 9 Title 0 8 6 4 2 │ │
## │ └────────────┘ │ ├───────────────────────────────┤ │
## │ 1 2 3 │ │ │ │
## ├─────────────────────────────────────┴─────────────────────────────────────────────────┤
## │ Contexts: R = Root Window rrrrrrrrrrrrrrrrrrrrrr │
## │ W = Application Window rIrrrrFSSSSSSSSSFrrrrr │
## │ F = Frame Corners rrrrrrS13TTTT642Srrrrr │
## │ S = Frame Sides rIrrrrSwwwwwwwwwSrrrrr │
## │ T = Title Bar rrrrrrSwwwwwwwwwSrrrrr │
## │ I = Icon rIrrrrFSSSSSSSSSFrrrrr │
## │ A = Any rrrrrrrrrrrrrrrrrrrrrr │
## ├─────────────────────────────────────┬─────────────────────────────────────────────────┤
## │ Modifier keys: │ AddToFunc name [I|M|C|H|D] │
## │ ============== │ ========================== │
## │ N - no modifier (none pressed) │ "I" - immediately │
## │ A - any modifier (0 or more) │ "C" - single mouse click │
## │ S - Shift key (Shift_L) │ "D" - double mouse click │
## │ M - Meta or Alt key (Alt_L) │ "H" - mouse click hold │
## │ C - Control key (Control_L) │ "M" - mouse click move │
## │ 4 - Windows left key (Super_L) │ │
## ├─────────────────────────────────────┴─────────────────────────────────────────────────┤
## │ The keynames used are the standard X11 key names, as define in file │
## │ /usr/include/X11/keysymdef.h. But its even easier to just run "xev". │
## └───────────────────────────────────────────────────────────────────────────────────────┘
###############################################################################################
## ╔════════════════════════╗
## ║ KEY & MOUSE BINDINGS ║
## ╚════════════════════════╝
## ┌─────────────────┐
## │ MENU BINDINGS │
## └─────────────────┘
##
## ┌───────────────────────────────────────────────┬────────────────────┐
## │ Mouse/Key │ Action │
## ├───────────────────────────────────────────────┼────────────────────┤
## │ Mouse: Single Click, Button #1 (Root Window) │ Open AppMenu │
## │ Key Combo: Ctrl + Esc │ Open AppMenu │
## ├───────────────────────────────────────────────┼────────────────────┤
## │ Mouse #3: Single Click on the TitleBar │ Open WindowOpsMenu │
## │ Mouse: Single Click on Icon │ Open WindowOpsMenu │
## │ Key Combo: Alt + F8 │ Open WindowOpsMenu │
## │ Key Combo: Alt + Space │ Open WindowOpsMenu │
## ├───────────────────────────────────────────────┼────────────────────┤
## │ Mouse: Double Click, Button #1 (Root Window) │ Open FvwmMenu │
## │ Mouse: Single Click, Button #3 (Root Window) │ Open RootOpsMenu │
## │ Key Combo: Alt + Tab │ Open WindowList │
## └───────────────────────────────────────────────┴────────────────────┘
##
## AppMenu - provides quick access to standard tools like email, file manager etc.
## FvwmMenu - the main program menu. FvwmMenu is also a sub-menu of AppMenu.
## WindowOpsMenu - provides window operations for the current window.
## RootOpsMenu - provides tools to debug and modify this fvwm.
## Key binding for MainMenu.
#Key Escape A C Menu AppMenu Root c c
Key Escape A C Menu MainMenu Root c c
## Mouse bindings for MainMenu.
Mouse 1 R A MouseButtonOneF
DestroyFunc MouseButtonOneF
AddToFunc MouseButtonOneF
+ C Menu MainMenu Nop
+ H Popup MainMenu
+ D Menu MainMenu Nop
## Mouse bindings for WindowOpsMenu
#Mouse 1 T A TitleBarFunctions
Mouse 3 T A TitleBarFunctions
Mouse 3 F A Menu WindowOpsMenu Nop
Mouse 3 S A Menu WindowOpsMenu Nop
Mouse 3 I A Menu WindowOpsMenu Nop
#Mouse 1 2 N Menu WindowOpsMenu Interior 0 0
## Mouse binding for RootOpsMenu
Mouse 3 R A Menu MenuRootOpts Nop
## Key bindings for WindowOpsMenu - Alt + F8, Alt + Space
Key F8 A M Current Menu WindowOpsMenu Interior 0 0
Key space A M Current Menu WindowOpsMenu Interior 0 0
## ┌─────────────────────────────┐
## │ WINDOW OPERATION BINDINGS │
## └─────────────────────────────┘
##
## ┌───────────────────────────────────────────────┬─────────────────────────────────────┐
## │ Mouse/Key │ Action │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Key Combo: Alt + F10 │ MaximizeToggle │
## │ Key Combo: Alt + Up │ MaximizeToggle │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Alt key + Mouse Button 1, Hold+drag on Window │ Move Window │
## │ Key Combo: Alt + F7 │ Move Window │
## │ Key Combo: Alt + F6 │ Resize Window │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Key Combo: Alt + Tab │ Switch Focus (via WindowList) │
## │ Key Combo: Win + Tab │ Switch Focus (Next in SE direction) │
## │ Key Combo: Win + Shift + Tab │ Switch Focus (Next in NW direction) │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Mouse: Double Click on TitleBar │ Shade Toggle │
## │ Mouse: Roller Forward/Backward │ Shade/UnShade │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Key Combo: Alt + F9 │ Minimize (Iconify) │
## │ Mouse: Button #1, Double Click on Icon │ Restore (DeIconify) │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Key Combo: Alt + F4 │ Close Window │
## └───────────────────────────────────────────────┴─────────────────────────────────────┘
## Key bindings to Maximize/UnMaximize the current window. Alt + F10 and Alt + Up.
Key F10 A M MaximizeToggle
Key Up A M MaximizeToggle
## Drag/Move the current window.
Mouse 1 W M FuncFvwmRaiseLowerX Move
## Mouse bindings to Shade/UnShade the current window.
Mouse 4 T A WindowShade True
Mouse 5 T A WindowShade False
DestroyFunc TitleBarFunctions
AddToFunc TitleBarFunctions
+ C Focus
+ C Menu WindowOpsMenu Interior 0 0
+ D WindowShade
+ M Move
## Key bindings for window move + resize - Alt + F7, Alt + F6
Key F7 A M Current MoveWindow
Key F6 A M Current ResizeWindow
DestroyFunc MoveWindow
AddToFunc MoveWindow
+ I ThisWindow (Maximized) Break
+ I WarpToWindow 50 50
+ I Move
DestroyFunc ResizeWindow
AddToFunc ResizeWindow
+ I WarpToWindow 100 100
+ I Resize
## Binding to switch focus via WindowList menu - Alt + Tab
Key Tab A M WindowList (CurrentDesk, !Sticky, AcceptsFocus) Root c c \
NoCurrentDeskTitle, NoGeometry, CurrentAtEnd, IconifiedAtEnd, MaxLabelWidth 60
## Binding to switch focus to next window in a SE direction - Win + Tab.
Key Tab A 4 ScanForWindow South East (CurrentDesk, !Iconic, \
!Sticky, AcceptsFocus, CirculateHit) WindowListFunc
## ^^^^^^^^^^^^^^<--- Changed (ActivateWindowFunc)
## Binding to switch focus to next window in a NW direction - Win + Shift + Tab.
Key Tab A S4 ScanForWindow North West (CurrentDesk, !Iconic, \
!Sticky, AcceptsFocus, CirculateHit) WindowListFunc
## ^^^^^^^^^^^^^^<--- Changed (ActivateWindowFunc)
## Key binding for Iconify (Minimize) - Alt + F9
Key F9 A M ThisWindow (Iconifiable, !Iconic) Thumbnail
## Mouse binding for DeIconify (Restore)
Mouse 1 I A ThisWindow (Iconic) MouseDeIconify
DestroyFunc MouseDeIconify
AddToFunc MouseDeIconify
+ D Iconify False
## Close Window - Alt + F4
Key F4 A M Close
## ┌────────────────────────────────┐
## │ DESKTOP SWITCH/MOVE BINDINGS │
## └────────────────────────────────┘
##
## ┌────────────────────────────────────────┬────────────────────────────────────────────────┐
## │ Key/Mouse │ Action │
## ├────────────────────────────────────────┼────────────────────────────────────────────────┤
## │ Key Combo: Win + n │ Switch to desktop n │
## │ Key Combo: Alt + Left/Right │ Switch to Desktop on the Left/Right │
## │ Mouse Roller Forwd/Bkwd in Root Window │ Switch to Desktop on the Left/Right │
## ├────────────────────────────────────────┼────────────────────────────────────────────────┤
## │ Key Combo: Win + Shft + n │ Move Current Window to Desktop n │
## │ Key Combo: Win + Shft + Left/Right │ Move Current Window to Left/Right Desktop │ │
## └────────────────────────────────────────┴────────────────────────────────────────────────┘
## Switch to Desktop N ( Win + n, where n is a desktop num )
PipeRead ' for zz in $(seq $[infostore.desk_min] $[infostore.desk_max]) ; do \
echo "Key $zz A 4 GotoDesk 0 $zz" ; done '
## Switch Desktop to the Left/Right, ( Win + Left/Right )
Key Left A M GotoDesk -1 $[infostore.desk_min] $[infostore.desk_max]
Key Right A M GotoDesk 1 $[infostore.desk_min] $[infostore.desk_max]
## Switch Desktop to the Left/Right - Mouse wheel - Forward/Back
Mouse 4 R A GotoDesk -1 $[infostore.desk_min] $[infostore.desk_max]
Mouse 5 R A GotoDesk 1 $[infostore.desk_min] $[infostore.desk_max]
## Move to Desktop/Workspace N ( Win + Shift + m, where n is a desktop num )
PipeRead ' for zz in $(seq $[infostore.desk_min] $[infostore.desk_max]) ; do \
echo "Key $zz A S4 Current MoveToDesk 0 $zz" ; done '
## Move current window to left/right desktop, ( Win + Shift + Left/Right )
Key Right A S4 SwitchMoveDesktop 1
Key Left A S4 SwitchMoveDesktop -1
DestroyFunc SwitchMoveDesktop
AddToFunc SwitchMoveDesktop
+ I MoveToDesk $0 $[infostore.desk_min] $[infostore.desk_max]
+ I GotoDesk $0 $[infostore.desk_min] $[infostore.desk_max]
#+ I FlipFocus
## ┌──────────────────────────────────────────────────────┐
## │ MULTIMEDIA KEY BINDINGS - BRIGHTNESS, VOLUME + MPD │
## └──────────────────────────────────────────────────────┘
##
## ┌───────────────────────────────────────────────┬─────────────────────────────────────┐
## │ Mouse/Key │ Action │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ BrightnessUp Key │ Increase Brightness │
## │ BrightnessDown Key │ Decrease Brightness │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ Mute Key │ Mute Volume │
## │ RaiseVolume Key │ Increase Volume │
## │ LowerVolume Key │ Decrease Volume │
## ├───────────────────────────────────────────────┼─────────────────────────────────────┤
## │ AudioNext Key │ Next Track │
## │ AudioPrev Key │ Last Track │
## │ AudioPlay Key │ Toggle Play/Pause │
## │ AudioStop Key │ Stop │
## └───────────────────────────────────────────────┴─────────────────────────────────────┘
## Binding to mute or increase/decrease the volume, with visual notification.
## A "get volume" script :- https://github.com/ivoarch/.dotfiles/blob/master/bin/get-volume
Key XF86AudioMute A A PerlEval notify_mute ;
Key XF86AudioRaiseVolume A A PerlEval notify_volume "3%+" ;
Key XF86AudioLowerVolume A A PerlEval notify_volume "3%-" ;
## Binding to notify changes in brightness. Using Gtk2::Notify rather
## than notify-send for better results.
Key XF86MonBrightnessDown A A PerlEval notify_brightness ;
Key XF86MonBrightnessUp A A PerlEval notify_brightness ;
## Bindings to control MPD playback.
Key XF86AudioNext A A Exec mpc -q next
Key XF86AudioPrev A A Exec mpc -q prev
Key XF86AudioPlay A A Exec mpc -q toggle
Key XF86AudioStop A A Exec mpc -q stop
## ╔════════════════════════════════╗
## ║ FUNCTION/MODULE DEFINITIONS ║
## ╚════════════════════════════════╝
## ┌─────────────────────────────────────────┐
## │ FUNCTIONS USED TO SWITCH WINDOW FOCUS │
## └─────────────────────────────────────────┘
## A builtin fvwm function used by the WindowList command.
## Slightly altered here to run Layer command on Iconic windows.
DestroyFunc WindowListFunc
AddToFunc WindowListFunc
+ I ThisWindow (Iconic) Layer
+ I Iconify False
+ I FlipFocus NoWarp
+ I Raise
#+ I WarpToWindow 5p 5p <-- change
## Used by the above Win+Tab binding.
## Similar to WindowListFunc, except that the order of WindowList is preserved.
DestroyFunc ActivateWindowFunc
AddToFunc ActivateWindowFunc
+ I ThisWindow (Iconic) Layer
+ I Iconify False
+ I Focus
+ I Raise
+ I WarpToWindow 5p 5p
## ┌─────────────────────────────────────┐
## │ FUNCTIONS USED TO TOGGLE MAXIMIZE │
## └─────────────────────────────────────┘
## Using State 5 to differentiate between FullMaximized (true) or NearMaximized (false).
DestroyFunc MaximizeToggle
AddToFunc MaximizeToggle
+ I ThisWindow (!Maximized, Maximizable) NearMaximize
+ I TestRc (Match) Break
+ I ThisWindow (Maximized, !State 5) FullMaximize
+ I TestRc (Match) Break
+ I RestoreWindowSize
DestroyFunc NearMaximize
AddToFunc NearMaximize
+ I State 5 False
+ I ResizeMoveMaximize 990p 549p 50-50w 50-50w-11p
## Changed ^^^^^
DestroyFunc FullMaximize
AddToFunc FullMaximize
+ I State 5 True
+ I WindowStyle !Title, !Borders, ResizeHintOverride
+ I UpdateStyles
+ I Maximize True 100 100
+ I WindowStyle !Maximizable, FixedSize, FixedPosition
+ I UpdateStyles
DestroyFunc RestoreWindowSize
AddToFunc RestoreWindowSize
+ I State 5 False
+ I DestroyWindowStyle
+ I UpdateStyles
+ I Maximize False
+ I PerlEval my $zz = split( /\s+/, "$[*]" ) ; \
if ( $zz == 2 ) { cmd(" WindowId $[w.id] Resize $[0-] \n") } \
if ( $zz == 4 ) { cmd(" WindowId $[w.id] Resize $[0-1] \n") ; \
cmd(" WindowId $[w.id] AnimatedMove $[2-3] \n") }
## ┌───────────────────────────────────────────────────────┐
## │ FUNCTIONS+MODULE TO ICONIFY WINDOWS WITH THUMBNAILS │
## └───────────────────────────────────────────────────────┘
## Creates thumbnail icons for minimized windows, as based on fvwm FAQ #7.18.
DestroyFunc Thumbnail
AddToFunc Thumbnail
+ I Echo "Thumbnail +++: $[w.id]"
+ I ThisWindow (Shaded) Break
+ I Raise
+ I ThisWindow (Iconifiable, !Iconic) PipeRead " xwd -silent -id $[w.id] | \
convert -resize 80x -quality 0 xwd:- png:$[FVWM_USERDIR]/icon.tmp.$[w.id].png && \
echo WindowStyle IconSize `identify $[FVWM_USERDIR]/icon.tmp.$[w.id].png | \
sed -r -n \'s/^.*PNG\\s([0-9]+)x([0-9]+)\\s.*$/\\1 \\2/p\' `, \
IconOverride, Icon $[FVWM_USERDIR]/icon.tmp.$[w.id].png "
+ I Iconify
## For every window restored, this function is called by FvwmEvent. It deletes the thumbnail,
## and restores window styles. Any remaining icons on the desktop are re-ordered.
DestroyFunc DeThumbnail
AddToFunc DeThumbnail
+ I Exec rm -f $[FVWM_USERDIR]/icon.tmp.$[w.id].png
+ I DestroyWindowStyle
+ I WindowListFunc
+ I All (CurrentPage, Iconic) PlaceAgain Icon
## An FvwmEvent module that always calls function DeThumbnail when a window is restored.
*EventDeIconify: deiconify DeThumbnail
AddToFunc StartFunction I Module FvwmEvent EventDeIconify
## ┌───────────────────────────────────────────────────────────────────────────┐
## │ FUNCTIONS+MODULE THAT REFOCUSES THE LAST-FOCUSED WINDOW ON EACH DESKTOP │
## └───────────────────────────────────────────────────────────────────────────┘
## Functions to remember the last focused window for each desktop. Such that when the desktop
## is switched, the correct window then receives focus. A newly opened window automatically
## become the last focused window on its desktop. The functions here are run by an FvwmEvent
## module whenever windows are opened/closed.
## This function is run by FvwmEvent when a new window is added.
## States 2 & 3 are used to label newly-added windows, and last-focused windows.
## State 2 - Made True for the last focused but not Iconic window on its desktop.
## State 3 - Made True for any newly added windows.
DestroyFunc NewWindowF
AddToFunc NewWindowF
+ I ThisWindow (CurrentDesk ) Break
+ I ThisWindow (AcceptsFocus) Raise
+ I ThisWindow (AcceptsFocus) State 3 True
+ I ThisWindow (AcceptsFocus) FlipFocus NoWarp
+ I NewDeskFocusF
DestroyFunc NewDeskFocusF
AddToFunc NewDeskFocusF
+ I Next ( CurrentDesk, State 3 ) FlipFocus NoWarp
+ I TestRc (Match) Break
+ I Next ( CurrentDesk, State 2 ) FlipFocus NoWarp
+ I TestRc (Match) Break
+ I Prev ( CurrentDesk, Focused, !Iconic ) FlipFocus NoWarp
+ I TestRc (Match) Break
+ I Prev ( CurrentDesk, !Focused, !Iconic, !FvwmButtons, !stalonetray ) FlipFocus NoWarp # CHANGE
+ I TestRc (Match) Break
DestroyFunc MarkWindowAsActiveF
AddToFunc MarkWindowAsActiveF
+ I Current (!Iconic, CurrentDesk) All (CurrentDesk, !Focused) State 2 False
+ I Current (!Iconic, CurrentDesk) All (CurrentDesk) State 3 False
+ I Current (!Iconic, CurrentDesk) State 2 True
+ I All ( "FButtonsTray|FvwmButtons|stalonetray" ) State 2 False
AddToFunc StartFunction I Module FvwmEvent TrackFocus
DestroyModuleConfig TrackFocus: *
*TrackFocus: Cmd Function
*TrackFocus: new_desk NewDeskFocusF
*TrackFocus: destroy_window NewDeskFocusF
*TrackFocus: focus_change MarkWindowAsActiveF
*TrackFocus: add_window NewWindowF
#--------------------------------------------------------------------------#
## ╔══════════════════════════════╗
## ║ OTHER MODULE DEFINITIONS ║
## ╚══════════════════════════════╝
## Spawn both server and client to provide a FvwmCommand shell terminal.
AddToFunc StartFunction I Module FvwmCommandS
AddToFunc StartFunction I Module FvwmConsole -terminal urxvt -g 60x20 -fg grey70 \
-fn $[fvwm_bitmap_normal_font]
# -geometry 60x18 -name UrxvtFvwmConsole
## Animate window iconify and deiconify actions with an FvwmAnimate module.
AddToFunc StartFunction I Module FvwmAnimate
DestroyModuleConfig FvwmAnimate: *
*FvwmAnimate: Effect Frame
*FvwmAnimate: Iterations 32
*FvwmAnimate: Width 2
*FvwmAnimate: Twist 0.500000
*FvwmAnimate: Delay 10
## Spawn a FvwmPerl module, such that the PerlEval function is now available.
## Also preload with my own custom perl module.
DestroyFunc StartPerlModule
AddToFunc StartPerlModule
+ I KillModule FvwmPerl
+ I ModuleSynchronous FvwmPerl --export PerlEval
+ I PerlEval use lib `fvwm-perllib dir` ;
+ I PerlEval use lib "$[FVWM_USERDIR]" ;
+ I PerlEval use MyPerl::Notify qw( notify_volume notify_mute notify_brightness ) ;
#+ I PerlEval use MyPerl::Notify qw( notify_volume notify_mute notify_brightness testsub ) ;
AddToFunc StartFunction I StartPerlModule
#### FVWMIDENT
Style FvwmIdent BorderColorset 30, BorderWidth 2, HandleWidth 2, WindowListSkip
DestroyModuleConfig FvwmIdent: *
*FvwmIdent: Font $[fvwm_bitmap_normal_font]
#*FvwmIdent: Font -gohu-gohufont-medium-r-normal--11-*-iso8859-1
*FvwmIdent: Colorset 3
#### FvwmEvent module to prevent mplayer from switching to the top layer.
DestroyModuleConfig FE-max: *
*FE-max: Cmd Function
*FE-max: configure_window SomeFunc
DestroyFunc SomeFunc
AddToFunc SomeFunc
+ I All (Maximized, CurrentPage) ThisWindow ("mplayer2") Layer 0 4
AddToFunc StartFunction I Module FvwmEvent FE-max
#-------------------------------------------------------------#
Key C A 4 Exec xfce4-popup-clipman
Key G A 4 Exec gmrun
Key F2 A M Exec gmrun
## Win-S toggles the dzen status bar - hidden or visible.
Key S A 4 ToggleDzenStatus
DestroyFunc ToggleDzenStatus
AddToFunc ToggleDzenStatus
+ I Test (F /dev/shm/conky-perl-dzen/halt) Exec rm /dev/shm/conky-perl-dzen/halt
+ I TestRc (Match) Break
+ I Exec touch /dev/shm/conky-perl-dzen/halt
Key R A 4 Module FvwmRearrange -u -flaty -desk -resize -cascade -animate \
-incx 40p -incy 55p 10p 10p 900p 450p
DestroyFunc NearMaxFunc
AddToFunc NearMaxFunc
+ I ThisWindow ResizeMove frame 986p 543p 19p 19p
############################
## NCMPCPP MUSIC PLAYER ##
############################
InfoStoreAdd Ncmpcpp_desk 7
InfoStoreAdd Ncmpcpp_x 397
DestroyStyle Ncmpcpp
Style Ncmpcpp StartsOnDesk $[infostore.Ncmpcpp_desk], BorderWidth 2, HandleWidth 2, \
PositionPlacement $[infostore.Ncmpcpp_x]p 240p, InitialMapCommand StartNcmpcpp
DestroyFunc StartNcmpcpp
AddToFunc StartNcmpcpp
+ I RestoreWindowSize 74c 16c
+ I Move $[infostore.Ncmpcpp_x]p 240p
DestroyStyle Spectrum
Style Spectrum StartsOnDesk $[infostore.Ncmpcpp_desk], StaysOnBottom, WindowListSkip, \
NeverFocus, BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement $[infostore.Ncmpcpp_x]p 482p, InitialMapCommand StartSpectrum
DestroyFunc StartSpectrum
AddToFunc StartSpectrum
+ I RestoreWindowSize 148c 14c
+ I Move $[infostore.Ncmpcpp_x]p 482p
DestroyStyle *mp3coverart*
Style *mp3coverart* StartsOnDesk $[infostore.Ncmpcpp_desk], !Title, StaysOnTop, \
BorderColorset 30, NeverFocus, !Borders, !Handles, PositionPlacement 806p 212p, \
InitialMapCommand Move 809p 242p
################################
## TRANSMISSION + HISTOGRAM ##
################################
DestroyFunc StartTransmission
AddToFunc StartTransmission
+ I Exec exec sh -c 'pgrep transmission-d || transmission-daemon'
+ I Module FvwmButtons sar-rx
+ I Schedule 1000 Exec exec urxvt \
-T Trcli -g 74x16 \
-fg "#808079" \
-bg "grey10" \
-fn "$[fvwm_bitmap_bold_font]" \
-fb "$[fvwm_bitmap_bold_font]" \
-pixmap "$[fvwm_term_tile];style=tiled" \
--color0 "#2E2E2B" --color8 "#2E2E2B" \
--color1 "#B23636" --color9 "#B23636" \
--color3 "#80784C" --color11 "#80784C" \
--color4 "#33424C" --color12 "#33424C" \
--color6 "#32453F" --color14 "#32453F" \
--color7 "#878780" --color15 "#878780" \
-e transmission-remote-cli
DestroyStyle Trcli
Style Trcli StartsOnPage 6, PositionPlacement 396p 207p, InitialMapCommand Move 396p 207p
DestroyStyle sar-rx
Style sar-rx StartsOnDesk 6, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
FixedSize, !Maximizable, TitleAtLeft, \
Font $[fvwm_bitmap_bold_font], \
PositionPlacement 396p 450p, InitialMapCommand Move 396p 450p
DestroyModuleConfig sar-rx: *
*sar-rx: Geometry 592x114
*sar-rx: BoxSize fixed
*sar-rx: Columns 592
*sar-rx: Rows 114
*sar-rx: Padding 0 0
*sar-rx: Frame 0
*sar-rx: Font None
*sar-rx: (40x114, Padding 0 0, Swallow (NoOld, Kill, NoHints, SwallowNew, Close) \
"axis" 'Exec exec feh -^ axis /home/nostromo/temp-histo-sar/500KBps.png ' )
*sar-rx: (552x114, Padding 0 0, Swallow (NoOld, Kill, NoHints, SwallowNew, Close) \
"sarrx" 'Exec exec $[fvwm_scripts]/sar-rx.pl ' )
#########################################
#### APPLICATION SPECIFIC STYLES ####
#########################################
DestroyStyle zenity
Style zenity !Borders, !Handles, !Title, PositionPlacement Center
DestroyStyle pinentry-gtk-2
Style pinentry-gtk-2 PositionPlacement Center
Style stalonetray !Title, !Borders, !Handles, WindowListSkip
Style Screenruler !Title, !Borders, !Handles, StaysOnTop, WindowListSkip
Style Screenruler SnapGrid 4 4
Style gmrun !Title, PositionPlacement Center
Style cryptkeeper* !Title, PositionPlacement Center
Style Yad PositionPlacement Center
Style fpm2 PositionPlacement Center
Style Xfce4-clipman-settings PositionPlacement Center
Style xzoom* TitleAtLeft
# Colorset used for the border on status windows
Colorset 30 fg #303344, bg #677A75
#Colorset 31 fg #36403D, bg #36403D
Colorset 31 fg #52615C, bg #52615C
DestroyStyle System
Style System StartsOnDesk 7, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 18p, InitialMapCommand Move 20p 18p
DestroyStyle Disks
Style Disks StartsOnDesk 7, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 138p, InitialMapCommand Move 20p 138p
DestroyStyle Processes
Style Processes StartsOnDesk 7, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 326p, InitialMapCommand Move 20p 326p
DestroyStyle Flexget
Style Flexget StartsOnDesk 6, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 18p, InitialMapCommand Move 20p 18p
DestroyStyle Television
Style Television StartsOnDesk 6, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 138p, InitialMapCommand Move 20p 138p
DestroyStyle Movies
Style Movies StartsOnDesk 6, StaysOnBottom, WindowListSkip, NeverFocus, \
BorderColorset 31, BorderWidth 2, HandleWidth 2, \
PositionPlacement 20p 340p, InitialMapCommand Move 20p 340p
DestroyStyle FvwmConsole
Style FvwmConsole StartsOnDesk 1, BorderWidth 2, HandleWidth 2, \
BorderColorset 30, TitleAtLeft, PositionPlacement Center, \
InitialMapCommand RestoreWindowSize 54c 16c 50-50w 50-50w
Style tmux1 !Title, StartsOnPage 4, InitialMapCommand NearMaximize
#############################################################################
## To "Read" config files from folder $0.
DestroyFunc ReadFolder
AddToFunc ReadFolder I PipeRead ' \
for i in "$0/"[0-9][0-9][0-9]* ; do \
[ -f "$i" ] && echo Read "$i" ; done '
Echo ReadFolder "$[FVWM_USERDIR]/Menu-Defs"
ReadFolder "$[FVWM_USERDIR]/Menu-Defs"
## An imagemagick command to calculate the average RGB color of an image :-
## $ convert "dark-digital-texture--1024x768.jpg" -resize 1x1 txt:
## Also : http://mkweb.bcgsc.ca/color_summarizer/?analyze
SetEnv fvwm_scripts $[FVWM_USERDIR]/scripts
#########################################
# THE START-FUNCTION - MAIN DECLARATION #
#########################################
AddToFunc StartFunction
+ I Echo "START-FUNCTION - Main Declarations"
## The root wallpaper.
+ I Exec fvwm-root --retain-pixmap $[fvwm_wallpapers]/dark-digital-texture--1024x768.png
## Delete any old thumbnail icon images.
+ I Exec exec rm $[FVWM_USERDIR]/icon.tmp.* 2>/dev/null
## The main urxvt terminal with a tmux session.
+ I Exec exec sh -c " $HOME/bin/tmuxer_1.sh tmux1 && urxvt -title tmux1 -e tmux attach -t tmux1 "
## The dzen status bar.
+ I Exec exec $[fvwm_scripts]/dzen-status.pl
## The notifications panel
#+ I Exec exec tint2
+ I Exec exec stalonetray --geometry 4x1+500+-25
## The clipboard manager
+ I Exec exec xfce4-clipman
## Start the urxvt daemon
+ I Exec exec urxvtd -q -o -f
## The window compositor. (xinitrc ?) Check the path to compton with 'which' ???
## Uses config file ~/.config/compton.conf
+ I Exec exec compton -b
+ I Exec exec sh -c " eval $(gnome-keyring-daemon -s --components=pkcs11,secrets,ssh,gpg) "
## Disable the synaptic touchpad. (xinitrc ?)
+ I Exec exec synclient touchpadoff=1
## Empty the system trash. It should be empty at startup anyways. apt-get install trash-cli.
+ I Exec exec trash-empty
## Volume mixer for the notification tray.
#+ I Exec exec pnmixer
## Begin on desktop 6.
+ I GotoDesk 0 6
## Start the MPD daemon
+ I Exec exec mpd 2>/dev/null
## The MPD music client
+ I Exec exec $[fvwm_scripts]/ncmpcpp-helper.pl
+ I Exec exec $[fvwm_scripts]/system-info.pl
+ I Exec exec $[fvwm_scripts]/disk-usage.pl
+ I Exec exec $[fvwm_scripts]/top-processes.pl
## The transmission torrent daemon and client.
+ I StartTransmission
+ I Exec exec $[fvwm_scripts]/flexget-torrents-added.pl
+ I Exec exec $[fvwm_scripts]/flexget-premieres+docos.pl
+ I Exec exec $[fvwm_scripts]/flexget-movies.pl
#################
## MAIN MENU ##
#################
DestroyMenu MainMenu
AddToMenu MainMenu
+ DynamicPopupAction Function MainMenuFunc
DestroyFunc MainMenuFunc
AddToFunc MainMenuFunc
+ I DestroyMenu PassMenu
+ I DestroyMenu recreate MainMenu
+ I Test (F $[HOME]/002-Private/fvwm) Read $[HOME]/002-Private/fvwm/MenuPasswords
+ I AddToMenu MainMenu " &term " Exec exec urxvt -fn $[fvwm_bitmap_normal_font] -fg grey70
+ I AddToMenu MainMenu " &web " Exec exec iceweasel
+ I None (Thunderbird) AddToMenu MainMenu " &email" \
Exec $[fvwm_scripts]/launch-thunderbird.sh
+ I Test (F $[HOME]/002-Private/fvwm) \
AddToMenu MainMenu " &pass " Popup PassMenu
+ I AddToMenu MainMenu "" Nop
+ I AddToMenu MainMenu " &config" Popup "FvwmMenu-Settings"
+ I AddToMenu MainMenu " &utils " Popup "FvwmMenu-Accessories"
+ I AddToMenu MainMenu " &dev " Popup "FvwmMenu-Development"
+ I AddToMenu MainMenu " &graph " Popup "FvwmMenu-Graphics"
+ I AddToMenu MainMenu " &net " Popup "FvwmMenu-Network"
+ I AddToMenu MainMenu " &media " Popup "FvwmMenu-Multimedia"
+ I AddToMenu MainMenu " &office" Popup "FvwmMenu-Office"
+ I AddToMenu MainMenu " &system" Popup "FvwmMenu-System"
+ I AddToMenu MainMenu "" Nop
+ I AddToMenu MainMenu " e&xit " Popup ExitMenu
DestroyMenu ExitMenu
AddToMenu ExitMenu
+ " &shutdown " Exec sudo poweroff
+ " &reboot " Exec sudo reboot
## FvwmMenu-* popups menus below generated by : $ fvwm-menu-desktop | less
DestroyMenu "FvwmMenu-Accessories"
AddToMenu "FvwmMenu-Accessories"
+ "Bulk Rename" Exec /usr/lib/i386-linux-gnu/Thunar/ThunarBulkRename
+ "Catfish" Exec catfish
+ "Gucharmap" Exec gucharmap
+ "Figaro" Exec fpm2
+ "GVim" Exec gvim -f
+ "Galculator" Exec galculator
+ "Leafpad" Exec leafpad
+ "Urxvt" Exec urxvt
+ "Sakura" Exec sakura
+ "ScreenRuler" Exec screenruler
+ "Task Manager" Exec xfce4-taskmanager
+ "Thunar" Exec thunar
+ "XTerm" Exec xterm
+ "colorname" Exec /usr/bin/colorname
DestroyMenu "FvwmMenu-Development"
AddToMenu "FvwmMenu-Development"
+ "Geany" Exec geany
+ "PyCrust" Exec /usr/bin/pycrust
+ "XRCed" Exec /usr/bin/xrced
## Add in acroread
DestroyMenu "FvwmMenu-Graphics"
AddToMenu "FvwmMenu-Graphics"
+ "Evince" Exec evince
+ "Gcolor2" Exec gcolor2
+ "Eye of Gnome" Exec eog
+ "ImageMagick" Exec /usr/bin/display.im6
+ "Mirage" Exec mirage
+ "Viewnior" Exec viewnior
+ "colorname" Exec /usr/bin/colorname
DestroyMenu "FvwmMenu-Network"
AddToMenu "FvwmMenu-Network"
+ "Iceweasel" Exec iceweasel
+ "Transmission" Exec transmission-gtk
+ "gFTP" Exec gftp-gtk
DestroyMenu "FvwmMenu-Multimedia"
AddToMenu "FvwmMenu-Multimedia"
+ "Xfce-mixer" Exec xfce4-mixer
+ "PNMixer" Exec pnmixer
+ "Pavucontrol" Exec pavucontrol
+ "VLC" Exec /usr/bin/vlc --started-from-file
+ "WinFF" Exec winff
## Add in acroread
DestroyMenu "FvwmMenu-Office"
AddToMenu "FvwmMenu-Office"
+ "Evince" Exec evince
+ "qpdfview" Exec qpdfview --unique
DestroyMenu "FvwmMenu-Settings"
AddToMenu "FvwmMenu-Settings"
+ "ARandR" Exec arandr
+ "Flash" Exec flash-player-properties
+ "LxAppearance" Exec lxappearance
+ "Thunar Settings" Exec thunar-settings
+ "Thunar Volman" Exec thunar-volman-settings
DestroyMenu "FvwmMenu-System"
AddToMenu "FvwmMenu-System"
+ "GDebi" Exec gdebi-gtk
+ "GParted" Exec gparted-pkexec
+ "Gigolo" Exec gigolo
+ "Htop" Exec xterm -e htop
+ "Task Man" Exec xfce4-taskmanager
############################################################################
#######################
## WINDOW OPS MENU ##
#######################
DestroyMenu WindowOpsMenu
AddToMenu WindowOpsMenu
+ DynamicPopupAction Function WindowOpsMenuF
DestroyFunc WindowOpsMenuF
AddToFunc WindowOpsMenuF
+ I DestroyMenu recreate WindowOpsMenu ### "Pick" seems redundant here. ###
+ I ThisWindow ( Iconic) AddToMenu WindowOpsMenu " WinOps " Title
+ I ThisWindow (!Iconic) AddToMenu WindowOpsMenu " WinOps " Title
+ I ThisWindow (!Iconic, !Maximized) AddToMenu WindowOpsMenu " Move " Pick Move
+ I ThisWindow (!Iconic, !Maximized, Maximizable) \
AddToMenu WindowOpsMenu " Maximize" FullMaximize
+ I ThisWindow (!Iconic, Maximized) AddToMenu WindowOpsMenu " Restore " RestoreWindowSize
+ I ThisWindow (!Iconic) AddToMenu WindowOpsMenu " Iconify " Pick ThumbnailToggle
+ I ThisWindow ( Iconic) AddToMenu WindowOpsMenu " (De)Iconify " Pick DeThumbnail
+ I ThisWindow (!Iconic,!Sticky) AddToMenu WindowOpsMenu " Sticky " Pick Stick
+ I ThisWindow (!Iconic, Sticky) AddToMenu WindowOpsMenu " (Un)Sticky" Pick Stick
+ I ThisWindow (!Iconic,!State 9) AddToMenu WindowOpsMenu " Titled" AddTitleBarF
+ I ThisWindow (!Iconic, State 9) AddToMenu WindowOpsMenu " (Un)Titled" RemoveTitleBarF
+ I ThisWindow (!Iconic) AddToMenu WindowOpsMenu " Layer " Popup LayerMenu
+ I ThisWindow (!Iconic) AddToMenu WindowOpsMenu " Send To " Popup MoveToDeskM
+ I ThisWindow (!Iconic) AddToMenu WindowOpsMenu "" Nop
+ I AddToMenu WindowOpsMenu " Close " Pick Close
## Would work better if I could use PerlEval to find a clever way to test if
## the Titlebar is on or not. Preferable to using "State 9" methinks.
DestroyFunc AddTitleBarF
AddToFunc AddTitleBarF
+ I ThisWindow ( !State 9 ) WindowStyle Title
+ I ThisWindow ( !State 9 ) State 9 True
DestroyFunc RemoveTitleBarF
AddToFunc RemoveTitleBarF
+ I ThisWindow ( State 9 ) WindowStyle !Title
+ I ThisWindow ( State 9 ) State 9 False
+ I TestRc Break
DestroyMenu MenuCascade
AddToMenu MenuCascade
+ "&3: 900x450" Module FvwmRearrange -u -flaty -desk -resize -cascade -animate -incx 40p -incy 55p 10p 10p 900p 450p
+ "&4: 860x395" Module FvwmRearrange -u -flaty -desk -resize -cascade -animate -incx 40p -incy 55p 10p 10p 860p 395p
+ "&5: 820x340" Module FvwmRearrange -u -flaty -desk -resize -cascade -animate -incx 40p -incy 55p 10p 10p 820p 340p
DestroyMenu MoveToDeskM
PipeRead ' for zz in $(seq $[infostore.desk_min] $[infostore.desk_max]) ; do \
echo "AddToMenu MoveToDeskM Desk\\ $zz Pick MoveToDesk 0 $zz \n" ; done '
DestroyMenu LayerMenu
AddToMenu LayerMenu
+ " Top " WindowStyle StaysOnTop
+ " Default " WindowStyle StaysPut
+ " Bottom " WindowStyle StaysOnBottom
############################################################################
#####################
## ROOT OPS MENU ##
#####################
DestroyMenu MenuRootOpts
AddToMenu MenuRootOpts
+ " RootOps " Title
+ " &Identify" Module FvwmIdent
+ " &Console " Module FvwmConsole -terminal urxvt -g 60x20 -fg grey70 -fn $[fvwm_bitmap_normal_font]
+ " &Modules" Popup "FvwmModules"
+ " &Animate" Popup "MenuFvwmAnimate"
+ " &Xkill " Exec exec xkill
#+ " &Cascade " Popup "MenuCascade"
DestroyMenu "FvwmModules"
AddToMenu "FvwmModules" "FVWM" Title Top
+ "Fvwm&Auto" Module FvwmAuto 300 raise lower
+ "Fvwm&Backer" Module FvwmBacker
+ "FvwmBa&nner" Module FvwmBanner
+ "FvwmB&uttons" Module FvwmButtons
+ "FvwmButtons (&Debian)" Module FvwmButtons DebianFvwmButtons
+ "Fvwm&CommandS" Module FvwmCommandS
+ "FvwmC&onsole" Module FvwmConsole -terminal urxvt -geometry 60x18 -name UrxvtFvwmConsole
+ "FvwmCpp" Module FvwmCpp
+ "FvwmDebug" Module FvwmDebug
+ "FvwmDragWell" Module FvwmDragWell
+ "Fvwm&Event" Module FvwmEvent
+ "FvwmForm" Module FvwmForm
+ "Fvwm&Gtk" Module FvwmGtk
+ "Fvwm&IconBox" Module FvwmIconBox
+ "FvwmIconMan" Module FvwmIconMan
+ "FvwmM&4" Module FvwmM4
+ "Fvwm&Pager" Module FvwmPager 0 6
+ "FvwmPro&xy" Module FvwmProxy
+ "Fvwm&Rearrange (cascade)" Module FvwmRearrange -cascade
+ "FvwmRearrange (&horiz)" Module FvwmRearrange -tile -h
+ "F&vwmRearrange (vert)" Module FvwmRearrange -tile
+ "Fvwm&Save" Module FvwmSave
+ "FvwmSaveDesk" Module FvwmSaveDesk
+ "FvwmScript" Module FvwmScript
+ "FvwmScroll" Module FvwmScroll
+ "Fvwm&Talk" Module FvwmTalk
+ "FvwmTas&kBar" Module FvwmTaskBar
+ "FvwmTheme" Module FvwmTheme
+ "FvwmTile" Module FvwmTile
+ "Fvwm&Wharf" Module FvwmWharf
+ "FvwmWindowMenu" Module FvwmWindowMenu
+ "FvwmWin&List" Module FvwmWinList
#####################################################################################
## 9 perl scripts pasted into one file. #
#####################################################################################
## 1. dzen-status.pl #
#####################################################################################
#!/usr/bin/perl
## A perl status script that pipes into dzen. The script creates its own xbm icons. And
## internet stats are displayed for wlan0. Also depends on xdotool, wpasupplicant, conky.
use strict ;
use warnings ;
use v5.14 ;
use Time::HiRes ;
use Fcntl ':flock' ;
########################
## CONFIG VARS etc. ##
########################
## The temporary work folder - tmpfs.
my $wrkdir = "/dev/shm/conky-perl-dzen" ;
## The folder in which xbm icons for the cpu graph are stored.
my $xbmdir = "$wrkdir/xbm-icons" ;
## BASIC COLOR SCHEME - the color names come from /etc/X11/rgb.txt.
#my $color_black = "gray3" ; # the default background color
#my $color_black = "#111114" ; # the default background color
my $color_black = "#0D0D0D" ; # the default background color
#my $color_blackish = "#212229" ;
my $color_blackish = "#202024" ;
#my $color_grey = "#383A45" ;
my $color_grey = "#454541" ;
my $color_white = "#61615C" ; # the default foreground color
my $color_hiwhite = "#808079" ;
#my $color_icon = "SteelBlue4" ;
my $color_icon = "#5C6873" ;
# #5C6873
## Font & geometry for dzen.
my $dzen_pos_y = 584 ;
my $dzen_pos_x = 0 ;
my $dzen_height = 16 ;
my $dzen_width = 1024 ;
my $bitmap_font = "-gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1" ;
## Maximum workspace index. If you have 7 workspaces, then set this to 6.
my $wksp_min = 1 ;
my $wksp_max = 7 ;
################
#### MAIN ####
################
## CREATE A WORKING-FOLDER - tmpfs in /dev/shm. The lockfile ensures just one
## running instance of this script.
my $lockfile = $wrkdir."/lockf" ;
unless (-e $wrkdir) { mkdir $wrkdir || die "Cannot mkdir $wrkdir." }
unless (-e $xbmdir) { mkdir $xbmdir || die "Cannot mkdir $xbmdir." }
open(MYFILE, ">>$lockfile") || die "Cannot open lockfile" ;
flock(MYFILE, 6 ) || die "Is conky-perl-dzen already running? Flock failed." ;
chdir $wrkdir || die "Unable to chdir to $wrkdir" ;
unlink "stop" ;
unlink "halt" ;
say STDOUT $wrkdir ;
## MAKE XBM ICONS TO USE LATER as labels and to display cpu_graphs.
my ( $cpuicon, $wifiicon, $clockicon, $dwnicon, $upicon, $memicon, $volicon ) = ("") x 7 ;
mk_xbm_icons() ;
mk_cpugraph_icons($xbmdir) ;
## START/OPEN THE DZEN PROCESS
my $dzen_cmd = " | dzen2 -x $dzen_pos_x -y $dzen_pos_y -h $dzen_height -tw $dzen_width " ;
$dzen_cmd = $dzen_cmd." -bg \\$color_black -ta l -fn $bitmap_font " ;
open(DZEN, $dzen_cmd) || die "DZEN failed.\n" ;
## Set the default buffer to output DZEN and to "always flush".
select(DZEN) ;
$| = 1;
## START/OPEN THE CONKY PROCESS - but heredoc the conky config file first.
mk_conkyrc() ;
open(CONKY, "conky -c conkyrc 2>/dev/null | ") || die "CONKY failed. \n" ;
## WORKSPACE INDICATOR - an indicator is stored in this array for each wrkspce.
my @dsktp = () ;
foreach my $num ($wksp_min..$wksp_max) {
my $d = "-" ;
my $m = ($num == $wksp_min) ? $wksp_max : $num-1 ;
my $n = ($num == $wksp_max) ? $wksp_min : $num+1 ;
$dsktp[$num] = "^fg($color_white)".$d.$m.$d.$d."^bg($color_hiwhite)^fg($color_black)" ;
$dsktp[$num] .= $num."^bg()^fg($color_white)".$d.$d.$n.$d ;
}
## Two arrays for two cpus, to store the cpu usage for the last 16 seconds. Start with zeros.
my @cpu_data1 = (0) x 16 ;
my @cpu_data2 = (0) x 16 ;
## Scalars used later to store stats from conky.
my ( $cpu1, $cpu2, $memx, $sdax, $dwnx, $upx, $vol ) = (0) x 7 ;
## An array of spacer vars of varying lengths - used below for nicer formatting.
my @s = () ; foreach my $i (0..9) { $s[$i] = " " x $i }
##################
## MAIN LOOP ##
##################
while (<CONKY>) {
## obtain raw system stats from conky.
chop ; ( $cpu1, $cpu2, $memx, $sdax, $dwnx, $upx, $vol ) = split ;
## Update the cpu_graph arrays with new data
pop @cpu_data1 ;
pop @cpu_data2 ;
unshift(@cpu_data1, cpu_calc($cpu1) ) ;
unshift(@cpu_data2, cpu_calc($cpu2) ) ;
## From the arrays, obtain cpu_graphs for cpu1 & cpu2.
my $cpu_graph1 = sprintf("%3d%%", $cpu1)."^fg($color_grey) " ;
$cpu_graph1 .= "^i(".$xbmdir."/".join("", @cpu_data1[0..3]).".xbm)" ;
$cpu_graph1 .= "^i(".$xbmdir."/".join("", @cpu_data1[4..7]).".xbm)" ;
$cpu_graph1 .= "^i(".$xbmdir."/".join("", @cpu_data1[8..11]).".xbm)" ;
$cpu_graph1 .= "^i(".$xbmdir."/".join("", @cpu_data1[12..15]).".xbm)" ;
$cpu_graph1 .= "^fg($color_white)" ;
my $cpu_graph2 = sprintf("%3d%%", $cpu2)."^fg($color_grey) " ;
$cpu_graph2 .= "^i(".$xbmdir."/".join("", @cpu_data2[0..3]).".xbm)" ;
$cpu_graph2 .= "^i(".$xbmdir."/".join("", @cpu_data2[4..7]).".xbm)" ;
$cpu_graph2 .= "^i(".$xbmdir."/".join("", @cpu_data2[8..11]).".xbm)" ;
$cpu_graph2 .= "^i(".$xbmdir."/".join("", @cpu_data2[12..15]).".xbm)" ;
## obtain the memory used indicator.
my $mem_used = sprintf("%4s/1Gb" , $memx) ;
## obtain the download speed indicator.
my $dwnspd = ($dwnx < 1000) ?
sprintf("%4dkB/s", $dwnx) :
sprintf("%4.2fMB/s", $dwnx/1000) ;
## obtain the upload speed indicator.
my $upspd = ($upx < 1000) ?
sprintf("%4dkB/s", $upx) :
sprintf("%4.2fMB/s", $upx/1000) ;
## obtain the wifi signal strength indicator - depends on wpasupplicant.
my $wifidbm = readpipe("timeout .1 /sbin/wpa_cli signal_poll 2>/dev/null" ) ;
$wifidbm =~ s/^.+RSSI[=][-]([0-9]+).+$/-$1dBm/s ;
$wifidbm = " 0dBm" if ($wifidbm !~ /^-[0-9]+dBm$/) ;
## obtain the day, month and time indicator.
my @mnths = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my ( $sec, $min, $hour, $mday, $mon, $deleteme ) = localtime();
my $spcr = "" ; $spcr = " " if ($mday < 10) ;
my $cln = ":" ;
my $time_osd = sprintf("%s %s %s$cln%s$cln%s%s",
$mday, $mnths[$mon], sprintf("%02d", $hour),
sprintf("%02d", $min), sprintf("%02d", $sec), $spcr ) ;
## join the various icons and indicator, with spacers in between.
my $z = $cpuicon.$s[2].$cpu_graph1.$s[2].$cpu_graph2 ;
$z .= $s[3].$memicon.$s[3].$mem_used ;
$z .= $s[3].$dwnicon.$s[2].$dwnspd ;
$z .= $s[3].$upicon.$s[2].$upspd ;
$z .= $s[3].$wifiicon.$s[2].$wifidbm ;
$z .= $s[3].$clockicon.$s[3].$time_osd ;
## A "stop" file in the current folder is an external request to kill the script.
die if (-e "stop") ;
## This sub-loop responds to quick changes in workspace by updating every 0.2 sec.
my $dtp_old = 100 ;
for (1..4) {
## A "halt" file in the current folder is an external request to pause the script.
if (-e "halt") {
close DZEN ;
close CONKY ;
Time::HiRes::sleep(0.1) while (-e "halt") ;
open(DZEN, $dzen_cmd) || die "DZEN failed.\n" ;
open(CONKY, "conky -c conkyrc 2>/dev/null | ") || die "CONKY failed. \n" ;
}
# find the workspace num, print its indicator, followed by the other defined indicators.
my $dtp = readpipe("xdotool get_desktop") ; chomp $dtp ;
say DZEN $s[2].$dsktp[$dtp].$s[3].$z if ($dtp != $dtp_old) ;
$dtp_old = $dtp ;
Time::HiRes::sleep(0.2) ;
}
}
close DZEN ;
close CONKY ;
###################
## SUBROUTINES ##
###################
sub cpu_calc {
my $cpux = shift ;
for ( my $x = 0 ; $x < 6 ; $x++ ) {
if ( $cpux <= ($x+1)*100/6 ) {
return $x ;
}
}
}
sub mk_cpugraph_icons {
my $num_cols = 8 ;
my $num_rows = 12 ;
## There surely must be a more elegant way...
for (my $aa = 0 ; $aa <= 5 ; $aa++ ) {
for (my $bb = 0 ; $bb <= 5 ; $bb++ ) {
for (my $cc = 0 ; $cc <= 5 ; $cc++ ) {
for (my $dd = 0 ; $dd <= 5 ; $dd++ ) {
## Define a new array of arrays filled with zeros.
my @zzz = () ;
my @yyy = (0) x $num_cols ;
for ( my $x = $num_rows ; $x > 0 ; $x-- ) { push(@zzz, [@yyy]) }
## Array members represent pixels in the xbm file. Set pixels to
## reflect a cpu graph xbm for the 4 values $aa $bb $cc $dd
my $num = $num_rows-2 ;
for ( my $col = 0 ; $col < 8 ; $col++ ) {
for ( my $row = 0 ; $row < $num_rows-1 ; $row++ ) {
if ( $col < 2 ) { $zzz[$row][$col] = 1 if ( $row >= $num-2*$aa ) }
elsif ( $col < 4 ) { $zzz[$row][$col] = 1 if ( $row >= $num-2*$bb ) }
elsif ( $col < 6 ) { $zzz[$row][$col] = 1 if ( $row >= $num-2*$cc ) }
else { $zzz[$row][$col] = 1 if ( $row >= $num-2*$dd ) }
}
}
## The xbm icon created here will resemble the Data::Dump output for \@zzz .
#Data::Dump::dump($arx);
write_xbm_file(\@zzz, $xbmdir."/".$aa.$bb.$cc.$dd.".xbm") ;
}
}
}
}
}
# Expects that $_ is a reference to meter array
sub write_xbm_file {
my ($ary, $xbmfile) = @_ ;
my $wdth = @{$ary->[0]} ;
my $hght = @$ary ;
open(XBM, ">$xbmfile") || die "Failed to open test.xbm" ;
say XBM "#define stop_width $wdth\n#define stop_height $hght" ;
print XBM 'static unsigned char stop_bits[]'." = {\n" ;
for ( my $row = 0 ; $row <= $hght-1 ; $row++ ) {
for (my $col = 0 ; $col < $wdth ; $col+=8) {
my $bin = join('', reverse(@{$ary->[$row]}[$col..$col+7])) ;
printf(XBM ' 0x%02X,', oct("0b$bin")) ;
}
print XBM "\n" ;
}
print XBM ' };' ;
close XBM ;
}
## Purpose : Make some xbm icons used by dzen. Put them in the current folder.
##
sub mk_xbm_icons {
open XBM, ">", "wifi_sig.xbm" || die " open XBM wifi_sig.xbm failed " ;
print XBM <<'EOF';
#define temp_width 19
#define temp_height 12
static unsigned char temp_bits[] = {
0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0xb0, 0x01, 0x00,
0xb0, 0x01, 0x00, 0xb0, 0x01, 0x00, 0xb0, 0x0d, 0x00, 0xb0, 0x0d, 0x00,
0xb0, 0x6d, 0x00, 0xb0, 0x6d, 0x00, 0xb0, 0x6d, 0x00, 0x00, 0x00, 0x00};
EOF
close XBM ;
$wifiicon = "^bg($color_blackish)^fg($color_icon)^i(wifi_sig.xbm)^bg()^fg($color_white)" ;
open XBM, ">", "down.xbm" || die " open XBM down.xbm failed " ;
print XBM <<'EOF';
#define temp_width 19
#define temp_height 12
static unsigned char temp_bits[] = {
0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00,
0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0xe0, 0x3f, 0x00,
0xc0, 0x1f, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x00};
EOF
close XBM ;
$dwnicon = "^bg($color_blackish)^fg($color_icon)^i(down.xbm)^bg()^fg($color_white)" ;
open XBM, ">", "up.xbm" || die " open XBM up.xbm failed " ;
print XBM <<'EOF';
#define up_width 19
#define up_height 12
static unsigned char up_bits[] = {
0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x80, 0x0f, 0x00, 0xc0, 0x1f, 0x00,
0xe0, 0x3f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00,
0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00};
EOF
close XBM ;
$upicon = "^bg($color_blackish)^fg($color_icon)^i(up.xbm)^bg()^fg($color_white)" ;
open XBM, ">", "clock.xbm" || die " open XBM clock.xbm failed " ;
print XBM <<'EOF';
#define temp_width 22
#define temp_height 12
static unsigned char temp_bits[] = {
0x00, 0x1e, 0x00, 0x80, 0x7f, 0x00, 0xc0, 0xdf, 0x00, 0xc0, 0xef, 0x00,
0xe0, 0xf7, 0x01, 0xe0, 0xfb, 0x01, 0xe0, 0x03, 0x01, 0xe0, 0xff, 0x01,
0xc0, 0xff, 0x00, 0xc0, 0xff, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x1e, 0x00};
EOF
close XBM ;
$clockicon = "^bg($color_blackish)^fg($color_icon)^i(clock.xbm)^bg()^fg($color_white)" ;
open XBM, ">", "cpu.xbm" || die " open XBM cpu.xbm failed " ;
print XBM <<'EOF';
#define temp_width 20
#define temp_height 16
static unsigned char temp_bits[] = {
0x00, 0x00, 0x00, 0x20, 0x49, 0x00, 0x20, 0x49, 0x00, 0xf0, 0xff, 0x00,
0xf0, 0xff, 0x00, 0xf8, 0xff, 0x01, 0x70, 0xe0, 0x00, 0x70, 0xe0, 0x00,
0x78, 0xe0, 0x01, 0x70, 0xe0, 0x00, 0xf0, 0xff, 0x00, 0xf8, 0xff, 0x01,
0xf0, 0xff, 0x00, 0x20, 0x49, 0x00, 0x20, 0x49, 0x00, 0x00, 0x00, 0x00};
EOF
close XBM ;
$cpuicon = "^bg($color_blackish)^fg($color_icon)^i(cpu.xbm)^bg()^fg($color_white)" ;
open XBM, ">", "mem.xbm" || die " open XBM mem.xbm failed " ;
print XBM <<'EOF';
#define tit_width 20
#define tit_height 16
static unsigned char tit_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x00,
0x20, 0x49, 0x00, 0xf0, 0xff, 0x00, 0xf0, 0xff, 0x00, 0x30, 0xc0, 0x00,
0x30, 0xc0, 0x00, 0xf0, 0xff, 0x00, 0xf0, 0xff, 0x00, 0x20, 0x49, 0x00,
0x20, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
EOF
close XBM ;
$memicon = "^bg($color_blackish)^fg($color_icon)^i(mem.xbm)^bg()^fg($color_white)" ;
}
# Purpose : To write a config file for conky to the current working directory.
sub mk_conkyrc {
open XBM, ">", "conkyrc" || die " open conkyrc failed " ;
print XBM <<'EOF';
background no
out_to_console yes
out_to_x no
own_window_type panel
cpu_avg_samples 1
net_avg_samples 1
update_interval 1
total_run_times 0
format_human_readable
uppercase no
use_spacer none
short_units yes
double_buffer yes
TEXT
${cpu cpu1} ${cpu cpu2} ${mem} ${fs_used_perc /} ${downspeedf wlan0} ${upspeedf wlan0} ${mixer}
EOF
close XBM ;
}
#####################################################################################
## ncmpcpp-helper.pl #
#####################################################################################
#!/usr/bin/perl
## NCMPCPP-HELPER.PL :
## Expects mp3 files to have an embedded cover image.
#use strict ;
use warnings ;
use v5.14 ;
use POSIX ":sys_wait_h";
use File::Temp qw/ tempdir / ;
use Audio::MPD ;
use Proc::ProcessTable ;
my $music_directory = "/home/nostromo/Music" ;
my $timeout = 20 ;
my $urx_ncmpcpp_name = "Ncmpcpp" ;
#my $urx_ncmpcpp_font = "-gohu-gohufont-medium-r-normal--14-100-100-100-c-80-iso8859-1" ;
my $urx_ncmpcpp_font = "-gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso10646-1" ;
my $urx_ncmpcpp_colors = ' -fg gainsboro ' ;
$urx_ncmpcpp_colors .= ' --color0 \'#808079\' --color8 \'#808079\' ' ; # black
$urx_ncmpcpp_colors .= ' --color4 \'#626B73\' --color12 \'#838F99\' ' ; # blue
$urx_ncmpcpp_colors .= ' --color6 \'#698B8C\' --color14 \'#7CA5A6\' ' ; # cyan
$urx_ncmpcpp_colors .= ' --color5 \'#756C80\' --color13 \'#756C80\' ' ; # magenta
$urx_ncmpcpp_colors .= ' --color1 \'#917474\' --color9 \'#917474\' ' ; # red
$urx_ncmpcpp_colors .= ' --color3 \'#807060\' --color11 \'#8C7B69\' ' ; # yellow (brown)
$urx_ncmpcpp_colors .= ' --color7 \'#75756F\' --color15 \'#999991\' ' ; # white
my $feh_image_size = "160x160" ;
my $feh_image_default = "/home/nostromo/Pictures/crunchbang-logo-120x120.jpg" ;
my $feh_image_title = "mp3coverart.png" ;
my $urx_spectrum_name = "Spectrum" ;
my $urx_spectrum_font = "-misc-fixed-medium-r-normal--6-60-75-75-c-40-iso8859-1" ;
## Create temporary work folder.
my $wrkdir = tempdir(CLEANUP=>1);
chdir $wrkdir ;
say STDERR $wrkdir ;
## ┌───────────────┐
## │ THREE FORKS │
## └───────────────┘
## Fork 3 processes and retain their PIDs, such that they can be monitored later.
## The three processes being 1] a urxvt term, in which will run ncmpcpp, 2] a feh image
## viewer that displays coverart for songs, and 3] a urxvt term, in which will run
## "spectrum", a spectrum analyzer that works with MPD.
#### 1] FORK URXVT TO RUN NCMPCPP
## Fork "ncmpcpp" that runs within a urxvt term. Please leave $urx_ncmpcpp_pid unchopped.
my $urx_ncmpcpp_pid = fork() ;
die "unable to fork: $!" unless defined($urx_ncmpcpp_pid) ;
my $urx_ncmpcpp_cmnd = "urxvt -title $urx_ncmpcpp_name " ;
$urx_ncmpcpp_cmnd .= " -fn \"$urx_ncmpcpp_font\" " ;
$urx_ncmpcpp_cmnd .= $urx_ncmpcpp_colors.'-e ncmpcpp ' ;
#$urx_ncmpcpp_cmnd .= $urx_ncmpcpp_colors.'-e ncmpcpp -c /home/nostromo/temp-next-ncmpcpp/next-ncmpcpp2.conf ' ;
if ( !$urx_ncmpcpp_pid ) {
exec( $urx_ncmpcpp_cmnd ) ;
die "you shouldn't be here! : $!" ;
}
#### 2] START FEH TO DISPLAY COVERART
my $cmd = "convert -border 2x2 -bordercolor \"#677A75\" -quality 1 $feh_image_default -adaptive-resize $feh_image_size blah1.png ; " ;
$cmd .= " composite -gravity center blah1.png /home/nostromo/Pictures/thach-198x198.png mp3coverart.png" ;
system("$cmd") ;
system( " feh -R 1 -x mp3coverart.png &>/dev/null & " ) ;
#### 3] START HELPER SCRIPT FOR SPECTRUM ANALYZER.
## The spectrum analyser isn't started directly here. A backgrounded helper script is
## started, which in turn starts/stops/restarts the spectrum analyzer as needed. The
## idea being that the spectrum analyser only needs to run when a song is actually playing.
## Use heredoc to create the helper script.
## The "spectrum analyser" is restarted only when file "mpdplay" is detected.
open OUT, ">", "spectrum.pl" || die " open spectrum.pl failed " ;
print OUT <<'EOF' ;
#!/usr/bin/perl
while (1) {
print "\x1b\x5b\x3f\x32\x35\x6c\n" ; ## invisible cursor
print "\x1b\x5b\x48\x1b\x5b\x4a\n" ; ## clear screen
if (-e "mpdplay") { system("spectrum -p") }
sleep 1 ;
}
EOF
close OUT ;
## The "spectrum analyzer" is only started when the "mpdplay" file exists.
system("touch mpdplay") ;
## Start the helper script running within a urxvt term.
chmod 0777, "spectrum.pl" ;
system( "urxvt -title $urx_spectrum_name -fg '#8C8C85' -fn $urx_spectrum_font -e ./spectrum.pl & " ) ;
## Wait for above processes to start properly. Then obtain the PIDs for "feh" and for the
## helper script "spectrum.pl"
sleep 5 ;
my $spectrum_pid = my $feh_pid = 0 ;
my $t = new Proc::ProcessTable ;
foreach my $p ( @{$t->table} ) {
my $x = $p->cmndline ;
my $v = qr/$feh_image_title/ ;
$spectrum_pid = $p->pid if $x =~ /perl.+spectrum.pl/i ;
$feh_pid = $p->pid if $x =~ $v ;
}
## DEBUG
say STDERR "feh_pid : $feh_pid urx_spectrum_pid : $spectrum_pid " ;
#### ESTABLISH CONNECTION TO MPD
## Establish a new connection to the running MPD server.
my $mpd = Audio::MPD->new( {
host => 'localhost',
port => 6600,
conntype => 'reuse',
} );
## Loop here until an Audio::MPD::Common::Item::Song object is acquired for the current song.
my $current = $mpd->current ;
until ( ref($current) ) {
sleep 4 ;
$current = $mpd->current ;
}
## Timestamp used to measure seconds since MPD status was "play".
my $tstamp_active = time() ;
while ( 1 ) {
my $mp3file = $current->file ;
## Remove any old image files in the folder.
unlink glob "FRONT* OTHER*" ;
## Look for an embedded image inside the mp3, and resize.
my $alice = readpipe(" eyeD3 -i . ".$music_directory."/\"".$mp3file."\" 2>&1 1>/dev/null ") ;
if ( defined $alice && $alice =~ /^.+\s[.]\/(.+)[.][.][.].*$/s ) {
my $x = $1 ;
my $cmd = "convert -border 2x2 -bordercolor \"#677A75\" -quality 1 \"$x\" -adaptive-resize $feh_image_size blah1.png " ;
$cmd .= " && composite -gravity center blah1.png /home/nostromo/Pictures/thach-198x198.png mp3coverart.png" ;
system( $cmd ) if defined $x && -f $x ;
}
## Loop here until the current mp3 file changes.
while ( $current->file eq $mp3file ) {
## Check that ncmpcpp is still running. And if not, then killall and exit.
if ( waitpid($urx_ncmpcpp_pid, WNOHANG) > 0 ) {
say STDERR "kill spectrum.pl : $spectrum_pid " ; ## DEBUG
say STDERR "kill feh_pid : $feh_pid " ; ## DEBUG
kill 'SIGTERM', $spectrum_pid ;
kill 'SIGTERM', $feh_pid ;
exit 0 ;
}
## Loop until a fresh Status object is obtained for MPD.
my $mpd_status = $mpd->status ;
until ( ref($mpd_status) ) {
sleep 4 ;
$mpd_status = $mpd->status ;
}
## Start "spectrum" if MPD status is "play". But if stopped/paused for more than
## $timeout seconds, then kill "spectrum". Such that the spectrum analyzer only
## runs when MPD is playing a song.
my $mpd_state = $mpd_status->state ;
if ( $mpd_state eq "play" ) {
$tstamp_active = time() ;
system("touch mpdplay") if ! -e "mpdplay" ;
} elsif ( -e "mpdplay" && time() - $tstamp_active >= $timeout ) {
killspectrum() ;
}
sleep 4 ;
$current = $mpd->current ;
until ( ref($current) ) {
sleep 4 ;
$current = $mpd->current ;
}
}
}
## Find and kill the PID of the "spectrum" analyzer. If it exists, then it is the only
## child process of helper script "spectrum.pl" (which has a PID of $spectrum_pid).
sub killspectrum {
my $t = new Proc::ProcessTable ;
foreach my $p ( @{$t->table} ){
if ($p->ppid == $spectrum_pid ) {
say STDERR "the child of spectrum.pl is : ".$p->pid ; ## DEBUG
unlink "mpdplay" ;
kill 'SIGTERM', $p->pid ;
}
} ;
}
#####################################################################################
## system-info.pl #
#####################################################################################
#!/usr/bin/perl
## SYSTEM INFO -
use strict ;
use warnings ;
use v5.14 ;
use File::Temp qw/ tempdir / ;
use POSIX qw(mkfifo) ;
use Net::Ping ;
use Scalar::Util::Numeric qw(isint) ;
## Depends on libscalar-util-numeric-perl
my $tperiod = 60 ;
my $timeout = 1200 ;
#### URXVT CONFIG
my $cols = 20 ;
my $rows = 7 ;
my $urxvt_name = "System" ;
my $urxvt_fg = '#6B6B66' ;
my $urxvt_geom = "${cols}x${rows}" ;
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso10646-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"$urxvt_fg\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
$urxvt_opts .= ' --color3 \'#736556\' --color11 \'#736556\' ' ; ## brown/yellow
#### TERMINAL ESCAPE CODES
## Color codes.
my $c_label = colorcode(4) ; ## color of the disk label.
my $c_box = colorcode(0) ; ## color of the box chars.
my $c_bar = colorcode(3) ; ## color of the progress bar.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ; ## bold
## Tput codes.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; ## carriage return & delete to EOL.
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; ## tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; ## tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
## Box chars.
my $box_fork = "\xE2\x94\x9C" ;
my $box_cnr = "\xE2\x94\x94" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## An invisible cursor for the terminal.
print $tput_civis ;
#### MAIN LOOP
## Timestamps used to ensure that values for "Updates" and "IP:" are updated less often.
my $tstamp_aptitude = 0 ;
## Initial values.
my $deb_updates = my $rx_bytes = my $tx_bytes = my $rx_bytes_offset = my $tx_bytes_offset = 0 ;
while ( 1 ) {
my $uptime = readpipe "cat /proc/uptime" ;
$uptime =~ s/[.].+$// ;
$uptime = time_formatted($uptime) ;
$deb_updates = debnum() ;
my $celcius = readpipe "cat /sys/bus/acpi/devices/LNXTHERM\:00/thermal_zone/temp" ;
$celcius /= 1000 ;
$rx_bytes = update_rx_bytes() ;
$tx_bytes = update_tx_bytes() ;
my @sys = ( "${tput_cel}${c_label}#System${norm}" ) ;
my $num = $cols - 9 ;
push @sys, sprintf("${tput_cel} ${c_box}${bold}${box_fork}${norm}Uptime%${num}s ", $uptime) ;
$num = $cols - 10 ;
push @sys, sprintf("${tput_cel} ${c_box}${bold}${box_fork}${norm}Updates%${num}s ", $deb_updates) ;
$num = $cols - 11 ;
my $rx = unit_convert($rx_bytes + $rx_bytes_offset) ;
push @sys, sprintf("${tput_cel} ${c_box}${bold}${box_fork}${norm}Download%${num}s ", $rx ) ;
$num = $cols - 9 ;
my $tx = unit_convert($tx_bytes + $tx_bytes_offset) ;
push @sys, sprintf("${tput_cel} ${c_box}${bold}${box_fork}${norm}Upload%${num}s ", $tx) ;
$num = $cols - 9 ;
push @sys, sprintf("${tput_cel} ${c_box}${bold}${box_cnr}${norm}Temp%${num}s\xC2\xB0C ", $celcius) ;
push @sys, ${tput_cel} ;
my $lastx = pop @sys ;
foreach (@sys) { say } ;
print $lastx ;
sleep $tperiod ;
foreach (1..$rows) { say $tput_up } ;
}
#### SUBROUTINES
## Return the terminal escape chars that encode color $1.
sub colorcode { return "\x1b[0;38;5;".shift."m" }
sub time_formatted {
my $x = shift ;
my $z = "" ;
my $hrs = int($x/3600) ;
my $mins = int( ($x%3600) / 60 ) ;
return sprintf "%dh%02dm", $hrs, $mins if $hrs > 0 ;
return sprintf "%dm", $mins ;
}
## Return the number of debian package to be updated. Only updates to the most
## value if $timeout seconds have elapsed since the last.
sub debnum {
return $deb_updates if time - $tstamp_aptitude < $timeout ;
my @x = readpipe "aptitude search '~'U " ;
$tstamp_aptitude = time ;
return scalar @x ;
}
sub unit_convert {
my $x = shift ;
$x = ( $x < 999 ) ? $x."B" :
( $x < 1023477 ) ? int($x/1024 + .5)."K" :
( $x < 1048041226 ) ? int($x/1048576 + .5)."M" : sprintf( "%.1fG", $x/1073741824 ) ;
return $x ;
}
## On 32bit systems, .../rx_bytes has a maximum value 4Gib. So $rx_bytes_offset
## is used to detect and offset any wrap-around errors.
sub update_rx_bytes {
my $x = readpipe "cat /sys/class/net/wlan0/statistics/rx_bytes" ;
chop $x ;
return $rx_bytes if not isint($x) ;
$rx_bytes_offset += 4294967296 if $rx_bytes > 3000000000 && $x < 1000000000 ;
return $x ;
}
## On 32bit systems, .../tx_bytes has a maximum value 4Gib. So $tx_bytes_offset
## is used to detect and offset any wrap-around errors.
sub update_tx_bytes {
my $x = readpipe "cat /sys/class/net/wlan0/statistics/tx_bytes" ;
chop $x ;
return $tx_bytes if not isint($x) ;
$tx_bytes_offset += 4294967296 if $tx_bytes > 3000000000 && $x < 1000000000 ;
return $x ;
}
#####################################################################################
## disk-usage.pl #
#####################################################################################
#!/usr/bin/perl
## DISK INFO
use strict ;
use warnings ;
use v5.14 ;
use File::Temp qw/ tempdir / ;
use POSIX qw(mkfifo) ;
#use File::Slurp
my @disks = ( "sda3", "sda5", "sda8", "sdb1", "sda12" ) ;
my $tperiod = 60 ;
#### URXVT OPTIONS
my $cols = 20 ;
my $rows = 12 ;
my $urxvt_name = "Disks" ;
my $urxvt_fg = '#6B6B66' ;
my $urxvt_geom = "${cols}x${rows}" ;
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso10646-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"$urxvt_fg\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
$urxvt_opts .= ' --color3 \'#736556\' --color11 \'#736556\' ' ; ## brown/yellow
#### TERMINAL ESCAPE CODES
## Color codes.
my $c_label = colorcode(4) ; ## color of the disk label.
my $c_cnr = colorcode(0) ; ## color of the corner char.
my $c_bar = colorcode(3) ; ## color of the progress bar.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ;
## Tput codes.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; ## carriage return & delete to EOL.
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; ## tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; ## tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
## Box chars.
my $box_cnr = "\xE2\x94\x94" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## An invisible cursor for the terminal.
print $tput_civis ;
#### MAIN LOOP
while (1) {
## Extract disk usage info from "/bin/df", and store it as hashes.
my @dfh = readpipe " df --block-size=1048576 " ;
my %maxx = my %used = my %perc = () ;
foreach ( @dfh ) {
next if not /^\/dev/ ;
my @x = split /\s+/ ;
$x[0] =~ s/^.*\/// ;
$x[4] =~ s/%$// ;
$maxx{$x[0]} = int($x[1]/1024 + .5) ;
$used{$x[0]} = int($x[2]/1024 + .5) ;
$perc{$x[0]} = $x[4] ;
}
## The usage info for each device in @disks is formatted, and pushed into @outx.
my @outx = () ;
foreach my $x (@disks) {
## Proceed only if hash data exists for this device.
next if not defined $maxx{$x} ;
## $usage is set to empty for the first device - to improve the overall look.
my $usage = (@outx > 0) ? "$used{$x}G/$maxx{$x}G" : "" ;
## Format the progress bar and info, and push to @outx.
my $w = $cols - length($x) - 2 ;
push @outx, sprintf "${tput_cel}${c_label}#%s${norm}%${w}s ", $x, $usage if @outx < $rows ;
push @outx, $tput_cel." ".$c_cnr.$bold.$box_cnr.$norm."[".$c_bar.probar($perc{$x}).$norm."] " if @outx < $rows ;
push @outx, $tput_cel if @outx < $rows ;
}
## Print formatted info in @outx to stdout.
my $lastx = pop @outx ;
foreach (@outx) { say } ;
print $lastx ;
## Sleep, then reposition the cursor to the top.
sleep $tperiod ;
foreach (1..$rows) { say $tput_up } ;
}
#### SUBROUTINES
## Return the terminal escape chars that encode color $1.
sub colorcode { return "\x1b[0;38;5;".shift."m" }
sub probar {
my @progress=( " ", "- ", "= ",
"=- ", "== ", "==- ",
"=== ", "===- ", "==== ",
"====- ", "===== ", "=====- ",
"====== ", "======- ", "======= ",
"=======- ", "======== ", "========- ",
"========= ", "=========- ", "========== ",
"==========- ", "=========== ", "===========- ",
"============ ", "============- ", "============= ",
"=============- ", "============== ", "==============-",
"===============", ) ;
my $z = shift ;
my $idx = int(($z/100)*$#progress + .49) ;
return $progress[$idx] ;
}
#####################################################################################
## top-processes.pl #
#####################################################################################
#!/usr/bin/perl
## TREETOP SCRIPT -
use strict ;
use warnings ;
use v5.14 ;
use File::Temp qw/ tempdir / ;
use POSIX qw(mkfifo) ;
use Data::Dump ;
use List::MoreUtils qw(uniq) ;
#### URXVT OPTIONS
## Basic options for urxvt...
my $cols = 20 ;
my $rows = 17 ;
my $urxvt_name = "Processes" ;
my $urxvt_fg = '#6B6B66' ;
my $urxvt_geom = "${cols}x${rows}-17+17" ;
## Additional urxvt opts for the rgb colors to match the colo".$norm.$c1."r codes used above.
#$urxvt_opts .= ' -bg \'#0D0D0D\' ' ; # -fg gainsboro
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"$urxvt_fg\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
$urxvt_opts .= ' --color6 \'#52524E\' --color14 \'#52524E\' ' ; ## cyan
#### CHARS FOR FORMATTING
## Codes used to color the tree-lists.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ; ## bold
my $c1 = colorcode(4) ; ## color for the title (c1) and the title-hash (c5)
my $c2 = colorcode(0) ; ## color for the box-chars
my $c3 = colorcode(6) ; ## color for metric units.
## Tput escape char combos for piping formatted text into a term.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; # \r$(tput el) -- carriage return & delete to end-of-line
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; # tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; # tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set the default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## An invisible cursor for the urxvt.
print $tput_civis ;
## Create a conky config
## Start a conky process to obtain process stats.
mk_conkyrc() ;
open(CONKY, "conky -c conkyrc 2>/dev/null | ") || die "CONKY failed. \n" ;
my @cpux = my @memx = my @iox = () ;
while (<CONKY>) {
## Clear the output arrays
@cpux = @memx = @iox = () ;
## Extract data fields from conky. %ior and %iow store info about processes
## that read/write to/from disk.
my @arx = split(/-O-|\n/) ;
my @cpu_data = @arx[0..7] ;
my @mem_data = @arx[8..15] ;
my %ior = @arx[16..23] ;
my %iow = @arx[24..31] ;
#### CPU PERFORMANCE - format info to the output array @cpux
for (my $x = 0, my $wdth = $cols - 8 ; $x < $#cpu_data ; ) {
my $legend = substr($cpu_data[$x++], 0, $wdth ) ;
my $percentage = int($cpu_data[$x++] + .5) ;
my $formatt = "${norm}%-${wdth}s %3d%% " ;
push @cpux, sprintf( $formatt, $legend, $percentage ) ;
}
#### MEM PERFORMANCE - format info to the output array @memx
for (my $x = 0, my $wdth = $cols - 9; $x < $#mem_data ; ) {
my $legend = substr($mem_data[$x++], 0, $wdth) ;
my $formatt = "${norm}%-${wdth}s %5s " ;
push @memx, sprintf( $formatt , $legend, unit_convert($mem_data[$x++]) ) ;
}
#### IO PERFORMANCE - format info to the output array @iox
## @allprocs stores all the proc names found in %ior and %iow
## %io_sum stores the combined read/write IO for all processes in %ior and %iow
my %io_sum = () ;
my @allprocs = uniq keys(%ior), keys(%iow) ;
foreach my $x ( @allprocs ) {
$ior{$x} = 0 if not defined $ior{$x} ;
$iow{$x} = 0 if not defined $iow{$x} ;
$io_sum{$x} = $ior{$x} + $iow{$x} ;
}
## The top processes sorted by total r/w IO are now listed in @io_top.
my @io_top = sort { $io_sum{$b} <=> $io_sum{$a} } keys %io_sum ;
## Format the info to output array @iox.
my $wdth = $cols - 13 ;
foreach my $x ( @io_top ) {
my $legend = substr($x, 0, $wdth) ;
my $formatt = "${norm}%-${wdth}s %4s %4s " ;
push @iox, sprintf( $formatt, $legend, unit_convert($ior{$x}), unit_convert($iow{$x}) ) ;
last if $io_sum{$x} == 0 or @iox == 4 ;
}
#### PRINT INFO TO STDOUT
## Print @cpux info
print $tput_up x ($rows - 1) ;
say $tput_cel.$c1."#Cpu".$norm ;
add_boxchars(\@cpux) ;
foreach ( @cpux ) { say } ;
## Print @memx info
say $tput_cel."\n".$tput_cel.$c1."#Memory".$norm ;
add_boxchars(\@memx) ;
foreach ( @memx ) { say } ;
## Print @iox info
say $tput_cel ;
$wdth = $cols - 7 ;
my $formatt = $tput_cel.$c1."%-".$wdth."s".$norm.$c1."%s ".$norm."\n" ;
printf $formatt, "#In/Out", "↑ ↓" ;
add_boxchars(\@iox) ;
## For remaining blank lines til bottom of term, delete to end of line.
for ( my $x = 4 - @iox ; $x > 0 ; $x-- ) { push @iox, $tput_cel } ;
my $lastio = pop @iox ;
foreach ( @iox ) { say } ;
print $lastio ;
}
#### SUBROUTINES
sub colorcode { return "\x1b[0;38;5;".shift."m" }
sub unit_convert {
my $x = shift ;
$x = ( $x < 999 ) ? $x."B" :
( $x < 999499 ) ? int($x/1000 + .5)."K" : int($x/1000000 + .5)."M" ;
return $x ;
}
## arg1 = ref to array
sub add_boxchars {
my $aa = shift ;
my $lastx = $#$aa ;
## utf8 box chars to draw the tree-list.
my $fork = "${bold}\xE2\x94\x9C${norm}" ;
my $cnr = "${bold}\xE2\x94\x94${norm}" ;
for (my $x = 0 ; $x < $lastx ; $x++ ) { $$aa[$x] = " $c2$fork$norm".$$aa[$x] }
$$aa[$lastx] = " $c2$cnr$norm".$$aa[$lastx] ;
}
sub mk_conkyrc {
open TXT, ">", "conkyrc" || die " open conkyrc failed " ;
print TXT <<'EOF';
background no
out_to_console yes
out_to_x no
own_window_type panel
cpu_avg_samples 1
update_interval 5
total_run_times 0
format_human_readable no
no_buffers yes
uppercase no
use_spacer none
short_units yes
double_buffer yes
top_cpu_separate false
top_name_width 20
# ${top_io name 1}|${top_io io_write 1}|${top_io name 2}|${top_mem io_write 2}|${top_io name 3}|${top_io io_write 3}
# ${top_io name 1}-O-${top_io io_perc 1}-O-${top_io name 2}-O-${top_mem io_perc 2}-O-${top_io name 3}-O-${top_io io_perc 3}-O-
TEXT
${top name 1}-O-${top cpu 1}-O-\
${top name 2}-O-${top cpu 2}-O-\
${top name 3}-O-${top cpu 3}-O-\
${top name 4}-O-${top cpu 4}-O-\
${top_mem name 1}-O-${top_mem mem_res 1}-O-\
${top_mem name 2}-O-${top_mem mem_res 2}-O-\
${top_mem name 3}-O-${top_mem mem_res 3}-O-\
${top_mem name 4}-O-${top_mem mem_res 4}-O-\
${top_io name 1}-O-${top_io io_read 1}-O-\
${top_io name 2}-O-${top_io io_read 2}-O-\
${top_io name 3}-O-${top_io io_read 3}-O-\
${top_io name 4}-O-${top_io io_read 4}-O-\
${top_io name 1}-O-${top_io io_write 1}-O-\
${top_io name 2}-O-${top_io io_write 2}-O-\
${top_io name 3}-O-${top_io io_write 3}-O-\
${top_io name 4}-O-${top_io io_write 4}-O-
EOF
close TXT ;
}
#####################################################################################
## flexget-torrents-added.pl #
#####################################################################################
#!/usr/bin/perl
#### Script to display "torrents_added.txt"
use strict ;
use warnings ;
use v5.14 ;
use File::Temp qw( tempdir ) ;
use POSIX qw( mkfifo ) ;
use File::Slurp qw( :std ) ;
use Scalar::Util::Numeric qw( isint ) ;
#use Data::Dump qw( dump ) ;
## List file that contains details of recently added torrents.
my $listfile = "/home/nostromo/flexget-config/lists/x-torrents-added.txt" ;
## Seconds between update of this display.
my $tperiod = 60 ;
my $rows = 7 ;
my $cols = 20 ;
my $urxvt_name = "Flexget" ;
my $urxvt_geom = "${cols}x${rows}-19+19" ;
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"#6B6B66\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
## Codes used to color the tree-lists.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ; ## bold
my $c1 = colorcode(4) ; ## color for the title (c1) and the title-hash (c5)
my $c2 = colorcode(0) ; ## color for the box-chars
## Tput escape char combos for piping formatted text into a term.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; # \r$(tput el) -- carriage return & delete to end-of-line
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; # tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; # tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set the default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## An invisible cursor for the urxvt.
print $tput_civis ;
while ( 1 ) {
my @ary = read_file $listfile ;
@ary = @ary[($#ary-$rows+3)..$#ary] ;
chomp @ary ;
for ( my $x = 0 ; $x <= $#ary ; $x++ ) {
( my $se, my $ep, my $show ) = split '::', $ary[$x] ;
if ( isint $ep ) {
my $idx = ".".$se."x".$ep ;
my $name = substr $show, 0, $cols - length($idx) - 3 ;
$ary[$x] = $name.$idx ;
} else {
$ary[$x] = substr $show, 0, $cols - 3 ;
}
}
add_boxchars( \@ary ) ;
say $tput_up x ($rows - 1) ;
say $tput_cel.$c1."#Torrents.Added".$norm ;
# my $lastx = pop @ary ;
foreach my $x ( @ary ) { say $tput_cel.$x } ;
# print $lastx ;
sleep $tperiod ;
# print STDERR "+" ;
# sleep 100;
# foreach (1..$rows) { say $tput_up } ;
}
#### SUBROUTINES
sub colorcode { return "\x1b[0;38;5;".shift."m" }
## arg1 = a ref to array
sub add_boxchars {
my $aa = shift ;
my $lastx = $#$aa ;
## utf8 box chars to draw the tree-list.
my $fork = "${bold}\xE2\x94\x9C${norm}" ;
my $cnr = "${bold}\xE2\x94\x94${norm}" ;
for (my $x = 0 ; $x < $lastx ; $x++ ) { $$aa[$x] = " $c2$fork$norm".$$aa[$x] }
$$aa[$lastx] = " $c2$cnr$norm".$$aa[$lastx] ;
}
#####################################################################################
## flexget-premieres+docos.txt #
#####################################################################################
#!/usr/bin/perl
#### SCRIPT TO DISPLAY PREMIERES + DOCOS
use strict ;
use warnings ;
use v5.14 ;
use File::Temp qw( tempdir ) ;
use POSIX qw( mkfifo ) ;
use File::Slurp qw( :std ) ;
use List::MoreUtils qw( uniq ) ;
#use Data::Dump qw( dump ) ;
#### CONFIG
## Paths to list files.
my $file_mvgroups = "/home/nostromo/flexget-config/lists/x-mvgroups.txt" ;
my $file_premieres = "/home/nostromo/flexget-config/lists/x-premieres.txt" ;
## Seconds between display update.
my $tperiod = 60 ;
## Num of entries to display for each list.
my $entries_mvgroups = 5 ;
my $entries_premieres = 4 ;
## MVGroups only - An array of keywords, used to discard titles.
my @excl = qw( nova season history soillse ) ;
## MVGroups only - A hash for replacement abbreviations
## key = matching word, value = abbreviation.
## Well known serials must be listed here, or else they will be discarded.
## my %repl = ( "Our.World" => "OW: ",
## "Unreported.World" => "UW: ",
## "Smithsonian.Channel" => "",
## ) ;
#### URXVT CONFIG
my $rows = 13 ;
my $cols = 20 ;
my $urxvt_name = "Television" ;
my $urxvt_geom = "${cols}x${rows}-19+19" ;
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"#6B6B66\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
# #626B73 sat = .15
# #5C6873 sat = .20
#### ESCAPE CODE CHARS
## Codes used to color the tree-lists.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ; ## bold
my $c1 = colorcode(4) ; ## color for the title (c1) and the title-hash (c5)
my $c2 = colorcode(0) ; ## color for the box-chars
## Tput escape char combos for piping formatted text into a term.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; # \r$(tput el) -- carriage return & delete to end-of-line
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; # tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; # tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set the default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## Set an invisible cursor for the urxvt.
print $tput_civis ;
while ( 1 ) {
#### OBTAIN PREMIERE TITLES
## Read in doco titles from the premieres list file.
my @firsts = read_file $file_premieres ;
chomp @firsts ;
## Keep only the last $entries_premieres entries.
@firsts = @firsts[$#firsts-$entries_premieres+1..$#firsts] ;
## Restrict length of each title string and tidy up.
for ( my $x = 0 ; $x <= $#firsts ; $x++ ) {
$firsts[$x] = substr $firsts[$x], 0, ($cols - 3) ;
$firsts[$x] =~ s/[\s.]\w{0,2}$// ;
}
#### OBTAIN AND PARSE MVGROUP TITLES
## Read in doco titles from the mvgroups list file.
my @mvgrp = read_file $file_mvgroups ;
chomp @mvgrp ;
## Remove titles that match keywords listed in @excl.
@mvgrp = grep_list( \@mvgrp, \@excl ) ;
## Discard any 3-letter prefixes to each list item - a network channel label.
@mvgrp = grep { s/^\w{1,3}[.]//i ; 1 } @mvgrp ;
## Discard suffixed meta info for each item - quality, resolution, release group etc.
@mvgrp = grep { s/[.](\d\d\dp|\wdtv)[.].+$//i ; 1 } @mvgrp ;
## Discard any duplicate titles.
@mvgrp = uniq @mvgrp ;
## Replace prefixed tv-series info for titles from well known serials with an abbreviation.
@mvgrp = grep { s/^Smithsonian[.]Channel[.]/SC: /i ; 1 } @mvgrp ;
@mvgrp = grep { s/^National[.]Geographic[.]/NG: /i ; 1 } @mvgrp ;
@mvgrp = grep { s/.*Our[.]World.+20\d\d[.]/OW: /i ; 1 } @mvgrp ;
@mvgrp = grep { s/.*Unreported[.]World.+20\d\d[.]/UW: /i ; 1 } @mvgrp ;
@mvgrp = grep { s/.*Dispatches.+20\d\d[.]//i ; 1 } @mvgrp ;
@mvgrp = grep { s/^History[.]Channel[.]/HC: /i ; 1 } @mvgrp ;
## Discard any remaining titles from tv serials - the titles left with a year date.
@mvgrp = grep !/[.]\d\d\d\d[.]/, @mvgrp ;
## Keep only the last $entries_mvgroups entries.
@mvgrp = @mvgrp[$#mvgrp-$entries_mvgroups+1..$#mvgrp] ;
## Restrict the length of each title string and tidy up.
for ( my $x = 0 ; $x <= $#mvgrp ; $x++ ) {
$mvgrp[$x] = substr $mvgrp[$x], 0, ($cols - 3) ;
$mvgrp[$x] =~ s/[.]\w{0,2}$// ;
$mvgrp[$x] =~ s/[.]/ /g ;
}
#### DISPLAY LISTS WITH BOXCHARS
## Pretty format the arrays with boxchars.
add_boxchars( \@firsts ) ;
add_boxchars( \@mvgrp ) ;
## Move cursor to top of terminal.
print $tput_up x ($rows - 1) ;
## Print titles to stdout.
say $tput_cel.$c1."#Premieres".$norm ;
foreach my $x ( @firsts ) { say $tput_cel.$x } ;
say $tput_cel ;
say $tput_cel.$c1."#MVGroup".$norm ;
foreach my $x ( @mvgrp ) { say $tput_cel.$x } ;
sleep $tperiod ;
}
#### SUBROUTINES
## arg1 is ref to array, list of lines to grep
## arg2 is ref to array, list of words to fgrep with.
sub grep_list {
my @foo = @{$_[0]} ;
my @bar = @{$_[1]} ;
my @bob = () ;
TOP: foreach my $x ( @foo ) {
foreach my $v ( @bar ) {
my $w = qr/$v/i ;
next TOP if $x =~ $w ;
}
push @bob, $x ;
}
return @bob ;
}
sub colorcode { return "\x1b[0;38;5;".shift."m" }
## arg1 = a ref to array
sub add_boxchars {
my $aa = shift ;
my $lastx = $#$aa ;
## utf8 box chars to draw the tree-list.
my $fork = "${bold}\xE2\x94\x9C${norm}" ;
my $cnr = "${bold}\xE2\x94\x94${norm}" ;
for (my $x = 0 ; $x < $lastx ; $x++ ) { $$aa[$x] = " $c2$fork$norm".$$aa[$x] }
$$aa[$lastx] = " $c2$cnr$norm".$$aa[$lastx] ;
}
#####################################################################################
## flexget-movies.pl #
#####################################################################################
#!/usr/bin/perl
use strict ;
use warnings ;
use v5.14 ;
use feature "switch" ;
use File::Temp qw( tempdir ) ;
use POSIX qw( mkfifo ) ;
use File::Slurp qw( :std ) ;
use Scalar::Util::Numeric qw(isint) ;
use Data::Dump qw( dump ) ;
my $file_movies = "/home/nostromo/flexget-config/lists/x-movies.txt" ;
## Seconds between display update.
my $tperiod = 60 ;
## Num of entries to display for each list.
my $entries_drama = 3 ;
my $entries_thrill = 4 ;
my $entries_scifi = 3 ;
## Exclude titles with these languages.
my @badlang = qw( hindi tamil arabic panjabi malayalam bhojpuri urdu ) ;
#### URXVT CONFIG
my $rows = 16 ;
my $cols = 20 ;
my $urxvt_name = "Movies" ;
my $urxvt_geom = "${cols}x${rows}-19+19" ;
my $urxvt_opts = " -fn -gohu-gohufont-bold-r-normal--14-100-100-100-c-80-iso8859-1" ;
$urxvt_opts .= " -fb -xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1" ;
$urxvt_opts .= " -sbg -fg \"#6B6B66\" -T $urxvt_name -g $urxvt_geom " ;
$urxvt_opts .= ' --color0 \'#40403C\' --color8 \'#40403C\' ' ; ## black
$urxvt_opts .= ' --color4 \'#5C6873\' --color12 \'#5C6873\' ' ; ## blue
#$urxvt_opts .= ' --color7 \'#828275\' --color15 \'#828275\' ' ; ## white
$urxvt_opts .= ' --color7 \'#6B6B66\' --color15 \'#6B6B66\' ' ; ## white
#### ESCAPE CODE CHARS
## Codes used to color the tree-lists.
my $norm = "\x1b[0m" ; ## normal color
my $bold = "\x1b[1m" ; ## bold
my $c1 = colorcode(4) ; ## color for the title (c1) and the title-hash (c5)
my $c2 = colorcode(0) ; ## color for the box-chars
my $c3 = colorcode(7) ;
## Tput escape char combos for piping formatted text into a term.
my $tput_cel = "\x0d\x1b\x5b\x4b" ; # \r$(tput el) -- carriage return & delete to end-of-line
my $tput_clear = "\x1b\x5b\x48\x1b\x5b\x4a" ; # tput clear
my $tput_civis = "\x1b\x5b\x3f\x32\x35\x6c" ; # tput civis - make cursor invisible.
my $tput_up = "\x1b\x4d" ;
#### OPEN THE TERMINAL
## Create a temporary work directory :- http://stackoverflow.com/questions/3817687/in-perl-how-do-i-safely-create-a-temporary-fifo
my $wrkdir = tempdir( CLEANUP=>1 );
chdir $wrkdir ;
## Start the urxvt term. Formatted text to be piped into fifo1 later.
mkfifo("fifo1", 0700) or die "mkfifo(fifo1) failed: $!" ;
system( " urxvt $urxvt_opts -e cat fifo1 & " ) ;
open(FIFO1, "> fifo1") ;
## Set the default buffer to output FIFO1 and to "always flush".
select(FIFO1) ;
$| = 1 ;
## Set an invisible cursor for the urxvt.
print $tput_civis ;
while ( 1 ) {
my @ary = read_file $file_movies ;
chomp @ary ;
my @scifi = my @drama = my @thrill = () ;
TOP: foreach my $x ( @ary ) {
## Separate out the different fields of movie info .
## Discard the movie if it doesn't have english.
( my $name, my $rating, my $genres, my $langs, my $title ) = split '::', $x ;
next if $langs !~ /english/ ;
## Discard the movie if it contains bad language.
foreach my $v ( @badlang ) {
my $w = qr/$v/i ;
next TOP if $langs =~ $w ;
}
given ( $genres ) {
push @scifi, $name."::".$rating when /sci-fi|fantasy/ ;
push @thrill, $name."::".$rating when /thriller/ ;
push @drama, $name."::".$rating when /drama/ ;
}
}
## Keep only the last $entries_xxxx entries.
@drama = @drama[$#drama-$entries_drama+1..$#drama] ;
@thrill = @thrill[$#thrill-$entries_thrill+1..$#thrill] ;
@scifi = @scifi[$#scifi-$entries_scifi+1..$#scifi] ;
## Pretty format the arrays with boxchars.
add_boxchars( \@drama ) ;
add_boxchars( \@thrill ) ;
add_boxchars( \@scifi ) ;
## Move cursor to top of terminal.
print $tput_up x ($rows - 1) ;
## Print the titles to stdout.
say $tput_cel.$c1."#Dramas".$norm ;
foreach my $x ( @drama ) { say $tput_cel.$x } ;
say $tput_cel ;
say $tput_cel.$c1."#Thrillers".$norm ;
foreach my $x ( @thrill ) { say $tput_cel.$x } ;
say $tput_cel ;
say $tput_cel.$c1."#Fantasy/Scifi".$norm ;
foreach my $x ( @scifi ) { say $tput_cel.$x } ;
# say STDERR "+" ;
sleep $tperiod ;
}
#### SUBROUTINES
sub colorcode { return "\x1b[0;38;5;".shift."m" }
## arg1 = a ref to array
sub add_boxchars {
my $aa = shift ;
#my $lastx = $#$aa ;
## utf8 box chars to draw the tree-list.
my $fork = "${bold}\xE2\x94\x9C${norm}" ;
my $cnr = "${bold}\xE2\x94\x94${norm}" ;
for (my $x = 0 ; $x <= $#$aa ; $x++ ) {
my $c = ( $x < $#$aa ) ? $fork : $cnr ;
( my $name, my $rating ) = split '::', $$aa[$x] ;
my $numx = $cols - 4 - length($rating) ;
$name = substr $name, 0, $numx ;
$name =~ s/[\s.]\w{0,2}$// ;
$$aa[$x] = sprintf " $c2$c$norm%-${numx}s $c3%s$norm ", $name, $rating ;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.