-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmte.py
executable file
·191 lines (147 loc) · 4.51 KB
/
mte.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# MTE - MakeThingsEasier
# Licensed under the MIT License
# (c) Zhengli Wang
# More details at the root of this repository
# -------------------------
# Universal variables
# -------------------------
# Document relevant variables
__name__ = "MTE - MakeThingsEasier"
__author__ = "Zhengli Wang"
__description__ = """MTE - A command-line shortcuts utility."""
# Execution relevant variables
configFilename = "config.txt"
# -------------
# Imports
# -------------
# System libraries
import warnings
import configparser
import argparse
import os
# My custom libraries
import lib.cmd
# ----------------------
# Argument parsing
# ----------------------
argumentParser = argparse.ArgumentParser(
# Program name
prog=__name__,
# Program description
description=__description__,
# Add --help/-h flag
add_help=True,
)
# Create an optional, positional argument for "quick mode" (see README)
argumentParser.add_argument(
"action", action="store", default=None, nargs="*", help="Quick mode action."
)
# Create an optional, unpositional argument for specifying a config.txt for
# this run
# Default is configFilename, at the top of this file
argumentParser.add_argument(
"--config-file",
action="store",
default=configFilename,
required=False,
nargs=1,
help="Specify another config file than the default one for this run.",
dest="configFile",
)
# Create a namespace object for the parsed args
argumentNamespace = argumentParser.parse_args()
# There are cases where you might want to execute a multi-parted,
# space-separated command with quick mode.
#
# e.g. "mte.py chrome start"...
# ...if there is the following line in config.txt:
# "chrome start = start chrome.exe"
#
# Since argparse writes such commands into a list, we will rejoin
# it back with this line of code.
#
# ['chrome', 'start']
# ->
# 'chrome start'
argumentNamespace.action = " ".join(argumentNamespace.action)
# Use the overridden config file
configFilename = argumentNamespace.configFile
# --------------------
# Config parsing
# --------------------
defaultConfig = {"exitAfterArgvSuccess": "1", "showIntro": "1", "showWarnings": "0"}
configParser = configparser.ConfigParser()
# Bypass lowercasing of optionxform, preserving
# case-sensitvity
configParser.optionxform = str
# Load in default config
configParser["config"] = defaultConfig.copy()
# Overwrite default config
configParser.read(configFilename)
config = configParser["config"]
keyconfig = configParser["keyconfig"]
# -----------------------------------------------
# Command-line-like interface configuration
# -----------------------------------------------
# Special actions which are not defined in
# keyconfig
customActions = {"help": help, "exit": exit}
# All actions, including the keys in
# keyconfig
allActions = list(customActions.keys()) + list(keyconfig.keys())
def help():
"""
List all available commands. This is used for the
interactive MTE shell.
"""
print("Available commands: ")
# List all commands in form of:
# 'command1' 'command2' 'command3'...
for command in allActions:
print("'{}'".format(command), end=" ")
# New line
print("")
def runAction(action: str):
"""
Try to run action. If KeyError, print message and warn.
Returns 0 on success, returns 1 on failure.
"""
try:
os.system(keyconfig[action])
except KeyError:
print(
"This action is probably not defined. Enter 'help' to list available commands."
)
warnings.warn("Action not defined: " + action)
return 1
else:
return 0
commandLine = lib.cmd.Cmd(
runAction,
intro=__name__,
showIntro=(config["showIntro"] == "1"),
customActions={"help": help, "exit": exit},
)
# -------------------------
# Misc configurations
# -------------------------
if config["showWarnings"] == "0":
warnings.filterwarnings("ignore")
# ------------------------------------------------------
# Quick mode (the code might end after this block)
# ------------------------------------------------------
# Try to start in quick mode
# If quick mode succeeds, exit the program if
# config["exitAfterArgvSuccess"] is set to '1'
try:
# Make sure that there is an action at all
if argumentNamespace.action:
if runAction(argumentNamespace.action) == 0:
if config["exitAfterArgvSuccess"] == "1":
exit(0)
except ValueError:
pass
# -------------------------
# Start the main code
# -------------------------
commandLine.cmdloop()