Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate plugin repos exist #53

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/scripts/validate_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
import re
import sys
import subprocess

# Adjust path relative to the current script location
SCRIPT_DIR = os.path.dirname(__file__)
PLUGIN_FILE_PATH = os.path.join(SCRIPT_DIR, '../../plugin.py')

def parse_plugin_file():
plugin_data = {}

print(f"Checking if plugin file exists at: {PLUGIN_FILE_PATH}")
if not os.path.isfile(PLUGIN_FILE_PATH):
print(f"Plugin file not found at: {PLUGIN_FILE_PATH}")
sys.exit(1)

with open(PLUGIN_FILE_PATH, 'r') as plugin_file:
content = plugin_file.read()
print(f"Read content from plugin file, length: {len(content)}")

# Adjusted regex to be more robust and handle multi-line content
plugin_data_section = re.search(r'self\.plugindata\s*=\s*{(.*?)\n\s*}', content, re.DOTALL)
if plugin_data_section:
print("Found plugindata section")
plugin_lines = plugin_data_section.group(1).split('\n')
for line in plugin_lines:
line = line.strip()
if line.startswith('"Idle"'):
continue # Skip the Idle plugin
print(f"Processing line: {line}")
match = re.match(r'"(?P<key>[^"]+)"\s*:\s*\["(?P<author>[^"]+)",\s*"(?P<repository>[^"]+)",\s*"(?P<description>[^"]+)",\s*"(?P<branch>[^"]+)"\],?', line)
if match:
plugin_info = match.groupdict()
plugin_data[plugin_info["key"]] = plugin_info
else:
print("No plugin data section found in plugin file.")

return plugin_data

def validate_repository(author, repository, branch):
repo_url = f"https://github.com/{author}/{repository}"
repo_clone_cmd = f"git ls-remote --heads {repo_url} {branch}"
result = subprocess.run(repo_clone_cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error executing command: {repo_clone_cmd}")
print(f"stdout: {result.stdout}")
print(f"stderr: {result.stderr}")
return result.returncode == 0

def main():
print("Parsing plugin file...")
plugin_data = parse_plugin_file()
print(f"Parsed data: {plugin_data}")

if not plugin_data:
print("No plugin data found, exiting.")
sys.exit(1)

all_valid = True
for key, data in plugin_data.items():
print(f"Validating repository for plugin: {key}")
is_valid = validate_repository(data["author"], data["repository"], data["branch"])
if is_valid:
print(f"✅ Repository {data['author']}/{data['repository']} on branch {data['branch']} is valid.")
else:
print(f"❌ Repository {data['author']}/{data['repository']} on branch {data['branch']} is invalid.")
all_valid = False

if not all_valid:
print("One or more plugins are invalid.")
sys.exit(1) # Exit with a non-zero code to indicate failure

if __name__ == "__main__":
main()
31 changes: 31 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Validate Plugins

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch: # Allows manual trigger

jobs:
validate:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests

- name: Run validation script
run: python .github/scripts/validate_plugins.py
26 changes: 5 additions & 21 deletions plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


"""
<plugin key="PP-MANAGER" name="Python Plugin Manager" author="ycahome" version="1.5.42" externallink="https://www.domoticz.com/forum/viewtopic.php?f=65&t=22339">
<plugin key="PP-MANAGER" name="Python Plugin Manager" author="ycahome" version="1.5.43" externallink="https://www.domoticz.com/forum/viewtopic.php?f=65&t=22339">
<description>
<h2>Python Plugin Manager v.1.5.42</h2><br/>
<h3>Features</h3>
Expand All @@ -28,6 +28,7 @@
<options>
<option label="Idle" value="Idle" default="true" />
<option label="Dummy Plugin" value="Dummy_Plugin"/>
<option label="AWTRIX3" value="AWTRIX3"/>
<option label="Battery monitoring for Z-Wave nodes" value="BatteryLevel"/>
<option label="Buienradar.nl (Weather lookup)" value="Buienradar"/>
<option label="Chromecast plugin for Domoticz" value="ChromecastPlugin"/>
Expand All @@ -38,11 +39,9 @@
<option label="deCONZ bridge (For Conbee,Raspbee)" value="deCONZ"/>
<option label="Denon/Marantz Amplifier" value="Denon4306"/>
<option label="Domoticz Theme Manager" value="domoticz-theme-manager"/>
<option label="Disc usage" value="xfr_discusage"/>
<option label="Dutch earthquakes" value="xfr_aardbeving"/>
<option label="Dyson Pure Link" value="DysonPureLink"/>
<option label="Eartquake EMSC Data" value="SeismicPortal"/>
<option label="ebusd bridge" value="ebusd"/>
<option label="E-Flux" value="E-Flux"/>
<option label="Emmeti EQ 2021 and EQ 3021 ES hot water heat pumps" value="domoticz-emmeti-eq2021"/>
<option label="Emmeti Mirai heat pumps" value="domoticz-emmeti-mirai"/>
<option label="EMS bus Wi-Fi Gateway" value="ems-gateway"/>
Expand All @@ -59,19 +58,14 @@
<option label="iDetect Presence Detection" value="iDetect"/>
<option label="IthoWifi" value="IthoWifi"/>
<option label="IKEA Tradfri" value="IKEA-Tradfri"/>
<option label="Life 360 Presence" value="Life360"/>
<option label="Linky" value="Linky"/>
<option label="Link-Tap" value="Link-Tap"/>
<option label="Meteo Alarm EU RSS Reader" value="MeteoAlarmEU"/>
<option label="Mikrotik RouterOS" value="mikrotik-routeros"/>
<option label="Moon Phases" value="MoonPhases"/>
<option label="MQTT discovery" value="MQTTDiscovery"/>
<option label="Onkyo AV Receiver" value="Onkyo"/>
<option label="OpenAQ" value="xfr_openaq"/>
<option label="OpenWRT WiFi Presence MQTT translator" value="owrtwifi2domo"/>
<option label="Pi-hole summary" value="xfr_pihole"/>
<option label="PiMonitor" value="xfr-pimonitor"/>
<option label="Pioneer AVR" value="PioneerAVR"/>
<option label="Quatt" value="Quatt"/>
<option label="RTL_433 MQTT receiver" value="pyrtl433"/>
<option label="PZEM-016 PZEM-014 and PZEM-004T energy meters" value="pzem016"/>
Expand All @@ -82,7 +76,6 @@
<option label="Sonos Players" value="Sonos"/>
<option label="Sonoff Mini" value="sonoff-domoticz-plugin"/>
<option label="Sony Bravia TV (with Kodi remote)" value="sony"/>
<option label="Speedtest" value="xfr_speedtest"/>
<option label="Synology SurveillanceStation" value="SurveillanceStation"/>
<option label="SYSFS-Switches" value="SYSFS-Switches"/>
<option label="Tuya" value="tuyaha"/>
Expand All @@ -92,7 +85,6 @@
<option label="WLED" value="WLED"/>
<option label="Xiaomi Mi Flower Mate" value="Mi_Flower_mate_plugin"/>
<option label="Xiaomi Mi Robot Vacuum" value="xiaomi-mi-robot-vacuum"/>
<option label="Xiaomi PM2.5 Sensor" value="XiaomiPM"/>
<option label="Yamaha AV Receiver" value="YamahaPlug"/>
<option label="Yi Hack" value="YiHack"/>
<option label="Zigbee for Domoticz" value="Zigate"/>
Expand Down Expand Up @@ -163,21 +155,20 @@ def __init__(self):
# Plugin Key: [gitHub author, repository, plugin Text, Branch]
"Idle": ["Idle", "Idle", "Idle", "master"],
"Dummy_Plugin": ["ycahome", "Dummy_Plugin", "Dummy Plugin", "master"],
"AWTRIX3": ["galadril", "Domoticz-AWTRIX3-Plugin", "Integrate with AWTRIX3 Smart Clock", "master"],
"BatteryLevel": ["999LV", "BatteryLevel", "Battery monitoring for Z-Wave nodes", "master"],
"Buienradar": ["ffes", "domoticz-buienradar", "Buienradar.nl (Weather lookup)", "master"],
"AAPIPModule": ["febalci", "DomoticzCrowAlarm", "Crow Runner Alarm", "master"],
"ChromecastPlugin": ["Tsjippy", "ChromecastPlugin", "Chromecast plugin for Domoticz", "master"],
"CreasolDomBus": ["CreasolTech", "CreasolDomBus", "Creasol DomBus RS485 I/O/Sens modules", "master"],
"deCONZ": ["Smanar", "Domoticz-deCONZ", "deCONZ bridge (For Conbee,Raspbee)","master"],
"Denon4306": ["dnpwwo", "Domoticz-Denon-Plugin", "Denon/Marantz Amplifier", "master"],
"xfr_discusage": ["Xorfor", "Domoticz-Disc-usage-Plugin", "Disc usage", "master"],
"domoticz-dds238": ["CreasolTech", "domoticz-dds238", "DDS238 ZN/S energy meter, single phase, Modbus RTU", "master"],
"domoticz-dts238": ["CreasolTech", "domoticz-dts238", "DTS238 ZN/S energy meter, three phase, Modbus RTU", "master"],
"domoticz-theme-manager": ["galadril", "domoticz-theme-manager", "Domoticz Theme Manager", "master"],
"xfr_aardbeving": ["Xorfor", "Domoticz-LastDutchEarthquake-Plugin", "Dutch earthquakes", "master"],
"DysonPureLink": ["JanJaapKo", "DysonPureLink", "Dyson Pure Link", "master"],
"SeismicPortal": ["febalci", "DomoticzEarthquake", "Eartquake EMSC Data", "master"],
"ebusd": ["guillaumezin", "DomoticzEbusd", "ebusd bridge", "master"],
"E-Flux": ["galadril", "Domoticz-E-Flux-Plugin", "E-Flux by Road back office", "master"],
"domoticz-emmeti-eq2021": ["CreasolTech", "domoticz-emmeti-eq2021", "Emmeti EQ 2021 amd EQ 3021 ES hot water heat pumps", "master"],
"domoticz-emmeti-mirai": ["CreasolTech", "domoticz-emmeti-mirai", "Emmeti Mirai heat pumps", "master"],
"ems-gateway": ["bbqkees", "ems-esp-domoticz-plugin", "EMS bus Wi-Fi Gateway", "master"],
Expand All @@ -193,19 +184,14 @@ def __init__(self):
"iDetect": ["d-EScape", "Domoticz_iDetect", "iDetect Presence Detection", "master"],
"IthoWifi": ["galadril", "Domoticz-Itho-Wifi-Plugin", "Itho Wifi module", "master"],
"IKEA-Tradfri": ["moroen", "IKEA-Tradfri-plugin", "IKEA Tradfri", "master"],
"Life360": ["febalci", "DomoticzLife360", "Life 360 Presence", "master"],
"Linky": ["guillaumezin", "DomoticzLinky", "Linky", "master"],
"Link-Tap": ["DebugBill", "Link-Tap", "Link-Tap Watering System", "master"],
"MeteoAlarmEU": ["ycahome", "MeteoAlarmEU", "Meteo Alarm EU RSS Reader", "master"],
"mikrotik-routeros": ["mrin", "domoticz-routeros-plugin", "Mikrotik RouterOS", "master"],
"MoonPhases": ["ycahome", "MoonPhases", "Moon Phases", "master"],
"MQTTDiscovery": ["emontnemery", "domoticz_mqtt_discovery", "MQTT discovery", "master"],
"Onkyo": ["jorgh6", "domoticz-onkyo-plugin", "Onkyo AV Receiver", "master"],
"xfr_openaq": ["Xorfor", "Domoticz-OpenAQ-Plugin", "OpenAQ", "master"],
"xfr_pihole": ["Xorfor", "Domoticz-Pi-hole-Plugin", "Pi-hole summary", "master"],
"xfr-pimonitor": ["Xorfor", "Domoticz-PiMonitor-Plugin", "PiMonitor", "master"],
"owrtwifi2domo": ["enesbcs", "owrtwifi2domo", "OpenWRT WiFi Presence MQTT translator","master"],
"PioneerAVR": ["febalci", "DomoticzPioneerAVR", "Pioneer AVR", "master"],
"pyrtl433": ["enesbcs", "pyrtl433", "RTL_433 MQTT receiver", "master"],
"pzem016": ["CreasolTech", "domoticz-pzem-016", "PZEM-016 PZEM-014 PZEM-004T energy meters", "master"],
"Quatt": ["galadril", "Domoticz-Quatt-Plugin", "Quatt", "master"],
Expand All @@ -217,7 +203,6 @@ def __init__(self):
"sonoff-domoticz-plugin": ["bobzomer", "sonoff-domoticz-plugin", "Sonoff Mini", "master"],
"sony": ["gerard33", "sony-bravia", "Sony Bravia TV (with Kodi remote)", "master"],
"Synology SurveillanceStation": ["lolautruche", "SurveillanceStationDomoticz", "Synology SurveillanceStation", "master"],
"xfr_speedtest": ["Xorfor", "Domoticz-Speedtest-Plugin", "Speedtest", "master"],
"SYSFS-Switches": ["flatsiedatsie", "GPIO-SYSFS-Switches", "SYSFS-Switches", "master"],
"tuyaha": ["guino", "tuyaha", "Tuya", "master"],
"NUT_UPS": ["999LV", "NUT_UPS", "UPS Monitor", "master"],
Expand All @@ -226,7 +211,6 @@ def __init__(self):
"WAN-IP-CHECKER": ["ycahome", "WAN-IP-CHECKER", "Wan IP Checker", "master"],
"Mi_Flower_mate_plugin": ["flatsiedatsie", "Mi_Flower_mate_plugin", "Xiaomi Mi Flower Mate", "master"],
"xiaomi-mi-robot-vacuum": ["mrin", "domoticz-mirobot-plugin", "Xiaomi Mi Robot Vacuum", "master"],
"XiaomiPM": ["febalci", "DomoticzXiaomiPM2.5", "Xiaomi PM2.5 Sensor", "master"],
"YamahaPlug": ["thomas-villagers","domoticz-yamaha", "Yamaha AV Receiver", "master"],
"YiHack": ["galadril", "Domoticz-Yi-Hack-Plugin", "Yi Hack", "master"],
"Zigate": ["zigbeefordomoticz", "Domoticz-Zigbee", "Zigate plugin", "stable6"],
Expand Down