コード例 #1
0
 def settings(self, pname, updated=None):
     pinfo = __import__('plugins.' + pname, fromlist=[pname])
     if pinfo.hasconfig == True:
         plugincfg = ConfigParser()
         try:
             plugincfg.read(pinfo.configfile)
         except PermissionError:
             handlers.criterr(
                 "Permissions error on plugin configuration file. Please ensure you have write permissions for the directory."
             )
         return {
             'id': pname,
             'name': pinfo.name,
             'hasConfig': True,
             'configOpts': pinfo.configopts,
             'currentcfg': plugincfg,
             'updated': updated
         }
     else:
         return {
             'id': pname,
             'name': pinfo.name,
             'hasConfig': False,
             'updated': updated
         }
コード例 #2
0
ファイル: main.py プロジェクト: mashedkeyboard/Dashday
def getCfg():
    global maincfg
    global pluginlist
    global debugcfg

    try:
        configfile.read('config/dashday.cfg')
    except PermissionError:
        handlers.criterr("Permissions error on dashday.cfg. Please ensure you have write permissions for the directory.")
    maincfg = configfile['General']
    pluginlist = configfile['Plugins']['toload'].split(',')
    debugcfg = configfile['Debug']
コード例 #3
0
 def changeTime(self, scheduleRun):
     mainconfig = ConfigParser()
     try:
         mainconfig.read('config/headlights.cfg')
     except PermissionError:
         handlers.criterr(
             "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
         )
     mainconfig["Schedule"]["runat"] = scheduleRun
     with open('config/headlights.cfg', 'w') as headlightscfg:
         mainconfig.write(headlightscfg)
     headlights.reload()
     redirect('/', {'update': 'true'})
コード例 #4
0
def fetchLocalFrc(stationcode, key):
    url = 'http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/' + stationcode + '?res=daily&key=' + key
    request = urllib.request.Request(url)
    request.add_header('User-Agent', 'Headlights Client')
    request.add_header('Content-Type', 'application/json')
    try:
        response = urllib.request.urlopen(request).read().decode('UTF-8')
    except urllib.error.HTTPError as e:
        if e.code == 403:
            handlers.criterr(
                'HTTP error 403 (access denied). Check your API key and try again.'
            )
        else:
            handlers.criterr(
                'Unknown HTTP error. Error code ' + str(e.code) +
                '. Maybe the Met Office API (or your internet) is dead?')
    except Exception:
        import traceback
        handlers.criterr('Generic urllib exception: ' + traceback.format_exc())
    weatherobj = json.loads(response)
    try:
        weather = weatherobj['SiteRep']['DV']['Location']['Period'][0]['Rep'][
            0]
        return weather
    except KeyError:
        handlers.criterr(
            'Could not parse weather data. Sounds like the Met Office changed their API, but not their endpoint. :/'
        )  # oh noes! they changed their API?!?
コード例 #5
0
 def settings(self):
     mainconfig = ConfigParser()
     try:
         mainconfig.read('config/headlights.cfg')
     except PermissionError:
         handlers.criterr(
             "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
         )
     return {
         'runTime': mainconfig["Schedule"]["runat"],
         'name': mainconfig["General"]["HelloMyNameIs"],
         'pvend': mainconfig["General"]["Vendor"],
         'pprod': mainconfig["General"]["Product"]
     }
コード例 #6
0
def fetchRegionFrcAsText(regioncode, key):
    url = 'http://datapoint.metoffice.gov.uk/public/data/txt/wxfcs/regionalforecast/json/' + regioncode + '?key=' + key
    request = urllib.request.Request(url)
    request.add_header('User-Agent', 'Headlights Client')
    request.add_header('Content-Type', 'application/json')
    try:
        response = urllib.request.urlopen(request).read().decode(
            'UTF-8')  # Tries to read, will throw exception on 403 etc
    except urllib.error.HTTPError as e:
        if e.code == 403:
            handlers.criterr(
                'HTTP error 403 (access denied). Check your API key and try again.'
            )  # This is probably them forgetting to put their key in (correctly)
        else:
            handlers.criterr(
                'Unknown HTTP error. Error code ' + str(e.code) +
                '. Maybe the Met Office API (or your internet) is dead?'
            )  # Something very odd.
    except Exception:
        import traceback
        handlers.criterr('Generic urllib exception: ' +
                         traceback.format_exc())  # Something even odder
    weatherobj = json.loads(response)
    try:
        shortWthrText = weatherobj['RegionalFcst']['FcstPeriods']['Period'][0][
            'Paragraph'][1][
                '$']  # wahey the text! let's hope they never change the way their API returns...
    except KeyError:
        handlers.criterr(
            'Could not parse weather data. Sounds like the Met Office changed their API, but not their endpoint. :/'
        )  # oh noes! they changed their API?!?
    return str(shortWthrText)
コード例 #7
0
 def disablePlugin(self, pid):
     mainconfig = ConfigParser()
     try:
         mainconfig.read('config/headlights.cfg')
     except PermissionError:
         handlers.criterr(
             "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
         )
     pluginlist = mainconfig['Plugins']['toload'].split(',')
     pluginlist.remove(pid)
     mainconfig['Plugins']['toload'] = ','.join(pluginlist)
     with open('config/headlights.cfg', 'w') as headlightscfg:
         mainconfig.write(headlightscfg)
     headlights.reload()
     redirect('/plugins', {'disable': 'true'})
コード例 #8
0
ファイル: main.py プロジェクト: mashedkeyboard/Headlights
def init():
    global config
    global wtypes
    global weathercfg

    # Load configuration and all that jazz
    config = ConfigParser()
    if os.path.isfile('config/weather.cfg'):
        config.read('config/weather.cfg')
        weathercfg = config['Info']
    else:
        if "HEADLIGHTS_TESTMODE" in os.environ and os.environ[
                'HEADLIGHTS_TESTMODE'] == '1':
            try:
                weathercfg = {
                    'TextRegionCode': '514',
                    'ForecastLocation': '3672',
                    'DataPointKey': os.environ['HEADLIGHTS_DPKEY']
                }
            except KeyError:
                handlers.criterr(
                    "Incorrectly set test environment variables. Please set up Headlights correctly for testing."
                )
        else:
            handlers.err(
                'Cannot find weather.cfg. weather has not been loaded.')
            pluginloader.unload('weather')

    # Convert the weather types returned from the Met Office API into something vaguely sensible
    wtypes = {
        'NA': ['questionmark.png', ')', 'Unknown'],
        '1': ['sunny.png', 'B', 'Sunny'],
        '3': ['ptlycloudy.png', 'H', 'Partly cloudy'],
        '5': ['mist.png', 'E', 'Misty'],
        '6': ['fog.png', 'F', 'Foggy'],
        '7': ['cloudy.png', 'Y', 'Cloudy'],
        '8': ['overcast.png', '%', 'Overcast'],
        '11': ['drizzle.png', 'Q', 'Drizzly'],
        '12': ['lightrain.png', 'T', 'Light rain'],
        '15': ['heavyrain.png', 'R', 'Heavy rain'],
        '18': ['sleet.png', 'M', 'Sleet'],
        '21': ['hail.png', 'X', 'Hail'],
        '24': ['lightsnow.png', 'V', 'Light snow'],
        '27': ['heavysnow.png', 'W', 'Heavy snow'],
        '30': ['thunder.png', '0', 'Thunder']
    }
コード例 #9
0
def start():
    global headlightsjob
    global configfile
    if os.path.isfile('config/headlights.cfg'):
        configfile = ConfigParser()
        try:
            configfile.read('config/headlights.cfg')
        except Exception as e:
            handlers.criterr(
                "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
            )
    else:
        print("Please configure Headlights!")
        exit()
    print("Headlights started at " + time.strftime("%d/%m/%y %H:%M:%S"))
    main.start()
    refresh_eink(configfile)
    print("Headlights completed!")
コード例 #10
0
 def changeGeneral(self, name, pvend, pprod, escpos=True, eink=False):
     if eink:
         eink = True
     mainconfig = ConfigParser()
     try:
         mainconfig.read('config/headlights.cfg')
     except PermissionError:
         handlers.criterr(
             "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
         )
     mainconfig["General"]["HelloMyNameIs"] = name
     mainconfig["General"]["vendor"] = pvend
     mainconfig["General"]["product"] = pprod
     mainconfig["Output"]["eink"] = eink
     with open('config/headlights.cfg', 'w') as headlightscfg:
         mainconfig.write(headlightscfg)
     headlights.reload()
     redirect('/', {'update': 'true'})
コード例 #11
0
 def changeSettings(self, pname, psect, **kw):
     pname = unicodedata.normalize('NFKD', pname).encode('ascii', 'ignore')
     pinfo = __import__('plugins.' + pname, fromlist=[pname])
     if pinfo.hasconfig == True:
         plugincfg = ConfigParser()
         try:
             plugincfg.read(pinfo.configfile)
         except PermissionError:
             handlers.criterr(
                 "Permissions error on plugin configuration file. Please ensure you have write permissions for the directory."
             )
         for name, value in kw.items():
             plugincfg[psect][name] = value
         with open(pinfo.configfile, 'w') as configfile:
             plugincfg.write(configfile)
         redirect('/plugins/settings/' + pname, {'updated': 'true'})
     else:
         redirect('/plugins/settings/' + pname, {'updated': 'false'})
コード例 #12
0
    def index(self, enable='', disable='', delete=''):
        def pclass(plugin, enabledlist):
            if plugin in enabledlist:
                return {'class': 'success'}
            else:
                return {'class': 'none'}

        def pHasSettings(plugin):
            pinfo = __import__('plugins.' + plugin, fromlist=[plugin])
            if pinfo.hasconfig == True:
                return {}
            else:
                return {
                    'class': 'disabled',
                    'disabled': 'true'
                }  # returns disabled to disable the settings icon on the plugins page

        def getplugininfo(plugin):
            pinfo = __import__('plugins.' + plugin, fromlist=[plugin])
            return {
                'name': pinfo.name,
                'descrip': pinfo.description,
                'version': pinfo.version,
                'author': pinfo.author
            }

        mainconfig = ConfigParser()
        try:
            mainconfig.read('config/headlights.cfg')
        except PermissionError:
            handlers.criterr(
                "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
            )
        pluginlist = mainconfig['Plugins']['toload'].split(',')
        return {
            'enabled': pluginlist,
            'all': getSubdirectories('plugins'),
            'pclass': pclass,
            'getpinfo': getplugininfo,
            'enable': enable,
            'disable': disable,
            'delete': delete,
            'psclass': pHasSettings
        }
コード例 #13
0
def init(isfirst=False):
    global userconfig
    global nextRunTime
    global firstrun
    firstrun = isfirst
    if os.path.isfile('config/web.cfg') == True:
        userconfig = ConfigParser()
        try:
            userconfig.read('config/web.cfg')
        except PermissionError:
            handlers.criterr(
                "Permissions error on web.cfg. Please ensure you have write permissions for the directory."
            )
    else:
        print(
            "No configuration file found. Please configure Headlights's server."
        )
        exit()
    nextRunTime = "loading..."
コード例 #14
0
def setup_printer(maincfg, debugcfg, logging):
    # Connects to the printer (unless test mode is enabled, in which case starts a dummy instance)
    if debugcfg['TestMode'] == "1":
        logging.warning(
            'Headlights is in test mode. Nothing will actually be printed - you\'ll just see the output to the printer on the screen.'
        )
        p = printer.Dummy()
        logging.debug("Initialized dummy printer")
    else:
        try:
            p = printer.Usb(int(maincfg['Vendor'], 16),
                            int(maincfg['Product'], 16))
        except (usb.core.NoBackendError,
                escpos.exceptions.USBNotFoundError) as e:
            logging.debug(e)
            handlers.criterr(
                "Could not initialize printer. Check a printer matching the vendor and product in the config file is actually connected, and relaunch Headlights."
            )
        logging.debug("Initialized USB printer")
    return p
コード例 #15
0
def reload():
    global headlightsjob
    global configfile
    if os.path.isfile('config/headlights.cfg'):
        configfile = ConfigParser()
        try:
            configfile.read('config/headlights.cfg')
        except Exception as e:
            handlers.criterr(
                "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
            )
    else:
        print("Please configure Headlights!")
        exit()
    schedule.clear()
    refresh_eink(configfile)
    headlightsjob = schedule.every().day.at(
        configfile['Schedule']['runat']).do(start)
    web.serv.updateScheduledRun(
        headlightsjob.next_run.strftime("%d/%m/%y %H:%M:%S"))
コード例 #16
0
    def tweet_print(self, authkey):
        configfile = ConfigParser()
        try:
            configfile.read('config/headlights.cfg')
        except PermissionError:
            handlers.criterr(
                "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
            )
        maincfg = configfile['General']
        debugcfg = configfile['Debug']

        try:
            key = configfile['Web']['apiauth']
        except KeyError:
            key = ''
        if key != authkey:
            abort(401)
        p = printer.setup_printer(maincfg, debugcfg, logging)
        p.text(request.body)
        p.cut()
        abort(200)
コード例 #17
0
ファイル: main.py プロジェクト: mashedkeyboard/Dashday
def init():
    global config
    global wtypes
    global weathercfg

    # Load configuration and all that jazz
    config = configparser.ConfigParser()
    if os.path.isfile('config/weather.cfg'):
        config.read('config/weather.cfg')
        weathercfg = config['Info']
    else:
        if "DASHDAY_TESTMODE" in os.environ and os.environ['DASHDAY_TESTMODE'] == '1':
            try:
                weathercfg = {'TextRegionCode': '514', 'ForecastLocation': '3672', 'DataPointKey': os.environ['DASHDAY_DPKEY']}
            except KeyError:
                handlers.criterr("Incorrectly set test environment variables. Please set up Dashday correctly for testing.")
        else:
            handlers.err('Cannot find weather.cfg. weather has not been loaded.')
            pluginloader.unload('weather')

    # Convert the weather types returned from the Met Office API into something vaguely sensible
    wtypes = {'NA' : 'questionmark.png',
           '1' : 'sunny.png',
           '3' : 'ptlycloudy.png',
           '5' : 'mist.png',
           '6' : 'fog.png',
           '7' : 'cloudy.png',
           '8' : 'overcast.png',
           '11' : 'drizzle.png',
           '12' : 'lightrain.png',
           '15' : 'heavyrain.png',
           '18' : 'sleet.png',
           '21' : 'hail.png',
           '24' : 'lightsnow.png',
           '27' : 'heavysnow.png',
           '30' : 'thunder.png'
    }
コード例 #18
0
ファイル: datapoint.py プロジェクト: mashedkeyboard/Dashday
def fetchFrcWthrType(stationcode,key):
    url = 'http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/' + stationcode + '?res=daily&key=' + key
    request = urllib.request.Request(url)
    request.add_header('User-Agent','Dashday Client')
    request.add_header('Content-Type','application/json')
    try:
        response = urllib.request.urlopen(request).read().decode('UTF-8')
    except urllib.error.HTTPError as e:
        if e.code == 403:
            handlers.criterr('HTTP error 403 (access denied). Check your API key and try again.')
        else:
            handlers.criterr('Unknown HTTP error. Error code ' + str(e.code) + '. Maybe the Met Office API (or your internet) is dead?')
    except Exception:
        import traceback
        handlers.criterr('Generic urllib exception: ' + traceback.format_exc())
    weatherobj = json.loads(response)
    try:
        weatherType = weatherobj['SiteRep']['DV']['Location']['Period'][0]['Rep'][0]['W']
    except KeyError:
        handlers.criterr('Could not parse weather data. Sounds like the Met Office changed their API, but not their endpoint. :/') # oh noes! they changed their API?!?
    return(str(weatherType))
コード例 #19
0
ファイル: datapoint.py プロジェクト: mashedkeyboard/Dashday
def fetchRegionFrcAsText(regioncode,key):
    url = 'http://datapoint.metoffice.gov.uk/public/data/txt/wxfcs/regionalforecast/json/' + regioncode + '?key=' + key
    request = urllib.request.Request(url)
    request.add_header('User-Agent','Dashday Client')
    request.add_header('Content-Type','application/json')
    try:
        response = urllib.request.urlopen(request).read().decode('UTF-8') # Tries to read, will throw exception on 403 etc
    except urllib.error.HTTPError as e:
        if e.code == 403:
            handlers.criterr('HTTP error 403 (access denied). Check your API key and try again.') # This is probably them forgetting to put their key in (correctly)
        else:
            handlers.criterr('Unknown HTTP error. Error code ' + str(e.code) + '. Maybe the Met Office API (or your internet) is dead?') # Something very odd.
    except Exception:
        import traceback
        handlers.criterr('Generic urllib exception: ' + traceback.format_exc()) # Something even odder
    weatherobj = json.loads(response)
    try:
        shortWthrText = weatherobj['RegionalFcst']['FcstPeriods']['Period'][0]['Paragraph'][1]['$'] # wahey the text! let's hope they never change the way their API returns...
    except KeyError:
        handlers.criterr('Could not parse weather data. Sounds like the Met Office changed their API, but not their endpoint. :/') # oh noes! they changed their API?!?
    return(str(shortWthrText))
コード例 #20
0
        configfile['Schedule']['runat']).do(start)
    web.serv.updateScheduledRun(
        headlightsjob.next_run.strftime("%d/%m/%y %H:%M:%S"))


if __name__ == "__main__":
    global configfile
    # Load the configuration file
    # noinspection PyPackageRequirements
    if os.path.isfile('config/headlights.cfg'):
        configfile = ConfigParser()
        try:
            configfile.read('config/headlights.cfg')
        except Exception as e:
            handlers.criterr(
                "Permissions error on headlights.cfg. Please ensure you have write permissions for the directory."
            )

        web.serv.init()
        # Run the web server
        thr = threading.Thread(target=web.serv.run)
        thr.start()

        # Runs the API
        thr = threading.Thread(target=web.serv.run_api)
        thr.start()

        # Runs the scheduler and all that jazz
        thr = threading.Thread(target=runapp)
        thr.start()
    else:
コード例 #21
0
ファイル: main.py プロジェクト: mashedkeyboard/Dashday
def main():

    global maincfg
    global pluginlist
    global debugcfg
    global configfile

    # Let's make logging work. Formatting the log here
    logFormatter = logging.Formatter("%(asctime)s: %(levelname)s: %(message)s","%m/%d/%Y %I:%M:%S %p")
    rootLogger = logging.getLogger()
    rootLogger.setLevel(logging.NOTSET) # Make sure the root logger doesn't block any potential output to the fileHandler or consoleHandler

    # And output it to the console
    consoleHandler = logging.StreamHandler()
    consoleHandler.setFormatter(logFormatter)
    consoleHandler.setLevel(logging.WARNING) # Only output warnings to stdout
    rootLogger.addHandler(consoleHandler)
    
    # Finally, output the log to a file
    try:
        fileHandler = logging.FileHandler("dashday.log")
        fileHandler.setFormatter(logFormatter)
        fileHandler.setLevel(logging.INFO) # Output info to the log by default
        rootLogger.addHandler(fileHandler)
    except PermissionError:
        handlers.criterr("Permissions error on dashday.log. Please ensure you have write permissions for the directory.")

    # Wahey
    logging.info('Dashday process started')

    # Create a new configuration file instance
    configfile = configparser.ConfigParser()

    # Does the user even have a configuration file?
    if os.path.isfile('config/dashday.cfg') != True:
        # Check for test mode specified in the environment variables
        if "DASHDAY_TESTMODE" in os.environ and os.environ['DASHDAY_TESTMODE'] == '1':
            try:
                maincfg = {'HelloMyNameIs' : "TestModeUsr"}
                pluginlist = ['weather']
                debugcfg = {'TestMode': "1", 'LogLevel': "DEBUG"}
            except KeyError:
                handlers.criterr("Incorrectly set test environment variables. Please set up Dashday correctly for testing.")
            logging.warning("Running in environment variable based test mode.")
        else:
            handlers.criterr('dashday.cfg not found. Please configure dashday before launch.')
    else:
        getCfg()

    # And let's start the logging!
    numeric_level = getattr(logging, debugcfg['LogLevel'].upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError('Invalid log level: {0!s}'.format(loglevel))
    consoleHandler.setLevel(numeric_level)
    fileHandler.setLevel(numeric_level)

    # Connects to the printer (unless test mode is enabled, in which case starts a dummy instance)
    if debugcfg['TestMode'] == "1":
        logging.warning('Dashday is in test mode. Nothing will actually be printed - you\'ll just see the output to the printer on the screen.')
        p = printer.Dummy()
        logging.debug("Initialized dummy printer")
    else:
        try:
            p = printer.Usb(int(maincfg['Vendor'],16),int(maincfg['Product'],16))
        except (usb.core.NoBackendError,escpos.exceptions.USBNotFoundError) as e:
            logging.debug(e)
            handlers.criterr("Could not initialize printer. Check a printer matching the vendor and product in the config file is actually connected, and relaunch Dashday.")
        logging.debug("Initialized USB printer")


    # Setup the printer for the beautiful header, and then print it
    p.set(align="LEFT",text_type="B",width=2,height=2)
    logging.debug("Set the header printing style")
    p.text("Hello,\n" + maincfg['HelloMyNameIs'] + '\n\n')
    logging.debug("Printed the header")
    
    # Time to reset the font
    p.set("LEFT", "A", "normal", 1, 1)
    logging.debug("Unset the header printing style")
    
    p.text(datetime.datetime.now().strftime("%a %d %b"))
    
    # Load all the plugins in the plugins list in the config file
    for plugin in pluginlist:
        pluginloader.init(plugin)

    # Print all the things
    pluginloader.printAllPlugins(p)
    
    # Cut the paper! Magic!
    p.cut()
    logging.debug("Ended the print and cut the paper")

    # If we're in test mode, print the results to the screen
    if debugcfg['TestMode'] == "1":
        print(str(p.output))
        logging.debug("Printed dummy output to stdout")
        logging.debug("Debug logging enabled, printing to log:") # this would only appear if they did have debug logging enabled so yeah
        logging.debug(str(p.output))
       
    # Call the "wahey I'm done!" handler
    handlers.closed()