Skip to content

Commit 239cbaa

Browse files
authored
Merge pull request #12 from carlossilva2/dev
feat(Refactor-&-Remote-Store): Removed Registry Action from Core; Imp…
2 parents 7999ff0 + d2f91c5 commit 239cbaa

File tree

12 files changed

+227
-254
lines changed

12 files changed

+227
-254
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ wheels/
2727
*.egg-info/
2828
.installed.cfg
2929
*.egg
30+
31+
regutils.py

Tasker/__init__.py

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
11
import chalk
22

3-
from Tasker.parser import Parser
4-
5-
from Tasker.operations import Command
6-
from Tasker.operations import Echo
7-
from Tasker.operations import Input
8-
from Tasker.operations import Copy
9-
from Tasker.operations import Delete
10-
from Tasker.operations import Request
11-
from Tasker.operations import Registry
12-
from Tasker.operations import Move
13-
14-
from Tasker.cli import get_logger
15-
from Tasker.cli import get_args
16-
17-
from Tasker.inspector import inspect
18-
193
from Tasker.__version__ import __version__
4+
from Tasker.cli import get_args, get_logger
5+
from Tasker.inspector import inspect
6+
from Tasker.operations import Command, Copy, Delete, Echo, Input, Move, Request
7+
from Tasker.parser import Parser
208

219
__all__ = [
22-
#Colorizer
10+
# Colorizer
2311
"chalk",
24-
#Parser
12+
# Parser
2513
"Parser",
26-
#Operations
14+
# Operations
2715
"Command",
2816
"Echo",
2917
"Input",
3018
"Copy",
3119
"Delete",
3220
"Request",
33-
"Registry",
3421
"Move",
35-
#CLI
22+
# CLI
3623
"get_logger",
3724
"get_args",
38-
#Inspector
25+
# Inspector
3926
"inspect",
40-
#Version
41-
"__version__"
42-
]
27+
# Version
28+
"__version__",
29+
]

Tasker/__main__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ def main() -> None:
6060
)
6161
else:
6262
logger.error("Path and Name flags are required when creating Aliases")
63+
elif args.action == "install":
64+
if args.Extension is None:
65+
logger.error("Missing Extension flag `-e`. Check Help for command syntax")
66+
sys.exit(1)
67+
Parser.install_remote_extension(args.Extension, logger)
68+
elif args.action == "uninstall":
69+
if args.Extension is None:
70+
logger.error("Missing Extension flag `-e`. Check Help for command syntax")
71+
sys.exit(1)
72+
Parser.uninstall_extension(args.Extension, logger)
73+
elif args.action == "remote-search" or args.action == "remote-list":
74+
if args.action == "remote-search":
75+
if args.Extension is None:
76+
logger.error("Missing Extension flag `-e`. Check Help for command syntax")
77+
sys.exit(1)
78+
Parser.search_remote(args.Extension, logger)
79+
else:
80+
Parser.list_remote(logger)
6381
else:
6482
logger.error("Check Help for command syntax")
6583

Tasker/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.5.3"
1+
__version__ = "0.6.0"

Tasker/cli.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,18 @@ def get_args(version: str, logger: logging.Logger) -> argparse.Namespace:
3030
parser.add_argument(
3131
"action",
3232
help="What action should Tasker perform",
33-
choices=["list", "execute", "create", "edit", "extension", "alias"],
33+
choices=[
34+
"list",
35+
"execute",
36+
"create",
37+
"edit",
38+
"extension",
39+
"alias",
40+
"install",
41+
"uninstall",
42+
"remote-list",
43+
"remote-search",
44+
],
3445
)
3546

3647
options = parser.add_argument_group("parameters")
@@ -42,6 +53,14 @@ def get_args(version: str, logger: logging.Logger) -> argparse.Namespace:
4253
required=False,
4354
help=f"Instruction Set name flag. Use {chalk.green('`tasker list`')} for a list with all InstructionSets",
4455
)
56+
options.add_argument(
57+
"-e",
58+
"--Extension",
59+
type=str,
60+
metavar="",
61+
required=False,
62+
help="Usable only on `install`",
63+
)
4564
options.add_argument(
4665
"-f",
4766
"--File",

Tasker/common.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os.path as Path
2+
import subprocess
3+
import sys
24
from hashlib import md5
35
from os import listdir
46
from time import time
@@ -73,3 +75,14 @@ def reset(self) -> None:
7375
self.start_time = 0.0
7476
self.end_time = 0.0
7577
self.ellapsed_time = ""
78+
79+
80+
def pip(package: str):
81+
return subprocess.check_call([sys.executable, "-m", "pip", "install", package])
82+
83+
84+
def pip_freeze() -> list[str]:
85+
return [
86+
_.decode().split("==")[0]
87+
for _ in subprocess.check_output([sys.executable, "-m", "pip", "freeze"]).split()
88+
]

Tasker/operations.py

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,13 @@
66
import chalk
77
import requests
88

9-
from Tasker.regutils import backup
10-
119
from .common import alias, get_file_name, ref
1210
from .inspector import implements
1311
from .types import OperationType as Operation
1412
from .types import ParserType as Parser
15-
from .types import Registry as RegType
1613
from .types import Task
1714

18-
try:
19-
from .regutils import (
20-
create_key,
21-
get_key_value,
22-
get_type,
23-
parse_input,
24-
set_key_value,
25-
)
26-
except Exception:
27-
not_imported = True
15+
# from Tasker.regutils import backup
2816

2917

3018
@implements(Operation)
@@ -322,69 +310,6 @@ def get_state(self) -> bool:
322310
return self.__internal_state
323311

324312

325-
@implements(Operation)
326-
class Registry(Operation):
327-
"Registry Action"
328-
329-
__annotations__ = {
330-
"name": "Registry Action",
331-
"intent": "Change Windows Registry values/keys",
332-
}
333-
334-
def __init__(self, ctx: Parser, task: RegType, logger: Logger) -> None:
335-
if ctx.system != "Windows":
336-
ctx.abort(f"Operation not available on {ctx.system} Systems!")
337-
self.regex = r"\w>"
338-
self.context = ctx # Parser Context
339-
self.task = task # Current assigned Task
340-
self.logger = logger
341-
self.affected_files: list[str] = []
342-
self.__internal_state = True # Faulty execution flag
343-
self._type = "registry"
344-
ref(self)
345-
alias(self)
346-
347-
def execute(self) -> None:
348-
self.path = ">".join([self.task["start_key"], self.task["key"]])
349-
if self.task["function"] == "get":
350-
self.value = get_key_value(self.path, self.logger)
351-
elif self.task["function"] == "set":
352-
if self.task["value"] == "" or self.task["value"] == None:
353-
self.context.abort("No value was provided")
354-
self.safeguard = get_key_value(self.path, self.logger)
355-
parsed = parse_input(self.path)
356-
values = parsed[1]
357-
self.v = values[-1]
358-
values.pop()
359-
self.correct_path = ">".join([self.task["start_key"], *values])
360-
set_key_value(
361-
self.correct_path, self.v, get_type(self.task["type"]), self.task["value"]
362-
)
363-
self.value = get_key_value(self.path, self.logger)
364-
elif self.task["function"] == "create":
365-
create_key(self.path, self.task["value"])
366-
elif self.task["function"] == "backup":
367-
raise NotImplementedError(
368-
"Feature under development. Refer to future versions"
369-
)
370-
backup(self.task["start_key"], self.task["key"], self.task["rename"])
371-
372-
def rollback(self) -> None:
373-
if self.task["function"] == "set":
374-
set_key_value(
375-
self.correct_path, self.v, get_type(self.task["type"]), self.safeguard
376-
)
377-
self.logger.warn(f"Rolled back \"{self.task['name']}\" task")
378-
379-
def set_state(self, state: bool) -> None:
380-
"Sets the state for the Internal Fault flag"
381-
self.__internal_state = state
382-
383-
def get_state(self) -> bool:
384-
"Returns the of the Internal Fault flag"
385-
return self.__internal_state
386-
387-
388313
@implements(Operation)
389314
class Input(Operation):
390315
"Input Action"

Tasker/parser.py

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import sys
66
from hashlib import md5
77
from importlib.machinery import SourceFileLoader as importer
8-
from logging import Logger
8+
from logging import WARNING, Logger, getLogger
99
from time import time
1010
from typing import List, Literal, Union
1111
from webbrowser import open as FileOpener
1212

1313
import chalk
14+
from requests import get
1415

15-
from .common import Timer
16+
from .common import Timer, pip, pip_freeze
1617
from .inspector import implements
1718
from .operations import *
1819
from .types import (
@@ -25,7 +26,6 @@
2526
OP_INPUT,
2627
OP_INSTRUCTION,
2728
OP_MOVE,
28-
OP_REGISTRY,
2929
OP_REQUEST,
3030
OP_TASK,
3131
OP_ZIP,
@@ -146,10 +146,6 @@ def __execute(self, task: Task) -> bool:
146146
r = Request(self, task, self.logger)
147147
self.__operation_stack.append(r)
148148
r.execute()
149-
elif task["operation"] == "registry":
150-
reg = Registry(self, task, self.logger)
151-
self.__operation_stack.append(reg)
152-
reg.execute()
153149
elif task["operation"] == "custom":
154150
ex = next(
155151
(e for e in self.extensions if e["summon"] == task["extension_name"]),
@@ -468,3 +464,94 @@ def add_alias(alias: Alias, logger: Logger) -> None:
468464
sys.exit(1)
469465
settings["alias"].append(alias)
470466
json.dump(settings, open(f"{root}/.tasker/config.json", "w"), indent=4)
467+
468+
@staticmethod
469+
def install_remote_extension(extension: str, logger: Logger) -> bool:
470+
Parser.do_config()
471+
root = Path.expanduser("~")
472+
# Remove DEBUG WARNINGS
473+
getLogger("requests").setLevel(WARNING)
474+
getLogger("urllib3").setLevel(WARNING)
475+
# Get Context file
476+
context = get(
477+
"https://raw.githubusercontent.com/carlossilva2/pyTasker-actions/main/context.json"
478+
).json()
479+
# Check if extension exists on remote
480+
if extension not in context.keys():
481+
logger.error("Extension does not exist. Check spelling")
482+
return False
483+
# Check if extension is allowed on Current OS
484+
os = platform.system()
485+
if context[extension]["platform"] != os and context[extension]["platform"] != "*":
486+
logger.error(f"Extension cannot be installed in '{os}'")
487+
return False
488+
# Check for extension dependencies
489+
existing_modules = pip_freeze()
490+
for dep in context[extension]["dependencies"]:
491+
if dep not in existing_modules:
492+
pip(dep)
493+
# Retrieve Template
494+
template = get(context[extension]["extension"]).text
495+
# Install Extension locally
496+
_n = md5(f"{time()}_{extension}".encode("UTF-8")).hexdigest()[:10]
497+
f_name = f"extension_{_n}.py"
498+
with open(f"{root}/.tasker/Templates/{f_name}", "w") as ex:
499+
ex.write(template)
500+
ex.close()
501+
j: Settings = json.load(open(f"{root}/.tasker/config.json"))
502+
j["extensions"].append(
503+
{
504+
"name": extension,
505+
"file": f_name,
506+
"path": f"{root}/.tasker/Templates/{f_name}",
507+
}
508+
)
509+
json.dump(j, open(f"{root}/.tasker/config.json", "w"), indent=4)
510+
return True
511+
512+
@staticmethod
513+
def uninstall_extension(extension: str, logger: Logger) -> None:
514+
Parser.do_config()
515+
root = Path.expanduser("~")
516+
j: Settings = json.load(open(f"{root}/.tasker/config.json"))
517+
if extension not in [_["name"] for _ in j["extensions"]]:
518+
logger.error(f"{extension} is not installed")
519+
sys.exit(1)
520+
index = None
521+
for i, ex in enumerate(j["extensions"]):
522+
if ex["name"] == extension:
523+
index = i
524+
os.remove(ex["path"])
525+
break
526+
j["extensions"].pop(index)
527+
json.dump(j, open(f"{root}/.tasker/config.json", "w"), indent=4)
528+
logger.debug("Extension removed successfully")
529+
530+
@staticmethod
531+
def search_remote(extension: str, logger: Logger) -> None:
532+
Parser.do_config()
533+
# Remove DEBUG WARNINGS
534+
getLogger("requests").setLevel(WARNING)
535+
getLogger("urllib3").setLevel(WARNING)
536+
# Get Context file
537+
context = get(
538+
"https://raw.githubusercontent.com/carlossilva2/pyTasker-actions/main/context.json"
539+
).json()
540+
# Check if extension exists on remote
541+
if extension not in context.keys():
542+
logger.error("Extension does not exist. Check spelling")
543+
sys.exit(1)
544+
logger.debug(f"{extension}=={context[extension]['version']}")
545+
546+
@staticmethod
547+
def list_remote(logger: Logger) -> None:
548+
Parser.do_config()
549+
# Remove DEBUG WARNINGS
550+
getLogger("requests").setLevel(WARNING)
551+
getLogger("urllib3").setLevel(WARNING)
552+
# Get Context file
553+
context = get(
554+
"https://raw.githubusercontent.com/carlossilva2/pyTasker-actions/main/context.json"
555+
).json()
556+
for extension in context.keys():
557+
logger.debug(f"{extension}=={context[extension]['version']}")

0 commit comments

Comments
 (0)