From 59d482cad7bb490ddfcbf648f1db8d97c5e0cd8d Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Wed, 25 Nov 2020 11:38:20 +0000 Subject: [PATCH] Update to more recent Ansible roles --- ansible/roles/core/defaults/main.yml | 14 +- ansible/roles/core/files/.bash_aliases | 2 + ansible/roles/core/files/.vimrc | 154 ++++ .../roles/core/files/50unattended-upgrades | 91 +++ ansible/roles/core/files/adduser.sh | 32 + ansible/roles/core/files/authorized_yubikeys | 1 + ansible/roles/core/files/motd | 2 +- ansible/roles/core/files/pathogen.vim | 264 +++++++ .../core/files/ranger/plugins/__init__.py | 0 .../core/files/ranger/plugins/__init__.pyo | Bin 0 -> 136 bytes .../core/files/ranger/plugins/devicons.py | 322 +++++++++ .../core/files/ranger/plugins/devicons.pyo | Bin 0 -> 7007 bytes .../files/ranger/plugins/devicons_linemode.py | 19 + .../ranger/plugins/devicons_linemode.pyo | Bin 0 -> 1281 bytes .../ranger/plugins/ranger_devicons/.gitignore | 2 + .../ranger/plugins/ranger_devicons/LICENSE | 674 ++++++++++++++++++ .../plugins/ranger_devicons/LICENSE_NERDFONT | 22 + .../ranger/plugins/ranger_devicons/Makefile | 18 + .../ranger/plugins/ranger_devicons/README.md | 26 + .../plugins/ranger_devicons/__init__.py | 19 + .../plugins/ranger_devicons/__init__.pyo | Bin 0 -> 1316 bytes .../plugins/ranger_devicons/devicons.py | 322 +++++++++ .../plugins/ranger_devicons/devicons.pyo | Bin 0 -> 7039 bytes .../plugins/ranger_devicons/screenshot.png | Bin 0 -> 100551 bytes ansible/roles/core/files/ranger/rc.conf | 613 ++++++++++++++++ ansible/roles/core/files/sourcerer.vim | 216 ++++++ ansible/roles/core/tasks/configure-bash.yml | 7 +- ansible/roles/core/tasks/configure-ranger.yml | 14 + ansible/roles/core/tasks/configure-ssh.yml | 29 +- ansible/roles/core/tasks/configure-vim.yml | 62 +- ansible/roles/core/tasks/install-apps.yml | 16 +- ansible/roles/core/tasks/main.yml | 3 +- ansible/roles/docker/tasks/docker-install.yml | 10 + ansible/roles/fail2ban.yml | 6 + ansible/roles/fail2ban/defaults/main.yml | 3 +- .../roles/fail2ban/files/fail2ban/jail.local | 13 +- ansible/roles/fail2ban/tasks/configure.yml | 4 +- ansible/roles/fail2ban/tasks/install.yml | 2 +- ansible/roles/fail2ban/tasks/service.yml | 2 +- ansible/roles/nginx.yml | 6 + ansible/roles/nginx/tasks/configure.yml | 2 +- ansible/roles/nginx/tasks/install.yml | 2 +- ansible/roles/nginx/tasks/service.yml | 2 +- ansible/roles/postfix.yml | 6 + ansible/roles/postfix/tasks/configure.yml | 2 +- ansible/roles/postfix/tasks/install.yml | 2 +- ansible/roles/postfix/tasks/service.yml | 2 +- 47 files changed, 2970 insertions(+), 38 deletions(-) create mode 100644 ansible/roles/core/files/.vimrc create mode 100644 ansible/roles/core/files/50unattended-upgrades create mode 100755 ansible/roles/core/files/adduser.sh create mode 100644 ansible/roles/core/files/authorized_yubikeys create mode 100644 ansible/roles/core/files/pathogen.vim create mode 100644 ansible/roles/core/files/ranger/plugins/__init__.py create mode 100644 ansible/roles/core/files/ranger/plugins/__init__.pyo create mode 100755 ansible/roles/core/files/ranger/plugins/devicons.py create mode 100644 ansible/roles/core/files/ranger/plugins/devicons.pyo create mode 100755 ansible/roles/core/files/ranger/plugins/devicons_linemode.py create mode 100644 ansible/roles/core/files/ranger/plugins/devicons_linemode.pyo create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/.gitignore create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/LICENSE create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/LICENSE_NERDFONT create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/Makefile create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/README.md create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.py create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.pyo create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.py create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.pyo create mode 100644 ansible/roles/core/files/ranger/plugins/ranger_devicons/screenshot.png create mode 100644 ansible/roles/core/files/ranger/rc.conf create mode 100644 ansible/roles/core/files/sourcerer.vim create mode 100644 ansible/roles/core/tasks/configure-ranger.yml create mode 100644 ansible/roles/fail2ban.yml create mode 100644 ansible/roles/nginx.yml create mode 100644 ansible/roles/postfix.yml diff --git a/ansible/roles/core/defaults/main.yml b/ansible/roles/core/defaults/main.yml index da20db7..9150d83 100644 --- a/ansible/roles/core/defaults/main.yml +++ b/ansible/roles/core/defaults/main.yml @@ -1,8 +1,16 @@ --- -packages: [git, vim, ssh, libpam-yubico] +packages: [python-apt, git, vim, ssh, libpam-yubico, ranger] authusers: [user1, user2] ssh_port: 22 auth_methods: "publickey,keyboard-interactive" -git_email: "email@domain.com" +git_email: "someemail@gmail.com" git_name: "Shaun Reed" - +vim_plugins: [{ repo: 'dense-analysis/ale', dest: 'ale'}, +{ repo: 'chrisbra/Colorizer', dest: 'colorizer'}, +{ repo: 'ervandew/supertab', dest: 'supertab'}, +{ repo: 'chrisbra/unicode.vim', dest: 'unicode'}, +{ repo: 'vim-airline/vim-airline', dest: 'vim-airline'}, +{ repo: 'vim-airline/vim-airline-themes', dest: 'vim-airline-themes'}, +{ repo: 'mhinz/vim-signify', dest: 'signify'} +] +upgrades_email: someemail@gmail.com diff --git a/ansible/roles/core/files/.bash_aliases b/ansible/roles/core/files/.bash_aliases index ca1807e..4c0482c 100644 --- a/ansible/roles/core/files/.bash_aliases +++ b/ansible/roles/core/files/.bash_aliases @@ -18,3 +18,5 @@ alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo export LS_COLORS="di=1;34:ln=31;47:so=32:pi=33:ex=1;32:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43" export EDITOR=vim +export VISUAL=vim +export PATH=$PATH:/opt/ diff --git a/ansible/roles/core/files/.vimrc b/ansible/roles/core/files/.vimrc new file mode 100644 index 0000000..34d12b8 --- /dev/null +++ b/ansible/roles/core/files/.vimrc @@ -0,0 +1,154 @@ +" Single-quote is a comment written to be read +" Double-quotes are commented out code and can be removed or added + +" General Vim Settings + +" Define function in vim to remove whitespace +fun! TrimWhitespace() + let l:save = winsaveview() + keeppatterns %s/\s\+$//e + call winrestview(l:save) +endfun +"Call this on every attempt to save a file of types defined below.. +autocmd BufWritePre *.cpp,*.h,*.c,*.php :call TrimWhitespace() +""autocmd BufWritePre *.cpp,*.h,*.c,*.php :%s/\s\+$//ge +" Set terminal title when opening file +"" autocmd BufEnter * let &titlestring = ' ' . expand("%:t") +"" set title + +" Set tabwidth=2, adjust Vim shiftwidth to the same +set tabstop=2 shiftwidth=2 + +" expandtab inserts spaces instead of tabs +set expandtab + +" autindent inserts the next line at your current depth +set autoindent + +" mouse=a allows for mouse interaction with vim when supported +set mouse=a + +set number + +" Use Powerline symbols +""let g:airline_powerline_fonts = 1 + +" Enable Syntax Highlighting in Vim +syntax on +" Use Sourcerer color scheme by Xero +colorscheme sourcerer + +" Fix plugin compatibility issues +set nocp +" Allow backspace to remove all types of characters +set backspace=indent,eol,start + +" Custom Vim Keybindings + +" nnoremap " Modify and remove leading quotation + +" CPP Compile +""autocmd FileType cpp nmap :w!g++ -o %:r % && ./%:r + +" Set window jump to custom binding +" default Ctrl-W conflict - closes browser tabs +nnoremap + +nnoremap :!make -C build/ + +" Vim Plugin Settings + +" set rtp+=/path/to/rtp/that/included/pathogen/vim " if needed +" Enable Pathogen plugin manager +execute pathogen#infect() +filetype plugin indent on + +" Set Vim Airline theme +" base16 soda base16_pop laederon night_owl kalisi* ayu_mirage* raven +let g:airline_theme='kalisi' + +" Gitgutter installed for + - diffs in gutters within repo files + +" Ale linter settings +" Hover detail info in preview window +let g:ale_hover_to_preview = 1 +" Hover detail info in balloons +""let g:ale_set_balloons = 1 +let g:ale_sign_error = '' +let g:ale_sign_warning = '' +highlight ALEWarningSign ctermbg=Yellow +highlight ALEWarningSign ctermfg=Black +highlight ALEWarning ctermbg=DarkYellow +highlight ALEWarning ctermfg=White +highlight ALEErrorSign ctermbg=DarkRed +highlight ALEErrorSign ctermfg=White +highlight ALEError ctermfg=DarkRed +nmap (ale_previous_wrap) +nmap (ale_next_wrap) + +" Syntastic syntax checker settings +" See :help syntastic +""set statusline+=%#warningmsg# +""set statusline+=%{SyntasticStatuslineFlag()} +""set statusline+=%* +""let g:syntastic_always_populate_loc_list = 1 +""let g:syntastic_auto_loc_list = 1 +""let g:syntastic_check_on_open = 1 +""let g:syntastic_check_on_wq = 0 + +" Clang_complete settings +""let g:clang_library_path='/usr/lib/llvm-8/lib/' + +" Understand how the plugin works: :h signify-modus-operandi +" Spare the plugin some work and read: :h g:signify_vcs_list +" Signify plugin settings +" Diff gutter within Vim +"" let g:signify_vcs_list = ['git', 'hg'] +"" let g:signify_cursorhold_insert = 1 +"" let g:signify_cursorhold_normal = 1 +"" let g:signify_update_on_bufenter = 0 +"" let g:signify_update_on_focusgained = 1 +" +" Colorizer plugin settings +" See :h colorizer in Vim for more info +""let g:colorizer_colornames = 0 " Don't color literal names, like red, green, etc +let g:colorizer_auto_color = 1 +""let g:colorizer_skip_comments = 1 +""let g:colorizer_auto_filetype ='css,html,vim' +nnoremap :ColorToggle + +" Symbols important to vim / terminal layouts + +set termencoding=utf-8 +set encoding=utf-8 + +" air-line +let g:airline_powerline_fonts = 1 + +if !exists('g:airline_symbols') + let g:airline_symbols = {} +endif + +" unicode symbols +let g:airline_left_sep = '»' +let g:airline_left_sep = '▶' +let g:airline_right_sep = '«' +let g:airline_right_sep = '◀' +let g:airline_symbols.linenr = '␊' +let g:airline_symbols.linenr = '␤' +let g:airline_symbols.linenr = '¶' +let g:airline_symbols.branch = '⎇' +let g:airline_symbols.paste = 'ρ' +let g:airline_symbols.paste = 'Þ' +let g:airline_symbols.paste = '∥' +let g:airline_symbols.whitespace = 'Ξ' + +" airline symbols +let g:airline_left_sep = '' +let g:airline_left_alt_sep = '' +let g:airline_right_sep = '' +let g:airline_right_alt_sep = '' +let g:airline_symbols.branch = '' +let g:airline_symbols.readonly = '' +let g:airline_symbols.linenr = '' + diff --git a/ansible/roles/core/files/50unattended-upgrades b/ansible/roles/core/files/50unattended-upgrades new file mode 100644 index 0000000..9f417ff --- /dev/null +++ b/ansible/roles/core/files/50unattended-upgrades @@ -0,0 +1,91 @@ +// Automatically upgrade packages from these (origin:archive) pairs +// +// Note that in Ubuntu security updates may pull in new dependencies +// from non-security sources (e.g. chromium). By allowing the release +// pocket these get automatically pulled in. +Unattended-Upgrade::Allowed-Origins { + "${distro_id}:${distro_codename}"; + "${distro_id}:${distro_codename}-security"; + // Extended Security Maintenance; doesn't necessarily exist for + // every release and this system may not have it installed, but if + // available, the policy for updates is such that unattended-upgrades + // should also install from here by default. + "${distro_id}ESM:${distro_codename}"; + "${distro_id}:${distro_codename}-updates"; +// "${distro_id}:${distro_codename}-proposed"; +// "${distro_id}:${distro_codename}-backports"; +}; + +// List of packages to not update (regexp are supported) +Unattended-Upgrade::Package-Blacklist { +// "vim"; +// "libc6"; +// "libc6-dev"; +// "libc6-i686"; +}; + +// This option will controls whether the development release of Ubuntu will be +// upgraded automatically. +Unattended-Upgrade::DevRelease "false"; + +// This option allows you to control if on a unclean dpkg exit +// unattended-upgrades will automatically run +// dpkg --force-confold --configure -a +// The default is true, to ensure updates keep getting installed +//Unattended-Upgrade::AutoFixInterruptedDpkg "false"; + +// Split the upgrade into the smallest possible chunks so that +// they can be interrupted with SIGTERM. This makes the upgrade +// a bit slower but it has the benefit that shutdown while a upgrade +// is running is possible (with a small delay) +//Unattended-Upgrade::MinimalSteps "false"; + +// Install all unattended-upgrades when the machine is shutting down +// instead of doing it in the background while the machine is running +// This will (obviously) make shutdown slower +//Unattended-Upgrade::InstallOnShutdown "true"; + +// Send email to this address for problems or packages upgrades +// If empty or unset then no email is sent, make sure that you +// have a working mail setup on your system. A package that provides +// 'mailx' must be installed. E.g. "user@example.com" +Unattended-Upgrade::Mail "{{ upgrades_email }}"; + +// Set this value to "true" to get emails only on errors. Default +// is to always send a mail if Unattended-Upgrade::Mail is set +//Unattended-Upgrade::MailOnlyOnError "true"; + +// Remove unused automatically installed kernel-related packages +// (kernel images, kernel headers and kernel version locked tools). +Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; + +// Do automatic removal of new unused dependencies after the upgrade +// (equivalent to apt-get autoremove) +Unattended-Upgrade::Remove-Unused-Dependencies "true"; + +// Automatically reboot *WITHOUT CONFIRMATION* +// if the file /var/run/reboot-required is found after the upgrade +//Unattended-Upgrade::Automatic-Reboot "false"; + +// If automatic reboot is enabled and needed, reboot at the specific +// time instead of immediately +// Default: "now" +//Unattended-Upgrade::Automatic-Reboot-Time "02:00"; + +// Use apt bandwidth limit feature, this example limits the download +// speed to 70kb/sec +//Acquire::http::Dl-Limit "70"; + +// Enable logging to syslog. Default is False +// Unattended-Upgrade::SyslogEnable "false"; + +// Specify syslog facility. Default is daemon +// Unattended-Upgrade::SyslogFacility "daemon"; + +// Download and install upgrades only on AC power +// (i.e. skip or gracefully stop updates on battery) +// Unattended-Upgrade::OnlyOnACPower "true"; + +// Download and install upgrades only on non-metered connection +// (i.e. skip or gracefully stop updates on a metered connection) +// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true"; diff --git a/ansible/roles/core/files/adduser.sh b/ansible/roles/core/files/adduser.sh new file mode 100755 index 0000000..15f8510 --- /dev/null +++ b/ansible/roles/core/files/adduser.sh @@ -0,0 +1,32 @@ +#!/bin/bash +## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ## +## A custom bash script for creating new linux users. ## +## Syntax: ./adduser.sh ## +############################################################################### + +if [ "$#" -ne 2 ]; then + printf "Illegal number of parameters." + printf "\nUsage: sudo ./adduser.sh " + printf "\n\nAvailable groupd IDs:" + printf "\n60001......61183 Unused | 65520...............65533 Unused" + printf "\n65536.....524287 Unused | 1879048191.....2147483647 Unused\n" + exit +fi + +sudo adduser $1 --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password --uid $2 + +printf "\nEnter 1 if $1 should have sudo privileges. Any other value will continue and make no changes\n" +read choice +if [ $choice -eq 1 ] ; then +printf "\nConfiguring sudo for $1...\n" +sudo usermod -G sudo $1 +fi + +printf "\nEnter 1 to set a password for $1, any other value will exit with no password set\n" +read choice + +if [ $choice -eq 1 ] ; then +printf "\nChanging password for $1...\n" +sudo passwd $1 +fi + diff --git a/ansible/roles/core/files/authorized_yubikeys b/ansible/roles/core/files/authorized_yubikeys new file mode 100644 index 0000000..2148383 --- /dev/null +++ b/ansible/roles/core/files/authorized_yubikeys @@ -0,0 +1 @@ +user:cccckey1cccc:cccckey2cccc diff --git a/ansible/roles/core/files/motd b/ansible/roles/core/files/motd index 1e8eb1a..6e1218b 100644 --- a/ansible/roles/core/files/motd +++ b/ansible/roles/core/files/motd @@ -2,7 +2,7 @@ * - {{ ansible_hostname }} |.===. {{ ansible_fqdn }} + |.===. {}o o{} ----------------------ooO--(_)--Ooo-------------------------- # # diff --git a/ansible/roles/core/files/pathogen.vim b/ansible/roles/core/files/pathogen.vim new file mode 100644 index 0000000..3582fbf --- /dev/null +++ b/ansible/roles/core/files/pathogen.vim @@ -0,0 +1,264 @@ +" pathogen.vim - path option manipulation +" Maintainer: Tim Pope +" Version: 2.4 + +" Install in ~/.vim/autoload (or ~\vimfiles\autoload). +" +" For management of individually installed plugins in ~/.vim/bundle (or +" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your +" .vimrc is the only other setup necessary. +" +" The API is documented inline below. + +if exists("g:loaded_pathogen") || &cp + finish +endif +let g:loaded_pathogen = 1 + +" Point of entry for basic default usage. Give a relative path to invoke +" pathogen#interpose() or an absolute path to invoke pathogen#surround(). +" Curly braces are expanded with pathogen#expand(): "bundle/{}" finds all +" subdirectories inside "bundle" inside all directories in the runtime path. +" If no arguments are given, defaults "bundle/{}", and also "pack/{}/start/{}" +" on versions of Vim without native package support. +function! pathogen#infect(...) abort + if a:0 + let paths = filter(reverse(copy(a:000)), 'type(v:val) == type("")') + else + let paths = ['bundle/{}', 'pack/{}/start/{}'] + endif + if has('packages') + call filter(paths, 'v:val !~# "^pack/[^/]*/start/[^/]*$"') + endif + let static = '^\%([$~\\/]\|\w:[\\/]\)[^{}*]*$' + for path in filter(copy(paths), 'v:val =~# static') + call pathogen#surround(path) + endfor + for path in filter(copy(paths), 'v:val !~# static') + if path =~# '^\%([$~\\/]\|\w:[\\/]\)' + call pathogen#surround(path) + else + call pathogen#interpose(path) + endif + endfor + call pathogen#cycle_filetype() + if pathogen#is_disabled($MYVIMRC) + return 'finish' + endif + return '' +endfunction + +" Split a path into a list. +function! pathogen#split(path) abort + if type(a:path) == type([]) | return a:path | endif + if empty(a:path) | return [] | endif + let split = split(a:path,'\\\@]','\\&','') + endif +endfunction + +" Like findfile(), but hardcoded to use the runtimepath. +function! pathogen#runtime_findfile(file,count) abort + let rtp = pathogen#join(1,pathogen#split(&rtp)) + let file = findfile(a:file,rtp,a:count) + if file ==# '' + return '' + else + return fnamemodify(file,':p') + endif +endfunction + +" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=': diff --git a/ansible/roles/core/files/ranger/plugins/__init__.py b/ansible/roles/core/files/ranger/plugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/core/files/ranger/plugins/__init__.pyo b/ansible/roles/core/files/ranger/plugins/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..9fc3eb9558edefda87dd56b24c18e02dfe0e051f GIT binary patch literal 136 zcmZSn%*(Yga%WsJ0~9aauQ%ZAE?LcOi H05JmqnqVCz literal 0 HcmV?d00001 diff --git a/ansible/roles/core/files/ranger/plugins/devicons.py b/ansible/roles/core/files/ranger/plugins/devicons.py new file mode 100755 index 0000000..d69292f --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/devicons.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# coding=UTF-8 +# These glyphs, and the mapping of file extensions to glyphs +# has been copied from the vimscript code that is present in +# https://github.com/ryanoasis/vim-devicons +import re; +import os; + +# all those glyphs will show as weird squares if you don't have the correct patched font +# My advice is to use NerdFonts which can be found here: +# https://github.com/ryanoasis/nerd-fonts +file_node_extensions = { + '7z' : '', + 'a' : '', + 'ai' : '', + 'apk' : '', + 'asm' : '', + 'asp' : '', + 'aup' : '', + 'avi' : '', + 'bat' : '', + 'bmp' : '', + 'bz2' : '', + 'c' : '', + 'c++' : '', + 'cab' : '', + 'cbr' : '', + 'cbz' : '', + 'cc' : '', + 'class' : '', + 'clj' : '', + 'cljc' : '', + 'cljs' : '', + 'cmake' : '', + 'coffee' : '', + 'conf' : '', + 'cp' : '', + 'cpio' : '', + 'cpp' : '', + 'cs' : '', + 'css' : '', + 'cue' : '', + 'cvs' : '', + 'cxx' : '', + 'd' : '', + 'dart' : '', + 'db' : '', + 'deb' : '', + 'diff' : '', + 'dll' : '', + 'doc' : '', + 'docx' : '', + 'dump' : '', + 'edn' : '', + 'efi' : '', + 'ejs' : '', + 'elf' : '', + 'elm' : '', + 'epub' : '', + 'erl' : '', + 'ex' : '', + 'exe' : '', + 'exs' : '', + 'eex' : '', + 'f#' : '', + 'fifo' : '|', + 'fish' : '', + 'flac' : '', + 'flv' : '', + 'fs' : '', + 'fsi' : '', + 'fsscript' : '', + 'fsx' : '', + 'gem' : '', + 'gif' : '', + 'go' : '', + 'gz' : '', + 'gzip' : '', + 'h' : '', + 'hbs' : '', + 'hrl' : '', + 'hs' : '', + 'htaccess' : '', + 'htpasswd' : '', + 'htm' : '', + 'html' : '', + 'ico' : '', + 'img' : '', + 'ini' : '', + 'iso' : '', + 'jar' : '', + 'java' : '', + 'jl' : '', + 'jpeg' : '', + 'jpg' : '', + 'js' : '', + 'json' : '', + 'jsx' : '', + 'key' : '', + 'less' : '', + 'lha' : '', + 'lhs' : '', + 'log' : '', + 'lua' : '', + 'lzh' : '', + 'lzma' : '', + 'm4a' : '', + 'm4v' : '', + 'markdown' : '', + 'md' : '', + 'mkv' : '', + 'ml' : 'λ', + 'mli' : 'λ', + 'mov' : '', + 'mp3' : '', + 'mp4' : '', + 'mpeg' : '', + 'mpg' : '', + 'msi' : '', + 'mustache' : '', + 'o' : '', + 'ogg' : '', + 'pdf' : '', + 'php' : '', + 'pl' : '', + 'pm' : '', + 'png' : '', + 'pub' : '', + 'ppt' : '', + 'pptx' : '', + 'psb' : '', + 'psd' : '', + 'py' : '', + 'pyc' : '', + 'pyd' : '', + 'pyo' : '', + 'rar' : '', + 'rb' : '', + 'rc' : '', + 'rlib' : '', + 'rom' : '', + 'rpm' : '', + 'rs' : '', + 'rss' : '', + 'rtf' : '', + 's' : '', + 'so' : '', + 'scala' : '', + 'scss' : '', + 'sh' : '', + 'slim' : '', + 'sln' : '', + 'sql' : '', + 'styl' : '', + 'suo' : '', + 't' : '', + 'tar' : '', + 'tgz' : '', + 'ts' : '', + 'twig' : '', + 'vim' : '', + 'vimrc' : '', + 'wav' : '', + 'webm' : '', + 'xbps' : '', + 'xhtml' : '', + 'xls' : '', + 'xlsx' : '', + 'xml' : '', + 'xul' : '', + 'xz' : '', + 'yaml' : '', + 'yml' : '', + 'zip' : '', +} + +dir_node_exact_matches = { +# English + '.git' : '', + 'Desktop' : '', + 'Documents' : '', + 'Downloads' : '', + 'Dotfiles' : '', + 'Dropbox' : '', + 'Music' : '', + 'Pictures' : '', + 'Public' : '', + 'Templates' : '', + 'Videos' : '', +# Spanish + 'Escritorio' : '', + 'Documentos' : '', + 'Descargas' : '', + 'Música' : '', + 'Imágenes' : '', + 'Público' : '', + 'Plantillas' : '', + 'Vídeos' : '', +# French + 'Bureau' : '', + 'Documents' : '', + 'Images' : '', + 'Musique' : '', + 'Publique' : '', + 'Téléchargements' : '', + 'Vidéos' : '', +# Portuguese + 'Documentos' : '', + 'Imagens' : '', + 'Modelos' : '', + 'Música' : '', + 'Público' : '', + 'Vídeos' : '', + 'Área de trabalho' : '', +# Italian + 'Documenti' : '', + 'Immagini' : '', + 'Modelli' : '', + 'Musica' : '', + 'Pubblici' : '', + 'Scaricati' : '', + 'Scrivania' : '', + 'Video' : '', +# German + 'Bilder' : '', + 'Dokumente' : '', + 'Musik' : '', + 'Schreibtisch' : '', + 'Vorlagen' : '', + 'Öffentlich' : '', +# Hungarian + 'Dokumentumok' : '', + 'Képek' : '', + 'Modelli' : '', + 'Zene' : '', + 'Letöltések' : '', + 'Számítógép' : '', + 'Videók' : '', +} + +file_node_exact_matches = { + '.Xauthority' : '', + '.Xdefaults' : '', + '.Xresources' : '', + '.bash_aliases' : '', + '.bashprofile' : '', + '.bash_profile' : '', + '.bash_logout' : '', + '.bash_history' : '', + '.bashrc' : '', + '.dmrc' : '', + '.DS_Store' : '', + '.fasd' : '', + '.fehbg' : '', + '.gitconfig' : '', + '.gitattributes' : '', + '.gitignore' : '', + '.inputrc' : '', + '.jack-settings' : '', + '.mime.types' : '', + '.nvidia-settings-rc' : '', + '.pam_environment' : '', + '.profile' : '', + '.recently-used' : '', + '.selected_editor' : '', + '.vim' : '', + '.vimrc' : '', + '.viminfo' : '', + '.xinitrc' : '', + '.xinputrc' : '', + 'config' : '', + 'Dockerfile' : '', + 'docker-compose.yml' : '', + 'dropbox' : '', + 'exact-match-case-sensitive-1.txt' : 'X1', + 'exact-match-case-sensitive-2' : 'X2', + 'favicon.ico' : '', + 'a.out' : '', + 'bspwmrc' : '', + 'sxhkdrc' : '', + 'Makefile' : '', + 'Makefile.in' : '', + 'Makefile.ac' : '', + 'config.mk' : '', + 'config.m4' : '', + 'config.ac' : '', + 'configure' : '', + 'Rakefile' : '', + 'gruntfile.coffee' : '', + 'gruntfile.js' : '', + 'gruntfile.ls' : '', + 'gulpfile.coffee' : '', + 'gulpfile.js' : '', + 'gulpfile.ls' : '', + 'ini' : '', + 'ledger' : '', + 'package.json' : '', + 'package-lock.json' : '', + '.ncmpcpp' : '', + 'playlists' : '', + 'known_hosts' : '', + 'authorized_keys' : '', + 'license' : '', + 'LICENSE.md' : '', + 'LICENSE' : '', + 'LICENSE.txt' : '', + 'mimeapps.list' : '', + 'node_modules' : '', + 'procfile' : '', + 'react.jsx' : '', + 'README.rst' : '', + 'README.md' : '', + 'README.markdown' : '', + 'README' : '', + 'README.txt' : '', + 'user-dirs.dirs' : '', + 'webpack.config.js' : '', +} + +def devicon(file): + if file.is_directory: return dir_node_exact_matches.get(file.relative_path, '') + return file_node_exact_matches.get(os.path.basename(file.relative_path), file_node_extensions.get(file.extension, '')) diff --git a/ansible/roles/core/files/ranger/plugins/devicons.pyo b/ansible/roles/core/files/ranger/plugins/devicons.pyo new file mode 100644 index 0000000000000000000000000000000000000000..cef62c3d5014cea5f7c59892c46de2f577f88bd2 GIT binary patch literal 7007 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 IKF2q|0p|y$9smFU literal 0 HcmV?d00001 diff --git a/ansible/roles/core/files/ranger/plugins/devicons_linemode.py b/ansible/roles/core/files/ranger/plugins/devicons_linemode.py new file mode 100755 index 0000000..aeca62b --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/devicons_linemode.py @@ -0,0 +1,19 @@ +import ranger.api +from ranger.core.linemode import LinemodeBase +from .devicons import * + +@ranger.api.register_linemode +class DevIconsLinemode(LinemodeBase): + name = "devicons" + + uses_metadata = False + + def filetitle(self, file, metadata): + return devicon(file) + ' ' + file.relative_path + +@ranger.api.register_linemode +class DevIconsLinemodeFile(LinemodeBase): + name = "filename" + + def filetitle(self, file, metadata): + return devicon(file) + ' ' + file.relative_path diff --git a/ansible/roles/core/files/ranger/plugins/devicons_linemode.pyo b/ansible/roles/core/files/ranger/plugins/devicons_linemode.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5ba669256727e7bb1614be74808b5f8cc8576c50 GIT binary patch literal 1281 zcmcIj!EO^V5FPI(X$UDQ2OajzHemuT0|v(MUJRYQBTMvG*78W zNmVIT9daG|z=~#Fn)Rsa5~nl~+aBEzT@zhiD=H3XZy|bP(Z6lcN0^K3o`keNWt?Y9 z)G!qB-qt){RD5DQTkJMR&|ZWik*B`bs5 zE|(@;W$+qMWzTLBm5Fs6qt7{*$^?_iDMjI5ik4q3=A3^vwYQ%f=OY0)vD18I>M5`C zrCU#J?ei9T>9!RcEx!a*G`hFJ@qJl%Bt$CfiHtGJvNm%r%P^3gvXoM<9hN|dlh76A z%s9_6m$heKwm3EJ?7`jzVhwx<>4C79;1?c?`X|k2Qnaz`$FZaOSeCb`-jbaDMluS5 z)c%@ejiN-3H6Ut0jC^WPuKN(E_`W3n$X_h*Bk|bM1^^m7YP=1N?)o1j;9WhC=@AbU z#HSfsr0KemS=xZ~n`LBZdoo_Ec+~cw78BC3 + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/LICENSE_NERDFONT b/ansible/roles/core/files/ranger/plugins/ranger_devicons/LICENSE_NERDFONT new file mode 100644 index 0000000..bde3f5c --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/ranger_devicons/LICENSE_NERDFONT @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Ryan L McIntyre + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/Makefile b/ansible/roles/core/files/ranger/plugins/ranger_devicons/Makefile new file mode 100644 index 0000000..d8062de --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/ranger_devicons/Makefile @@ -0,0 +1,18 @@ +RANGER_DIR=$(if $(XDG_CONFIG_HOME),$(XDG_CONFIG_HOME),$(HOME)/.config)/ranger +PLUGIN_DIR=$(RANGER_DIR)/plugins +RC_FILE=$(RANGER_DIR)/rc.conf + +install: + install -d $(PLUGIN_DIR) + install -b devicons.py $(PLUGIN_DIR)/devicons.py + install -b __init__.py $(PLUGIN_DIR)/devicons_linemode.py + grep -q 'default_linemode devicons' $(RC_FILE) || echo '# a plugin that adds file glyphs / icon support to Ranger:' >> $(RC_FILE) + grep -q 'default_linemode devicons' $(RC_FILE) || echo '# https://github.com/alexanderjeurissen/ranger_devicons' >> $(RC_FILE) + grep -q 'default_linemode devicons' $(RC_FILE) || echo 'default_linemode devicons' >> $(RC_FILE) + +uninstall: + sed -i.old -E '/^# a plugin that adds file glyphs/d' $(RC_FILE) + sed -i.old -E '/^# https:\/\/github.com\/alexanderjeurissen\/ranger_devicons/d' $(RC_FILE) + sed -i.old -E '/^default_linemode devicons/d' $(RC_FILE) + $(RM) $(PLUGIN_DIR)/devicons.py + $(RM) $(PLUGIN_DIR)/devicons_linemode.py diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/README.md b/ansible/roles/core/files/ranger/plugins/ranger_devicons/README.md new file mode 100644 index 0000000..693caf8 --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/ranger_devicons/README.md @@ -0,0 +1,26 @@ +# File icons for the Ranger file manager + +This plugin introduces a new linemode that prefixes file names with a file icon + +![image](https://raw.githubusercontent.com/alexanderjeurissen/ranger_devicons/master/screenshot.png) + +## Prerequisites +This plugin uses glyphs from a patched NERDfont. So in order for this plugin to work you need to +install a NERDfont and set it as the default font for your terminal. + +I personally use the Source Code Pro patched NERDfont(this is also the font displayed in the +screenshot), this and other NERDfonts and the install instructions for these fonts can be found in +the following repository: https://github.com/ryanoasis/nerd-fonts + +## Install instructions +### Stable method: +A makefile is included to install and uninstall this plugin. to install simply run: +`make install` and to uninstall the plugin run `make uninstall`. + +### Experimental method: +Ranger has added support for loading directories in the plugins folder to `master` which makes it easier to install and keep plugins updated. +To install, just clone the repo into the plugins folder: +```bash +git clone https://github.com/alexanderjeurissen/ranger_devicons ~/.config/ranger/plugins/ranger_devicons +``` +Then add `default_linemode devicons` to your `rc.conf`. diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.py b/ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.py new file mode 100644 index 0000000..aeca62b --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.py @@ -0,0 +1,19 @@ +import ranger.api +from ranger.core.linemode import LinemodeBase +from .devicons import * + +@ranger.api.register_linemode +class DevIconsLinemode(LinemodeBase): + name = "devicons" + + uses_metadata = False + + def filetitle(self, file, metadata): + return devicon(file) + ' ' + file.relative_path + +@ranger.api.register_linemode +class DevIconsLinemodeFile(LinemodeBase): + name = "filename" + + def filetitle(self, file, metadata): + return devicon(file) + ' ' + file.relative_path diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.pyo b/ansible/roles/core/files/ranger/plugins/ranger_devicons/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..be4fd7992ec3056b5bcf9db51f823a22b2aa3694 GIT binary patch literal 1316 zcmcIj!EO^V5FPI(X$UDQ2BXivorSC^Jd;S{dqk2e*NR)nA*{i?`xU97E#Gxks~Tp)Dv6|Bg|EHPeR&XGA=VE zY8Z-mZ)=_}Dn2hgTdX!)&|ZWSk#BkPZoH`d)^V2!T+U_sXCio;Ly-VM(LqGPSaeBW zWr=u%zKDu97MG1vF)*?7My7uvA`pF5Bq_<+Q_*JfX%1foM0?&`bR=qfQ8*TT#jXr? z!)95An+&%GRN1qeL}g+f$LMnoWmSeUlU<6!pNW>=EaselE^BW;InGA{aAK$Vs;sBH z%9n0EwY6_ev&|qk#@03%Gg^KLC~S;kgX8;Rc;rPY>xqn^jj78y8xsbyVvJOL?O*~Z zc0yN_i_&?HDXl$wvxTd1W{>%Rz%^hZvIo#!f?s$n>ffYaND0TX9>Uo d$piLSZ2y-{!@ol7cvNwyPShY7s;B*-`VE!)9OwW5 literal 0 HcmV?d00001 diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.py b/ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.py new file mode 100644 index 0000000..d69292f --- /dev/null +++ b/ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# coding=UTF-8 +# These glyphs, and the mapping of file extensions to glyphs +# has been copied from the vimscript code that is present in +# https://github.com/ryanoasis/vim-devicons +import re; +import os; + +# all those glyphs will show as weird squares if you don't have the correct patched font +# My advice is to use NerdFonts which can be found here: +# https://github.com/ryanoasis/nerd-fonts +file_node_extensions = { + '7z' : '', + 'a' : '', + 'ai' : '', + 'apk' : '', + 'asm' : '', + 'asp' : '', + 'aup' : '', + 'avi' : '', + 'bat' : '', + 'bmp' : '', + 'bz2' : '', + 'c' : '', + 'c++' : '', + 'cab' : '', + 'cbr' : '', + 'cbz' : '', + 'cc' : '', + 'class' : '', + 'clj' : '', + 'cljc' : '', + 'cljs' : '', + 'cmake' : '', + 'coffee' : '', + 'conf' : '', + 'cp' : '', + 'cpio' : '', + 'cpp' : '', + 'cs' : '', + 'css' : '', + 'cue' : '', + 'cvs' : '', + 'cxx' : '', + 'd' : '', + 'dart' : '', + 'db' : '', + 'deb' : '', + 'diff' : '', + 'dll' : '', + 'doc' : '', + 'docx' : '', + 'dump' : '', + 'edn' : '', + 'efi' : '', + 'ejs' : '', + 'elf' : '', + 'elm' : '', + 'epub' : '', + 'erl' : '', + 'ex' : '', + 'exe' : '', + 'exs' : '', + 'eex' : '', + 'f#' : '', + 'fifo' : '|', + 'fish' : '', + 'flac' : '', + 'flv' : '', + 'fs' : '', + 'fsi' : '', + 'fsscript' : '', + 'fsx' : '', + 'gem' : '', + 'gif' : '', + 'go' : '', + 'gz' : '', + 'gzip' : '', + 'h' : '', + 'hbs' : '', + 'hrl' : '', + 'hs' : '', + 'htaccess' : '', + 'htpasswd' : '', + 'htm' : '', + 'html' : '', + 'ico' : '', + 'img' : '', + 'ini' : '', + 'iso' : '', + 'jar' : '', + 'java' : '', + 'jl' : '', + 'jpeg' : '', + 'jpg' : '', + 'js' : '', + 'json' : '', + 'jsx' : '', + 'key' : '', + 'less' : '', + 'lha' : '', + 'lhs' : '', + 'log' : '', + 'lua' : '', + 'lzh' : '', + 'lzma' : '', + 'm4a' : '', + 'm4v' : '', + 'markdown' : '', + 'md' : '', + 'mkv' : '', + 'ml' : 'λ', + 'mli' : 'λ', + 'mov' : '', + 'mp3' : '', + 'mp4' : '', + 'mpeg' : '', + 'mpg' : '', + 'msi' : '', + 'mustache' : '', + 'o' : '', + 'ogg' : '', + 'pdf' : '', + 'php' : '', + 'pl' : '', + 'pm' : '', + 'png' : '', + 'pub' : '', + 'ppt' : '', + 'pptx' : '', + 'psb' : '', + 'psd' : '', + 'py' : '', + 'pyc' : '', + 'pyd' : '', + 'pyo' : '', + 'rar' : '', + 'rb' : '', + 'rc' : '', + 'rlib' : '', + 'rom' : '', + 'rpm' : '', + 'rs' : '', + 'rss' : '', + 'rtf' : '', + 's' : '', + 'so' : '', + 'scala' : '', + 'scss' : '', + 'sh' : '', + 'slim' : '', + 'sln' : '', + 'sql' : '', + 'styl' : '', + 'suo' : '', + 't' : '', + 'tar' : '', + 'tgz' : '', + 'ts' : '', + 'twig' : '', + 'vim' : '', + 'vimrc' : '', + 'wav' : '', + 'webm' : '', + 'xbps' : '', + 'xhtml' : '', + 'xls' : '', + 'xlsx' : '', + 'xml' : '', + 'xul' : '', + 'xz' : '', + 'yaml' : '', + 'yml' : '', + 'zip' : '', +} + +dir_node_exact_matches = { +# English + '.git' : '', + 'Desktop' : '', + 'Documents' : '', + 'Downloads' : '', + 'Dotfiles' : '', + 'Dropbox' : '', + 'Music' : '', + 'Pictures' : '', + 'Public' : '', + 'Templates' : '', + 'Videos' : '', +# Spanish + 'Escritorio' : '', + 'Documentos' : '', + 'Descargas' : '', + 'Música' : '', + 'Imágenes' : '', + 'Público' : '', + 'Plantillas' : '', + 'Vídeos' : '', +# French + 'Bureau' : '', + 'Documents' : '', + 'Images' : '', + 'Musique' : '', + 'Publique' : '', + 'Téléchargements' : '', + 'Vidéos' : '', +# Portuguese + 'Documentos' : '', + 'Imagens' : '', + 'Modelos' : '', + 'Música' : '', + 'Público' : '', + 'Vídeos' : '', + 'Área de trabalho' : '', +# Italian + 'Documenti' : '', + 'Immagini' : '', + 'Modelli' : '', + 'Musica' : '', + 'Pubblici' : '', + 'Scaricati' : '', + 'Scrivania' : '', + 'Video' : '', +# German + 'Bilder' : '', + 'Dokumente' : '', + 'Musik' : '', + 'Schreibtisch' : '', + 'Vorlagen' : '', + 'Öffentlich' : '', +# Hungarian + 'Dokumentumok' : '', + 'Képek' : '', + 'Modelli' : '', + 'Zene' : '', + 'Letöltések' : '', + 'Számítógép' : '', + 'Videók' : '', +} + +file_node_exact_matches = { + '.Xauthority' : '', + '.Xdefaults' : '', + '.Xresources' : '', + '.bash_aliases' : '', + '.bashprofile' : '', + '.bash_profile' : '', + '.bash_logout' : '', + '.bash_history' : '', + '.bashrc' : '', + '.dmrc' : '', + '.DS_Store' : '', + '.fasd' : '', + '.fehbg' : '', + '.gitconfig' : '', + '.gitattributes' : '', + '.gitignore' : '', + '.inputrc' : '', + '.jack-settings' : '', + '.mime.types' : '', + '.nvidia-settings-rc' : '', + '.pam_environment' : '', + '.profile' : '', + '.recently-used' : '', + '.selected_editor' : '', + '.vim' : '', + '.vimrc' : '', + '.viminfo' : '', + '.xinitrc' : '', + '.xinputrc' : '', + 'config' : '', + 'Dockerfile' : '', + 'docker-compose.yml' : '', + 'dropbox' : '', + 'exact-match-case-sensitive-1.txt' : 'X1', + 'exact-match-case-sensitive-2' : 'X2', + 'favicon.ico' : '', + 'a.out' : '', + 'bspwmrc' : '', + 'sxhkdrc' : '', + 'Makefile' : '', + 'Makefile.in' : '', + 'Makefile.ac' : '', + 'config.mk' : '', + 'config.m4' : '', + 'config.ac' : '', + 'configure' : '', + 'Rakefile' : '', + 'gruntfile.coffee' : '', + 'gruntfile.js' : '', + 'gruntfile.ls' : '', + 'gulpfile.coffee' : '', + 'gulpfile.js' : '', + 'gulpfile.ls' : '', + 'ini' : '', + 'ledger' : '', + 'package.json' : '', + 'package-lock.json' : '', + '.ncmpcpp' : '', + 'playlists' : '', + 'known_hosts' : '', + 'authorized_keys' : '', + 'license' : '', + 'LICENSE.md' : '', + 'LICENSE' : '', + 'LICENSE.txt' : '', + 'mimeapps.list' : '', + 'node_modules' : '', + 'procfile' : '', + 'react.jsx' : '', + 'README.rst' : '', + 'README.md' : '', + 'README.markdown' : '', + 'README' : '', + 'README.txt' : '', + 'user-dirs.dirs' : '', + 'webpack.config.js' : '', +} + +def devicon(file): + if file.is_directory: return dir_node_exact_matches.get(file.relative_path, '') + return file_node_exact_matches.get(os.path.basename(file.relative_path), file_node_extensions.get(file.extension, '')) diff --git a/ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.pyo b/ansible/roles/core/files/ranger/plugins/ranger_devicons/devicons.pyo new file mode 100644 index 0000000000000000000000000000000000000000..e101d3a49544cdb447c714f00f1baf236f16d959 GIT binary patch literal 7039 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

6af*64wPSA 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 literal 0 HcmV?d00001 diff --git a/ansible/roles/core/files/ranger/rc.conf b/ansible/roles/core/files/ranger/rc.conf new file mode 100644 index 0000000..faa1712 --- /dev/null +++ b/ansible/roles/core/files/ranger/rc.conf @@ -0,0 +1,613 @@ +# =================================================================== +# This file contains the default startup commands for ranger. +# To change them, it is recommended to create the file +# ~/.config/ranger/rc.conf and add your custom commands there. +# +# If you copy this whole file there, you may want to set the environment +# variable RANGER_LOAD_DEFAULT_RC to FALSE to avoid loading it twice. +# +# The purpose of this file is mainly to define keybindings and settings. +# For running more complex python code, please create a plugin in "plugins/" or +# a command in "commands.py". +# +# Each line is a command that will be run before the user interface +# is initialized. As a result, you can not use commands which rely +# on the UI such as :delete or :mark. +# =================================================================== + +# =================================================================== +# == Options +# =================================================================== + +# Which viewmode should be used? Possible values are: +# miller: Use miller columns which show multiple levels of the hierarchy +# multipane: Midnight-commander like multipane view showing all tabs next +# to each other +set viewmode miller +#set viewmode multipane + +# How many columns are there, and what are their relative widths? +set column_ratios 1,3,4 + +# Which files should be hidden? (regular expression) +set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$ + +# Show hidden files? You can toggle this by typing 'zh' +set show_hidden true + +# Ask for a confirmation when running the "delete" command? +# Valid values are "always", "never", "multiple" (default) +# With "multiple", ranger will ask only if you delete multiple files at once. +set confirm_on_delete multiple + +# Which script is used to generate file previews? +# ranger ships with scope.sh, a script that calls external programs (see +# README.md for dependencies) to preview images, archives, etc. +set preview_script ~/.config/ranger/scope.sh + +# Use the external preview script or display simple plain text or image previews? +set use_preview_script true + +# Automatically count files in the directory, even before entering them? +set automatically_count_files true + +# Open all images in this directory when running certain image viewers +# like feh or sxiv? You can still open selected files by marking them. +set open_all_images true + +# Be aware of version control systems and display information. +set vcs_aware false + +# State of the three backends git, hg, bzr. The possible states are +# disabled, local (only show local info), enabled (show local and remote +# information). +set vcs_backend_git enabled +set vcs_backend_hg disabled +set vcs_backend_bzr disabled + +# Use one of the supported image preview protocols +set preview_images false + +# Set the preview image method. Supported methods: +# +# * w3m (default): +# Preview images in full color with the external command "w3mimgpreview"? +# This requires the console web browser "w3m" and a supported terminal. +# It has been successfully tested with "xterm" and "urxvt" without tmux. +# +# * iterm2: +# Preview images in full color using iTerm2 image previews +# (http://iterm2.com/images.html). This requires using iTerm2 compiled +# with image preview support. +# +# * urxvt: +# Preview images in full color using urxvt image backgrounds. This +# requires using urxvt compiled with pixbuf support. +# +# * urxvt-full: +# The same as urxvt but utilizing not only the preview pane but the +# whole terminal window. +set preview_images_method w3m + +# Use a unicode "..." character to mark cut-off filenames? +set unicode_ellipsis false + +# Show dotfiles in the bookmark preview box? +set show_hidden_bookmarks true + +# Which colorscheme to use? These colorschemes are available by default: +# default, jungle, snow, solarized +set colorscheme default + +# Preview files on the rightmost column? +# And collapse (shrink) the last column if there is nothing to preview? +set preview_files true +set preview_directories true +set collapse_preview true + +# Save the console history on exit? +set save_console_history true + +# Draw the status bar on top of the browser window (default: bottom) +set status_bar_on_top false + +# Draw a progress bar in the status bar which displays the average state of all +# currently running tasks which support progress bars? +set draw_progress_bar_in_status_bar true + +# Draw borders around columns? +set draw_borders false + +# Display the directory name in tabs? +set dirname_in_tabs false + +# Enable the mouse support? +set mouse_enabled true + +# Display the file size in the main column or status bar? +set display_size_in_main_column true +set display_size_in_status_bar true + +# Display files tags in all columns or only in main column? +set display_tags_in_all_columns true + +# Set a title for the window? +set update_title false + +# Set the title to "ranger" in the tmux program? +set update_tmux_title false + +# Shorten the title if it gets long? The number defines how many +# directories are displayed at once, 0 turns off this feature. +set shorten_title 3 + +# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? +set tilde_in_titlebar false + +# How many directory-changes or console-commands should be kept in history? +set max_history_size 20 +set max_console_history_size 50 + +# Try to keep so much space between the top/bottom border when scrolling: +set scroll_offset 8 + +# Flush the input after each key hit? (Noticeable when ranger lags) +set flushinput true + +# Padding on the right when there's no preview? +# This allows you to click into the space to run the file. +set padding_right true + +# Save bookmarks (used with mX and `X) instantly? +# This helps to synchronize bookmarks between multiple ranger +# instances but leads to *slight* performance loss. +# When false, bookmarks are saved when ranger is exited. +set autosave_bookmarks true + +# You can display the "real" cumulative size of directories by using the +# command :get_cumulative_size or typing "dc". The size is expensive to +# calculate and will not be updated automatically. You can choose +# to update it automatically though by turning on this option: +set autoupdate_cumulative_size false + +# Turning this on makes sense for screen readers: +set show_cursor false + +# One of: size, natural, basename, atime, ctime, mtime, type, random +set sort natural + +# Additional sorting options +set sort_reverse false +set sort_case_insensitive true +set sort_directories_first true +set sort_unicode false + +# Enable this if key combinations with the Alt Key don't work for you. +# (Especially on xterm) +set xterm_alt_key false + +# Whether to include bookmarks in cd command +set cd_bookmarks true + +# Avoid previewing files larger than this size, in bytes. Use a value of 0 to +# disable this feature. +set preview_max_size 0 + +# Add the highlighted file to the path in the titlebar +set show_selection_in_titlebar true + +# The delay that ranger idly waits for user input, in milliseconds, with a +# resolution of 100ms. Lower delay reduces lag between directory updates but +# increases CPU load. +set idle_delay 2000 + +# When the metadata manager module looks for metadata, should it only look for +# a ".metadata.json" file in the current directory, or do a deep search and +# check all directories above the current one as well? +set metadata_deep_search false + +# Clear all existing filters when leaving a directory +set clear_filters_on_dir_change false + +# Disable displaying line numbers in main column +set line_numbers false + +# =================================================================== +# == Local Options +# =================================================================== +# You can set local options that only affect a single directory. + +# Examples: +# setlocal path=~/downloads sort mtime + +# =================================================================== +# == Command Aliases in the Console +# =================================================================== + +alias e edit +alias q quit +alias q! quitall +alias qa quitall +alias qall quitall +alias setl setlocal + +alias filter scout -prt +alias find scout -aeit +alias mark scout -mr +alias unmark scout -Mr +alias search scout -rs +alias search_inc scout -rts +alias travel scout -aefiklst + +# =================================================================== +# == Define keys for the browser +# =================================================================== + +# Basic +map Q quit! +map q quit +copymap q ZZ ZQ + +map R reload_cwd +map reset +map redraw_window +map abort +map change_mode normal +map ~ set viewmode! + +map i display_file +map ? help +map W display_log +map w taskview_open +map S shell $SHELL + +map : console +map ; console +map ! console shell%space +map @ console -p6 shell %%s +map # console shell -p%space +map s console shell%space +map r chain draw_possible_programs; console open_with%%space +map f console find%space +map cd console cd%space + +# Change the line mode +map Mf linemode filename +map Mi linemode fileinfo +map Mm linemode mtime +map Mp linemode permissions +map Ms linemode sizemtime +map Mt linemode metatitle + +# Tagging / Marking +map t tag_toggle +map ut tag_remove +map " tag_toggle tag=%any +map mark_files toggle=True +map v mark_files all=True toggle=True +map uv mark_files all=True val=False +map V toggle_visual_mode +map uV toggle_visual_mode reverse=True + +# For the nostalgics: Midnight Commander bindings +map help +map display_file +map edit +map copy +map cut +map console mkdir%space +map console delete +map exit + +# In case you work on a keyboard with dvorak layout +map move up=1 +map move down=1 +map move left=1 +map move right=1 +map move to=0 +map move to=-1 +map move down=1 pages=True +map move up=1 pages=True +map move right=1 +#map console delete +map console touch%space + +# VIM-like +copymap k +copymap j +copymap h +copymap l +copymap gg +copymap G +copymap +copymap + +map J move down=0.5 pages=True +map K move up=0.5 pages=True +copymap J +copymap K + +# Jumping around +map H history_go -1 +map L history_go 1 +map ] move_parent 1 +map [ move_parent -1 +map } traverse + +map gh cd ~ +map gc cd ~/.config +map ge cd /etc +map gu cd /usr +map gd cd /dev +map gl cd -r . +map gL cd -r %f +map go cd /opt +map gv cd /var +map gm cd /media +map gM cd /mnt +map gs cd /srv +map gr cd / +map gR eval fm.cd(ranger.RANGERDIR) +map g/ cd / +map g? cd /usr/share/doc/ranger + +# External Programs +map E edit +map du shell -p du --max-depth=1 -h --apparent-size +map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh +map yp shell -f echo -n %d/%f | xsel -i; xsel -o | xsel -i -b +map yd shell -f echo -n %d | xsel -i; xsel -o | xsel -i -b +map yn shell -f echo -n %f | xsel -i; xsel -o | xsel -i -b + +# Filesystem Operations +map = chmod + +map cw console rename%space +map a rename_append +map A eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%")) +map I eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"), position=7) + +map pp paste +map po paste overwrite=True +map pP paste append=True +map pO paste overwrite=True append=True +map pl paste_symlink relative=False +map pL paste_symlink relative=True +map phl paste_hardlink +map pht paste_hardlinked_subtree + +map dD console delete + +map dd cut +map ud uncut +map da cut mode=add +map dr cut mode=remove +map dt cut mode=toggle + +map yy copy +map uy uncut +map ya copy mode=add +map yr copy mode=remove +map yt copy mode=toggle + +# Temporary workarounds +map dgg eval fm.cut(dirarg=dict(to=0), narg=quantifier) +map dG eval fm.cut(dirarg=dict(to=-1), narg=quantifier) +map dj eval fm.cut(dirarg=dict(down=1), narg=quantifier) +map dk eval fm.cut(dirarg=dict(up=1), narg=quantifier) +map ygg eval fm.copy(dirarg=dict(to=0), narg=quantifier) +map yG eval fm.copy(dirarg=dict(to=-1), narg=quantifier) +map yj eval fm.copy(dirarg=dict(down=1), narg=quantifier) +map yk eval fm.copy(dirarg=dict(up=1), narg=quantifier) + +# Searching +map / console search%space +map n search_next +map N search_next forward=False +map ct search_next order=tag +map cs search_next order=size +map ci search_next order=mimetype +map cc search_next order=ctime +map cm search_next order=mtime +map ca search_next order=atime + +# Tabs +map tab_new ~ +map tab_close +map tab_move 1 +map tab_move -1 +map tab_move 1 +map tab_move -1 +map gt tab_move 1 +map gT tab_move -1 +map gn tab_new ~ +map gC tab_close +map uq tab_restore +map tab_open 1 +map tab_open 2 +map tab_open 3 +map tab_open 4 +map tab_open 5 +map tab_open 6 +map tab_open 7 +map tab_open 8 +map tab_open 9 + +# Sorting +map or set sort_reverse! +map oz set sort=random +map os chain set sort=size; set sort_reverse=False +map ob chain set sort=basename; set sort_reverse=False +map on chain set sort=natural; set sort_reverse=False +map om chain set sort=mtime; set sort_reverse=False +map oc chain set sort=ctime; set sort_reverse=False +map oa chain set sort=atime; set sort_reverse=False +map ot chain set sort=type; set sort_reverse=False +map oe chain set sort=extension; set sort_reverse=False + +map oS chain set sort=size; set sort_reverse=True +map oB chain set sort=basename; set sort_reverse=True +map oN chain set sort=natural; set sort_reverse=True +map oM chain set sort=mtime; set sort_reverse=True +map oC chain set sort=ctime; set sort_reverse=True +map oA chain set sort=atime; set sort_reverse=True +map oT chain set sort=type; set sort_reverse=True +map oE chain set sort=extension; set sort_reverse=True + +map dc get_cumulative_size + +# Settings +map zc set collapse_preview! +map zd set sort_directories_first! +map zh set show_hidden! +map set show_hidden! +map zI set flushinput! +map zi set preview_images! +map zm set mouse_enabled! +map zp set preview_files! +map zP set preview_directories! +map zs set sort_case_insensitive! +map zu set autoupdate_cumulative_size! +map zv set use_preview_script! +map zf console filter%space + +# Bookmarks +map ` enter_bookmark %any +map ' enter_bookmark %any +map m set_bookmark %any +map um unset_bookmark %any + +map m draw_bookmarks +copymap m um ` ' + +# Generate all the chmod bindings with some python help: +eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +{0} shell -f chmod u+{0} %s".format(arg)) + +eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -{0} shell -f chmod u-{0} %s".format(arg)) + +# =================================================================== +# == Define keys for the console +# =================================================================== +# Note: Unmapped keys are passed directly to the console. + +# Basic +cmap eval fm.ui.console.tab() +cmap eval fm.ui.console.tab(-1) +cmap eval fm.ui.console.close() +cmap eval fm.ui.console.execute() +cmap redraw_window + +copycmap +copycmap + +# Move around +cmap eval fm.ui.console.history_move(-1) +cmap eval fm.ui.console.history_move(1) +cmap eval fm.ui.console.move(left=1) +cmap eval fm.ui.console.move(right=1) +cmap eval fm.ui.console.move(right=0, absolute=True) +cmap eval fm.ui.console.move(right=-1, absolute=True) +cmap eval fm.ui.console.move_word(left=1) +cmap eval fm.ui.console.move_word(right=1) + +# Line Editing +cmap eval fm.ui.console.delete(-1) +cmap eval fm.ui.console.delete(0) +cmap eval fm.ui.console.delete_word() +cmap eval fm.ui.console.delete_word(backward=False) +cmap eval fm.ui.console.delete_rest(1) +cmap eval fm.ui.console.delete_rest(-1) +cmap eval fm.ui.console.paste() + +# And of course the emacs way +copycmap +copycmap +copycmap +copycmap +copycmap +copycmap +copycmap +copycmap + +# Note: There are multiple ways to express backspaces. (code 263) +# and (code 127). To be sure, use both. +copycmap + +# This special expression allows typing in numerals: +cmap false + +# =================================================================== +# == Pager Keybindings +# =================================================================== + +# Movement +pmap pager_move down=1 +pmap pager_move up=1 +pmap pager_move left=4 +pmap pager_move right=4 +pmap pager_move to=0 +pmap pager_move to=-1 +pmap pager_move down=1.0 pages=True +pmap pager_move up=1.0 pages=True +pmap pager_move down=0.5 pages=True +pmap pager_move up=0.5 pages=True + +copypmap k +copypmap j +copypmap h +copypmap l +copypmap g +copypmap G +copypmap d +copypmap u +copypmap n f +copypmap p b + +# Basic +pmap redraw_window +pmap pager_close +copypmap q Q i +pmap E edit_file + +# =================================================================== +# == Taskview Keybindings +# =================================================================== + +# Movement +tmap taskview_move up=1 +tmap taskview_move down=1 +tmap taskview_move to=0 +tmap taskview_move to=-1 +tmap taskview_move down=1.0 pages=True +tmap taskview_move up=1.0 pages=True +tmap taskview_move down=0.5 pages=True +tmap taskview_move up=0.5 pages=True + +copytmap k +copytmap j +copytmap g +copytmap G +copytmap u +copytmap n f +copytmap p b + +# Changing priority and deleting tasks +tmap J eval -q fm.ui.taskview.task_move(-1) +tmap K eval -q fm.ui.taskview.task_move(0) +tmap dd eval -q fm.ui.taskview.task_remove() +tmap eval -q fm.ui.taskview.task_move(-1) +tmap eval -q fm.ui.taskview.task_move(0) +tmap eval -q fm.ui.taskview.task_remove() + +# Basic +tmap redraw_window +tmap taskview_close +copytmap q Q w diff --git a/ansible/roles/core/files/sourcerer.vim b/ansible/roles/core/files/sourcerer.vim new file mode 100644 index 0000000..7a4d9fc --- /dev/null +++ b/ansible/roles/core/files/sourcerer.vim @@ -0,0 +1,216 @@ +" ██████ ██████ ██ ██ ██████ █████ █████ ██████ █████ ██████ +" ██░░░░ ██░░░░██░██ ░██░░██░░████░░░██ ██░░░██░░██░░████░░░██░░██░░██ +" ░░█████ ░██ ░██░██ ░██ ░██ ░░░██ ░░ ░███████ ░██ ░░░███████ ░██ ░░ +" ░░░░░██░██ ░██░██ ░██ ░██ ░██ ██░██░░░░ ░██ ░██░░░░ ░██ +" ██████ ░░██████ ░░██████░███ ░░█████ ░░██████░███ ░░██████░███ +" ░░░░░░ ░░░░░░ ░░░░░░ ░░░ ░░░░░ ░░░░░░ ░░░ ░░░░░░ ░░░ +" r e a d c o d e l i k e a w i z a r d +" +" sourcerer by xero harrison (http://sourcerer.xero.nu) +" ├─ based on sorcerer by Jeet Sukumaran (http://jeetworks.org) +" └─ based on mustang by Henrique C. Alves (hcarvalhoalves@gmail.com) + +set background=dark +hi clear + +if exists("syntax_on") + syntax reset +endif + +let colors_name = "sourcerer" + + +" █▓▒░ GUI colors +hi Normal guifg=#c2c2b0 guibg=#222222 gui=NONE +hi ColorColumn guifg=NONE guibg=#1c1c1c +hi Cursor guifg=NONE guibg=#626262 gui=NONE +hi CursorColumn guibg=#2d2d2d +hi CursorLine guibg=#2d2d2d +hi DiffAdd guifg=#000000 guibg=#3cb371 gui=NONE +hi DiffDelete guifg=#000000 guibg=#aa4450 gui=NONE +hi DiffChange guifg=#000000 guibg=#4f94cd gui=NONE +hi DiffText guifg=#000000 guibg=#8ee5ee gui=NONE +hi Directory guifg=#1e90ff guibg=NONE gui=NONE +hi ErrorMsg guifg=#ff6a6a guibg=NONE gui=bold +hi FoldColumn guifg=#68838b guibg=#4B4B4B gui=bold +hi Folded guifg=#406060 guibg=#232c2c gui=NONE +hi IncSearch guifg=#ffffff guibg=#ff4500 gui=bold +hi LineNr guifg=#878787 guibg=#3A3A3A gui=NONE +hi MatchParen guifg=#fff000 guibg=NONE gui=bold +hi ModeMsg guifg=#afafaf guibg=#222222 gui=bold +hi MoreMsg guifg=#2e8b57 guibg=NONE gui=bold +hi NonText guifg=#404050 guibg=NONE gui=NONE + +" completions +hi Pmenu guifg=#A8A8A8 guibg=#3A3A3A +hi PmenuSel guifg=#000000 guibg=#528B8B +hi PmenuSbar guifg=#000000 guibg=#528B8B +hi PmenuThumb guifg=#000000 guibg=#528B8B + +hi Question guifg=#00ee00 guibg=NONE gui=bold +hi Search guifg=#000000 guibg=#d6e770 gui=bold +hi SignColumn guifg=#ffffff guibg=NONE gui=NONE +hi SpecialKey guifg=#505060 guibg=NONE gui=NONE +hi SpellBad guisp=#ee2c2c gui=undercurl +hi SpellCap guisp=#0000ff gui=undercurl +hi SpellLocal guisp=#008b8b gui=undercurl +hi SpellRare guisp=#ff00ff gui=undercurl +hi StatusLine guifg=#000000 guibg=#808070 gui=bold +hi StatusLineNC guifg=#000000 guibg=#404c4c gui=italic +hi VertSplit guifg=#404c4c guibg=#404c4c gui=NONE +hi TabLine guifg=fg guibg=#d3d3d3 gui=underline +hi TabLineFill guifg=fg guibg=NONE gui=reverse +hi TabLineSel guifg=fg guibg=NONE gui=bold +hi Title guifg=#528b8b guibg=NONE gui=bold +hi Visual guifg=#000000 guibg=#6688aa gui=NONE +hi WarningMsg guifg=#ee9a00 guibg=NONE gui=NONE +hi WildMenu guifg=#000000 guibg=#87ceeb gui=NONE +hi ExtraWhitespace guifg=fg guibg=#528b8b gui=NONE + +" syntax highlighting +hi Comment guifg=#686858 gui=italic +hi Boolean guifg=#ff9800 gui=NONE +hi String guifg=#779b70 gui=NONE +hi Identifier guifg=#9ebac2 gui=NONE +hi Function guifg=#faf4c6 gui=NONE +hi Type guifg=#7e8aa2 gui=NONE +hi Statement guifg=#90b0d1 gui=NONE +hi Keyword guifg=#90b0d1 gui=NONE +hi Constant guifg=#ff9800 gui=NONE +hi Number guifg=#cc8800 gui=NONE +hi Special guifg=#719611 gui=NONE +hi PreProc guifg=#528b8b gui=NONE +hi Todo guifg=#8f6f8f guibg=#202020 gui=italic,underline,bold + +" diff +hi diffOldFile guifg=#88afcb guibg=NONE gui=italic +hi diffNewFile guifg=#88afcb guibg=NONE gui=italic +hi diffFile guifg=#88afcb guibg=NONE gui=italic +hi diffLine guifg=#88afcb guibg=NONE gui=italic +hi link diffSubname diffLine +hi diffAdded guifg=#3cb371 guibg=NONE gui=NONE +hi diffRemoved guifg=#aa4450 guibg=NONE gui=NONE +hi diffChanged guifg=#4f94cd guibg=NONE gui=NONE +hi link diffOnly Constant +hi link diffIdentical Constant +hi link diffDiffer Constant +hi link diffBDiffer Constant +hi link diffIsA Constant +hi link diffNoEOL Constant +hi link diffCommon Constant +hi link diffComment Constant + +" python +hi pythonException guifg=#90b0d1 guibg=NONE gui=NONE +hi pythonExClass guifg=#996666 guibg=NONE gui=NONE +hi pythonDecorator guifg=#888555 guibg=NONE gui=NONE +hi link pythonDecoratorFunction pythonDecorator + +" █▓▒░ 256 colors +hi Normal cterm=NONE ctermbg=NONE ctermfg=145 +hi ColorColumn cterm=NONE ctermbg=16 ctermfg=NONE +hi Cursor cterm=NONE ctermbg=241 ctermfg=fg +hi CursorColumn cterm=NONE ctermbg=16 ctermfg=fg +hi CursorLine cterm=NONE ctermbg=236 ctermfg=fg +hi DiffAdd cterm=NONE ctermbg=71 ctermfg=16 +hi DiffDelete cterm=NONE ctermbg=124 ctermfg=16 +hi DiffChange cterm=NONE ctermbg=68 ctermfg=16 +hi DiffText cterm=NONE ctermbg=117 ctermfg=16 +hi Directory cterm=NONE ctermbg=234 ctermfg=33 +hi ErrorMsg cterm=bold ctermbg=NONE ctermfg=203 +hi FoldColumn cterm=bold ctermbg=239 ctermfg=66 +hi Folded cterm=NONE ctermbg=16 ctermfg=60 +hi IncSearch cterm=bold ctermbg=202 ctermfg=231 +hi LineNr cterm=NONE ctermbg=237 ctermfg=102 +hi MatchParen cterm=bold ctermbg=NONE ctermfg=226 +hi ModeMsg cterm=bold ctermbg=NONE ctermfg=145 +hi MoreMsg cterm=bold ctermbg=234 ctermfg=29 +hi NonText cterm=NONE ctermbg=NONE ctermfg=59 +hi Pmenu cterm=NONE ctermbg=238 ctermfg=231 +hi PmenuSbar cterm=NONE ctermbg=250 ctermfg=fg +hi PmenuSel cterm=NONE ctermbg=149 ctermfg=16 +hi Question cterm=bold ctermbg=NONE ctermfg=46 +hi Search cterm=bold ctermbg=185 ctermfg=16 +hi SignColumn cterm=NONE ctermbg=NONE ctermfg=231 +hi SpecialKey cterm=NONE ctermbg=NONE ctermfg=59 +hi SpellBad cterm=undercurl ctermbg=NONE ctermfg=196 +hi SpellCap cterm=undercurl ctermbg=NONE ctermfg=21 +hi SpellLocal cterm=undercurl ctermbg=NONE ctermfg=30 +hi SpellRare cterm=undercurl ctermbg=NONE ctermfg=201 +hi StatusLine cterm=bold ctermbg=101 ctermfg=16 +hi StatusLineNC cterm=NONE ctermbg=102 ctermfg=16 +hi VertSplit cterm=NONE ctermbg=102 ctermfg=102 +hi TabLine cterm=bold ctermbg=102 ctermfg=16 +hi TabLineFill cterm=NONE ctermbg=102 ctermfg=16 +hi TabLineSel cterm=bold ctermbg=16 ctermfg=59 +hi Title cterm=bold ctermbg=NONE ctermfg=66 +hi Visual cterm=NONE ctermbg=67 ctermfg=16 +hi WarningMsg cterm=NONE ctermbg=234 ctermfg=208 +hi WildMenu cterm=NONE ctermbg=116 ctermfg=16 +hi ExtraWhitespace cterm=NONE ctermbg=66 ctermfg=fg + +hi Comment cterm=NONE ctermbg=NONE ctermfg=59 +hi Boolean cterm=NONE ctermbg=NONE ctermfg=208 +hi String cterm=NONE ctermbg=NONE ctermfg=101 +hi Identifier cterm=NONE ctermbg=NONE ctermfg=145 +hi Function cterm=NONE ctermbg=NONE ctermfg=230 +hi Type cterm=NONE ctermbg=NONE ctermfg=103 +hi Statement cterm=NONE ctermbg=NONE ctermfg=110 +hi Keyword cterm=NONE ctermbg=NONE ctermfg=110 +hi Constant cterm=NONE ctermbg=NONE ctermfg=208 +hi Number cterm=NONE ctermbg=NONE ctermfg=172 +hi Special cterm=NONE ctermbg=NONE ctermfg=64 +hi PreProc cterm=NONE ctermbg=NONE ctermfg=66 +hi Todo cterm=bold,underline ctermbg=234 ctermfg=96 + +hi diffOldFile cterm=NONE ctermbg=NONE ctermfg=67 +hi diffNewFile cterm=NONE ctermbg=NONE ctermfg=67 +hi diffFile cterm=NONE ctermbg=NONE ctermfg=67 +hi diffLine cterm=NONE ctermbg=NONE ctermfg=67 +hi diffAdded cterm=NONE ctermfg=NONE ctermfg=71 +hi diffRemoved cterm=NONE ctermfg=NONE ctermfg=124 +hi diffChanged cterm=NONE ctermfg=NONE ctermfg=68 +hi link diffSubname diffLine +hi link diffOnly Constant +hi link diffIdentical Constant +hi link diffDiffer Constant +hi link diffBDiffer Constant +hi link diffIsA Constant +hi link diffNoEOL Constant +hi link diffCommon Constant +hi link diffComment Constant + +hi pythonClass cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonDecorator cterm=NONE ctermbg=NONE ctermfg=101 +hi pythonExClass cterm=NONE ctermbg=NONE ctermfg=95 +hi pythonException cterm=NONE ctermbg=NONE ctermfg=110 +hi pythonFunc cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonFuncParams cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonKeyword cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonParam cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonRawEscape cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonSuperclasses cterm=NONE ctermbg=NONE ctermfg=fg +hi pythonSync cterm=NONE ctermbg=NONE ctermfg=fg + +hi Conceal cterm=NONE ctermbg=248 ctermfg=252 +hi Error cterm=NONE ctermbg=196 ctermfg=231 +hi Ignore cterm=NONE ctermbg=NONE ctermfg=234 +hi InsertModeCursorLine cterm=NONE ctermbg=16 ctermfg=fg +hi NormalModeCursorLine cterm=NONE ctermbg=235 ctermfg=fg +hi PmenuThumb cterm=reverse ctermbg=NONE ctermfg=fg +hi StatusLineAlert cterm=NONE ctermbg=160 ctermfg=231 +hi StatusLineUnalert cterm=NONE ctermbg=238 ctermfg=144 +hi Test cterm=NONE ctermbg=NONE ctermfg=fg +hi Underlined cterm=underline ctermbg=NONE ctermfg=111 +hi VisualNOS cterm=bold,underline ctermbg=NONE ctermfg=fg +hi cCursor cterm=reverse ctermbg=NONE ctermfg=fg +hi iCursor cterm=NONE ctermbg=210 ctermfg=16 +hi lCursor cterm=NONE ctermbg=145 ctermfg=234 +hi nCursor cterm=NONE ctermbg=NONE ctermfg=145 +hi vCursor cterm=NONE ctermbg=201 ctermfg=16 + +hi Pmenu cterm=NONE ctermfg=248 ctermbg=237 +hi PmenuSel cterm=NONE ctermfg=16 ctermbg=66 +hi PmenuSbar cterm=NONE ctermfg=16 ctermbg=66 +hi PmenuThumb cterm=NONE ctermfg=16 ctermbg=66 + diff --git a/ansible/roles/core/tasks/configure-bash.yml b/ansible/roles/core/tasks/configure-bash.yml index a3df8c6..5182c20 100644 --- a/ansible/roles/core/tasks/configure-bash.yml +++ b/ansible/roles/core/tasks/configure-bash.yml @@ -10,4 +10,9 @@ - name: Set skeleton files for new users template: src=files/.bash_aliases dest=/etc/skel/.bash_aliases - + +- name: Configure unattended upgrades + template: + src: files/50unattended-upgrades + dest: /etc/apt/apt.conf.d/50unattended-upgrades + diff --git a/ansible/roles/core/tasks/configure-ranger.yml b/ansible/roles/core/tasks/configure-ranger.yml new file mode 100644 index 0000000..c20562a --- /dev/null +++ b/ansible/roles/core/tasks/configure-ranger.yml @@ -0,0 +1,14 @@ +--- +- name: Configure ranger + copy: + src: files/ranger + dest: "{{ item }}" + with_items: + - /home/ansibleuser/.config + - /etc/skel/.config + +- name: Set ranger permissions + file: + dest: /home/ansibleuser/.config/ranger/ + group: ansibleuser + owner: ansibleuser diff --git a/ansible/roles/core/tasks/configure-ssh.yml b/ansible/roles/core/tasks/configure-ssh.yml index cc94d4d..1845ca2 100644 --- a/ansible/roles/core/tasks/configure-ssh.yml +++ b/ansible/roles/core/tasks/configure-ssh.yml @@ -11,17 +11,22 @@ template: src=files/sshd dest=/etc/pam.d/sshd - name: Add authusers file - copy: - dest: "/etc/authusers" - content: | - user1 - user2 + lineinfile: + dest: /etc/authusers + line: '{{ item }}' + with_items: + - 'user1' + - 'user2' - name: Add authorized_yubikeys file copy: - dest: "/etc/ssh/authorized_yubikeys" - content: | - user:cccckey1cccc:cccckey2cccc + src: files/authorized_yubikeys + dest: /etc/ssh/ + +- name: Copy adduser.sh script + copy: + src: files/adduser.sh + dest: /home/ansibleuser/ - name: Add custom /etc/hosts lineinfile: @@ -29,15 +34,15 @@ line: '{{ item }}' with_items: - '127.0.0.1 localhost' - - '127.0.0.2 www.otherhost.com otherhost' + - '123.123.123.12 some.domain.com somewhere' + - '12.12.12.12 other.domains.com somewhereelse' - name: Add SSH Keys lineinfile: - dest: /home/ansible/.ssh/authorized_keys + dest: /home/ansibleuser/.ssh/authorized_keys line: '{{ item }}' with_items: - - 'ssh-idrsa AAZ1NTE5AAAAIA+ndydG+ddddpdddaabvbumkiuyk7778678676547564563434XwmnYb user@host' - + - 'ssh-rsa 1232346A+7654475n4x5y6GL657+V6mJ5Yp23s6I6o4+6N ansibleuser@host' - name: Copy ssh configuration file template: src=files/sshd_config dest=/etc/ssh/sshd_config diff --git a/ansible/roles/core/tasks/configure-vim.yml b/ansible/roles/core/tasks/configure-vim.yml index 6cfdbc9..838d2e6 100644 --- a/ansible/roles/core/tasks/configure-vim.yml +++ b/ansible/roles/core/tasks/configure-vim.yml @@ -1,10 +1,60 @@ --- -- name: Clone github.com/shaunrd0/klips +- name: Create vim directories + file: + path: "{{ item }}" + state: directory + with_items: + - /home/ansibleuser/.vim/ + - /home/ansibleuser/.vim/colors/ + - /home/ansibleuser/.vim/plugin/ + - /home/ansibleuser/.vim/doc/ + - /home/ansibleuser/.vim/bundle/ + - /home/ansibleuser/.vim/autoload/ + - /etc/skel/.vim/ + - /etc/skel/.vim/colors/ + - /etc/skel/.vim/plugin/ + - /etc/skel/.vim/doc/ + - /etc/skel/.vim/bundle/ + - /etc/skel/.vim/autoload/ + +- name: Install Pathogen, sourcerer theme + copy: + src: files/{{ item.src }} + dest: /home/ansibleuser/.vim/{{ item.dest }} + with_items: + - { src: 'pathogen.vim', dest: 'autoload/pathogen.vim'} + - { src: 'sourcerer.vim', dest: 'colors/sourcerer.vim'} + +- name: Install sourcerer theme + copy: + src: files/pathogen.vim + dest: /home/ansibleuser/.vim/autoload/ + +- name : Install vim plugins git: - repo: https://github.com/shaunrd0/klips.git - clone: yes - dest: /etc/klips/ + repo: https://github.com/{{ item.repo }} + dest: /home/ansibleuser/.vim/bundle/{{ item.dest }} + with_items: "{{ vim_plugins }}" -- name: Run Vim setup script - script: /etc/ansible/roles/core/files/setup-vim.sh +- name: Install Pathogen, sourcerer theme within skeleton files + copy: + src: files/{{ item.src }} + dest: /etc/skel/.vim/{{ item.dest }} + with_items: + - { src: 'pathogen.vim', dest: 'autoload/pathogen.vim'} + - { src: 'sourcerer.vim', dest: 'colors/sourcerer.vim'} + +- name: Install vim plugins within skeleton files + git: + repo: https://github.com/{{ item.repo }} + dest: /etc/skel/.vim/bundle/{{ item.dest }} + with_items: "{{ vim_plugins }}" + +- name: Configure vim + template: + src: files/.vimrc + dest: "{{ item }}" + with_items: + - /home/ansibleuser/.vimrc + - /etc/skel/.vimrc diff --git a/ansible/roles/core/tasks/install-apps.yml b/ansible/roles/core/tasks/install-apps.yml index 4233fc2..1d7aa3c 100644 --- a/ansible/roles/core/tasks/install-apps.yml +++ b/ansible/roles/core/tasks/install-apps.yml @@ -1,4 +1,18 @@ --- - name: Install packages - apt: name="{{ item }}" state=latest + package: name="{{ item }}" state=present with_items: "{{ packages }}" +- name: Ensure package lists are up-to-date + apt: + update_cache: yes +- name: Ensure packages are up-to-date + apt: + upgrade: dist +- name: Remove unused packages from the cache + apt: + autoclean: yes +- name: Remove dependencies that are no longer required + apt: + autoremove: yes + + diff --git a/ansible/roles/core/tasks/main.yml b/ansible/roles/core/tasks/main.yml index bcb46d3..dbfa82a 100644 --- a/ansible/roles/core/tasks/main.yml +++ b/ansible/roles/core/tasks/main.yml @@ -13,7 +13,8 @@ - import_tasks: configure-git.yml # Vim -#- import_tasks: configure-vim.yml +- import_tasks: configure-vim.yml +- import_tasks: configure-ranger.yml # Bash - import_tasks: configure-bash.yml diff --git a/ansible/roles/docker/tasks/docker-install.yml b/ansible/roles/docker/tasks/docker-install.yml index f47b1cb..7119449 100644 --- a/ansible/roles/docker/tasks/docker-install.yml +++ b/ansible/roles/docker/tasks/docker-install.yml @@ -25,3 +25,13 @@ state: present notify: restart docker +- name: Install python-pip package + package: + name: python-pip + state: latest + +- name: Install Docker python packages + pip: + name: docker + name: docker-compose + diff --git a/ansible/roles/fail2ban.yml b/ansible/roles/fail2ban.yml new file mode 100644 index 0000000..193d48f --- /dev/null +++ b/ansible/roles/fail2ban.yml @@ -0,0 +1,6 @@ +--- +- hosts: plumbi + become: yes + roles: + - fail2ban + diff --git a/ansible/roles/fail2ban/defaults/main.yml b/ansible/roles/fail2ban/defaults/main.yml index 6ecbedc..5bedec8 100644 --- a/ansible/roles/fail2ban/defaults/main.yml +++ b/ansible/roles/fail2ban/defaults/main.yml @@ -10,7 +10,8 @@ nginx_http_auth: "true" nginx_nobinary: "true" nginx_nohome: "true" nginx_noproxy: "true" -nginx_noscan: "true" +nginx_wplogin: "true" +nginx_noscan: "true" nginx_noenv: "true" nginx_noscript: "true" sshd: "true" diff --git a/ansible/roles/fail2ban/files/fail2ban/jail.local b/ansible/roles/fail2ban/files/fail2ban/jail.local index 40156d3..30efbba 100644 --- a/ansible/roles/fail2ban/files/fail2ban/jail.local +++ b/ansible/roles/fail2ban/files/fail2ban/jail.local @@ -394,7 +394,16 @@ port = http,https filter = nginx-noenv logpath = /var/log/nginx/access.log maxretry = 1 -bantime = 4 +bantime = 4h + +[nginx-wplogin] +enabled = {{ nginx_wplogin }} +port = http,https +filter = nginx-wplogin +logpath = /var/log/nginx/access.log +maxretry = 1 +bantime = 4h + [nginx-nobinary] @@ -407,7 +416,7 @@ bantime = -1 [sshd-badproto] enabled = {{ sshd_badproto }} -port = {{ ssh+port }} +port = {{ ssh_port }} filter = sshd-badproto logpath = /var/log/auth.log maxretry = 1 diff --git a/ansible/roles/fail2ban/tasks/configure.yml b/ansible/roles/fail2ban/tasks/configure.yml index e332f81..1cb9f73 100644 --- a/ansible/roles/fail2ban/tasks/configure.yml +++ b/ansible/roles/fail2ban/tasks/configure.yml @@ -1,7 +1,7 @@ --- -- name: Copy fail2ban jail.local configuration +- name: Copy jail.local configuration template: src=files/fail2ban/jail.local dest=/etc/fail2ban/jail.local -- name: Copy fail2ban jail filters +- name: Copy jail filters copy: src=files/fail2ban/filter.d/ dest=/etc/fail2ban/filter.d/ diff --git a/ansible/roles/fail2ban/tasks/install.yml b/ansible/roles/fail2ban/tasks/install.yml index 4233fc2..df33b1d 100644 --- a/ansible/roles/fail2ban/tasks/install.yml +++ b/ansible/roles/fail2ban/tasks/install.yml @@ -1,4 +1,4 @@ --- - name: Install packages - apt: name="{{ item }}" state=latest + package: name="{{ item }}" state=present with_items: "{{ packages }}" diff --git a/ansible/roles/fail2ban/tasks/service.yml b/ansible/roles/fail2ban/tasks/service.yml index c985524..43ac755 100644 --- a/ansible/roles/fail2ban/tasks/service.yml +++ b/ansible/roles/fail2ban/tasks/service.yml @@ -1,3 +1,3 @@ --- -- name: Start and enable fail2ban service +- name: Start and enable services service: name=fail2ban state=restarted enabled=yes diff --git a/ansible/roles/nginx.yml b/ansible/roles/nginx.yml new file mode 100644 index 0000000..3cac957 --- /dev/null +++ b/ansible/roles/nginx.yml @@ -0,0 +1,6 @@ +--- +- hosts: plumbi + become: yes + roles: + - nginx + diff --git a/ansible/roles/nginx/tasks/configure.yml b/ansible/roles/nginx/tasks/configure.yml index 1468f8f..150377e 100644 --- a/ansible/roles/nginx/tasks/configure.yml +++ b/ansible/roles/nginx/tasks/configure.yml @@ -1,5 +1,5 @@ --- -- name: Copy nginx configuration file +- name: Copy nginx.cong configuration template: src=files/nginx/nginx.conf dest=/etc/nginx/nginx.conf - name: Copy index.html file diff --git a/ansible/roles/nginx/tasks/install.yml b/ansible/roles/nginx/tasks/install.yml index 4233fc2..df33b1d 100644 --- a/ansible/roles/nginx/tasks/install.yml +++ b/ansible/roles/nginx/tasks/install.yml @@ -1,4 +1,4 @@ --- - name: Install packages - apt: name="{{ item }}" state=latest + package: name="{{ item }}" state=present with_items: "{{ packages }}" diff --git a/ansible/roles/nginx/tasks/service.yml b/ansible/roles/nginx/tasks/service.yml index aefe3d6..cbdc118 100644 --- a/ansible/roles/nginx/tasks/service.yml +++ b/ansible/roles/nginx/tasks/service.yml @@ -1,3 +1,3 @@ --- -- name: Start and enable nginx service +- name: Start and enable services service: name=nginx state=restarted enabled=yes diff --git a/ansible/roles/postfix.yml b/ansible/roles/postfix.yml new file mode 100644 index 0000000..e88bbd2 --- /dev/null +++ b/ansible/roles/postfix.yml @@ -0,0 +1,6 @@ +--- +- hosts: plumbi + become: yes + roles: + - postfix + diff --git a/ansible/roles/postfix/tasks/configure.yml b/ansible/roles/postfix/tasks/configure.yml index fdcc49c..7ef6b53 100644 --- a/ansible/roles/postfix/tasks/configure.yml +++ b/ansible/roles/postfix/tasks/configure.yml @@ -1,5 +1,5 @@ --- -- name: Copy postfix configuration template +- name: Copy configuration template template: src=files/postfix/main.cf dest=/etc/postfix/main.cf - name: Copy postfix sasl_passwd diff --git a/ansible/roles/postfix/tasks/install.yml b/ansible/roles/postfix/tasks/install.yml index 4233fc2..df33b1d 100644 --- a/ansible/roles/postfix/tasks/install.yml +++ b/ansible/roles/postfix/tasks/install.yml @@ -1,4 +1,4 @@ --- - name: Install packages - apt: name="{{ item }}" state=latest + package: name="{{ item }}" state=present with_items: "{{ packages }}" diff --git a/ansible/roles/postfix/tasks/service.yml b/ansible/roles/postfix/tasks/service.yml index 40e2109..099a108 100644 --- a/ansible/roles/postfix/tasks/service.yml +++ b/ansible/roles/postfix/tasks/service.yml @@ -1,3 +1,3 @@ --- -- name: Start and enable postfix service +- name: Start and enable services service: name=postfix state=restarted enabled=yes