2019-01-05 20:43:48 +01:00
import logging
2022-09-09 18:38:08 +02:00
from pathlib import Path
2019-07-27 21:08:19 +02:00
import requests
2022-02-19 12:33:11 +01:00
from cbpi . configFolder import ConfigFolder
2019-08-16 21:36:55 +02:00
from cbpi . utils . utils import load_config
2021-01-30 22:29:33 +01:00
from zipfile import ZipFile
2019-01-05 20:43:48 +01:00
from cbpi . craftbeerpi import CraftBeerPi
import os
2022-02-26 21:45:10 +01:00
import pkgutil
2019-01-05 20:43:48 +01:00
import shutil
2021-01-30 22:29:33 +01:00
import click
2022-09-12 21:54:51 +02:00
import pathlib
2021-02-06 14:11:30 +01:00
from subprocess import call
2022-02-26 21:45:10 +01:00
from colorama import Fore , Back , Style
import importlib
2022-02-19 12:33:11 +01:00
from importlib_metadata import metadata
2022-02-26 21:45:10 +01:00
from tabulate import tabulate
from PyInquirer import prompt , print_json
2022-04-26 07:19:25 +02:00
import platform
2022-09-24 21:55:36 +02:00
import time
2019-07-27 21:08:19 +02:00
2022-02-20 11:50:44 +01:00
class CraftBeerPiCli ( ) :
def __init__ ( self , config ) - > None :
self . config = config
pass
def setup ( self ) :
print ( " Setting up CraftBeerPi " )
self . config . create_home_folder_structure ( )
self . config . create_config_file ( )
def start ( self ) :
if self . config . check_for_setup ( ) is False :
return
print ( " START " )
cbpi = CraftBeerPi ( self . config )
cbpi . start ( )
def setup_one_wire ( self ) :
print ( " Setting up 1Wire " )
with open ( ' /boot/config.txt ' , ' w ' ) as f :
f . write ( " dtoverlay=w1-gpio,gpiopin=4,pullup=on " )
print ( " /boot/config.txt created " )
def list_one_wire ( self ) :
print ( " List 1Wire " )
call ( [ " modprobe " , " w1-gpio " ] )
call ( [ " modprobe " , " w1-therm " ] )
2021-07-04 11:23:19 +02:00
try :
2022-02-20 11:50:44 +01:00
for dirname in os . listdir ( ' /sys/bus/w1/devices ' ) :
if ( dirname . startswith ( " 28 " ) or dirname . startswith ( " 10 " ) ) :
print ( dirname )
2021-07-04 11:23:19 +02:00
except Exception as e :
print ( e )
2022-02-20 11:50:44 +01:00
def plugins_list ( self ) :
result = [ ]
print ( " " )
print ( Fore . LIGHTYELLOW_EX , " List of active plugins " , Style . RESET_ALL )
print ( " " )
discovered_plugins = {
name : importlib . import_module ( name )
for finder , name , ispkg
in pkgutil . iter_modules ( )
if name . startswith ( ' cbpi ' ) and len ( name ) > 4
2022-02-26 21:45:10 +01:00
}
2022-02-20 11:50:44 +01:00
for key , module in discovered_plugins . items ( ) :
try :
meta = metadata ( key )
result . append ( dict ( Name = meta [ " Name " ] , Version = meta [ " Version " ] , Author = meta [ " Author " ] , Homepage = meta [ " Home-page " ] , Summary = meta [ " Summary " ] ) )
except Exception as e :
print ( e )
print ( Fore . LIGHTGREEN_EX , tabulate ( result , headers = " keys " ) , Style . RESET_ALL )
def plugin_create ( self ) :
print ( " Plugin Creation " )
print ( " " )
questions = [
{
' type ' : ' input ' ,
' name ' : ' name ' ,
' message ' : ' Plugin Name: ' ,
}
]
answers = prompt ( questions )
2022-09-16 10:25:31 +02:00
name = " cbpi4- " + str ( answers [ " name " ] ) . replace ( ' _ ' , ' - ' ) . replace ( ' ' , ' - ' )
2022-02-20 11:50:44 +01:00
if os . path . exists ( os . path . join ( " . " , name ) ) is True :
print ( " Cant create Plugin. Folder {} already exists " . format ( name ) )
return
2021-02-01 01:38:04 +01:00
2022-02-20 11:50:44 +01:00
url = ' https://github.com/Manuel83/craftbeerpi4-plugin-template/archive/main.zip '
r = requests . get ( url )
with open ( ' temp.zip ' , ' wb ' ) as f :
f . write ( r . content )
with ZipFile ( ' temp.zip ' , ' r ' ) as repo_zip :
repo_zip . extractall ( )
2022-09-24 21:55:36 +02:00
time . sleep ( 1 ) # windows dev container permissions problem otherwise
2022-02-20 11:50:44 +01:00
2022-09-24 21:55:36 +02:00
os . rename ( os . path . join ( " . " , " craftbeerpi4-plugin-template-main " ) , os . path . join ( " . " , name ) )
2022-02-20 11:50:44 +01:00
os . rename ( os . path . join ( " . " , name , " src " ) , os . path . join ( " . " , name , name ) )
import jinja2
templateLoader = jinja2 . FileSystemLoader ( searchpath = os . path . join ( " . " , name ) )
templateEnv = jinja2 . Environment ( loader = templateLoader )
TEMPLATE_FILE = " setup.py "
template = templateEnv . get_template ( TEMPLATE_FILE )
outputText = template . render ( name = name )
with open ( os . path . join ( " . " , name , " setup.py " ) , " w " ) as fh :
fh . write ( outputText )
TEMPLATE_FILE = " MANIFEST.in "
template = templateEnv . get_template ( TEMPLATE_FILE )
outputText = template . render ( name = name )
with open ( os . path . join ( " . " , name , " MANIFEST.in " ) , " w " ) as fh :
fh . write ( outputText )
TEMPLATE_FILE = os . path . join ( " / " , name , " config.yaml " )
operatingsystem = str ( platform . system ( ) ) . lower ( )
if operatingsystem . startswith ( " win " ) :
TEMPLATE_FILE = str ( TEMPLATE_FILE ) . replace ( ' \\ ' , ' / ' )
template = templateEnv . get_template ( TEMPLATE_FILE )
outputText = template . render ( name = name )
with open ( os . path . join ( " . " , name , name , " config.yaml " ) , " w " ) as fh :
fh . write ( outputText )
print ( " " )
print ( " " )
print ( " Plugin {} {} {} created! " . format ( Fore . LIGHTGREEN_EX , name , Style . RESET_ALL ) )
print ( " " )
print ( " Developer Documentation: https://openbrewing.gitbook.io/craftbeerpi4_support/readme/development " )
print ( " " )
print ( " Happy developing! Cheers " )
print ( " " )
print ( " " )
def autostart ( self , name ) :
''' Enable or disable autostart '''
if ( name == " status " ) :
if os . path . exists ( os . path . join ( " /etc/systemd/system " , " craftbeerpi.service " ) ) is True :
print ( " CraftBeerPi Autostart is {} ON {} " . format ( Fore . LIGHTGREEN_EX , Style . RESET_ALL ) )
else :
print ( " CraftBeerPi Autostart is {} OFF {} " . format ( Fore . RED , Style . RESET_ALL ) )
elif ( name == " on " ) :
print ( " Add craftbeerpi.service to systemd " )
try :
if os . path . exists ( os . path . join ( " /etc/systemd/system " , " craftbeerpi.service " ) ) is False :
srcfile = self . config . get_file_path ( " craftbeerpi.service " )
destfile = os . path . join ( " /etc/systemd/system " )
shutil . copy ( srcfile , destfile )
print ( " Copied craftbeerpi.service to /etc/systemd/system " )
os . system ( ' systemctl enable craftbeerpi.service ' )
print ( ' Enabled craftbeerpi service ' )
os . system ( ' systemctl start craftbeerpi.service ' )
print ( ' Started craftbeerpi.service ' )
else :
print ( " craftbeerpi.service is already located in /etc/systemd/system " )
except Exception as e :
print ( e )
return
return
elif ( name == " off " ) :
print ( " Remove craftbeerpi.service from systemd " )
try :
status = os . popen ( ' systemctl list-units --type=service --state=running | grep craftbeerpi.service ' ) . read ( )
if status . find ( " craftbeerpi.service " ) != - 1 :
os . system ( ' systemctl stop craftbeerpi.service ' )
print ( ' Stopped craftbeerpi service ' )
os . system ( ' systemctl disable craftbeerpi.service ' )
print ( ' Removed craftbeerpi.service as service ' )
else :
print ( ' craftbeerpi.service service is not running ' )
if os . path . exists ( os . path . join ( " /etc/systemd/system " , " craftbeerpi.service " ) ) is True :
os . remove ( os . path . join ( " /etc/systemd/system " , " craftbeerpi.service " ) )
print ( " Deleted craftbeerpi.service from /etc/systemd/system " )
else :
print ( " craftbeerpi.service is not located in /etc/systemd/system " )
except Exception as e :
print ( e )
return
return
2021-02-01 01:38:04 +01:00
2022-02-26 21:45:10 +01:00
2022-02-20 11:50:44 +01:00
def chromium ( self , name ) :
''' Enable or disable autostart '''
if ( name == " status " ) :
if os . path . exists ( os . path . join ( " /etc/xdg/autostart/ " , " chromium.desktop " ) ) is True :
print ( " CraftBeerPi Chromium Desktop is {} ON {} " . format ( Fore . LIGHTGREEN_EX , Style . RESET_ALL ) )
else :
print ( " CraftBeerPi Chromium Desktop is {} OFF {} " . format ( Fore . RED , Style . RESET_ALL ) )
elif ( name == " on " ) :
print ( " Add chromium.desktop to /etc/xdg/autostart/ " )
try :
if os . path . exists ( os . path . join ( " /etc/xdg/autostart/ " , " chromium.desktop " ) ) is False :
srcfile = self . config . get_file_path ( " chromium.desktop " )
destfile = os . path . join ( " /etc/xdg/autostart/ " )
shutil . copy ( srcfile , destfile )
print ( " Copied chromium.desktop to /etc/xdg/autostart/ " )
else :
print ( " chromium.desktop is already located in /etc/xdg/autostart/ " )
except Exception as e :
print ( e )
return
return
elif ( name == " off " ) :
print ( " Remove chromium.desktop from /etc/xdg/autostart/ " )
try :
if os . path . exists ( os . path . join ( " /etc/xdg/autostart/ " , " chromium.desktop " ) ) is True :
os . remove ( os . path . join ( " /etc/xdg/autostart/ " , " chromium.desktop " ) )
print ( " Deleted chromium.desktop from /etc/xdg/autostart/ " )
else :
print ( " chromium.desktop is not located in /etc/xdg/autostart/ " )
except Exception as e :
print ( e )
return
return
2019-01-21 22:33:29 +01:00
2019-08-16 21:36:55 +02:00
2021-01-30 22:29:33 +01:00
@click.group ( )
2022-02-19 12:33:11 +01:00
@click.pass_context
@click.option ( ' --config-folder-path ' , ' -c ' , default = " ./config " , type = click . Path ( ) , help = " Specify where the config folder is located. Defaults to ' ./config ' . " )
2022-09-12 21:54:51 +02:00
@click.option ( ' --logs-folder-path ' , ' -l ' , default = " " , type = click . Path ( ) , help = " Specify where the log folder is located. Defaults to ' ../logs ' relative from the config folder. " )
@click.option ( ' --debug-log-level ' , ' -d ' , default = " 30 " , type = int , help = " Specify the log level you want to write to all logs. 0=ALL, 10=DEBUG, 20=INFO 30(default)=WARNING, 40=ERROR, 50=CRITICAL " )
def main ( context , config_folder_path , logs_folder_path , debug_log_level ) :
2022-02-26 21:45:10 +01:00
print ( " --------------------- " )
print ( " Welcome to CBPi " )
print ( " --------------------- " )
2022-09-12 21:54:51 +02:00
if logs_folder_path == " " :
logs_folder_path = os . path . join ( Path ( config_folder_path ) . absolute ( ) . parent , ' logs ' )
formatter = logging . Formatter ( ' %(asctime)s - %(levelname)s - %(name)s - %(message)s ' )
logging . basicConfig ( format = formatter , level = debug_log_level , stream = logging . StreamHandler ( ) )
2022-09-09 18:38:08 +02:00
logger = logging . getLogger ( )
2022-09-12 21:54:51 +02:00
try :
if not os . path . isdir ( logs_folder_path ) :
logger . info ( f " logs folder ' { logs_folder_path } ' doesnt exist and we are trying to create it " )
pathlib . Path ( logs_folder_path ) . mkdir ( parents = True , exist_ok = True )
logger . info ( f " logs folder ' { logs_folder_path } ' successfully created " )
logger . addHandler ( logging . handlers . RotatingFileHandler ( os . path . join ( logs_folder_path , f " cbpi.log " ) , maxBytes = 1000000 , backupCount = 3 ) )
except Exception as e :
logger . warning ( " log folder or log file could not be created or accessed. check folder and file permissions or create the logs folder somewhere you have access with a start option like ' --log-folder-path=./logs ' " )
logging . critical ( e , exc_info = True )
cbpi_cli = CraftBeerPiCli ( ConfigFolder ( config_folder_path , logs_folder_path ) )
2022-02-20 11:50:44 +01:00
context . obj = cbpi_cli
2019-08-16 21:36:55 +02:00
2022-02-19 12:33:11 +01:00
@main.command ( )
@click.pass_context
def setup ( context ) :
2021-01-30 22:29:33 +01:00
''' Create Config folder '''
2022-02-20 11:50:44 +01:00
context . obj . setup ( )
2021-02-01 01:38:04 +01:00
2022-02-19 12:33:11 +01:00
@main.command ( )
2022-02-20 11:50:44 +01:00
@click.pass_context
2021-02-06 14:19:51 +01:00
@click.option ( ' --list ' , is_flag = True , help = " List all 1Wire Devices " )
@click.option ( ' --setup ' , is_flag = True , help = " Setup 1Wire on Raspberry Pi " )
2022-02-20 11:50:44 +01:00
def onewire ( context , list , setup ) :
2021-02-06 14:14:11 +01:00
''' Setup 1wire on Raspberry Pi '''
2021-02-06 14:19:51 +01:00
if setup is True :
2022-02-20 11:50:44 +01:00
context . obj . setup_one_wire ( )
2021-02-06 14:11:30 +01:00
if list is True :
2022-02-20 11:50:44 +01:00
context . obj . list_one_wire ( )
2021-02-06 14:19:51 +01:00
2022-02-19 12:33:11 +01:00
@main.command ( )
@click.pass_context
def start ( context ) :
2022-02-20 11:50:44 +01:00
context . obj . start ( )
2021-02-01 01:38:04 +01:00
2022-02-19 12:33:11 +01:00
@main.command ( )
@click.pass_context
def plugins ( context ) :
2021-01-30 22:29:33 +01:00
''' List active plugins '''
2022-02-20 11:50:44 +01:00
context . obj . plugins_list ( )
2021-02-01 01:38:04 +01:00
2022-04-26 07:19:25 +02:00
@main.command ( )
2022-02-20 11:50:44 +01:00
@click.pass_context
def create ( context ) :
2022-02-26 21:45:10 +01:00
''' Create New Plugin '''
2022-02-20 11:50:44 +01:00
context . obj . plugin_create ( )
2022-02-19 12:33:11 +01:00
@main.command ( )
@click.pass_context
2022-02-20 11:50:44 +01:00
@click.argument ( ' name ' )
2022-02-19 12:33:11 +01:00
def autostart ( context , name ) :
2022-02-28 11:15:02 +01:00
''' (on|off|status) Enable or disable autostart '''
2022-02-20 11:50:44 +01:00
context . obj . autostart ( name )
2021-02-01 01:38:04 +01:00
2019-01-21 22:33:29 +01:00
2022-02-19 12:33:11 +01:00
@main.command ( )
@click.pass_context
2022-02-20 11:50:44 +01:00
@click.argument ( ' name ' )
2022-02-19 12:33:11 +01:00
def chromium ( context , name ) :
2022-02-28 11:15:02 +01:00
''' (on|off|status) Enable or disable Kiosk mode '''
2022-02-20 11:50:44 +01:00
context . obj . chromium ( name )