Skip to content

Instantly share code, notes, and snippets.

@cpl
Last active March 3, 2018 16:19
Show Gist options
  • Save cpl/653bfe66c3a05cc33b1f67dcc91f06b0 to your computer and use it in GitHub Desktop.
Save cpl/653bfe66c3a05cc33b1f67dcc91f06b0 to your computer and use it in GitHub Desktop.
ad [beta]
#!/usr/bin/python
"""Create UNIX environment alias shortcuts."""
import sys
import os
from aluminium.utils import Paths
from aluminium.utils import initialize_config
STORE_FILE = os.path.join(Paths.CONFIG_DIR.value, 'ad', 'ads')
STRING_CMD = "alias %s='cd %s'" # For creating cd commands
STRING_ALS = "%s=%s" # For creating alias shortcuts
HELP_MSG = '''\
USAGE:
ad [-c] [-d PATH] [-f] <alias>
ad del (<alias_number>)
ad [(-h|-l)]
OPTIONS:
-c Create a command alias instead of a variable alias.
-d PATH Create an alias (command or variable) to a given PATH.
-f Force alias creation, ignore path error.
-l, --list List active aliases, their number and type.
-h, --help Display this help message.
'''
def initialize():
"""Create the aluminium config directory, ad directory and files."""
initialize_config()
with open(STORE_FILE, 'a'):
pass
print('Please source %s to your system aliases' % STORE_FILE)
def create(path, alias, mode=0):
"""Create an alias or command based on the mode."""
if not is_duplicate(path, alias):
selected_string = None
# Select which format string to use
if mode == 0:
selected_string = STRING_ALS
elif mode == 1:
selected_string = STRING_CMD
else:
raise Exception('Undefined mode for ad, mode: %d' % mode)
# Write the new alias/command to the ads file
selected_string += '\n'
with open(STORE_FILE, 'a') as store:
store.write(selected_string % (alias, path))
def list_store():
"""List all existing aliases."""
with open(STORE_FILE, 'r') as store:
lines = store.readlines()
# Check for empty store file
if len(lines) == 0:
print('Alias store file is empty.')
return
# Print header
print('%4s %4s %10s %40s' % ('NUM', 'TYPE', 'ALIAS', 'PATH'))
# Read store file entries
for index, alias in enumerate(lines):
alias = alias.rstrip().split('=')
alias_type = 'COM' if alias[0].startswith('alias') else 'VAR'
# Read alias name and path based on type
if alias_type == 'VAR':
alias_name = alias[0]
alias_path = alias[1]
else:
alias_name = alias[0].split(' ')[1]
alias_path = alias[1].split(' ')[:-1]
# Replace long home path with ~ short sign
alias_path = alias_path.replace(Paths.HOME.value, '~')
# Print rows
print('%4d %4s %10s %40s' % (index,
alias_type,
alias_name,
alias_path))
def is_duplicate(user_path, user_alias):
"""Check for duplicates."""
with open(STORE_FILE, 'r') as store:
for index, alias in enumerate(store.readlines()):
# Read alias type
alias = alias.rstrip().split('=')
alias_type = 'COM' if alias[0].startswith('alias') else 'VAR'
# Read alias name and path based on type
if alias_type == 'VAR':
alias_name = alias[0]
alias_path = alias[1]
else:
alias_name = alias[0].split(' ')[1]
alias_path = alias[1].split(' ')[:-1]
# Check for duplicates
if alias_path == user_path:
print('DUPLICATE ALIAS PATH FOUND:')
print('%4s %4s %10s %40s' % ('NUM', 'TYPE', 'ALIAS', 'PATH'))
print('[%4d] %4s %10s %40s' % (index,
alias_type,
alias_name,
alias_path))
return True
elif alias_name == user_alias:
print('DUPLICATE ALIAS NAME FOUND:')
print('%4s %4s %10s %40s' % ('NUM', 'TYPE', 'ALIAS', 'PATH'))
print('%4d %4s %10s %40s' % (index,
alias_type,
alias_name,
alias_path))
return True
return False
# TODO: Implement remove using name [<name>]
# TODO: Implement multi number/name removal [<>|<>]...
def remove(number):
"""Remove an alias given it's number."""
lines = []
# Read file lines into memory
with open(STORE_FILE, 'r') as store:
lines = store.readlines()
# Check for out of bounds
if number > len(lines):
raise Exception('Out of bounds number for alias: %d' % number)
# Only re-write lines that don't match the index
with open(STORE_FILE, 'w') as store:
for index, line in enumerate(lines):
if index != number:
store.write(line)
def main():
# Check if initialization is required
if not os.path.isfile(STORE_FILE):
initialize()
# Store length of arguments
arg_len = len(sys.argv)
# Use given path [-d path] or current working directory
path =\
sys.argv[sys.argv.index('-d')+1] if '-d' in sys.argv else os.getcwd()
# Check that the given path is a directory, ignore with [-f]
if not os.path.isdir(path) and '-f' not in sys.argv:
raise Exception('Given path is not a directory!')
# Print help message in the most basic case
if arg_len == 1 or '--help' in sys.argv or '-h' in sys.argv:
print(HELP_MSG)
# List the aliases in the store file
elif '-l' in sys.argv or '--list' in sys.argv:
list_store()
# Create command alias
elif '-c' in sys.argv:
create(path, sys.argv[-1], 1)
# Try to remove alias
elif sys.argv[1] == 'del':
try:
remove(int(sys.argv[2]))
except Exception as e:
print(e)
# Create alias
elif arg_len > 1:
create(path, sys.argv[-1], 0)
else:
print('Try something like this...?')
print(HELP_MSG)
if __name__ == '__main__':
main()
"""Utility functions and variables."""
import os
import enum
class Paths(enum.Enum):
HOME = os.path.expanduser('~')
CONFIG_DIR = os.path.join(HOME, '.config', 'aluminium')
ROOT_DIR = os.path.abspath(os.path.join(__file__, os.pardir))
MODULE_DIR = os.path.join(ROOT_DIR, 'modules')
def initialize_config():
# Create `~/.config/aluminium` directory
if not os.path.isdir(Paths.CONFIG_DIR.value):
os.makedirs(Paths.CONFIG_DIR.value)
# Find all existing modules
for module_name in os.listdir(Paths.MODULE_DIR.value):
if module_name.startswith('__'):
continue
# Create `~/.config/aluminium/module` directories for each module
module_config_path = os.path.join(Paths.CONFIG_DIR.value, module_name)
if not os.path.isdir(module_config_path):
os.makedirs(module_config_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment