diff --git a/2fa.py b/2fa.py index c11897f..50c2add 100644 --- a/2fa.py +++ b/2fa.py @@ -35,11 +35,11 @@ secret = input('secret : ') or pyotp.random_base32() uri = pyotp.totp.TOTP(secret).provisioning_uri(name, issuer) qr = qrgen(uri).replace(' ', ' ')[:-1] max_len = len(qr.split('\n')[1]) -print(uri+'\n'+qr) +print(f'{uri}\n{qr}') del name, issuer, uri, qr while True: code = pyotp.TOTP(secret).now() seconds = int(time.strftime('%S')) remain = 60-seconds if seconds >= 30 else 30-seconds - print(f'{code} ({remain})'.center(max_len), end='\r') + print(f'{code} ({remain})'.center(max_len), end='\r') time.sleep(1) \ No newline at end of file diff --git a/acidbox/setup b/acidbox/setup index aa27fa6..462d262 100755 --- a/acidbox/setup +++ b/acidbox/setup @@ -1,7 +1,7 @@ #!/bin/sh set -e -function setup_motd() { +setup_motd() { RESET='\033[0m' GREEN='\033[0;32m' BGREEN='\033[1;32m' @@ -11,7 +11,7 @@ function setup_motd() { RED='\033[1;31m' BLUE='\033[1;34m' UBLUE='\033[4;34m' - echo "╔═══════════════════════╦══════════════════════════════════════════════════════════════╗ + echo -e "╔═══════════════════════╦══════════════════════════════════════════════════════════════╗ ║${GREEN} ▄▄▄· ▄▄· ▪ ·▄▄▄▄ ${RESET}║ ${RED}Connection Notice${RESET} ║ ║${GREEN} ▐█ ▀█ ▐█ ▌▪██ ██▪ ██ ${RESET}╟──────────────────────────────────────────────────────────────╢ ║${GREEN} ▄█▀▀█ ██ ▄▄▐█·▐█· ▐█▌ ${RESET}║ ║ @@ -33,7 +33,7 @@ ${YELLOW}Type ${BGREEN}cmds${YELLOW} to see a list of commands available.${RESET ${GREY}*${YELLOW} Stay in your home directory, keep the system clean, and make regular backups." > /etc/motd } -function setup_user() { +setup_user() { sudo useradd -m -G ssh -s /bin/bash $1 mkdir /home/$1/.scripts wget -O /home/$1/.bashrc https://git.supernets.org/acidvegas/acidbox/blob/master/files/.bashrc @@ -43,4 +43,6 @@ function setup_user() { wget -O /home/$1/.scripts/vhosts https://git.supernets.org/acidvegas/acidbox/blob/master/files/vhosts echo "clear && reset" > /home/$1/.bash_logout echo "[[ -f ~/.bashrc ]] && . ~/.bashrc" > /home/$1/.bash_profile -} \ No newline at end of file +} + +setup_motd \ No newline at end of file diff --git a/btkb.sh b/btkb.sh deleted file mode 100644 index 6b56fa3..0000000 --- a/btkb.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -sudo pacman -S bluez bluez-utils -sudo systemctl enable bluetooth && sudo systemctl start bluetooth -sudo sed -i 's/#AutoEnable=false/AutoEnable=true/' /etc/bluetooth/main.conf -bluetoothctl power on -bluetoothctl agent KeyboardOnly -bluetoothctl pairable on -bluetoothctl scan on -bluetoothctl pair CC:C5:0A:20:91:5B -bluetoothctl trust CC:C5:0A:20:91:5B -bluetoothctl connect CC:C5:0A:20:91:5B -bluetoothctl scan off \ No newline at end of file diff --git a/docs/gpg.md b/docs/gpg.md index af24aba..6689b38 100644 --- a/docs/gpg.md +++ b/docs/gpg.md @@ -1,4 +1,6 @@ -# Create a key +# GPG Cheat Sheet + +## Create a key `gpg --expert --full-generate-key` * RSA (set your own capabilities) * Set to Certify only. @@ -10,7 +12,7 @@ * `adduid` * `save` -# Backup key +## Backup key * `mv ~/.gnupg/secring.gpg ~/.backup/gpg/` * `mv ~/.gnupg/pubring.gpg ~/.backup/gpg/` * `gpg -a --export-secret-key > secret_key.gpg` @@ -20,25 +22,25 @@ * `gpg --list-secret-keys` * `rm secret_subkeys.gpg` -# Revoke cert +## Revoke cert * `gpg -a --output revoke.asc --gen-revoke ''` -# Import/Export public key +## Import/Export public key * `gpg --import public.key` * `gpg --output public.key --armor --export ` -# Import/Export private key +## Import/Export private key * `gpg --export-secret-keys --armor > privkey.asc` * `gpg --import privkey.asc` -# Edit keys +## Edit keys * `gpg --edit-key ` -# List (secret) keys +## List (secret) keys * `gpg --list-keys` * `gpg --list-secret-keys` -# Encrypt/Decrypt +## Encrypt/Decrypt * `gpg --recipient user-id --encrypt doc` * `gpg --output doc --decrypt doc.gpg` @@ -47,26 +49,26 @@ or... * `gpg -c --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65536 doc` * `gpg --output doc --decrypt doc.gpg` -# Signing +## Signing * `gpg --output doc.sig --sign doc` * `gpg --output doc.sig --clearsign doc` * `gpg --output doc.sig --detach-sig doc` -# Verify +## Verify * `gpg --verify doc.sig` * `gpg --verify archlinux-version.iso.sig` * `gpg --verify archlinux-version.iso.sig /path/to/archlinux-version.iso` * `gpg --with-fingerprint ` -# Send keys +## Send keys * `gpg --send-keys ` * `gpg --refresh-keys` -# Get keys +## Get keys * `gpg --recv-key ''` * `gpg --fingerprint ''` -# Sign key +## Sign key * `gpg --lsign-key ''` or... diff --git a/docs/ssh.md b/docs/ssh.md index d3fd080..4bc551f 100644 --- a/docs/ssh.md +++ b/docs/ssh.md @@ -1,8 +1,9 @@ -A full write-up on OpenSSH usage with security in mind. +# SSH Security +> A full write-up on OpenSSH usage with security in mind. --- -# Table of Contents +## Table of Contents * [Generating An SSH Key Pair](#generating-an-ssh-key-pair) - [Linux](#linux) - [Windows](#windows) @@ -29,8 +30,8 @@ A full write-up on OpenSSH usage with security in mind. --- -## Generating An SSH Key Pair -### Linux +### Generating An SSH Key Pair +#### Linux Generate a key using the **Ed25519** algorithm with 500 KDF rounds: * `ssh-keygen -t ed25519 -a 500 -C "$(whoami)@$(hostname)-$(date -I)"` @@ -42,7 +43,7 @@ You only need to backup your private key. Public keys can be regenerated from th Copy your public key to clipboard: * `cat ~/.ssh/acidvegas@pi-2017-01-01.pub` -### Windows +#### Windows Download & run [puttygen](https://the.earth.li/~sgtatham/putty/latest/w32/puttygen.exe). Once opened, change the key type to **ED25519** under the *Parameters* box, and then click the *Generate* button. @@ -53,8 +54,8 @@ You only need to backup your private key. Public keys can be regenerated by clic Copy the data in the box labeled *Public key for pasting into OpenSSH authorized_keys file*. -## Getting Your Client To Use Your SSH Key -### Linux +### Getting Your Client To Use Your SSH Key +#### Linux * `ssh -p 65150 -i ~/.ssh/acidvegas@pi-2017-01-01 acidvegas@192.168.1.10` or... @@ -71,7 +72,7 @@ Host acidbox * `chmod 600 ~/.ssh/config` * Usage: `ssh acidbox` -### Windows +#### Windows Download & run the [putty](https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe) client. Once opened, select `Connection -> SSH -> Auth` from the *Category* box. Click the *Browse* button and select your private key. @@ -84,8 +85,8 @@ SSH into your server by clicking your saved session from the *Saved Sessions* bo --- -## Setup Server -### Harden OpenSSH Daemon +### Setup Server +#### Harden OpenSSH Daemon * `nano /etc/ssh/sshd_config` ``` AddressFamily any @@ -128,7 +129,7 @@ Protocol 2 * The `Port` option should be set to a non-standard port *(High-value port number recommended)*. * The `PrintMotd` option can be changed to **yes** if the file `/etc/motd` exists. This is shown after the user authenticates. -### Create A New User On The Server +#### Create A New User On The Server Create a new user on the server with a password: * `useradd -m -s /bin/bash acidvegas` * `passwd acidvegas` @@ -137,7 +138,7 @@ Create an **ssh** group and add your user to the group. * `groupadd ssh` * `gpasswd -a acidvegas ssh` -### Copy Your Public Key To Your Shell +#### Copy Your Public Key To Your Shell * `nano /etc/ssh/authorized_keys/acidvegas` *(Paste your public key data in this file)* **Note:** This is only required if you are using the `AuthorizedKeysFile /etc/ssh/authorized_keys/%u` line in your `sshd_config` file. For using the standard `~/.ssh/authorized_keys` file, do the follow: @@ -152,8 +153,8 @@ Create an **ssh** group and add your user to the group. --- -# Extra Security -### Allow Incoming SSH Connections Through IPTables +### Extra Security +#### Allow Incoming SSH Connections Through IPTables ``` iptables -A INPUT -i eth0 -p tcp --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 65150 -m conntrack --ctstate ESTABLISHED -j ACCEPT @@ -164,10 +165,10 @@ You can also allow only incomming connection from a specific IP address instead iptables -A INPUT -i eth0 -p tcp -s 192.168.1.99 --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT ``` -### Lock Users In A Chroot Jail Environment +#### Lock Users In A Chroot Jail Environment See [mkchroot](https://github.com/acidvegas/mkchroot) repository for details. -### Port Knocking +#### Port Knocking The following is an example which uses the port knocking sequence `8881 -> 7777 -> 9991` to open port 65150 for 30 seconds. ##### Server @@ -216,8 +217,8 @@ Download & install the [knockd](http://www.zeroflux.org/projects/knock) package. stop_command = /usr/bin/iptables -D TCP -s %IP% -p tcp --dport 65150 -j ACCEPT ``` -##### Knocking Your Server -###### Using Nmap +#### Knocking Your Server +##### Using Nmap Download & install the [nmap](https://nmap.org/) package. * `nano knock.sh` @@ -232,12 +233,12 @@ done ``` * Usage: `sh knock.sh example.server.com 8881 7777 9991` -###### Using Knockd +##### Using Knockd Download & install the [knockd](http://www.zeroflux.org/projects/knock) package. * `knock -v example.server.com 8881:tcp 7777:tcp 9991:tcp` -### Jump Hosts +#### Jump Hosts * `ssh -J ` The `` option can be `user@host`, `user@host:port` or an host setup in your `~/.ssh/config`. @@ -265,7 +266,7 @@ Connect to your target host with `ssh targetbox` --- -## Sources +### Sources * https://wiki.archlinux.org/index.php/Port_knocking * https://wiki.archlinux.org/index.php/SSH_keys * https://wiki.mozilla.org/Security/Guidelines/OpenSSH diff --git a/gitremote.sh b/gitremote.sh deleted file mode 100644 index ce6bb3f..0000000 --- a/gitremote.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -set -e -for u in $HOME/dev/git/*/; do - for d in $(find $u -name .git -type d -prune | sort); do - u=$(basename $u) - r=$(basename -s .git `git --git-dir $d config --get remote.origin.url`) - echo "updating $r..." - git -C $d remote remove origin - git -C $d remote add origin git@github.com:$s/$r.git - git -C $d remote set-url --add --push origin git@github.com:$u/$r.git - git -C $d remote set-url --add --push origin git@gitlab.com:$u/$r.git - git -C $d remote set-url --add --push origin git@contra:$r.git - done -done \ No newline at end of file diff --git a/mkchroot b/mkchroot new file mode 100755 index 0000000..4b22e2c --- /dev/null +++ b/mkchroot @@ -0,0 +1,153 @@ +#!/bin/sh +set -e + +CHROOT_BASE="/var/jail" + +display_help() { + echo "usage: mkchroot [option]" + echo -e "\nexample: mkchroot --create=acidvegas bash cp irssi ls mkdir mv rm screen wget" + echo -e "\noptions:" + echo " -c, --create=USER create a new chroot jail" + echo " -d, --destroy=USER destroy a chroot jail" + echo " -l, --list list chroot jails" + echo " -h, --help display this help and exit" +} + +create_jail() { + [ $EUID -ne 0 ] && echo "insufficent privledges" && exit 1 + if [ ${#1} -ne 2 ]; then + CHROOT_USER="${1#*=}" + CHROOT_CMDS="${@:2}" + else + CHROOT_USER=$2 + CHROOT_CMDS="${@:3}" + fi + CHROOT_DIR="$CHROOT_BASE/$CHROOT_USER" + CHROOT_PWD="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1)" + [ -d $CHROOT_DIR ] && echo "chroot jail already exists for $CHROOT_USER at $CHROOT_DIR" && exit 1 + echo "creating initial directory structure..." + mkdir -v $CHROOT_DIR + mkdir -pv $CHROOT_DIR/{dev,etc,home,proc,usr} + mkdir -v $CHROOT_DIR/dev/pts + mkdir -v $CHROOT_DIR/home/$CHROOT_USER + mkdir -v $CHROOT_DIR/usr/share + echo "making required devices nodes..." + mknod -m 666 $CHROOT_DIR/dev/null c 1 3 + echo "created device node: $CHROOT_DIR/dev/null" + mknod -m 666 $CHROOT_DIR/dev/tty c 5 0 + echo "created device node: $CHROOT_DIR/dev/tty" + mknod -m 666 $CHROOT_DIR/dev/random c 1 8 + echo "created device node: $CHROOT_DIR/dev/random" + mknod -m 666 $CHROOT_DIR/dev/zero c 1 5 + echo "created device node: $CHROOT_DIR/dev/zero" + echo "copying required shared libraries..." + for x in ${CHROOT_CMDS[@]}; do + for y in $(ldd $(which $x)|grep -v dynamic|cut -d " " -f 3|sed 's/://'|sort|uniq); do + cp --parents -v $y $CHROOT_DIR + done + done + echo "copying additional required files..." + if [ ! -d $CHROOT_DIR/bin ] && [ -d $CHROOT_DIR/usr/bin ]; then + cp -r $CHROOT_DIR/usr/bin $CHROOT_DIR/bin # This can be improved. + fi + if [ ! -d $CHROOT_DIR/lib ] && [ -d $CHROOT_DIR/usr/lib ]; then + cp -r $CHROOT_DIR/usr/lib $CHROOT_DIR/lib # This can be improved. + fi + cp -v /etc/{hosts,ld.so.cache,ld.so.conf,localtime,nsswitch.conf,resolv.conf} $CHROOT_DIR/etc/ + cp -v /lib/ld-linux.so.* $CHROOT_DIR/lib/ + cp -rv /lib/terminfo/ $CHROOT_DIR/lib/ + cp -rv /usr/share/terminfo/ $CHROOT_DIR/usr/share/ + grep $CHROOT_USER /etc/passwd > $CHROOT_DIR/etc/passwd + grep $CHROOT_USER /etc/group > $CHROOT_DIR/etc/group + grep $CHROOT_USER /etc/shadow > $CHROOT_DIR/etc/shadow + echo -e "[[ \$- != *i* ]] && return\nalias ls='ls --color=auto'\nPS1='\e[1;30mjail\e[0m | \e[1;34m> \e[0;32m\w \e[0;37m: '" > $CHROOT_DIR/home/$CHROOT_USER/.bash_profile + if ! id $CHROOT_USER >/dev/null 2>&1; then + useradd -s /bin/bash -M -p $CHROOT_PWD $CHROOT_USER + echo "added $CHROOT_USER user" + fi + if [ ! $(getent group jail) ]; then + groupadd jail + echo "added jail group" + fi + if ! getent group jail | grep &>/dev/null "\b${CHROOT_USER}\b"; then + gpasswd -a $CHROOT_USER jail + echo "added $CHROOT_USER to jail group" + fi + echo "setting permissions..." + chown -v root:root $CHROOT_DIR + chown -v root:tty $CHROOT_DIR/dev/tty + chown -v $CHROOT_USER:$CHROOT_USER $CHROOT_DIR/home/$CHROOT_USER + chmod -Rv 755 $CHROOT_DIR/home/$CHROOT_USER + chattr +i $CHROOT_DIR/etc/group + chattr +i $CHROOT_DIR/etc/hosts + chattr +i $CHROOT_DIR/etc/nsswitch.conf + chattr +i $CHROOT_DIR/etc/passwd + chattr +i $CHROOT_DIR/etc/resolv.conf + chattr +i $CHROOT_DIR/etc/shadow + echo "mounting pseudoterminal slave device on $CHROOT_DIR/dev/pts" + if ! grep -q "devpts $CHROOT_DIR/dev/pts devpts rw,noatime,mode=600,ptmxmode=000 0 0" /etc/fstab; then + echo -e "\ndevpts $CHROOT_DIR/dev/pts devpts rw,noatime,mode=600,ptmxmode=000 0 0" >> /etc/fstab + mount -av + fi + if ! grep -q "proc $CHROOT_DIR/proc proc rw,noatime,gid=26,hidepid=2 0 0" /etc/fstab; then + echo -e "\nproc $CHROOT_DIR/proc proc rw,noatime,gid=26,hidepid=2 0 0" >> /etc/fstab + mount -av + fi + if grep -q "AuthorizedKeysFile" /etc/ssh/sshd_config; then + if ! grep -q "AuthorizedKeysFile /etc/ssh/authorized_keys/%u" /etc/ssh/sshd_config; then + sed 's/AuthorizedKeysFile.*/AuthorizedKeysFile /etc/ssh/authorized_keys/%u/' /etc/ssh/sshd_config > /etc/ssh/sshd_config + echo "updated sshd_config with AuthorizedKeysFile" + fi + else + sed -i "1iAuthorizedKeysFile /etc/ssh/authorized_keys/%u" /etc/ssh/sshd_config + fi + if ! grep $'Match Group jail\n\tChrootDirectory /var/jail/%u' /etc/ssh/sshd_config; then + echo -e "\nMatch Group jail\n\tChrootDirectory /var/jail/%u" >> /etc/ssh/sshd_config + echo "updated sshd_config with ChrootDirectory" + fi + echo -e "\nchroot jail for $CHROOT_USER created at $CHROOT_DIR" + echo "password for $CHROOT_USER is: $CHROOT_PWD" +} + +destroy_jail() { + [ $EUID -ne 0 ] && echo "insufficent privledges" && exit 1 + if [[ ${#1} -ne 2 ]]; then + CHROOT_USER="${1#*=}" + else + CHROOT_USER=$2 + fi + CHROOT_DIR="$CHROOT_BASE/$CHROOT_USER" + if mount | grep -q "$CHROOT_DIR/dev/pts"; then + umount -v $CHROOT_DIR/dev/pts + echo "unmounted pseudoterminal slave device" + fi + if mount | grep -q "$CHROOT_DIR/proc"; then + umount -v $CHROOT_DIR/proc + echo "unmounted proc device" + fi + if [ -d $CHROOT_DIR ]; then + chattr -i $CHROOT_DIR/etc/* + rm -rfv $CHROOT_DIR + fi + if id $CHROOT_USER >/dev/null 2>&1; then + userdel -f $CHROOT_USER + echo "deleted $CHROOT_USER user" + fi + echo "jail destroyed" +} + +list_jails() { + CHROOT_DIRS=$(getent group jail | cut -d: -f4 | sed 's/,/ /g') + for i in ${CHROOT_DIRS[@]}; do + echo " * $i" + done +} + +[ "$#" -eq 0 ] && echo -e "invalid or missing arguments\n" && display_help && exit 1 +case $1 in + -c|--create=*) create_jail "$@" ;; + -d|--destroy=*) destroy_jail "$@" ;; + -l|--list) list_jails ;; + -h|--help) display_help ;; + *) echo -e "invalid or missing arguments\n"; display_help ; exit 1;; +esac diff --git a/networking/ap.py b/networking/ap.py deleted file mode 100644 index 48545fc..0000000 --- a/networking/ap.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -import re, subprocess - -interface = 'wlp1s0' - -def between(source, start, stop): - data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source) - if data : return data.group(1) - else : return False - -output = subprocess.check_output(f'sudo iwlist {interface} scanning | egrep \'Cell |Channel|Frequency|Encryption|Quality|ESSID|Mode\'', shell=True).decode() -access_points = output.split(' Cell ')[1:] -print('\033[30m\033[47mMAC Address Channel Frequency Quality Signal Mode Encryption ESSID\033[0m') -for ap in access_points: - address = between(ap, 'Address: ', '\n') - channel = between(ap, 'Channel:', '\n').ljust(7) - frequency = between(ap, 'Frequency:', ' GHz')[:3] - quality = between(ap, 'Quality=', ' Signal') - signal = between(ap, 'Signal level=', ' dBm') - encryption = between(ap, 'Encryption key:', '\n').ljust(10) - essid = between(ap, 'ESSID:\"', '\"\n') - mode = between(ap, 'Mode:', '\n') - print(f'{address} | {channel} | {frequency} GHz | {quality} | {signal} dBm | {mode} | {encryption} | {essid}') \ No newline at end of file diff --git a/networking/discover.py b/networking/discover.py index 23d9538..d3a4343 100644 --- a/networking/discover.py +++ b/networking/discover.py @@ -4,7 +4,7 @@ import subprocess def portscan(ip): ports = list() try: - cmd = subprocess.check_output('sudo nmap -F ' + ip, shell=True).decode() + cmd = subprocess.check_output('nmap -F ' + ip, shell=True).decode() output = cmd.split('SERVICE')[1].split('MAC')[0].split('\n') for item in output: port = item.split('/')[0] @@ -17,7 +17,7 @@ def portscan(ip): def scanhosts(subnet): data = list() matrix = {'ip':list(),'host':list(),'ports':list()} - cmd = subprocess.check_output(f'sudo nmap -sP {subnet}/24', shell=True).decode() + cmd = subprocess.check_output(f'nmap -sP {subnet}/24', shell=True).decode() output = cmd.split('Nmap scan report for ')[1:-1] for item in output: ip = item.split('\n')[0] diff --git a/progress.sh b/progress.sh new file mode 100644 index 0000000..a090f90 --- /dev/null +++ b/progress.sh @@ -0,0 +1,7 @@ +PROGRESS='#' +for PERCENT in {1..100}; do + echo -ne "$PERCENT%\t$PROGRESS\r" + PROGRESS="$PROGRESS#" + sleep 0.05 +done +echo -e "\n" \ No newline at end of file diff --git a/scales.py b/scales.py deleted file mode 100644 index 8cbe94b..0000000 --- a/scales.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python -# guitar scales generator - developed by acidvegas in python (https://acid.vegas/random) - -scales = { - 'algerian' : '2131131', # 1 = Half-step | 2 = Whole-step | 3 = Whole-step-Half-step - 'aeolian' : '2122122', - 'blues' : '321132', - 'chromatic' : '1111111', - 'dorian' : '2122212', - 'half_whole_diminished' : '12121212', - 'harmonic_minor' : '2122131', - 'ionian' : '2212221', - 'locrian' : '1221222', - 'lydian' : '2221221', - 'major' : '2212221', - 'major_pentatonic' : '22323', - 'melodic_minor' : '2122221', - 'mixolydian' : '2212212', - 'natural_minor' : '2122122', - 'persian' : '1311231', - 'phrygian' : '1222122', - 'whole_half_diminished' : '21212121', - 'whole_tone' : '2222222' -} - -def generate_notes(key): - notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#'] - while notes[0] != key: - notes.append(notes.pop(0)) - return notes - -def generate_scale(string, scale_notes, full=False): - notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper()) - notes.append(notes[0]) - for index,note in enumerate(notes): - if note in scale_notes: - notes[index] = notes[index].center(5, '-') - else: - notes[index] = '-'*5 - return notes - -def get_pattern(pattern): - new_pattern = list() - for step in pattern: - if step == '1' : new_pattern.append('H') - elif step == '2' : new_pattern.append('W') - elif step == '3' : new_pattern.append('WH') - return ' '.join(new_pattern) - -def scale(type, key): - last = 0 - notes = generate_notes(key) - scale_notes = [notes[0],] - for step in scales[type]: - last += int(step) - if last >= len(notes): - last -= len(notes) - scale_notes.append(notes[last]) - return scale_notes - -def print_scale(root, type, full=False): - if root.upper() not in ('A','A#','B','C','C#','D','D#','E','F','F#','G','G#'): - raise SystemExit('invalid root note') - elif type.lower() not in scales: - raise SystemExit('invalid scale type') - else: - frets = (24,147) if full else (12,75) - print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1])) - print(' ┌' + '┬'.join('─'*5 for x in range(frets[0])) + '┐') - print('0 │' + '│'.join(str(x).center(5) for x in range(1,frets[0]+1)) + '│') - print(' ├' + '┼'.join('─'*5 for x in range(frets[0])) + '┤') - scale_notes = scale(type, root) - for string in ('eBGDAE'): - string_notes = generate_scale(string, scale_notes, full) - print(string + ' │' + '│'.join(note.center(5, '-') for note in string_notes[1:]) + '│') - print(' └' + '┴'.join('─'*5 for x in range(frets[0])) + '┘') - print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1])) - -def print_scales(): - max_key = max(len(x) for x in scales) - max_value = max(len(get_pattern(scales[x])) for x in scales) - print('NAME'.ljust(max_key+3) + 'PATTERN'.rjust(max_value)) - for name, pattern in scales.items(): - print(name.ljust(max_key) + ' │ ' + get_pattern(pattern).rjust(max_value)) - -# Main -print_scales() -print_scale('F#','major')