craftbeerpi4-pione/cbpi/cli.py

458 lines
17 KiB
Python
Raw Normal View History

2019-01-21 22:33:29 +01:00
import argparse
2019-08-16 21:36:55 +02:00
import datetime
2019-01-05 20:43:48 +01:00
import logging
2019-08-16 21:36:55 +02:00
import subprocess
import sys
import re
2019-07-27 21:08:19 +02:00
import requests
import yaml
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-01-25 11:33:21 +01:00
import platform
2019-01-05 20:43:48 +01:00
import pathlib
import shutil
2021-01-30 22:29:33 +01:00
import yaml
import click
2021-02-06 14:11:30 +01:00
from subprocess import call
import zipfile
2021-10-16 14:22:04 +02:00
from importlib_metadata import version, metadata
2019-01-05 20:43:48 +01:00
2021-01-30 22:29:33 +01:00
from jinja2 import Template
2019-01-05 20:43:48 +01:00
2021-02-01 01:38:04 +01:00
2019-01-05 20:43:48 +01:00
def create_config_file():
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "config.yaml")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "config.yaml")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", 'config')
2019-01-05 20:43:48 +01:00
shutil.copy(srcfile, destfile)
2021-02-16 20:37:51 +01:00
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "actor.json")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "actor.json")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", 'config')
2021-01-26 20:21:53 +01:00
shutil.copy(srcfile, destfile)
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "sensor.json")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "sensor.json")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", 'config')
2021-01-26 20:21:53 +01:00
shutil.copy(srcfile, destfile)
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "kettle.json")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "kettle.json")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", 'config')
2021-01-26 20:21:53 +01:00
shutil.copy(srcfile, destfile)
if os.path.exists(os.path.join(".", 'config', "fermenter_data.json")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "fermenter_data.json")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "step_data.json")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "step_data.json")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", 'config')
2021-01-26 20:21:53 +01:00
shutil.copy(srcfile, destfile)
2021-02-16 20:37:51 +01:00
if os.path.exists(os.path.join(".", 'config', "config.json")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "config.json")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", 'config', "dashboard", "cbpi_dashboard_1.json")) is False:
2021-02-07 01:43:35 +01:00
srcfile = os.path.join(os.path.dirname(__file__), "config", "dashboard", "cbpi_dashboard_1.json")
2021-02-07 02:02:33 +01:00
destfile = os.path.join(".", "config", "dashboard")
2021-01-26 20:21:53 +01:00
shutil.copy(srcfile, destfile)
if os.path.exists(os.path.join(".", 'config', "carftbeerpi.service")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "craftbeerpi.service")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
if os.path.exists(os.path.join(".", 'config', "chromium.desktop")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "chromium.desktop")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
2021-02-16 20:37:51 +01:00
print("Config Folder created")
2021-01-26 20:21:53 +01:00
2019-01-05 20:43:48 +01:00
def create_home_folder_structure():
2021-02-07 02:02:33 +01:00
pathlib.Path(os.path.join(".", 'logs/sensors')).mkdir(parents=True, exist_ok=True)
pathlib.Path(os.path.join(".", 'config')).mkdir(parents=True, exist_ok=True)
pathlib.Path(os.path.join(".", 'config/dashboard')).mkdir(parents=True, exist_ok=True)
pathlib.Path(os.path.join(".", 'config/dashboard/widgets')).mkdir(parents=True, exist_ok=True)
2021-02-27 20:09:19 +01:00
pathlib.Path(os.path.join(".", 'config/recipes')).mkdir(parents=True, exist_ok=True)
2022-02-17 21:42:54 +01:00
pathlib.Path(os.path.join(".", 'config/fermenterrecipes')).mkdir(parents=True, exist_ok=True)
pathlib.Path(os.path.join(".", 'config/upload')).mkdir(parents=True, exist_ok=True)
2021-01-26 20:21:53 +01:00
print("Folder created")
2019-01-05 20:43:48 +01:00
2021-02-01 01:38:04 +01:00
2021-02-06 14:11:30 +01:00
def setup_one_wire():
print("Setting up 1Wire")
2021-02-19 23:41:53 +01:00
with open('/boot/config.txt', 'w') as f:
2021-02-06 14:11:30 +01:00
f.write("dtoverlay=w1-gpio,gpiopin=4,pullup=on")
print("/boot/config.txt created")
def list_one_wire():
print("List 1Wire")
call(["modprobe", "w1-gpio"])
call(["modprobe", "w1-therm"])
try:
for dirname in os.listdir('/sys/bus/w1/devices'):
if (dirname.startswith("28") or dirname.startswith("10")):
print(dirname)
except Exception as e:
print(e)
2019-01-21 22:33:29 +01:00
def copy_splash():
2021-02-07 02:02:33 +01:00
srcfile = os.path.join(".", "config", "splash.png")
destfile = os.path.join(".", 'config')
2019-01-21 22:33:29 +01:00
shutil.copy(srcfile, destfile)
2019-07-27 21:08:19 +02:00
print("Splash Srceen created")
2021-02-01 01:38:04 +01:00
2019-08-05 20:51:20 +02:00
def clear_db():
import os.path
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", "craftbeerpi.db")) is True:
os.remove(os.path.join(".", "craftbeerpi.db"))
2019-08-05 20:51:20 +02:00
print("database Cleared")
def recursive_chown(path, owner, group):
for dirpath, dirnames, filenames in os.walk(path):
shutil.chown(dirpath, owner, group)
for filename in filenames:
shutil.chown(os.path.join(dirpath, filename), owner, group)
2021-02-01 01:38:04 +01:00
2019-07-27 21:08:19 +02:00
def check_for_setup():
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", "config", "config.yaml")) is False:
2019-07-27 21:08:19 +02:00
print("***************************************************")
print("CraftBeerPi Config File not found: %s" % os.path.join(".", "config", "config.yaml"))
print("Please run 'cbpi setup' before starting the server ")
print("***************************************************")
return False
if os.path.exists(os.path.join(".", "config", "upload")) is False:
print("***************************************************")
print("CraftBeerPi upload folder not found: %s" % os.path.join(".", "config/upload"))
print("Please run 'cbpi setup' before starting the server ")
print("***************************************************")
2019-07-27 21:08:19 +02:00
return False
2022-02-17 21:42:54 +01:00
# if os.path.exists(os.path.join(".", "config", "fermenterrecipes")) is False:
# print("***************************************************")
# print("CraftBeerPi fermenterrecipes folder not found: %s" % os.path.join(".", "config/fermenterrecipes"))
# print("Please run 'cbpi setup' before starting the server ")
# print("***************************************************")
# return False
backupfile = os.path.join(".", "restored_config.zip")
if os.path.exists(os.path.join(backupfile)) is True:
print("***************************************************")
print("Found backup of config. Starting restore")
required_content=['dashboard/', 'recipes/', 'upload/', 'config.json', 'config.yaml']
zip=zipfile.ZipFile(backupfile)
zip_content_list = zip.namelist()
zip_content = True
print("Checking content of zip file")
for content in required_content:
try:
check = zip_content_list.index(content)
except:
zip_content = False
if zip_content == True:
print("Found correct content. Starting Restore process")
output_path = pathlib.Path(os.path.join(".", 'config'))
2022-01-25 11:33:21 +01:00
system = platform.system()
print(system)
if system != "Windows":
owner = output_path.owner()
group = output_path.group()
print("Removing old config folder")
shutil.rmtree(output_path, ignore_errors=True)
print("Extracting zip file to config folder")
zip.extractall(output_path)
2022-01-25 11:33:21 +01:00
zip.close()
if system != "Windows":
print("Changing owner and group of config folder recursively to {}:{}".format(owner,group))
recursive_chown(output_path, owner, group)
print("Removing backup file")
os.remove(backupfile)
else:
print("Wrong Content in zip file. No restore possible")
print("Removing zip file")
os.remove(backupfile)
print("***************************************************")
return True
2019-07-27 21:08:19 +02:00
else:
return True
2021-01-30 22:29:33 +01:00
def plugins_add(package_name):
2019-08-16 21:36:55 +02:00
if package_name is None:
2021-01-30 22:29:33 +01:00
print("Pleaes provide a plugin Name")
2019-08-16 21:36:55 +02:00
return
if package_name == 'autostart':
2021-11-03 09:30:16 +01:00
print("Add craftbeerpi.service to systemd")
try:
if os.path.exists(os.path.join("/etc/systemd/system","craftbeerpi.service")) is False:
srcfile = os.path.join(".", "config", "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
if package_name == 'chromium':
print("Add chromium.desktop to /etc/xdg/autostart/")
try:
if os.path.exists(os.path.join("/etc/xdg/autostart/","chromium.desktop")) is False:
srcfile = os.path.join(".", "config", "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
installation = True
2021-01-30 22:29:33 +01:00
try:
try:
p_metadata= metadata(package_name)
p_name=p_metadata['Name']
2022-02-17 21:42:54 +01:00
#if p_name != package_name:
# print("Error. Package name {} does not exist. Did you mean {}".format(package_name,p_name))
# installation = False
except Exception as e:
print("Error. Package {} cannot be found in installed packages".format(package_name))
installation = False
if installation:
with open(os.path.join(".", 'config', "config.yaml"), 'rt') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
if package_name in data["plugins"]:
print("")
print("Plugin {} already active".format(package_name))
print("")
return
data["plugins"].append(package_name)
with open(os.path.join(".", 'config', "config.yaml"), 'w') as outfile:
yaml.dump(data, outfile, default_flow_style=False)
print("")
print("Plugin {} activated".format(package_name))
print("")
2021-01-30 22:29:33 +01:00
except Exception as e:
print(e)
pass
def plugin_remove(package_name):
2019-08-16 21:36:55 +02:00
if package_name is None:
2021-01-30 22:29:33 +01:00
print("Pleaes provide a plugin Name")
return
if package_name == 'autostart':
2021-11-03 09:30:16 +01:00
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
if package_name == 'chromium':
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
2021-01-30 22:29:33 +01:00
try:
2021-02-07 02:02:33 +01:00
with open(os.path.join(".", 'config', "config.yaml"), 'rt') as f:
2021-01-30 22:29:33 +01:00
data = yaml.load(f, Loader=yaml.FullLoader)
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
data["plugins"] = list(filter(lambda k: package_name not in k, data["plugins"]))
2021-02-07 02:02:33 +01:00
with open(os.path.join(".", 'config', "config.yaml"), 'w') as outfile:
2021-01-30 22:29:33 +01:00
yaml.dump(data, outfile, default_flow_style=False)
2021-02-01 01:38:04 +01:00
print("")
2021-01-30 22:29:33 +01:00
print("Plugin {} deactivated".format(package_name))
print("")
except Exception as e:
print(e)
pass
2021-02-01 01:38:04 +01:00
def plugins_list():
2021-01-30 22:29:33 +01:00
print("--------------------------------------")
2021-10-16 14:22:04 +02:00
print("List of active plugins")
2021-01-30 22:29:33 +01:00
try:
2021-02-07 02:02:33 +01:00
with open(os.path.join(".", 'config', "config.yaml"), 'rt') as f:
2021-01-30 22:29:33 +01:00
data = yaml.load(f, Loader=yaml.FullLoader)
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
for p in data["plugins"]:
try:
p_metadata= metadata(p)
p_Homepage= p_metadata['Home-page']
p_version = p_metadata['Version']
p_Author = p_metadata['Author']
print("- ({})\t{}".format(p_version,p))
except Exception as e:
print (e)
pass
2021-01-30 22:29:33 +01:00
except Exception as e:
print(e)
pass
print("--------------------------------------")
2021-02-01 01:38:04 +01:00
def plugin_create(name):
2021-02-07 02:02:33 +01:00
if os.path.exists(os.path.join(".", name)) is True:
2021-01-30 22:29:33 +01:00
print("Cant create Plugin. Folder {} already exists ".format(name))
2019-08-16 21:36:55 +02:00
return
2021-01-30 22:29:33 +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)
2019-08-16 21:36:55 +02:00
2021-01-30 22:29:33 +01:00
with ZipFile('temp.zip', 'r') as repo_zip:
repo_zip.extractall()
2019-08-16 21:36:55 +02:00
2021-02-07 02:02:33 +01:00
os.rename("./craftbeerpi4-plugin-template-main", os.path.join(".", name))
os.rename(os.path.join(".", name, "src"), os.path.join(".", name, name))
2019-08-16 21:36:55 +02:00
2021-01-30 22:29:33 +01:00
import jinja2
2019-01-05 20:43:48 +01:00
2021-03-03 23:49:41 +01:00
templateLoader = jinja2.FileSystemLoader(searchpath=os.path.join(".", name))
2021-01-30 22:29:33 +01:00
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "setup.py"
template = templateEnv.get_template(TEMPLATE_FILE)
2021-02-01 01:38:04 +01:00
outputText = template.render(name=name)
2021-02-07 02:02:33 +01:00
with open(os.path.join(".", name, "setup.py"), "w") as fh:
2021-01-30 22:29:33 +01:00
fh.write(outputText)
TEMPLATE_FILE = "MANIFEST.in"
template = templateEnv.get_template(TEMPLATE_FILE)
2021-02-01 01:38:04 +01:00
outputText = template.render(name=name)
2021-03-03 23:49:41 +01:00
with open(os.path.join(".", name, "MANIFEST.in"), "w") as fh:
2021-01-30 22:29:33 +01:00
fh.write(outputText)
2021-02-01 01:38:04 +01:00
TEMPLATE_FILE = os.path.join("/", name, "config.yaml")
2021-01-30 22:29:33 +01:00
template = templateEnv.get_template(TEMPLATE_FILE)
2021-02-01 01:38:04 +01:00
outputText = template.render(name=name)
2021-02-07 02:02:33 +01:00
with open(os.path.join(".", name, name, "config.yaml"), "w") as fh:
2021-01-30 22:29:33 +01:00
fh.write(outputText)
print("")
print("")
2021-02-01 01:38:04 +01:00
print(
2022-02-17 21:42:54 +01:00
"Plugin {} created! See https://openbrewing.gitbook.io/craftbeerpi4_support/readme/development how to run your plugin ".format(
2021-02-01 01:38:04 +01:00
name))
2021-01-30 22:29:33 +01:00
print("")
print("Happy Development! Cheers")
print("")
print("")
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()
2021-02-01 01:38:04 +01:00
def main():
level = logging.INFO
logging.basicConfig(level=level, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
2021-01-30 22:29:33 +01:00
pass
2019-08-16 21:36:55 +02:00
2021-01-30 22:29:33 +01:00
@click.command()
def setup():
'''Create Config folder'''
print("Setting up CraftBeerPi")
create_home_folder_structure()
create_config_file()
2019-01-21 22:33:29 +01:00
2021-02-01 01:38:04 +01:00
2021-02-06 14:11:30 +01:00
@click.command()
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")
def onewire(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:
setup_one_wire()
2021-02-06 14:11:30 +01:00
if list is True:
list_one_wire()
2021-02-06 14:19:51 +01:00
2021-02-06 14:11:30 +01:00
2021-01-30 22:29:33 +01:00
@click.command()
def start():
if check_for_setup() is False:
2019-07-27 21:08:19 +02:00
return
2021-01-30 22:29:33 +01:00
print("START")
cbpi = CraftBeerPi()
cbpi.start()
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
@click.command()
def plugins():
'''List active plugins'''
plugins_list()
return
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
@click.command()
@click.argument('name')
def add(name):
'''Activate Plugin, autostart or chromium '''
2021-01-30 22:29:33 +01:00
plugins_add(name)
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
@click.command()
@click.argument('name')
def remove(name):
'''Deactivate Plugin, autostart or chromium'''
2021-01-30 22:29:33 +01:00
plugin_remove(name)
2021-02-01 01:38:04 +01:00
2019-01-21 22:33:29 +01:00
2021-01-30 22:29:33 +01:00
@click.command()
@click.argument('name')
def create(name):
'''Create New Plugin'''
2021-01-30 22:29:33 +01:00
plugin_create(name)
2021-02-01 01:38:04 +01:00
2021-01-30 22:29:33 +01:00
main.add_command(setup)
main.add_command(start)
main.add_command(plugins)
2021-02-06 14:11:30 +01:00
main.add_command(onewire)
2021-01-30 22:29:33 +01:00
main.add_command(add)
main.add_command(remove)
main.add_command(create)