def lineify(self, url, expanded, both, pretty): """ Returns an output-ready line for a given url. The line may include only the short url, only the long/expanded url or both, depending on the parameters passed. Arguments: url (str): The short url. expanded (bool): Whether or not to show the expanded link. both (bool): Whether or not to show both the short and the expanded link (takes precedence over 'expanded'). pretty (bool): Whether or not to make the output pretty. Returns: The short url if neither 'expanded' nor 'both' is set, both the short and the expanded url, in the schema '<short> => <expanded>' if 'both' is set, else only the expanded link if 'expanded' is set. If 'pretty' is True, the line is returned in a formatted fashion (with color), else in plain format. """ if both: line = '{0} => {1}'.format(url.short, url.long) elif expanded: line = url.long else: line = url.short if pretty: marked = self.list_item.format(line) line = ecstasy.beautify(marked, ecstasy.Color.Red) return line
def copy(self, copy, url): """ Copies a url to the clipboard if possible. "If possible" means the url is only copied if no other url has so-far been copied to the clipboard during the same fetch() call, and also only if the 'copy' is set. If the url is copied, it is formatted using ecstasy to make it bold. Arguments: copy (bool): Whether or not to allow copying to the clipboard at all. url (str): The url to (possibly) copy. Returns: The original url if the 'copy' flag is unset or another link has already been copied to the clipboard during the same call to fetch(), else the url, formatted with ecstasy to appear bold in the terminal. """ if copy and not self.already_copied: self.already_copied = True pyperclip.copy(url) url = ecstasy.beautify('<{0}>'.format(url), ecstasy.Style.Bold) return url
def main(): text = "<Beware><(0) the <Jabberwock, my <son>>>!\n"\ "The <jaws> <(-2)that> <bite>, <(-1)the> <(2)claws> that <(3)catch>!\n"\ "<(0)One>, <two>! <(0!)One>, <(!)two>!\n"\ "The <(0,1)vorpal> <blade went> <snicker-<snack>>!" formats = [ ecstasy.Fill.Yellow, ecstasy.Color.Yellow | ecstasy.Fill.Blue, ecstasy.Style.Blink | ecstasy.Color.Cyan, ecstasy.Fill.Magenta | ecstasy.Style.Blink | ecstasy.Color.White, ecstasy.Style.Invert, ecstasy.Style.Hidden ] always = { ("two", "blade went"): ecstasy.Color.Red | ecstasy.Fill.White, "Beware": ecstasy.Color.Yellow | ecstasy.Fill.Red | ecstasy.Style.Underline } beauty = ecstasy.beautify(text, ecstasy.Color.Red, formats, always, One=ecstasy.Fill.Cyan) print(beauty)
def format(category, key, value, full): """ Formats a key/value pair for output. Handles special cases such as country-name expansion (the API returns them as ISO abbreviations, e.g. 'DE', but often the full name, e.g. 'Germany', is really wanted) Arguments: category (str): The category of the data. key (str): The key of the data-point. value (str): The value of the data-point. full (bool): Whether to show full country names or short ISO abbreviations (e.g. 'Germany' or 'DE'). Returns: A pretty list-item. """ if category == 'countries': if key == 'None': key = 'Other' elif full: key = lnk.countries.names[key] elif key == 'direct': key = key.title() line = ' <-> {0}: {1}'.format(key, value) pretty = ecstasy.beautify(line, ecstasy.Color.Yellow) return pretty
def get_levels(additional): """ Transforms and formats error levels. Each additional level passed to the constructor of Error is either the error string, in which case its level is 1 or a Error.Message tuple consisting of that same error string and additionally an integer specifying the level. This information is parsed here, such that the result is a list of level strings. Moreover, each key/value pair of each error message is formatted with ecstasy to make it look pretty. Arguments: additional (dict): The additional error messages. Returns: A list of strings for each level of verbosity. """ # Each nested list corresponds to one further level of verbosity levels = [[], [], [], []] for key, value in additional.items(): if key and value: level = 1 # default if isinstance(value, Message): level = value.level value = value.what line = "<{0}>: {1}".format(key, value) line = ecstasy.beautify(line, ecstasy.Color.Red) levels[level].append(line) return ["\n".join(level) if level else None for level in levels]
def main(): text = "<NaNaNa> <NaNaNa>\n<NaNaNa> <NaNaNa>\n<Batman>" line_1 = [ecstasy.Style.Blink, ecstasy.Color.Blue] line_2 = [ecstasy.Color.Yellow, ecstasy.Fill.Red] text = ecstasy.beautify(text, line_1, line_2, ecstasy.Style.Bold) print(text)
def warn(what): """ Outputs and formats a warning. Arguments: what (str): The warning string to output. """ what = "\a<Warning>: {0}".format(what) formatted = ecstasy.beautify(what, ecstasy.Color.Yellow) click.echo(formatted)
def main(): text = "<Muffins> <are> <super> <radical>!" styles = { ("Muffins", "super"): ecstasy.Color.Blue, "radical": ecstasy.Style.Blink } text = ecstasy.beautify(text, styles, are=ecstasy.Fill.Red) print(text)
def __init__(self, service, command): with lnk.config.Manager(service) as manager: self.url = manager['url'] self.api = '{0}/v{1}'.format(self.url, manager['version']) self.config = manager['commands'][command] self.endpoints = self.config['endpoints'] self.settings = self.config.get('settings') self.sets = self.config.get('sets') self.queue = Queue() self.lock = threading.Lock() self.error = None self.parameters = {} self.list_item = ecstasy.beautify(' <+> {0}', ecstasy.Color.Red)
def fetch(self, _, login, password, show, who): """ Fetches an oauth2 access-token for a given login and password. Arguments: _: This is the --generate flag, just a dummy parameter because it must be passed from the command-line to initiate the procedure but has no actual use here. login (str): The user's login (username). password (str): The user's password. show (bool): Whether or not to return the access-token for output once retrieved. Returns: If the show flag is set, the raw key as a string if self.raw is True, else the key in a pretty box. If the show flag is unset, an empty string is returned (such that nothing appears in the command-line output). """ if who: who = lnk.config.get('bitly', 'login') return '{0}\n'.format(who) if who else 'Nobody.\n' if not login: login = click.prompt('Login') if not password: password = click.prompt('Password', hide_input=True) key = self.request(login, password) with lnk.config.Manager('bitly', write=True) as manager: manager['key'] = key manager['login'] = login success = ecstasy.beautify('<Success!>', ecstasy.Color.Magenta) click.echo(success) if show: if self.raw: return key return lnk.beauty.boxify([[key]]) + '\n' return ''
def sub_listify(self, category, points, limit, full): """ Handles transforming data for a category into a level-2 list. While listify handles all data and takes care of formatting timespans, this method handles only data for a single category. Because this data is on the second level of each list (0th level is the category, 1st is the timespan and 2nd are the data-points), it is formatted differently than the data on level-1 (the level-1 bullet is a '+', the level-2 bullet a '-'). This method also handles special cases for key-names and also country-name expansion. Arguments: category (str): The name of the category of this data. points (list): The data points for this category (the list contains dictionaries with the keys 'id' and 'count'). limit (int): A limit on the number of data-points retrieved per timespan. full (bool): Whether to show full country names or short ISO abbreviations (e.g. 'Germany' or 'DE'). """ lines = [] for n, point in enumerate(points): if n == limit: break subject = point["id"] if subject == "unknown": subject = subject.title() if category == "countries" and full: subject = lnk.countries.names[subject] clicks = point["count"] line = ecstasy.beautify(" <-> {0}: {1}", ecstasy.Color.Yellow) lines.append(line.format(subject, clicks)) return lines
def fetch(self, _): # First request an authorization token as part of the oauth handshake. authorize_url = self.flow.step1_get_authorize_url() # The user is redirected to Google's authorization page where permission # must be granted to the lnk application to access the user's data click.echo("Redirecting you to Google's authorization page ...") webbrowser.open(authorize_url) code = click.prompt('Please enter the authorization code', hide_input=True) # Now exchange the authorization token for credentials, i.e. # an access_token that must be passed as part of the oauth protocol # with any API call, and a refresh_token that can be used to refresh # the access_token, which expires after a certain time (~ 1 hour). credentials = self.flow.step2_exchange(code) storage = oauth2client.file.Storage(self.credentials_path) storage.put(credentials) success = ecstasy.beautify('<Success!>', ecstasy.Color.Magenta) click.echo(success)
# -*- coding: utf-8 -*- """A Cache Manager.""" import ecstasy import click import os import re import sys from li.errors import LicenseError CACHE_PATH = os.path.join(os.environ['HOME'], '.license') HIT_MESSAGE = ecstasy.beautify( "Cache-<Hit> for {0}: '{1}'.", ecstasy.Color.Green ) MISS_MESSAGE = ecstasy.beautify( 'Cache-<Miss> for {0}.', ecstasy.Color.Red ) def read(author, kind): """ Attempts to read the cache to fetch missing arguments. This method will attempt to find a '.license' file in the 'CACHE_DIRECTORY', to read any arguments that were not passed to the license utility.
def __init__(self, service, what="Missing authorization code!", **additional): logo = ecstasy.beautify("<lnk>", ecstasy.Style.Bold) details = "You have not yet authorized {0} to ".format(logo) details += "access your private {0} information. ".format(service) hint = "Run 'lnk {0} key --generate'.".format(service) super(AuthorizationError, self).__init__(what, Details=details, Hint=hint, **additional)