#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
"""
$ python3(.6) python_barebone.py
This script will do the following things:
Load it's own path and check for an existing include/ dir in it,
so you can simply load whatever is in there as import <modulename>.
Then it will set up python logging with some pretty verbose information.
There are examples for Console, File and Syslog destinations.
After logging is set up, this script will parse it's command line
using argparse and if it encounters a '-d' or '--debug' as parameter,
it will enable full debug logging to all enabled/configured
destinations (handlers).
have fun.. ;)
2018-08-28 hackbyte (d. mitzlaff / pythonstuff at hackbyte period de)
I'm open for donations if you like, i'm just a poor life artist. ;)
bitcoin: 1bytoroRvXLGc1FWTob5h1oH92VMdUSFi
ethereum: 0x97cfdffb3bd4d77694891dabe701cff2d277dfbd
Or just ask me .. google knows me. ;)
Oh well, i'm open for comments, critics and suggestions too,
i'm pretty new with this python stuff. ;)
"""
################################################################################
#
# first imports
#
import os, sys, shutil, time, datetime, locale, asyncio, json
import logging, logging.handlers, inspect, operator, argparse
################################################################################
#
# save scriptpath
#
# from https://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
# https://stackoverflow.com/questions/1296501/find-path-to-currently-running-file
# https://docs.python.org/3.6/library/inspect.html and
# https://docs.python.org/3.6/library/os.path.html
# https://stackoverflow.com/questions/8663076/python-best-way-to-add-to-sys-path-relative-to-the-current-running-script
#
scriptpath = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
#
# save our scriptname (basename of the full blown path like above)
#
scriptname = os.path.basename(inspect.getfile(inspect.currentframe()))
#
# (if) we want to include stuff from an include/ dir _in the path where the script lies in_!
#
# from https://stackoverflow.com/questions/2349991/how-to-import-other-python-files
# https://stackoverflow.com/questions/8663076/python-best-way-to-add-to-sys-path-relative-to-the-current-running-script
# https://docs.python.org/3/library/importlib.html#module-importlib ...
#
if 'include' == os.path.basename(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))):
#
# save the dirname of the parent directory
#
scriptpath = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
#
# or else
#
else:
#
# save our dir
#
scriptpath = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
#
# set includepath als include within scriptpath dir
#
includepath = scriptpath + '/include'
#
# check if includepath exists
# see https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python
#
if os.path.isdir(includepath):
#
# if so, set it as additional import path
#
sys.path.insert(0, includepath)
#
# if not
#
else:
#
# complain!!!
#
print("No include path found!")
#
# and gtfo
#
sys.exit(23)
#
# pudb debugging...... if needed, you can anywhere in the source
# activate the debugger with putting 'set_trace()' in a line
#
# see https://stackoverflow.com/questions/1623039/python-debugging-tips
# https://pypi.org/project/pudb/ and
# http://heather.cs.ucdavis.edu/~matloff/pudb.html
#
##from pudb import set_trace
#
################################################################################
#
# Now We're sure to have any needed include path.... for reasons
#
# load helper stuff (from my own stuff ;))
#
##import stuff_helper
# or
##from stuff_helper import myfunc
#
################################################################################
#
# set up and configure python logging.
#
# see https://docs.python.org/3.6/howto/logging.html
# https://docs.python.org/3.6/howto/logging-cookbook.html
# https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/
#
# create log object
#
log = logging.getLogger()
#
# by default, log all INFO messages. ;)
#
log.setLevel(logging.INFO)
#
# Formatting for anything not syslog (so we need our own timestamp)
# watch out for the '.%(msecs)03d' part, it is useful if your
# script may output several messages within one second. ;)
#
# see: https://stackoverflow.com/questions/31328300/python-logging-module-logging-timestamp-to-include-microsecond
# https://stackoverflow.com/questions/6290739/python-logging-use-milliseconds-in-time-format
#
logformatter_main = logging.Formatter(
'%(asctime)s.%(msecs)03d ' +
'%(levelname)-8s ' +
'%(filename)-16s ' +
'%(funcName)-12s ' +
'%(lineno)04d ' +
'%(message)s',
'%Y%m%d%H%M%S')
#
# for syslog (so we do not need our own timestamp)
#
logformatter_syslog = logging.Formatter(
'%(levelname)-8s ' +
'%(filename)-16s ' +
'%(funcName)-12s ' +
'%(lineno)04d ' +
'%(message)s')
#
# create console log handler (stdout/stderr)
#
logcons = logging.StreamHandler()
#
# log even debug stuff to console (if enabled below;))
#
logcons.setLevel(logging.DEBUG)
#
# make it fancy
#
logcons.setFormatter(logformatter_main)
#
# and add handler to log..
#
log.addHandler(logcons)
#
# create file handler which logs debug messages too
#
#logfile = logging.FileHandler(config['butler_home'] + '/allmessages.log')
#logfile.setLevel(logging.DEBUG)
#logfile.setFormatter(logformatter_main)
#log.addHandler(logfile)
#
# create a syslog handler, by default it will only log
# INFO and more important messages...
#
#logsys = logging.handlers.SysLogHandler(address = '/dev/log')
#logsys.setLevel(logging.INFO)
#logsys.setFormatter(logformatter_syslog)
#log.addHandler(logsys)
################################################################################
#
# now, parse command line arguments...
#
# see: https://docs.python.org/3/library/argparse.html
# https://pymotw.com/2/argparse/
# https://docs.python.org/3/howto/argparse.html
#
# create parser object and give it a description.
#
parser = argparse.ArgumentParser(description=scriptname + ' commandline parameters.')
#
# add argument -c/--config for a configfile
# default will be (our_path)/config/config.json
#
parser.add_argument(
"-c", "--config",
dest="config_file",
action="store",
default=scriptpath+"/config/config.json",
metavar="FILE",
help="Use configuration from FILE")
#
# add argument -d/--debug as simple boolean toggle,
# defaults to false.
#
parser.add_argument(
"-d", "--debug",
dest="debug",
action="store_true",
default=False,
help="show heavy masses(!!) of debug output.")
#
# add argument -t/--test for test-run, defaults to false.
#
parser.add_argument(
"-t", "--test",
dest="test",
action="store_true",
default=False,
help="for testing environment")
#
# add an argument for some parameter (telegram api token in my case;)
#
parser.add_argument(
"-a", "--api",
dest="token",
action="store",
default="",
metavar="TELEGRAM_TOKEN",
help="Telegram bot api token to use")
#
# And add an argument for a owner id for telegram too
#
parser.add_argument(
"-o", "--owner",
dest="owner",
action="store",
default="",
metavar="UID",
help="Owner ID")
#
# mkay now the f.. parse that!! ;)
#
cmdline = parser.parse_args()
################################################################################
#
# if debug parameter is set from commandline, make it so........
#
if cmdline.debug:
log.setLevel(logging.DEBUG)
################################################################################
#
# we're alive!
#
log.debug("python version " + str(sys.version).replace('\n', ''))
log.debug("program '"+scriptname+"' start " + '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
################################################################################
#
# log what we got from commandline.....
#
log.debug("cmdline.config_file = " + str(cmdline.config_file))
log.debug("cmdline.debug = " + str(cmdline.debug))
log.debug("cmdline.test = " + str(cmdline.test))
log.debug("cmdline.token = " + str(cmdline.token))
log.debug("cmdline.owner = " + str(cmdline.owner))
################################################################################
#
# yeah..........................................................................
#
# Here you can start your program, and use any log method from above.
#
# here come some examples.
log.debug("Well, this is a debug message!")
log.info("This is a simple info message. ;)")
log.warning("We also can WARN about things now!")
log.error("Even if we encounter some errors.")
log.critical("We even can tell the user if a critical problem occurs.")
# All done, clean exit. ;)
sys.exit()
Comments