def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-d", "--delay"): try: # make sure argument is a valid value (float) self.delay = float(a) except: raise exception.InvalidOptionException("delay") elif o in ("-u", "--url"): try: # try to fix the url formatting self.url = self.fix_uri(a) except Exception, e: raise exception.InvalidOptionException("url", e.message) else: # this should never happen! raise Exception(_("Unhandled option. See --help for details."))
def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ use_kana_only = False for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-k", "--kana"): use_kana_only = True elif o in ("-z", "--zenkaku"): self.use_zenkaku = True elif o in ("-g", "--granularity"): try: # make sure argument is a valid value (int) self.granularity = int(a) except: raise exception.InvalidOptionException("granularity") if self.granularity <= 0: raise exception.InvalidOptionException( "granularity", "Must be higher than zero") elif o in ("-d", "--delay"): try: # make sure argument is a valid value (float) self.line_delay = float(a) except: raise exception.InvalidOptionException("delay") if self.line_delay <= 0: raise exception.InvalidOptionException( "delay", "Must be higher than zero") else: # this should never happen! raise Exception(_("Unhandled option. See --help for details.")) # fill in other important properties if self.use_zenkaku: digmap_kana = self.digmap_kana_zenkaku digmap_alpha_num = self.digmap_alpha_num_zenkaku self.space = self.space_zenkaku self.proportion = 2 else: digmap_kana = self.digmap_kana_hangaku digmap_alpha_num = self.digmap_alpha_num_hangaku self.space = self.space_hangaku self.proportion = 1 self.digmap.extend(digmap_kana) if not use_kana_only: self.digmap.extend(digmap_alpha_num)
def _parse_args(self, prepared_args): for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-i", "--invert"): self.options['invert'] = True elif o in ("-w", "--wide"): try: # makes sure this is a valid integer self.options['wide'] = int(a) except: raise exception.InvalidOptionException("wide") elif o in ("-c", "--contrast"): self.options['contrast'] = True elif o in ("-s", "--set"): self.options['customcharset'] = a elif o in ("-f", "--framedelay"): try: self.option['framedelay'] = int(a) except: raise exception.InvalidOptionException("framedelay") elif o in ("-z", "--scale"): try: self.options['scale'] = int(a) except: raise exception.InvalidOptionException("scale") elif o in ("-d", "--delay"): try: # make sure argument is a valid value (float) self.delay = float(a) except: raise exception.InvalidOptionException("delay") elif o in ("-p", "--path"): # make sure argument is a valid value (existing path) self.path = a if not os.path.exists( self.path) and self.path[0:4].lower() != 'http': raise exception.PathNotFoundException( self.path, _("Make sure the file or directory exists.")) else: # this should never happen! raise Exception(_("Unhandled option. See --help for details.")) # last validations if self.path in (None, ''): raise exception.InvalidOptionException( "path", _("It is mandatory option"), help=self._message_no_path())
def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-r", "--raw"): self.clean_html = False elif o in ("-f", "--format"): #remove escaping self.print_format = common.unescape_string(a) elif o in ("-u", "--url"): try: # try to fix the url formatting self.url = self.fix_uri(a) except Exception as e: error_message = "" if hasattr(e, 'message'): error_message = e.message else: error_message = e raise exception.InvalidOptionException( "url", error_message) else: # this should never happen! raise Exception(_("Unhandled option. See --help for details.")) # last validations if self.url in (None, ''): raise exception.InvalidOptionException("url", "It is mandatory option", help=self._message_no_url())
def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-n", "--no-adjust"): self.adjust = False elif o in ("-p", "--path"): # make sure argument is a valid value (existing path) self.path = a if not os.path.exists(self.path): raise exception.PathNotFoundException( self.path, _("Make sure the file exists.")) if not os.path.isfile(self.path): raise exception.InvalidOptionException( "--path", _("Make sure it is a file")) elif o in ("-d", "--delay"): try: # make sure argument is a valid value (float) self.delay = float(a) except: raise exception.InvalidOptionException("delay") else: # this should never happen! raise Exception(_("Unhandled option. See --help for details."))
def autorun(self, args, loop=True): """ The accessible method for dynamically running a screen. This method will basically parse the arguments, prepare them with the method `_parse_args` that is inherited in sub-classes, and with the property `cli_opts` that holds the formatting of the arguments. Once all is ready to go, this will call the `_run_cycle` method, which is filled in the sub-classes with the algorithms to display text on screen to behave as a screensaver. The arguments of this method are: * args: (MANDATORY) the arguments passed when termsaver is executed from command-line. See `termsaver` script for details. * loop: (OPTIONAL) defines if termsaver should be executing on an infinite looping (goes on until the keyboard interrupt (Ctrl+C) is pressed), or not. This is up to the screen action (or end-user through configuable setting) to decide. """ # prepare values and validate if not args: args = '' if not self.cli_opts \ or 'opts' not in self.cli_opts.keys() \ or not self.cli_opts['opts']: self.cli_opts['opts'] = '' if not self.cli_opts['long_opts']: self.cli_opts['long_opts'] = [] else: if not type(self.cli_opts['long_opts']) is list or \ [type(i) == str for i in self.cli_opts['long_opts']] \ != [True for __ in range(len(self.cli_opts['long_opts']))]: # # Don't worry too much about errors here. This is supposed to # help developers while programming screens for this app. # raise Exception("Value of 'long_opts' in cli_opts dict MUST "\ "be a list of strings.") try: self._parse_args( getopt.getopt(args, self.cli_opts['opts'], self.cli_opts['long_opts'])) except getopt.GetoptError, e: raise exception.InvalidOptionException("", str(e))
def _run_cycle(self): """ Executes a cycle of this screen. The actions taken here, for each cycle, are as follows: * retrieve data from `url` * parses the data into a XML dom document object * parses the document object into a list of dictionaries * print using `typing_print` """ self.doc_xml_string(self.fetch(self.url)) self.parse_data() self.clear_screen() for item in self.data: new_text = item try: new_text = common.unescape_string(self.print_format % new_text) # remove HTML tags is applicable if self.clean_html: new_text = common.strip_html(new_text) except: raise exception.InvalidOptionException( "format", _("There was an error while using your format.")) if self.center_vertically or self.center_horizontally: self.get_terminal_size() if self.center_vertically: new_text = self.center_text_vertically(new_text) if self.center_horizontally: new_text = self.center_text_horizontally(new_text) self.typing_print(new_text) time.sleep(self.sleep_between_items) if self.cleanup_per_item: self.clear_screen()
class RSSFeedScreenBase(UrlFetcherBase, TypingHelperBase, PositionHelperBase, XMLReaderHelperBase): """ A base class used to handle RSS feeds, and display them accordingly. This also includes the `TypingHelperBase` and `PositionHelperBase` to add functionality of typing writer display, and certain positioning features. The instantiation of this class takes two additional arguments, compared with its base class: * tags: defines the list of string tags of the RSS that you are interest in. Accepted values are: * pubDate * title * link * description * print_format: defines the formating to be printed out, based on the tags available (use python string format with dictionary. eg. '%(title)s (%(pubDate)s)\n\n') When inheriting from this screen, you can also take advantage of the following properties and functionalities: * `sleep_between_items`: Sleeping time, in seconds, between each RSS item displayed. * `cleanup_per_item`: Defines if termsaver should clean the screen for each item being read * `center_vertically`: Defines if the information displayed should be vertically centered on screen. * `center_horizontally`: Defines if the information displayed should be horizontally centered on screen. """ sleep_between_items = 1 """ Sleeping time, in seconds, between each RSS item displayed. """ cleanup_per_item = False """ Defines if termsaver should clean the screen for each item being read """ center_vertically = False """ Defines if the information displayed should be vertically centered on screen. """ center_horizontally = False """ Defines if the information displayed should be horizontally centered on screen. """ clean_html = True """ Defines that the output text must be cleaned from HTML tags. """ def __init__(self, name, description, url=None, tags=None, print_format=None, delay=None, cli_opts=None): """ Creates a new instance of this class. This constructor has two additional arguments, compared with its base class: * tags: defines the list of string tags of the RSS that you are interest in. Accepted values are: * pubDate * title * link * description * print_format: defines the formating to be printed out, based on the tags available (use python string format with dictionary. eg. '%(title)s (%(pubDate)s)\n\n') """ UrlFetcherBase.__init__(self, name, description, url, delay, cli_opts) XMLReaderHelperBase.__init__(self, "item", tags) self.print_format = print_format # build deafults if not cli_opts: self.cli_opts = { 'opts': 'hrd:u:f:', 'long_opts': ['raw', 'help', 'delay=', 'url=', 'format='] } if not print_format: self.print_format = '%(title)s (%(pubDate)s)\n\n' def _usage_options_example(self): """ Describe here the options and examples of this screen. The method `_parse_args` will be handling the parsing of the options documented here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ print _(""" Options: -h, --help Displays this help message -u, --url The URL path of the RSS feed (text) to be displayed -r, --raw Shows all text available (with HTML if any) -f, --format The printing format according to values available in RSS feed: * pubDate * title * link * description You must use python dictionary based formatting style (see examples for details) Example: $ %(app_name)s %(screen)s -u http://rss.cnn.com/rss/edition.rss This will trigger the screensaver to fetch the contents from the CNN feed and display it in default formatting: '%%(title)s (%%(pubDate)s)\\n' $ %(app_name)s %(screen)s -u http://rss.cnn.com/rss/edition.rss \\ -f '%%(title)s (%%(pubDate)s)\\n%%(description)s\\n%%(link)s' This will trigger the screensaver to fetch the contents from the CNN feed and display all contents as specified in the formatting. """) % { 'app_name': constants.App.NAME, 'screen': self.name, 'description': self.description, } def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-r", "--raw"): self.clean_html = False elif o in ("-f", "--format"): #remove escaping self.print_format = common.unescape_string(a) elif o in ("-u", "--url"): try: # try to fix the url formatting self.url = self.fix_uri(a) except Exception, e: raise exception.InvalidOptionException("url", e.message) else: # this should never happen! raise Exception(_("Unhandled option. See --help for details.")) # last validations if self.url in (None, ''): raise exception.InvalidOptionException("url", "It is mandatory option", help=self._message_no_url())
class UrlFetcherBase(ScreenBase, TypingHelperBase, URLFetcherHelperBase): """ A base class used to handle URL fetched contents, and display them accordingly. This also includes the `TypingHelperBase` to add functionality of typing writer display. The instantiation of this class takes two additional arguments, compared with its base class: * url: the URL address to fetch data from * `delay`: defines the delay for printing out characters of a string """ url = "" """ the URL address to fetch data from """ def __init__(self, name, description, url=None, delay=None, cli_opts=None): """ Creates a new instance of this class. This constructor has two additional arguments, compared with its base class: * url: the URL address to fetch data from * `delay`: defines the delay for printing out characters of a string """ ScreenBase.__init__(self, name, description, cli_opts) if not cli_opts: self.cli_opts = { 'opts': 'hd:u:', 'long_opts': ['help', 'delay=', 'url='], } self.delay = delay self.url = url def _run_cycle(self): """ Executes a cycle of this screen. The actions taken here, for each cycle, are as follows: * retrieve data from `url` * print using `typing_print` """ data = self.fetch(self.url) self.clear_screen() self.typing_print(data) def _message_no_url(self): """ Defines a method to be overriden by inheriting classes, with the purpose to display extra help information for specific errors. """ return "" def _usage_options_example(self): """ Describe here the options and examples of this screen. The method `_parse_args` will be handling the parsing of the options documented here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ print _(""" Options: -u, --url Defines the URL location from where the information should be fetched, then displayed. This option is MANDATORY. -d, --delay Sets the speed of the displaying characters default is 0.003 of a second (advised to keep between 0.01 and 0.001). -h, --help Displays this help message Examples: $ %(app_name)s %(screen)s -u www.google.com This will trigger the screensaver to fetch the HTML contents of this web site and display progressively. $ %(app_name)s %(screen)s -u www.google.com -d 0 This will trigger the screensaver to fetch the HTML contents of this web site with no delay (too fast for a screensaver, but it's your choice that matters!) """) % { 'screen': self.name, 'app_name': constants.App.NAME, } def _parse_args(self, prepared_args): """ Handles the special command-line arguments available for this screen. Although this is a base screen, having these options prepared here can save coding for screens that will not change the default options. See `_usage_options_example` method for documentation on each of the options being parsed here. Additionally, this is dependent on the values exposed in `cli_opts`, passed to this class during its instantiation. Only values properly configured there will be accepted here. """ for o, a in prepared_args[0]: # optlist, args if o in ("-h", "--help"): self.usage() self.screen_exit() elif o in ("-d", "--delay"): try: # make sure argument is a valid value (float) self.delay = float(a) except: raise exception.InvalidOptionException("delay") elif o in ("-u", "--url"): try: # try to fix the url formatting self.url = self.fix_uri(a) except Exception, e: raise exception.InvalidOptionException("url", e.message) else: # this should never happen! raise Exception(_("Unhandled option. See --help for details.")) # last validations if self.url in (None, ''): raise exception.InvalidOptionException("url", _("It is mandatory option"), help=self._message_no_url())