Skip to content

Commit

Permalink
support for lib50>3 and ssh passphrases
Browse files Browse the repository at this point in the history
  • Loading branch information
Jelleas committed Aug 7, 2021
1 parent 818c546 commit 8f93c22
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 18 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
'submit50': [('**.py', 'python', None),],
},
description="This is submit50, with which you can submit solutions to problems for CS50.",
install_requires=["lib50>=2,<3", "requests>=2.19", "termcolor>=1.1"],
install_requires=["lib50>=3,<4", "requests>=2.19", "termcolor>=1.1"],
keywords=["submit", "submit50"],
name="submit50",
python_requires=">=3.6",
Expand Down
107 changes: 90 additions & 17 deletions submit50/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
import os
import argparse
import enum
import gettext
import logging
import pkg_resources
Expand All @@ -21,6 +21,29 @@

SUBMIT_URL = "https://submit.cs50.io"

class LogLevel(enum.IntEnum):
DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
ERROR = logging.ERROR


class ColoredFormatter(logging.Formatter):
COLORS = {
"ERROR": "red",
"WARNING": "yellow",
"DEBUG": "cyan",
"INFO": "magenta",
}

def __init__(self, fmt, use_color=True):
super().__init__(fmt=fmt)
self.use_color = use_color

def format(self, record):
msg = super().format(record)
return msg if not self.use_color else termcolor.colored(msg, getattr(record, "color", self.COLORS.get(record.levelname)))


class Error(Exception):
pass
Expand Down Expand Up @@ -50,6 +73,30 @@ def check_version():
"Please upgrade."))


def setup_logging(level):
"""
Sets up logging for lib50.
level 'info' logs all git commands run to stderr
level 'debug' logs all git commands and their output to stderr
"""
logger = logging.getLogger("lib50")

# Set verbosity level on the lib50 logger
logger.setLevel(level.upper())

handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(ColoredFormatter("(%(levelname)s) %(message)s", use_color=sys.stderr.isatty()))

# Direct all logs to sys.stderr
logger.addHandler(handler)

# Don't animate the progressbar if LogLevel is either info or debug
lib50.ProgressBar.DISABLED = logger.level < LogLevel.WARNING

# Show exceptions when debugging
excepthook.verbose = logger.level == LogLevel.DEBUG


def cprint(text="", color=None, on_color=None, attrs=None, **kwargs):
"""Colorizes text (and wraps to terminal's width)."""
# Assume 80 in case not running in a terminal
Expand All @@ -62,7 +109,7 @@ def cprint(text="", color=None, on_color=None, attrs=None, **kwargs):
color=color, on_color=on_color, attrs=attrs, **kwargs)


def prompt(included, excluded):
def prompt(honesty, included, excluded):
if included:
cprint(_("Files that will be submitted:"), "green")
for file in included:
Expand All @@ -76,16 +123,33 @@ def prompt(included, excluded):
for other in excluded:
cprint("./{}".format(other), "yellow")

# If there's no honesty question, continue.
if not honesty:
return True

# Prompt for honesty
try:
answer = input(_("Keeping in mind the course's policy on academic honesty, "
"are you sure you want to submit these files (yes/no)? "))
# Show default message
if honesty == True:
honesty_question = _(
"Keeping in mind the course's policy on academic honesty, "
"are you sure you want to submit these files (yes/no)? "
)
# If a custom message is configured, show that instead
else:
honesty_question = str(honesty)

# Get the user's answer
answer = input(honesty_question)
except EOFError:
answer = None
print()

# If no answer given, or yes is not given, don't continue
if not answer or not re.match(f"^\s*(?:{_('y|yes')})\s*$", answer, re.I):
return False


# Otherwise, do continue
return True


Expand All @@ -102,9 +166,9 @@ def excepthook(type, value, tb):

cprint(_("Submission cancelled."), "red")


excepthook.verbose = True


class LogoutAction(argparse.Action):
def __init__(self, option_strings, dest=argparse.SUPPRESS, default=argparse.SUPPRESS, help=_("logout of submit50")):
super().__init__(option_strings, dest=dest, nargs=0, default=default, help=help)
Expand All @@ -124,20 +188,29 @@ def main():

parser = argparse.ArgumentParser(prog="submit50")
parser.add_argument("--logout", action=LogoutAction)
parser.add_argument("-v", "--verbose",
action="store_true",
help=_("show commands being executed"))
parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {__version__}")
parser.add_argument("slug", help=_(
"prescribed identifier of work to submit"))
parser.add_argument(
"--log-level",
action="store",
default="warning",
choices=[level.name.lower() for level in LogLevel],
type=str.lower,
help=_('warning: displays usage warnings.'
'\ninfo: adds all commands run.'
'\ndebug: adds the output of all commands run.')
)
parser.add_argument(
"-V", "--version",
action="version",
version=f"%(prog)s {__version__}"
)
parser.add_argument(
"slug",
help=_("prescribed identifier of work to submit")
)

args = parser.parse_args()

excepthook.verbose = args.verbose
if args.verbose:
logging.basicConfig(level=os.environ.get("SUBMIT50_LOGLEVEL", "INFO"))
# Disable progress bar so it doesn't interfere with log
lib50.ProgressBar.DISABLED = True
setup_logging(args.log_level)

check_announcements()
check_version()
Expand Down

0 comments on commit 8f93c22

Please sign in to comment.