Removing the HACS directory from being tracked. 'git -r --cached .' #588
This commit is contained in:
parent
93c5bb6837
commit
ef4b017a5b
|
@ -1,61 +0,0 @@
|
|||
<h1 align="center">
|
||||
<a name="logo" href="http://www.vCloudInfo.com/tag/iot"><img src="https://raw.githubusercontent.com/CCOSTAN/Home-AssistantConfig/master/config/www/custom_ui/floorplan/images/branding/twitter_profile.png" alt="Bear Stone Smart Home" width="200"></a>
|
||||
<br>
|
||||
Bear Stone Smart Home Documentation
|
||||
</h1>
|
||||
<h4 align="center">Be sure to :star: my configuration repo so you can keep up to date on any daily progress!</h4>
|
||||
<div align="center">
|
||||
<h4>
|
||||
<a href="https://travis-ci.org/CCOSTAN/Home-AssistantConfig"><img src="https://travis-ci.org/CCOSTAN/Home-AssistantConfig.svg?branch=master"/></a>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig/stargazers"><img src="https://img.shields.io/github/stars/CCOSTAN/Home-AssistantConfig.svg?style=plasticr"/></a>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig/commits/master"><img src="https://img.shields.io/github/last-commit/CCOSTAN/Home-AssistantConfig.svg?style=plasticr"/></a>
|
||||
</h4>
|
||||
</div>
|
||||
<p><font size="3">
|
||||
Custom Components. Sometimes I use them for temporary fixes to existing components. Sometimes I use them to extend functionality with niche components other people have written but haven't merged into the main HASS branch. Either way, a great way to extend the power of Home Assistant. The main management component now for custom components is HACS. This is the Home Assistant community store. It allows for point and click installations of Custom Components.</p>
|
||||
<div align="center"><a name="menu"></a>
|
||||
<h4>
|
||||
<a href="http://www.vCloudInfo.com/tag/iot">
|
||||
Blog
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig#devices">
|
||||
Devices
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc">
|
||||
Todo List
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://twitter.com/BearStoneHA">
|
||||
Smart Home Stats
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://www.vcloudinfo.com/click-here">
|
||||
Follow Me
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig/tree/master/config">
|
||||
Code
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/CCOSTAN/Home-AssistantConfig#diagram">
|
||||
Diagram
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://youtube.com/vCloudInfo">
|
||||
Youtube
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://amzn.to/2HXSx2M">
|
||||
Merch
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
<a name="bottom" href="https://github.com/CCOSTAN/Home-AssistantConfig#logo"><img align="right" border="0" src="https://raw.githubusercontent.com/CCOSTAN/Home-AssistantConfig/master/config/www/custom_ui/floorplan/images/branding/up_arrow.png" width="25" ></a>
|
||||
|
||||
**Still have questions on my Config?** <br>
|
||||
**Message me on twitter :** [![Follow CCostan](https://img.shields.io/twitter/follow/CCostan)](https://www.twitter.com/ccostan) or [![Follow Bear Stone Home](https://img.shields.io/twitter/follow/BearStoneHA)](https://www.twitter.com/BearStoneHA)
|
||||
<!-- Subscribe Section -->
|
||||
<a href="http://eepurl.com/dmXFYz"><img align="center" border="0" src="https://raw.githubusercontent.com/CCOSTAN/Home-AssistantConfig/master/config/www/custom_ui/floorplan/images/branding/email_link.png" height="50" ></a>.
|
||||
<!-- Subscribe Section END-->
|
|
@ -1,336 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Om",
|
||||
"add": "tilføj",
|
||||
"appdaemon_apps": "AppDaemon-apps",
|
||||
"appdaemon_plural": "AppDaemon-apps",
|
||||
"background_task": "Baggrundsopgave kører. Denne side vil genindlæses automatisk.",
|
||||
"check_log_file": "Tjek din logfil for flere detaljer.",
|
||||
"continue": "Fortsæt",
|
||||
"disabled": "Deaktiveret",
|
||||
"documentation": "Dokumentation",
|
||||
"element": "element",
|
||||
"hacs_is_disabled": "HACS er deaktiveret",
|
||||
"install": "Installer",
|
||||
"installed": "installeret",
|
||||
"integration": "Integration",
|
||||
"integration_plural": "Integrationer",
|
||||
"integrations": "Integrationer",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace-element",
|
||||
"lovelace_elements": "Lovelace-elementer",
|
||||
"manage": "administrer",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon-apps",
|
||||
"netdaemon_plural": "NetDaemon-apps",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace-elementer",
|
||||
"plugins": "Lovelace-elementer",
|
||||
"python_script": "Python-script",
|
||||
"python_script_plural": "Python-scripts",
|
||||
"python_scripts": "Python-scripts",
|
||||
"repositories": "Repositories",
|
||||
"repository": "Repository",
|
||||
"settings": "indstillinger",
|
||||
"theme": "Tema",
|
||||
"theme_plural": "Temaer",
|
||||
"themes": "Temaer",
|
||||
"uninstall": "Afinstaller",
|
||||
"version": "Version"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Kun en enkelt konfiguration af HACS er tilladt."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Personlig adgangstoken er ikke korrekt."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver opdagelse & sporing af AppDaemon-apps",
|
||||
"netdaemon": "Aktiver opdagelse og sporing af NetDaemon-apps",
|
||||
"python_script": "Aktivér opdagelse og sporing af python_scripts",
|
||||
"sidepanel_icon": "Sidepanelikon",
|
||||
"sidepanel_title": "Sidepanelets titel",
|
||||
"theme": "Aktivér opdagelse og sporing af temaer",
|
||||
"token": "GitHub personlig adgangstoken"
|
||||
},
|
||||
"description": "Hvis du har brug for hjælp til konfigurationen, så kig her: https:\/\/hacs.xyz\/docs\/configuration\/start"
|
||||
}
|
||||
}
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Er du sikker på, at du vil tilføje dette til dine Lovelace-ressourcer?",
|
||||
"bg_task": "Handlingen er deaktiveret, mens baggrundsopgaver kører.",
|
||||
"cancel": "Annuller",
|
||||
"continue": "Er du sikker på, at du vil fortsætte?",
|
||||
"delete": "Er du sikker på, at du vil slette '{Item}'?",
|
||||
"delete_installed": "'{item}' er installeret. Du skal afinstallere det, før du kan slette det.",
|
||||
"exist": "{item} findes allerede",
|
||||
"generic": "Er du sikker?",
|
||||
"home_assistant_is_restarting": "Vent venligst - Home Assistant genstarter nu.",
|
||||
"home_assistant_version_not_correct": "Du kører Home Assistant version '{haversion}', men dette repository kræver som minimum version '{minversion}'.",
|
||||
"no": "Nej",
|
||||
"no_upgrades": "Der er ingen opdateringer tilgængelig",
|
||||
"ok": "OK",
|
||||
"overwrite": "Dette vil overskrive den.",
|
||||
"reload_data": "Dette genindlæser data fra alle repositories, som HACS kender til. Dette vil tage nogen tid at fuldføre.",
|
||||
"restart_home_assistant": "Er du sikker på, at du vil genstarte Home Assistant?",
|
||||
"uninstall": "Er du sikker på, at du vil afinstallere '{Item}'?",
|
||||
"upgrade_all": "Dette vil opdatere alle repositories. Sørg for at du har læst udgivelsesnoterne for dem alle, inden du fortsætter.",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"dialog_about": {
|
||||
"frontend_version": "Frontend-version",
|
||||
"installed_repositories": "Installerede repositories",
|
||||
"integration_version": "Integrationsversion",
|
||||
"useful_links": "Nyttige links"
|
||||
},
|
||||
"dialog_add_repo": {
|
||||
"limit": "Kun de første 100 repositories vises. Brug søgningen til at filtrere, hvad du har brug for",
|
||||
"no_match": "Der blev ikke fundet nogen repositories, der matcher dit filter",
|
||||
"sort_by": "Sorter efter",
|
||||
"title": "Tilføj repository"
|
||||
},
|
||||
"dialog_custom_repositories": {
|
||||
"category": "Kategori",
|
||||
"no_category": "Manglende kategori",
|
||||
"no_repository": "Manglende repository",
|
||||
"title": "Brugerdefinerede repositories",
|
||||
"url_placeholder": "Tilføj brugerdefineret repository-webadresse"
|
||||
},
|
||||
"dialog_info": {
|
||||
"author": "Udvikler",
|
||||
"downloads": "Downloads",
|
||||
"install": "Installer dette repository i HACS",
|
||||
"loading": "Indlæser oplysninger...",
|
||||
"no_info": "Udvikleren har ikke givet flere oplysninger om dette repository",
|
||||
"open_repo": "Åbn repository",
|
||||
"stars": "Stjerner",
|
||||
"version_installed": "Installeret version"
|
||||
},
|
||||
"dialog_install": {
|
||||
"restart": "Husk, at du skal genstarte Home Assistant, før ændringer af integrationer (custom_components) træder i kræft.",
|
||||
"select_version": "Vælg version",
|
||||
"show_beta": "Vis betaversioner",
|
||||
"type": "Type",
|
||||
"url": "Webadresse"
|
||||
},
|
||||
"dialog_update": {
|
||||
"available_version": "Tilgængelig version",
|
||||
"changelog": "Udgivelsesnoter",
|
||||
"installed_version": "Installeret version",
|
||||
"title": "Ventende opdatering"
|
||||
},
|
||||
"entry": {
|
||||
"information": "Oplysninger",
|
||||
"intro": "Opdateringer og vigtige meddelelser vises her, hvis der er nogen",
|
||||
"messages": {
|
||||
"disabled": {
|
||||
"content": "Tjek din logfil for flere detaljer",
|
||||
"title": "HACS er deaktiveret"
|
||||
},
|
||||
"has_pending_tasks": {
|
||||
"content": "Nogle repositories vises muligvis ikke, før dette er fuldført",
|
||||
"title": "Baggrundsopgaver venter"
|
||||
},
|
||||
"resources": {
|
||||
"content": "Du har {number} Lovelace-elementer, der ikke er indlæst korrekt i Lovelace.",
|
||||
"title": "Ikke indlæst i Lovelace"
|
||||
},
|
||||
"restart": {
|
||||
"content": "Du har {number} integrationer, der kræver en genstart af Home Assistant. Du kan genstarte fra 'Serveradministration'-sektionen under Indstillinger i Home Assistant-brugerfladen.",
|
||||
"title": "Afventer genstart"
|
||||
},
|
||||
"startup": {
|
||||
"content": "HACS starter op. Der kan i dette tidsrum mangle nogle oplysninger, eller de kan være ukorekte.",
|
||||
"title": "HACS starter op"
|
||||
},
|
||||
"wrong_frontend_installed": {
|
||||
"content": "Du har version {running} af HACS-frontend installeret, men version {expected} var forventet, hvis dette ser du denne besked. Home Assistant kunne ikke installere den nye version. Prøv at genstarte Home Assistant.",
|
||||
"title": "Uventet frontend-version"
|
||||
},
|
||||
"wrong_frontend_loaded": {
|
||||
"content": "Du kører version {running} af HACS-frontend, men version {expected} var forventet. Du bør rydde din browser-cache.",
|
||||
"title": "Uventet frontend-version"
|
||||
}
|
||||
},
|
||||
"pending_updates": "Ventende opdateringer"
|
||||
},
|
||||
"menu": {
|
||||
"about": "Om HACS",
|
||||
"clear": "Ryd alle nye",
|
||||
"custom_repositories": "Brugerdefinerede repositories",
|
||||
"dismiss": "Afvis alle nye repositories",
|
||||
"documentation": "Dokumentation",
|
||||
"open_issue": "Opret issue",
|
||||
"reload": "Genindlæs vindue"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver opdagelse og sporing af AppDaemon-apps",
|
||||
"country": "Filtrer med landekode.",
|
||||
"debug": "Aktiver debug.",
|
||||
"experimental": "Aktivér eksperimentelle funktioner",
|
||||
"netdaemon": "Aktiver opdagelse og sporing af NetDaemon-apps",
|
||||
"not_in_use": "Ikke i brug med YAML",
|
||||
"release_limit": "Antal udgivelser, der skal vises.",
|
||||
"sidepanel_icon": "Sidepanelikon",
|
||||
"sidepanel_title": "Sidepanelets titel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Denne integration understøtter config_flow. Det betyder, at du nu kan gå til integrationssektionen i din brugerflade for at konfigurere den.",
|
||||
"config_flow_title": "Brugerfladekonfiguration understøttet",
|
||||
"integration_not_loaded": "Denne integration er ikke indlæst i Home Assistant.",
|
||||
"no_restart_required": "Ingen genstart påkrævet",
|
||||
"not_loaded": "Ikke indlæst",
|
||||
"plugin_not_loaded": "Dette element er ikke føjet til dine Lovelace-ressourcer.",
|
||||
"restart": "Du skal genstarte Home Assistant.",
|
||||
"restart_pending": "Afventer genstart"
|
||||
},
|
||||
"repository_card": {
|
||||
"dismiss": "Afvis",
|
||||
"hide": "Skjul",
|
||||
"information": "Oplysninger",
|
||||
"new_repository": "Nyt repository",
|
||||
"not_loaded": "Ikke indlæst",
|
||||
"open_issue": "Opret issue",
|
||||
"pending_restart": "Afventer genstart",
|
||||
"pending_update": "Ventende opdatering",
|
||||
"reinstall": "Geninstaller",
|
||||
"report": "Rapporter til fjernelse"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Tilføj til Lovelace",
|
||||
"authors": "Forfattere",
|
||||
"available": "Tilgængelig",
|
||||
"back_to": "Tilbage til",
|
||||
"changelog": "Udgivelsesnoter",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Marker denne",
|
||||
"frontend_version": "Frontend-version",
|
||||
"github_stars": "GitHub-stjerner",
|
||||
"goto_integrations": "Gå til integrationer",
|
||||
"hide": "Skjul",
|
||||
"hide_beta": "Skjul beta",
|
||||
"install": "Installer",
|
||||
"installed": "Installeret",
|
||||
"lovelace_copy_example": "Kopiér eksemplet til din Udklipsholder",
|
||||
"lovelace_instruction": "Tilføj dette til din lovelace-konfiguration",
|
||||
"lovelace_no_js_type": "Kunne ikke afgøre typen af dette element, tjek venligst repository'et.",
|
||||
"newest": "nyeste",
|
||||
"note_appdaemon": "Du skal stadig føje den til filen 'apps.yaml'",
|
||||
"note_installed": "Når det er installeret, vil dette være placeret i",
|
||||
"note_integration": "du skal stadig føje den til filen 'configuration.yaml'",
|
||||
"note_plugin": "du skal stadig tilføje det til din lovelace-konfiguration ('ui-lovelace.yaml' eller Tekstbaseret redigering)",
|
||||
"note_plugin_post_107": "du skal stadig tilføje det til din lovelace-konfiguration ('configuration.yaml' eller ressourceeditoren '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Opret issue",
|
||||
"open_plugin": "Åbn element",
|
||||
"reinstall": "Geninstaller",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Genstart Home Assistant",
|
||||
"show_beta": "Vis beta",
|
||||
"uninstall": "Afinstaller",
|
||||
"update_information": "Opdater oplysninger",
|
||||
"upgrade": "Opdater"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Søg efter repository"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Vis information om HACS",
|
||||
"title": "Om"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Det er her, du finder python_scripts, AppDaemon-apps og NetDaemon-apps",
|
||||
"title": "Automatisering"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Det er her, du finder temaer, brugerdefinerede kort og andre elementer til lovelace",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Det er her, du finder brugerdefinerede integrationer (custom_components)",
|
||||
"title": "Integrationer"
|
||||
},
|
||||
"pending_repository_upgrade": "Du kører version {installed}, version {available} er tilgængelig"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "TILFØJ ET BRUGERDEFINERET REPOSITORY",
|
||||
"adding_new_repo": "Tilføjer nyt repository '{repo}'",
|
||||
"adding_new_repo_category": "Med kategorien '{category}'.",
|
||||
"bg_task_custom": "Brugerdefinerede repositories er skjult, mens opgaver i baggrunden kører.",
|
||||
"category": "Kategori",
|
||||
"compact_mode": "Kompakt tilstand",
|
||||
"custom_repositories": "BRUGERDEFINEREDE REPOSITORIES",
|
||||
"delete": "Slet",
|
||||
"display": "Visning",
|
||||
"grid": "Gitter",
|
||||
"hacs_repo": "HACS-repo",
|
||||
"hidden_repositories": "Skjulte repositories",
|
||||
"missing_category": "Du skal vælge en kategori",
|
||||
"open_repository": "Åbn repository",
|
||||
"reload_data": "Genindlæs data",
|
||||
"reload_window": "Genindlæs vindue",
|
||||
"repository_configuration": "Konfiguration af repository",
|
||||
"save": "Gem",
|
||||
"table": "Tabel",
|
||||
"table_view": "Tabelvisning",
|
||||
"unhide": "Vis",
|
||||
"upgrade_all": "Opdater alle"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "stigende",
|
||||
"clear_new": "Marker alle som set",
|
||||
"descending": "faldende",
|
||||
"last_updated": "Sidst opdateret",
|
||||
"name": "Navn",
|
||||
"new_repositories": "Nye repositories",
|
||||
"new_repositories_note": "Du har over 10 nye repositories, der vises her, hvis du vil rydde dem alle, skal du klikke på de 3 prikker i øverste højre hjørne og afvise dem alle.",
|
||||
"no_repositories": "Ingen repositories",
|
||||
"no_repositories_desc1": "Det ser ud til, at du ikke har nogen repositories installeret i denne sektion endnu.",
|
||||
"no_repositories_desc2": "Klik på + i nederste hjørne for at tilføje dit første!",
|
||||
"no_repositories_found_desc1": "Der blev ikke fundet installerede repositories, der matcher \"{searchInput}\" i denne sektion.",
|
||||
"no_repositories_found_desc2": "Prøv at søge efter noget andet!",
|
||||
"pending_upgrades": "Ventende opdateringer",
|
||||
"placeholder_search": "Indtast en søgeterm...",
|
||||
"sort": "sorter",
|
||||
"stars": "Stjerner",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "siden",
|
||||
"day": "dag",
|
||||
"days": "dage",
|
||||
"hour": "time",
|
||||
"hours": "timer",
|
||||
"minute": "minut",
|
||||
"minutes": "minutter",
|
||||
"month": "måned",
|
||||
"months": "måneder",
|
||||
"one": "Et",
|
||||
"one_day_ago": "en dag siden",
|
||||
"one_hour_ago": "en time siden",
|
||||
"one_minute_ago": "et minut siden",
|
||||
"one_month_ago": "en måned siden",
|
||||
"one_second_ago": "et sekund siden",
|
||||
"one_year_ago": "et år siden",
|
||||
"second": "sekund",
|
||||
"seconds": "sekunder",
|
||||
"x_days_ago": "{x} dage siden",
|
||||
"x_hours_ago": "{x} timer siden",
|
||||
"x_minutes_ago": "{x} minutter siden",
|
||||
"x_months_ago": "{x} måneder siden",
|
||||
"x_seconds_ago": "{x} sekunder siden",
|
||||
"x_years_ago": "{x} år siden",
|
||||
"year": "år",
|
||||
"years": "år"
|
||||
}
|
||||
}
|
|
@ -1,265 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Über",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"appdaemon_plural": "AppDaemon Apps",
|
||||
"background_task": "Hintergrundprozess läuft. Diese Seite lädt neu, sobald dieser fertig ist.",
|
||||
"check_log_file": "Überprüfe die Logdatei für weitere Informationen.",
|
||||
"continue": "Fortfahren",
|
||||
"disabled": "Deaktiviert",
|
||||
"documentation": "Dokumentation",
|
||||
"element": "Element",
|
||||
"hacs_is_disabled": "HACS ist deaktiviert",
|
||||
"installed": "Installiert",
|
||||
"integration": "Integration",
|
||||
"integration_plural": "Integrationen",
|
||||
"integrations": "Integrationen",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace-Element",
|
||||
"lovelace_elements": "Lovelace-Elemente",
|
||||
"manage": "verwalten",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"netdaemon_plural": "NetDaemon Apps",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace-Elemente",
|
||||
"plugins": "Lovelace-Elemente",
|
||||
"python_script": "Python Skript",
|
||||
"python_script_plural": "Python Skripte",
|
||||
"python_scripts": "Python Skripte",
|
||||
"repositories": "Repositories",
|
||||
"settings": "Einstellungen",
|
||||
"theme": "Theme",
|
||||
"theme_plural": "Themes",
|
||||
"themes": "Themes",
|
||||
"version": "Version"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Es ist nur eine einzelne HACS-Instanz erlaubt."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Persönlicher Zugriffstoken ist falsch."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "AppDaemon App-Entdeckung & Nachverfolgung aktivieren",
|
||||
"netdaemon": "NetDaemon App-Entdeckung & Nachverfolgung aktivieren",
|
||||
"python_script": "Python Script-Entdeckung & Nachverfolgung aktivieren",
|
||||
"sidepanel_icon": "Sidepanel Symbol",
|
||||
"sidepanel_title": "Sidepanel Titel",
|
||||
"theme": "Theme-Entdeckung & Nachverfolgung aktivieren",
|
||||
"token": "Persönlicher GitHub Zugriffstoken"
|
||||
},
|
||||
"description": "Wenn du Hilfe mit den Einstellungen brauchst, kannst du hier nachsehen: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Möchtest du dies wirklich zu deinen Lovelace-Ressourcen hinzufügen?",
|
||||
"bg_task": "Die Aktion ist deaktiviert, während Hintergrundprozesse ausgeführt werden.",
|
||||
"cancel": "Abbrechen",
|
||||
"continue": "Bist du dir sicher, dass du fortfahren möchtest?",
|
||||
"delete": "Möchtest du '{item}' wirklich löschen?",
|
||||
"delete_installed": "'{item}' ist installiert. Du musst es deinstallieren, bevor du es löschen kannst.",
|
||||
"exist": "{item} existiert bereits",
|
||||
"generic": "Bist du dir sicher?",
|
||||
"home_assistant_is_restarting": "Bitte warte, Home Assistant wird jetzt neu gestartet.",
|
||||
"home_assistant_version_not_correct": "Du benutzt die Home Assistant-Version '{haversion}', für dieses Repository muss jedoch die Mindestversion '{minversion}' installiert sein.",
|
||||
"no": "Nein",
|
||||
"no_upgrades": "Keine Upgrades ausstehend",
|
||||
"ok": "OK",
|
||||
"overwrite": "Dadurch wird die Datei überschrieben.",
|
||||
"reload_data": "Hierdurch werden die Daten aller Repositories die HACS kennt neu geladen. Dies wird einige Zeit in Anspruch nehmen.",
|
||||
"restart_home_assistant": "Bist du dir sicher, dass du Home Assistant neu starten möchtest?",
|
||||
"uninstall": "Möchtest du '{item}' wirklich deinstallieren?",
|
||||
"upgrade_all": "Hierdurch werden all diese Repositories aktualisiert. Stelle sicher, dass du die Versionshinweise vorher gelesen hast.",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"dialog_add_repo": {
|
||||
"sort_by": "Sortiere nach"
|
||||
},
|
||||
"dialog_install": {
|
||||
"restart": "Denken Sie daran, dass Sie Home Assistant neu starten müssen, bevor Änderungen an Integrationen (custom_components) angewendet werden."
|
||||
},
|
||||
"entry": {
|
||||
"messages": {
|
||||
"resources": {
|
||||
"content": "Sie haben {number} Lovelace-Elemente, die in Lovelace nicht richtig geladen sind.",
|
||||
"title": "Nicht in Lovelace geladen"
|
||||
},
|
||||
"restart": {
|
||||
"content": "Sie haben {number} -Integrationen, die einen Neustart von Home Assistant erfordern. Dies können Sie im Abschnitt 'Server Controls' im Konfigurationsteil der Home Assistant-Benutzeroberfläche tun.",
|
||||
"title": "Ausstehender Neustart"
|
||||
},
|
||||
"wrong_frontend_installed": {
|
||||
"content": "Sie haben {running} des HACS-Frontends installiert, aber Version {expected} wurde erwartet. Wenn diese Meldung angezeigt wird, dass Home Assistant die neue Version nicht installieren konnte, starten Sie Home Assistant neu.",
|
||||
"title": "Unerwartete Frontend-Version"
|
||||
},
|
||||
"wrong_frontend_loaded": {
|
||||
"content": "Sie führen die Version {running} des HACS-Frontends aus, aber es wurde die Version {expected} erwartet. Sie sollten Ihren Browser-Cache leeren.",
|
||||
"title": "Unerwartete Frontend-Version"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"dismiss": "Alle neuen Repositories ausblenden"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "AppDaemon App-Entdeckung & Nachverfolgung aktivieren",
|
||||
"country": "Nach Ländercode filtern.",
|
||||
"debug": "Debug aktivieren.",
|
||||
"experimental": "Experimentelle Funktionen aktivieren",
|
||||
"netdaemon": "NetDaemon App-Entdeckung & Nachverfolgung aktivieren",
|
||||
"not_in_use": "Nicht in Verwendung mit YAML",
|
||||
"release_limit": "Anzahl anzuzeigender Releases.",
|
||||
"sidepanel_icon": "Sidepanel Symbol",
|
||||
"sidepanel_title": "Sidepanel Titel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Diese Integration unterstützt config_flow. Das bedeutet, dass du jetzt in den Integrationsbereich deiner Benutzeroberfläche wechseln kannst, um es zu konfigurieren.",
|
||||
"config_flow_title": "UI-Konfiguration unterstützt",
|
||||
"integration_not_loaded": "Diese Integration ist in Home Assistant nicht geladen.",
|
||||
"no_restart_required": "Kein Neustart erforderlich",
|
||||
"not_loaded": "Nicht geladen",
|
||||
"plugin_not_loaded": "Dieses Element wird nicht zu Ihren Lovelace-Ressourcen hinzugefügt.",
|
||||
"restart": "Du musst Home Assistant neu starten.",
|
||||
"restart_pending": "Neustart ausstehend"
|
||||
},
|
||||
"repository_card": {
|
||||
"dismiss": "Ausblenden",
|
||||
"not_loaded": "Nicht geladen",
|
||||
"open_source": "Quelldateien öffnen",
|
||||
"pending_restart": "Ausstehender Neustart",
|
||||
"report": "Melden zur Entfernung des Repositorys"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Zu Lovelace hinzufügen",
|
||||
"authors": "Autoren",
|
||||
"available": "Verfügbar",
|
||||
"back_to": "Zurück zu",
|
||||
"changelog": "Änderungsprotokoll",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Melden",
|
||||
"frontend_version": "Frontend Version",
|
||||
"github_stars": "GitHub Sterne",
|
||||
"goto_integrations": "Gehe zu Integrationen",
|
||||
"hide": "Verstecken",
|
||||
"hide_beta": "Beta verstecken",
|
||||
"install": "Installieren",
|
||||
"installed": "Installiert",
|
||||
"lovelace_copy_example": "Beispiel in die Zwischenablage kopieren",
|
||||
"lovelace_instruction": "Zum Hinzufügen zu deinen Lovelace-Einstellungen, benutze Folgendes",
|
||||
"lovelace_no_js_type": "Der Typ dieses Elements konnte nicht ermittelt werden. Überprüfen Sie das Repository.",
|
||||
"newest": "neueste",
|
||||
"note_appdaemon": "du musst es dann noch in die Datei 'apps.yaml' hinzufügen",
|
||||
"note_installed": "Wird installiert nach",
|
||||
"note_integration": "du musst es dann noch in die Datei 'configuration.yaml' hinzufügen",
|
||||
"note_plugin": "du musst es dann noch in deine Lovelace-Einstellungen ('ui-lovelace.yaml' oder im Raw-Konfigurationseditor) hinzufügen",
|
||||
"note_plugin_post_107": "Du musst es noch zu deiner Lovelace-Konfiguration hinzufügen ('configuration.yaml' oder der Ressourceneditor '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Problem melden",
|
||||
"open_plugin": "Element öffnen",
|
||||
"reinstall": "Neu installieren",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Home Assistant neu starten",
|
||||
"show_beta": "Beta anzeigen",
|
||||
"uninstall": "Deinstallieren",
|
||||
"update_information": "Aktualisierungsinformationen",
|
||||
"upgrade": "Aktualisieren"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Informationen zu HACS anzeigen",
|
||||
"title": "Über"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Hier finden Sie python_scripts, AppDaemon-Apps und NetDaemon-Apps",
|
||||
"title": "Automatisierung"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Hier finden Sie Themen, individuelle Karten und andere Elemente für Lovelace",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Hier finden Sie benutzerdefinierte Integrationen (custom_components)",
|
||||
"title": "Integrationen"
|
||||
},
|
||||
"pending_repository_upgrade": "Sie verwenden Version {installed}, Version {available} ist verfügbar"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "BENUTZERDEFINIERTES REPOSITORY HINZUFÜGEN",
|
||||
"adding_new_repo": "Hinzufügen eines neuen Repository '{repo}'",
|
||||
"adding_new_repo_category": "Mit der Kategorie '{category}'.",
|
||||
"bg_task_custom": "Custom Repositorys werden ausgeblendet, während Hintergrundaufgaben ausgeführt werden.",
|
||||
"category": "Kategorie",
|
||||
"compact_mode": "Kompakter Modus",
|
||||
"custom_repositories": "BENUTZERDEFINIERTE REPOSITORIES",
|
||||
"delete": "Löschen",
|
||||
"display": "Anzeige",
|
||||
"grid": "Gitter",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "versteckte Repositories",
|
||||
"missing_category": "Du musst eine Kategorie auswählen.",
|
||||
"open_repository": "Repository öffnen",
|
||||
"reload_data": "Daten neu laden",
|
||||
"reload_window": "Fenster neu laden",
|
||||
"repository_configuration": "Repository Konfiguration",
|
||||
"save": "Speichern",
|
||||
"table": "Tabelle",
|
||||
"table_view": "Tabellenansicht",
|
||||
"unhide": "einblenden",
|
||||
"upgrade_all": "Alles aktualisieren"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "Aufsteigend",
|
||||
"clear_new": "Alle neuen Repositories als gesehen markieren",
|
||||
"descending": "Absteigend",
|
||||
"last_updated": "Zuletzt aktualisiert",
|
||||
"name": "Name",
|
||||
"new_repositories": "Neue Repositories",
|
||||
"new_repositories_note": "Hier werden über 10 neue Repositorys angezeigt. Wenn Sie alle als gelesen markieren möchten, klicken Sie auf die 3 Punkte in der oberen rechten Ecke und blenden sie alle aus.",
|
||||
"pending_upgrades": "Ausstehende Upgrades",
|
||||
"placeholder_search": "Suchbegriff eingeben…",
|
||||
"sort": "Sortieren",
|
||||
"stars": "Sterne",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "vor",
|
||||
"day": "Tag",
|
||||
"days": "Tage",
|
||||
"hour": "Stunde",
|
||||
"hours": "Stunden",
|
||||
"minute": "Minute",
|
||||
"minutes": "Minuten",
|
||||
"month": "Monat",
|
||||
"months": "Monate",
|
||||
"one": "Eins",
|
||||
"one_day_ago": "vor einem Tag",
|
||||
"one_hour_ago": "vor einer Stunde",
|
||||
"one_minute_ago": "vor einer Minute",
|
||||
"one_month_ago": "vor einem Monat",
|
||||
"one_second_ago": "vor einer Sekunde",
|
||||
"one_year_ago": "vor einem Jahr",
|
||||
"second": "Sekunde",
|
||||
"seconds": "Sekunden",
|
||||
"x_days_ago": "vor {x} Tagen",
|
||||
"x_hours_ago": "vor {x} Stunden",
|
||||
"x_minutes_ago": "vor {x} Minuten",
|
||||
"x_months_ago": "vor {x} Monaten",
|
||||
"x_seconds_ago": "vor {x} Sekunden",
|
||||
"x_years_ago": "vor {x} Jahren",
|
||||
"year": "Jahr",
|
||||
"years": "Jahre"
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Σχετικά με",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"background_task": "Τρέχει μια διεργασία στο παρασκήνιο, η σελίδα θα ανανεωθεί μόλις αυτό ολοκληρωθεί.",
|
||||
"check_log_file": "Ελέγξτε το αρχείο καταγραφής για περισσότερες λεπτομέρειες.",
|
||||
"continue": "Να συνεχίσει",
|
||||
"disabled": "Απενεργοποιημένο",
|
||||
"documentation": "Τεκμηρίωση",
|
||||
"hacs_is_disabled": "Το HACS είναι απενεργοποιημένο",
|
||||
"installed": "εγκατεστημένο",
|
||||
"integration": "Ενσωμάτωση",
|
||||
"integrations": "Ενσωματωμένα",
|
||||
"manage": "διαχειρίζονται",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Πρόσθετα",
|
||||
"python_script": "Πρόγραμμα Python",
|
||||
"python_scripts": "Προγράμματα Python",
|
||||
"repositories": "Αποθετήρια",
|
||||
"settings": "ρυθμίσεις",
|
||||
"theme": "Θέμα",
|
||||
"themes": "Θέματα",
|
||||
"version": "Έκδοση"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Μονάχα μία ρύθμιση των παραμέτρων του HACS επιτρέπεται."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Το διακριτικό πρόσβασης δεν είναι σωστό."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Ενεργοποίηση εύρεσης & παρακολούθησης για το AppDaemon",
|
||||
"netdaemon": "Ενεργοποίηση εύρεσης & παρακολούθησης για το NetDaemon",
|
||||
"python_script": "Ενεργοποίηση εύρεσης & παρακολούθησης για τα python_scripts",
|
||||
"sidepanel_icon": "Εικονίδιο πλαϊνού πάνελ",
|
||||
"sidepanel_title": "Τίτλος πλαϊνού πάνελ",
|
||||
"theme": "Ενεργοποίηση εύρεσης & παρακολούθησης για τα θεμάτων",
|
||||
"token": "Διακριτικό πρόσβασης του GitHub"
|
||||
},
|
||||
"description": "Εάν χρειαστείτε βοήθεια με τις ρυθμίσεις ανατρέξτε εδώ: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Είστε βέβαιοι ότι θέλετε να προσθέσετε αυτό στους πόρους του Lovelace;",
|
||||
"bg_task": "Η ενέργεια είναι απενεργοποιημένη όσο εκτελούνται εργασίες στο παρασκήνιο",
|
||||
"cancel": "Ακύρωση",
|
||||
"continue": "Είστε βέβαιοι ότι θέλετε να συνεχίσετε;",
|
||||
"delete": "Είστε σίγουροι ότι θέλετε να διαγράψετε το '{item}';",
|
||||
"delete_installed": "Το '{item}' είναι εγκατεστημένο, πρέπει να το απεγκαταστήσετε πριν να το διαγράψετε.",
|
||||
"exist": "{item} υπάρχει ήδη",
|
||||
"generic": "Είστε βέβαιοι;",
|
||||
"home_assistant_is_restarting": "Περιμένετε, το Home Assistant επανεκκινείται τώρα.",
|
||||
"no": "Οχι",
|
||||
"no_upgrades": "Δεν υπάρχουν αναβαθμίσεις σε εκκρεμότητα",
|
||||
"ok": "Εντάξει",
|
||||
"overwrite": "Αυτό θα το αντικαταστήσει.",
|
||||
"restart_home_assistant": "Είστε βέβαιοι ότι θέλετε να κάνετε επανεκκίνηση του Home Assistant;",
|
||||
"uninstall": "Είστε βέβαιοι ότι θέλετε να απεγκαταστήσετε το '{item}';",
|
||||
"upgrade_all": "Αυτό θα αναβαθμίσει όλα αυτά τα αποθετήρια, βεβαιωθείτε ότι έχετε διαβάσει τις σημειώσεις έκδοσης για όλα πριν προχωρήσετε.",
|
||||
"yes": "Ναι"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Ενεργοποίηση εύρεσης & παρακολούθησης για το AppDaemon",
|
||||
"country": "Κριτήριο με βάση τον κωδικό χώρας.",
|
||||
"debug": "Ενεργοποίηση εντοπισμού σφαλμάτων.",
|
||||
"experimental": "Ενεργοποίση πειραματικών λειτουργιών",
|
||||
"netdaemon": "Ενεργοποίηση εύρεσης & παρακολούθησης για το NetDaemon",
|
||||
"not_in_use": "Δεν χρησιμοποιείται με το YAML",
|
||||
"release_limit": "Αριθμός εκδόσεων που να παραθέτονται.",
|
||||
"sidepanel_icon": "Εικονίδιο πλαϊνού πάνελ",
|
||||
"sidepanel_title": "Τίτλος πλαϊνού πάνελ"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"integration_not_loaded": "Αυτή η ενσωμάτωση δεν φορτώθηκε στο Home Assistant.",
|
||||
"no_restart_required": "Δεν απαιτείται επανεκκίνηση",
|
||||
"not_loaded": "Δεν έχει φορτωθεί",
|
||||
"plugin_not_loaded": "Αυτό το πρόσθετο δεν προστέθηκε στους πόρους του Lovelace.",
|
||||
"restart": "Πρέπει να κάνετε επανεκκίνηση του Home Assistant.",
|
||||
"restart_pending": "Επανεκκίνηση σε εκκρεμότητα"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Προσθήκη στο Lovelace",
|
||||
"authors": "Συγγραφείς",
|
||||
"available": "Διαθέσιμο",
|
||||
"back_to": "Πίσω στο",
|
||||
"changelog": "Σημειώσεις των αλλαγών",
|
||||
"downloads": "Λήψεις",
|
||||
"flag_this": "Σημείωσε αυτό",
|
||||
"frontend_version": "Έκδοση Frontend",
|
||||
"github_stars": "GitHub αστέρια",
|
||||
"goto_integrations": "Μετάβαση στις ενσωματώσεις",
|
||||
"hide": "Απόκρυψη",
|
||||
"hide_beta": "Απόκριση του beta",
|
||||
"install": "Εγκατάσταση",
|
||||
"installed": "Εγκατεστημένο",
|
||||
"lovelace_copy_example": "Αντίγραψε το παράδειγμα στο πρόχειρο",
|
||||
"lovelace_instruction": "Όταν το προσθέσετε στις ρυθμίσεις του lovelace χρησιμοποιήστε τούτο",
|
||||
"lovelace_no_js_type": "Δεν καταφέραμε να προσδιορίσουμε τον τύπο αυτού του προσθέτου, ελέξτε το αποθετήριο.",
|
||||
"newest": "νεότερο",
|
||||
"note_appdaemon": "εξακολουθεί να χρειάζεται να το προσθέσετε στο αρχείο 'apps.yaml'",
|
||||
"note_installed": "Όταν εγκατασταθεί, θα προστεθεί στο",
|
||||
"note_integration": "εξακολουθεί να χρειάζεται να το προσθέσετε στο αρχείο 'configuration.yaml'",
|
||||
"note_plugin": "εξακολουθεί να χρειάζετε να το προσθέσετε στις ρυθμίσεις του lovelace ('ui-lovelace.yaml' ή μέσω του γραφικού επεξεργαστή των ρυθμίσεων)",
|
||||
"open_issue": "Εκκρεμόν ζήτημα",
|
||||
"open_plugin": "Ανοιχτό πρόσθετο",
|
||||
"reinstall": "Επανεγκατάσταση",
|
||||
"repository": "Αποθετήριο",
|
||||
"restart_home_assistant": "Επανεκκίνηση του Home Assistant",
|
||||
"show_beta": "Εμφάνιση του beta",
|
||||
"uninstall": "Απεγκατάσταση",
|
||||
"update_information": "Ενημέρωση πληροφοριών",
|
||||
"upgrade": "Ενημέρωση"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "ΠΡΟΣΘΕΣΤΕ ΕΝΑ ΕΙΔΙΚΟ ΑΠΟΘΕΤΗΡΙΟ",
|
||||
"adding_new_repo": "Προσθήκη νέου αποθετηρίου '{repo}'",
|
||||
"adding_new_repo_category": "Με κατηγορία '{category}'.",
|
||||
"category": "Κατηγορία",
|
||||
"compact_mode": "Συμπαγής λειτουργία",
|
||||
"custom_repositories": "ΕΙΔΙΚΑ ΑΠΟΘΕΤΗΡΙΑ",
|
||||
"delete": "Διαγραφή",
|
||||
"display": "Εμφάνιση",
|
||||
"grid": "Πλέγμα",
|
||||
"hacs_repo": "Αποθετήριο του HACS",
|
||||
"hidden_repositories": "κρυφά αποθετήρια",
|
||||
"missing_category": "Πρέπει να επιλέξετε μια κατηγορία",
|
||||
"open_repository": "Ανοίξτε το αποθετήριο",
|
||||
"reload_data": "Επαναφόρτωση δεδομένων",
|
||||
"reload_window": "Επαναφόρτωση του παραθύρου",
|
||||
"repository_configuration": "Διαμόρφωση αποθετηρίου",
|
||||
"save": "Αποθήκευση",
|
||||
"table": "Πίνακας",
|
||||
"table_view": "Προβολή πίνακα",
|
||||
"unhide": "αποκρύψω",
|
||||
"upgrade_all": "Αναβάθμιση όλων"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "αύξουσα",
|
||||
"clear_new": "Απαλοιφή όλων των νέων αποθετηρίων",
|
||||
"descending": "φθίνουσα",
|
||||
"last_updated": "Τελευταία ενημέρωση",
|
||||
"name": "Ονομα",
|
||||
"new_repositories": "Νέα αποθετήρια",
|
||||
"pending_upgrades": "Εκκρεμείς αναβαθμίσεις",
|
||||
"placeholder_search": "Παρακαλώ πληκτρολογήστε έναν όρο προς αναζήτηση...",
|
||||
"sort": "είδος",
|
||||
"stars": "Αστέρια",
|
||||
"status": "Κατάσταση"
|
||||
},
|
||||
"time": {
|
||||
"ago": "πριν",
|
||||
"day": "ημέρα",
|
||||
"days": "ημέρες",
|
||||
"hour": "ώρα",
|
||||
"hours": "ώρες",
|
||||
"minute": "λεπτό",
|
||||
"minutes": "λεπτά",
|
||||
"month": "μήνας",
|
||||
"months": "μήνες",
|
||||
"one": "Ένα",
|
||||
"one_day_ago": "πριν από μία ημέρα",
|
||||
"one_hour_ago": "πριν από μια ώρα",
|
||||
"one_minute_ago": "πριν από ένα λεπτό",
|
||||
"one_month_ago": "πριν από ένα μήνα",
|
||||
"one_second_ago": "πριν από ένα δευτερόλεπτο",
|
||||
"one_year_ago": "πριν από ένα χρόνο",
|
||||
"second": "δευτερόλεπτο",
|
||||
"seconds": "δευτερόλεπτα",
|
||||
"x_days_ago": "{x} ημέρες πριν",
|
||||
"x_hours_ago": "{x} ώρες πριν",
|
||||
"x_minutes_ago": "{x} λεπτά πριν",
|
||||
"x_months_ago": "{x} μήνες πριν",
|
||||
"x_seconds_ago": "{x} δευτερόλεπτα πριν",
|
||||
"x_years_ago": "{x} χρόνια πριν",
|
||||
"year": "έτος",
|
||||
"years": "χρόνια"
|
||||
}
|
||||
}
|
|
@ -1,343 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "About",
|
||||
"add": "add",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"appdaemon_plural": "AppDaemon Apps",
|
||||
"background_task": "Background task running, this page will reload when it's done.",
|
||||
"check_log_file": "Check your log file for more details.",
|
||||
"continue": "Continue",
|
||||
"disabled": "Disabled",
|
||||
"documentation": "Documentation",
|
||||
"element": "element",
|
||||
"hacs_is_disabled": "HACS is disabled",
|
||||
"install": "Install",
|
||||
"installed": "installed",
|
||||
"integration": "Integration",
|
||||
"integration_plural": "Integrations",
|
||||
"integrations": "Integrations",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace element",
|
||||
"lovelace_elements": "Lovelace elements",
|
||||
"manage": "manage",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"netdaemon_plural": "NetDaemon Apps",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace elements",
|
||||
"plugins": "Lovelace elements",
|
||||
"python_script": "Python Script",
|
||||
"python_script_plural": "Python Scripts",
|
||||
"python_scripts": "Python Scripts",
|
||||
"repositories": "Repositories",
|
||||
"repository": "Repository",
|
||||
"settings": "settings",
|
||||
"theme": "Theme",
|
||||
"theme_plural": "Themes",
|
||||
"themes": "Themes",
|
||||
"uninstall": "Uninstall",
|
||||
"update": "Update",
|
||||
"version": "Version"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Only a single configuration of HACS is allowed."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Personal Access Token is not correct."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Enable AppDaemon apps discovery & tracking",
|
||||
"netdaemon": "Enable NetDaemon apps discovery & tracking",
|
||||
"python_script": "Enable python_scripts discovery & tracking",
|
||||
"sidepanel_icon": "Side panel icon",
|
||||
"sidepanel_title": "Side panel title",
|
||||
"theme": "Enable Themes discovery & tracking",
|
||||
"token": "GitHub Personal Access Token"
|
||||
},
|
||||
"description": "If you need help with the configuration have a look here: https:\/\/hacs.xyz\/docs\/configuration\/start\/",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Are you sure you want to add this to your Lovelace resources?",
|
||||
"bg_task": "Action is disabled while background tasks is running.",
|
||||
"cancel": "Cancel",
|
||||
"continue": "Are you sure you want to continue?",
|
||||
"delete": "Are you sure you want to delete \"{item}\"?",
|
||||
"delete_installed": "'{item}' is installed, you need to uninstall it before you can delete it.",
|
||||
"exist": "{item} already exists",
|
||||
"generic": "Are you sure?",
|
||||
"home_assistant_is_restarting": "Hold on, Home Assistant is now restarting.",
|
||||
"home_assistant_version_not_correct": "You are running Home Assistant version '{haversion}', but this repository requires minimum version '{minversion}' to be installed.",
|
||||
"no": "No",
|
||||
"no_upgrades": "No upgrades pending",
|
||||
"ok": "OK",
|
||||
"overwrite": "Doing this will overwrite it.",
|
||||
"reload_data": "This reloads the data of all repositories HACS knows about, this will take some time to finish.",
|
||||
"restart_home_assistant": "Are you sure you want to restart Home Assistant?",
|
||||
"uninstall": "Are you sure you want to uninstall \"{item}\"?",
|
||||
"upgrade_all": "This will upgrade all of these repositories, make sure that you have read the release notes for all of them before proceeding.",
|
||||
"yes": "Yes"
|
||||
},
|
||||
"dialog_about": {
|
||||
"frontend_version": "Frontend version",
|
||||
"installed_repositories": "Installed repositories",
|
||||
"integration_version": "Integration version",
|
||||
"useful_links": "Useful links"
|
||||
},
|
||||
"dialog_add_repo": {
|
||||
"limit": "Only the first 100 repositories are shown, use the search to filter what you need",
|
||||
"no_match": "No repositories found matching your filter",
|
||||
"sort_by": "Sort by",
|
||||
"title": "Add repository"
|
||||
},
|
||||
"dialog_custom_repositories": {
|
||||
"category": "Category",
|
||||
"no_category": "Missing category",
|
||||
"no_repository": "Missing repository",
|
||||
"title": "Custom repositories",
|
||||
"url_placeholder": "Add custom repository URL"
|
||||
},
|
||||
"dialog_info": {
|
||||
"author": "Author",
|
||||
"downloads": "Downloads",
|
||||
"install": "Install this repository in HACS",
|
||||
"loading": "Loading information...",
|
||||
"no_info": "The developer has not provided any more information for this repository",
|
||||
"open_issues": "Open issues",
|
||||
"open_repo": "Open repository",
|
||||
"stars": "Stars",
|
||||
"version_installed": "Version installed"
|
||||
},
|
||||
"dialog_install": {
|
||||
"restart": "Remember that you need to restart Home Assistant before changes to integrations (custom_components) are applied.",
|
||||
"select_version": "Select version",
|
||||
"show_beta": "Show beta versions",
|
||||
"type": "Type",
|
||||
"url": "URL"
|
||||
},
|
||||
"dialog_update": {
|
||||
"available_version": "Available version",
|
||||
"changelog": "Changelog",
|
||||
"installed_version": "Installed version",
|
||||
"title": "Update pending"
|
||||
},
|
||||
"entry": {
|
||||
"information": "Information",
|
||||
"intro": "Updates and important messages will show here if there are any",
|
||||
"messages": {
|
||||
"disabled": {
|
||||
"content": "Check your log file for more details",
|
||||
"title": "HACS is disabled"
|
||||
},
|
||||
"has_pending_tasks": {
|
||||
"content": "Some repositories might not show untill this is completed",
|
||||
"title": "Background tasks pending"
|
||||
},
|
||||
"resources": {
|
||||
"content": "You have {number} Lovelace elements that are not loaded properly in Lovelace.",
|
||||
"title": "Not loaded in Lovelace"
|
||||
},
|
||||
"restart": {
|
||||
"content": "You have {number} integrations that requires a restart of Home Assistant, you can do that from the 'Server Controls' section under the configuration part of Home Assistant UI.",
|
||||
"title": "Pending restart"
|
||||
},
|
||||
"startup": {
|
||||
"content": "HACS is starting up, during this time some information might be missing or incorrect",
|
||||
"title": "HACS is starting up"
|
||||
},
|
||||
"wrong_frontend_installed": {
|
||||
"content": "You have {running} of the HACS frontend installed, but version {expected} was expected, if this you see this message Home Assistant was not able to install the new version, try restarting Home Assistant.",
|
||||
"title": "Unexpected frontend version"
|
||||
},
|
||||
"wrong_frontend_loaded": {
|
||||
"content": "You are running version {running} of the HACS frontend, but version {expected} was expected, you should clear your browser cache.",
|
||||
"title": "Unexpected frontend version"
|
||||
}
|
||||
},
|
||||
"pending_updates": "Pending updates"
|
||||
},
|
||||
"menu": {
|
||||
"about": "About HACS",
|
||||
"clear": "Clear all new",
|
||||
"custom_repositories": "Custom repositories",
|
||||
"dismiss": "Dismiss all new repositories",
|
||||
"documentation": "Documentation",
|
||||
"open_issue": "Open issue",
|
||||
"reload": "Reload window"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Enable AppDaemon apps discovery & tracking",
|
||||
"country": "Filter with country code.",
|
||||
"debug": "Enable debug.",
|
||||
"experimental": "Enable experimental features",
|
||||
"netdaemon": "Enable NetDaemon apps discovery & tracking",
|
||||
"not_in_use": "Not in use with YAML",
|
||||
"release_limit": "Number of releases to show.",
|
||||
"sidepanel_icon": "Side panel icon",
|
||||
"sidepanel_title": "Side panel title"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "This integration supports config_flow, that means that you now can go to the integration section of your UI to configure it.",
|
||||
"config_flow_title": "UI Configuration supported",
|
||||
"integration_not_loaded": "This integration is not loaded in Home Assistant.",
|
||||
"no_restart_required": "No restart required",
|
||||
"not_loaded": "Not loaded",
|
||||
"plugin_not_loaded": "This plugin is not added to your Lovelace resources.",
|
||||
"restart": "You need to restart Home Assistant.",
|
||||
"restart_pending": "Restart pending"
|
||||
},
|
||||
"repository_card": {
|
||||
"dismiss": "dismiss",
|
||||
"hide": "Hide",
|
||||
"information": "Information",
|
||||
"new_repository": "New repository",
|
||||
"not_loaded": "Not loaded",
|
||||
"open_issue": "Open issue",
|
||||
"open_source": "Open source",
|
||||
"pending_restart": "Pending restart",
|
||||
"pending_update": "Pending update",
|
||||
"reinstall": "Reinstall",
|
||||
"report": "Report for removal",
|
||||
"update_information": "Update information"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Add to Lovelace",
|
||||
"authors": "Authors",
|
||||
"available": "Available",
|
||||
"back_to": "Back to",
|
||||
"changelog": "Change log",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Flag this",
|
||||
"frontend_version": "Frontend version",
|
||||
"github_stars": "GitHub stars",
|
||||
"goto_integrations": "Go to integrations",
|
||||
"hide": "Hide",
|
||||
"hide_beta": "Hide beta",
|
||||
"install": "Install",
|
||||
"installed": "Installed",
|
||||
"lovelace_copy_example": "Copy the example to your clipboard",
|
||||
"lovelace_instruction": "When you add this to your lovelace configuration use this",
|
||||
"lovelace_no_js_type": "Could not determine the type of this plugin, check the repository.",
|
||||
"newest": "newest",
|
||||
"note_appdaemon": "you still need to add it to your 'apps.yaml' file",
|
||||
"note_installed": "When installed, this will be located in",
|
||||
"note_integration": "you still need to add it to your 'configuration.yaml' file",
|
||||
"note_plugin": "you still need to add it to your lovelace configuration ('ui-lovelace.yaml' or the raw UI config editor)",
|
||||
"note_plugin_post_107": "you still need to add it to your lovelace configuration ('configuration.yaml' or the resource editor '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Open issue",
|
||||
"open_plugin": "Open element",
|
||||
"reinstall": "Reinstall",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Restart Home Assistant",
|
||||
"show_beta": "Show beta",
|
||||
"uninstall": "Uninstall",
|
||||
"update_information": "Update information",
|
||||
"upgrade": "Update"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search for repository"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Show information about HACS",
|
||||
"title": "About"
|
||||
},
|
||||
"automation": {
|
||||
"description": "This is where you find python_scripts, AppDaemon apps and NetDaemon apps",
|
||||
"title": "Automation"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "This is where you find themes, custom cards and other elements for lovelace",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "This is where you find custom integrations (custom_components)",
|
||||
"title": "Integrations"
|
||||
},
|
||||
"pending_repository_upgrade": "You are running version {installed}, version {available} is available"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "ADD CUSTOM REPOSITORY",
|
||||
"adding_new_repo": "Adding new repository '{repo}'",
|
||||
"adding_new_repo_category": "With category '{category}'.",
|
||||
"bg_task_custom": "Custom repositories are hidden while background tasks is running.",
|
||||
"category": "Category",
|
||||
"compact_mode": "Compact mode",
|
||||
"custom_repositories": "CUSTOM REPOSITORIES",
|
||||
"delete": "Delete",
|
||||
"display": "Display",
|
||||
"grid": "Grid",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "hidden repositories",
|
||||
"missing_category": "You need to select a category",
|
||||
"open_repository": "Open repository",
|
||||
"reload_data": "Reload data",
|
||||
"reload_window": "Reload window",
|
||||
"repository_configuration": "Repository configuration",
|
||||
"save": "Save",
|
||||
"table": "Table",
|
||||
"table_view": "Table view",
|
||||
"unhide": "unhide",
|
||||
"upgrade_all": "Upgrade all"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascending",
|
||||
"clear_new": "Clear all new repositories",
|
||||
"descending": "descending",
|
||||
"last_updated": "Last updated",
|
||||
"name": "Name",
|
||||
"new_repositories": "New Repositories",
|
||||
"new_repositories_note": "You have over 10 new repositories showing here, if you want to clear them all click the 3 dots in the top right corner and dismiss all of them.",
|
||||
"no_repositories": "No repositories",
|
||||
"no_repositories_desc1": "It seems like you don't have any repositories installed in this section yet.",
|
||||
"no_repositories_desc2": "Click on the + in the bottom corner to add your first!",
|
||||
"no_repositories_found_desc1": "No installed repositories matching \"{searchInput}\" found in this section.",
|
||||
"no_repositories_found_desc2": "Try searching for something else!",
|
||||
"pending_upgrades": "Pending upgrades",
|
||||
"placeholder_search": "Please enter a search term...",
|
||||
"sort": "sort",
|
||||
"stars": "Stars",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "ago",
|
||||
"day": "day",
|
||||
"days": "days",
|
||||
"hour": "hour",
|
||||
"hours": "hours",
|
||||
"minute": "minute",
|
||||
"minutes": "minutes",
|
||||
"month": "month",
|
||||
"months": "months",
|
||||
"one": "One",
|
||||
"one_day_ago": "one day ago",
|
||||
"one_hour_ago": "one hour ago",
|
||||
"one_minute_ago": "one minute ago",
|
||||
"one_month_ago": "one month ago",
|
||||
"one_second_ago": "one second ago",
|
||||
"one_year_ago": "one year ago",
|
||||
"second": "second",
|
||||
"seconds": "seconds",
|
||||
"x_days_ago": "{x} days ago",
|
||||
"x_hours_ago": "{x} hours ago",
|
||||
"x_minutes_ago": "{x} minutes ago",
|
||||
"x_months_ago": "{x} months ago",
|
||||
"x_seconds_ago": "{x} seconds ago",
|
||||
"x_years_ago": "{x} years ago",
|
||||
"year": "year",
|
||||
"years": "years"
|
||||
}
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Acerca de",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"appdaemon_plural": "AppDaemon Apps",
|
||||
"background_task": "Ejecutando tareas en segundo plano. Se refrescará automaticamente esta página al finalizar.",
|
||||
"check_log_file": "Compruebe el archivo de registro para obtener más detalles.",
|
||||
"continue": "Continuar",
|
||||
"disabled": "Deshabilitado",
|
||||
"documentation": "Documentación",
|
||||
"element": "elemento",
|
||||
"hacs_is_disabled": "HACS está deshabilitado",
|
||||
"installed": "instalado",
|
||||
"integration": "Integración",
|
||||
"integration_plural": "Integraciones",
|
||||
"integrations": "Integraciones",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Elemento de Lovelace",
|
||||
"lovelace_elements": "Elementos de Lovelace",
|
||||
"manage": "Administrar",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"netdaemon_plural": "Aplicaciones NetDaemon",
|
||||
"plugin": "Plugin",
|
||||
"plugin_plural": "Elementos de Lovelace",
|
||||
"plugins": "Plugins",
|
||||
"python_script": "Python Script",
|
||||
"python_script_plural": "Python Scripts",
|
||||
"python_scripts": "Python Scripts",
|
||||
"repositories": "Repositorios",
|
||||
"settings": "configuraciones",
|
||||
"theme": "Tema",
|
||||
"theme_plural": "Temas",
|
||||
"themes": "Temas",
|
||||
"version": "Versión"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Sólo se permite una única configuración de HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "El token de acceso personal no es correcto."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Habilitar el descubrimiento y seguimiento de las aplicaciones de AppDaemon",
|
||||
"netdaemon": "Habilitar el descubrimiento y seguimiento de las aplicaciones de NetDaemon",
|
||||
"python_script": "Habilitar el descubrimiento y seguimiento en python_scripts",
|
||||
"sidepanel_icon": "Ícono del panel lateral",
|
||||
"sidepanel_title": "Título del panel lateral",
|
||||
"theme": "Habilitar el descubrimiento y seguimiento de temas",
|
||||
"token": "Token de acceso personal de GitHub"
|
||||
},
|
||||
"description": "Si necesitas ayuda con la configuración, visita la siguiente pagina: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "¿Está seguro de que desea agregar esto a sus recursos de Lovelace?",
|
||||
"bg_task": "La acción está deshabilitada mientras se ejecutan tareas en segundo plano.",
|
||||
"cancel": "Cancelar",
|
||||
"continue": "Estás seguro de que quieres continuar?",
|
||||
"delete": "¿Seguro que quieres eliminar '{item}'?",
|
||||
"delete_installed": "'{item}' está instalado, debe desinstalarlo antes de poder eliminarlo.",
|
||||
"exist": "{item} ya existe",
|
||||
"generic": "¿Estás seguro?",
|
||||
"home_assistant_is_restarting": "Espera, Home Assistant se está reiniciando.",
|
||||
"home_assistant_version_not_correct": "Está ejecutando la versión '{haversion}' de Home Assistant, pero este repositorio requiere la instalación de la versión '{minversion}' mínima.",
|
||||
"no": "No",
|
||||
"no_upgrades": "No hay actualizaciones pendientes",
|
||||
"ok": "OK",
|
||||
"overwrite": "Si haces esto, se sobrescribirá.",
|
||||
"reload_data": "Esto recarga los datos de todos los repositorios que HACS conoce, esto tardará algún tiempo en finalizar.",
|
||||
"restart_home_assistant": "¿Está seguro de que desea reiniciar Home Assistant?",
|
||||
"uninstall": "¿Está seguro de que deseas desinstalar '{item}'?",
|
||||
"upgrade_all": "Esto actualizará todos estos repositorios, asegúrese de que ha leído las notas de la versión de todos ellos antes de continuar.",
|
||||
"yes": "Si"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Habilitar el descubrimiento y seguimiento de las aplicaciones de AppDaemon",
|
||||
"country": "Filtrar por el código de país.",
|
||||
"debug": "Habilitar depuración.",
|
||||
"experimental": "Habilitar funciones experimentales",
|
||||
"netdaemon": "Habilitar el descubrimiento y seguimiento de las aplicaciones de NetDaemon",
|
||||
"not_in_use": "No usarse con YAML",
|
||||
"release_limit": "Número de versiones a mostrar.",
|
||||
"sidepanel_icon": "Icono del panel lateral",
|
||||
"sidepanel_title": "Título del panel lateral"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Esta integración soporta config_flow, lo que significa que ahora puede ir a la sección de integración de su UI para configurarlo.",
|
||||
"config_flow_title": "Configuración de UI soportada",
|
||||
"integration_not_loaded": "Esta integración no se carga en Home Assistant.",
|
||||
"no_restart_required": "No es necesario reiniciar",
|
||||
"not_loaded": "No está cargado",
|
||||
"plugin_not_loaded": "Este plugin aun no se ha añadido a sus recursos de Lovelace.",
|
||||
"restart": "Es necesario reiniciar Home Assistant.",
|
||||
"restart_pending": "Reinicio pendiente"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Añadir a Lovelace",
|
||||
"authors": "Autores",
|
||||
"available": "Disponible",
|
||||
"back_to": "Volver a",
|
||||
"changelog": "Registro de cambios",
|
||||
"downloads": "Descargas",
|
||||
"flag_this": "Marcar esto",
|
||||
"frontend_version": "Versión del frontend",
|
||||
"github_stars": "Estrellas de GitHub",
|
||||
"goto_integrations": "Ir a integraciones",
|
||||
"hide": "Ocultar",
|
||||
"hide_beta": "Ocultar beta",
|
||||
"install": "Instalar",
|
||||
"installed": "Instalado",
|
||||
"lovelace_copy_example": "Copiar el ejemplo al clipboard",
|
||||
"lovelace_instruction": "Agregue lo siguiente en su configuración de lovelace",
|
||||
"lovelace_no_js_type": "No se pudo determinar el tipo de plugin, revise el repositorio.",
|
||||
"newest": "más nuevo",
|
||||
"note_appdaemon": "deberá agregar esto a su archivo 'apps.yaml'",
|
||||
"note_installed": "Cuando esté instalado, se ubicará en",
|
||||
"note_integration": "deberá agregar esto a su archivo 'configuration.yaml'",
|
||||
"note_plugin": "deberá agregar esto a su configuración de lovelace ('ui-lovelace.yaml' o en el editor UI de lovelace)",
|
||||
"note_plugin_post_107": "todavía necesita agregarlo a su configuración de lovelace ('configuration.yaml' o al editor de recursos '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Abrir issue",
|
||||
"open_plugin": "Abrir plugin",
|
||||
"reinstall": "Reinstalar",
|
||||
"repository": "Repositorio",
|
||||
"restart_home_assistant": "Reiniciar Home Assistant",
|
||||
"show_beta": "Mostrar beta",
|
||||
"uninstall": "Desinstalar",
|
||||
"update_information": "Actualizar información",
|
||||
"upgrade": "Actualizar"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Mostrar información sobre HACS",
|
||||
"title": "Acerca de"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Aquí es donde se encuentran python_scripts, aplicaciones AppDaemon y aplicaciones NetDaemon",
|
||||
"title": "Automatización"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Aquí es donde encontrarás temas, tarjetas personalizadas y otros elementos para lovelace",
|
||||
"title": "Interfaz"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Aquí es donde se encuentran las integraciones personalizadas (custom_components)",
|
||||
"title": "Integraciones"
|
||||
},
|
||||
"pending_repository_upgrade": "Está ejecutando la versión {installed}, la versión {available} está disponible"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "AGREGAR REPOSITORIO PERSONALIZADO",
|
||||
"adding_new_repo": "Añadiendo un nuevo repositorio '{repo}'.",
|
||||
"adding_new_repo_category": "Con la categoría '{category}'.",
|
||||
"bg_task_custom": "Los repositorios personalizados están ocultos mientras se ejecutan las tareas en segundo plano.",
|
||||
"category": "Categoría",
|
||||
"compact_mode": "Modo compacto",
|
||||
"custom_repositories": "REPOSITORIOS PERSONALIZADOS",
|
||||
"delete": "Eliminar",
|
||||
"display": "Mostrar",
|
||||
"grid": "Cuadrícula",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "repositorios ocultos",
|
||||
"missing_category": "Es necesario seleccionar una categoría",
|
||||
"open_repository": "Abrir repositorio",
|
||||
"reload_data": "Recargar datos",
|
||||
"reload_window": "Recargar ventana",
|
||||
"repository_configuration": "Configuración del repositorio",
|
||||
"save": "Guardar",
|
||||
"table": "Tabla",
|
||||
"table_view": "Vista de la tabla",
|
||||
"unhide": "mostrar",
|
||||
"upgrade_all": "Actualizar todo"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascendente",
|
||||
"clear_new": "Eliminar la lista los nuevos repositorios",
|
||||
"descending": "descendente",
|
||||
"last_updated": "Última actualización",
|
||||
"name": "Nombre",
|
||||
"new_repositories": "Nuevos Repositorios",
|
||||
"pending_upgrades": "Actualizaciones pendientes",
|
||||
"placeholder_search": "Por favor escriba una palabra clave de búsqueda...",
|
||||
"sort": "ordenar",
|
||||
"stars": "Estrellas",
|
||||
"status": "Estado"
|
||||
},
|
||||
"time": {
|
||||
"ago": "hace",
|
||||
"day": "dia",
|
||||
"days": "dias",
|
||||
"hour": "hora",
|
||||
"hours": "horas",
|
||||
"minute": "minuto",
|
||||
"minutes": "minutos",
|
||||
"month": "mes",
|
||||
"months": "meses",
|
||||
"one": "Uno",
|
||||
"one_day_ago": "hace un día",
|
||||
"one_hour_ago": "hace una hora",
|
||||
"one_minute_ago": "hace un minuto",
|
||||
"one_month_ago": "hace un mes",
|
||||
"one_second_ago": "hace un segundo",
|
||||
"one_year_ago": "hace un año",
|
||||
"second": "segundo",
|
||||
"seconds": "segundos",
|
||||
"x_days_ago": "hace {x} dias",
|
||||
"x_hours_ago": "hace {x} horas",
|
||||
"x_minutes_ago": "hace {x} minutos",
|
||||
"x_months_ago": "hace {x} meses",
|
||||
"x_seconds_ago": "hace {x} segundos",
|
||||
"x_years_ago": "hace {x} años",
|
||||
"year": "año",
|
||||
"years": "años"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "À propos de",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Applications AppDaemon",
|
||||
"background_task": "Tache de fond en cours, cette page se rechargera une fois terminée",
|
||||
"check_log_file": "Consultez votre fichier journal pour plus de détails.",
|
||||
"continue": "Continuer",
|
||||
"disabled": "Désactivé",
|
||||
"documentation": "Documentation",
|
||||
"hacs_is_disabled": "HACS est désactivé",
|
||||
"installed": "installés",
|
||||
"integration": "Intégration",
|
||||
"integrations": "Intégrations",
|
||||
"manage": "gérer",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "Applications NetDaemon",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Éléments Lovelace",
|
||||
"python_script": "Script Python",
|
||||
"python_scripts": "Scripts Python",
|
||||
"repositories": "Dépôts",
|
||||
"settings": "paramètres",
|
||||
"theme": "Thème",
|
||||
"themes": "Thèmes",
|
||||
"version": "Version"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Une seule configuration de HACS est autorisée."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Le jeton personnel d'accès est invalide."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Activer la découverte et le suivi des applications AppDaemon",
|
||||
"netdaemon": "Activer la découverte et le suivi des applications NetDaemon",
|
||||
"python_script": "Activer la découverte et le suivi des scripts python",
|
||||
"sidepanel_icon": "Icône de la barre latérale",
|
||||
"sidepanel_title": "Titre de la barre latérale",
|
||||
"theme": "Activer la découverte et le suivi des thèmes",
|
||||
"token": "Jeton d'accès personnel GitHub"
|
||||
},
|
||||
"description": "Si vous avez besoin d'aide pour la configuration, jetez un œil ici: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Êtes-vous sûr de vouloir l'ajouter à vos ressources Lovelace ?",
|
||||
"bg_task": "L'action est désactivée pendant l'exécution de tâches en arrière-plan.",
|
||||
"cancel": "Annuler",
|
||||
"continue": "Es-tu sur de vouloir continuer?",
|
||||
"delete": "Êtes-vous sûr de vouloir supprimer '{item}'?",
|
||||
"delete_installed": "'{item}' est installé, vous devez le désinstaller avant de pouvoir le supprimer.",
|
||||
"exist": "{item} existe déjà",
|
||||
"generic": "Êtes-vous sûr?",
|
||||
"home_assistant_is_restarting": "Attendez, Home Assistant redémarre maintenant.",
|
||||
"home_assistant_version_not_correct": "Vous utilisez la version '{haversion}' de Home Assistant, mais ce référentiel nécessite l'installation de la version minimale '{minversion}'.",
|
||||
"no": "Non",
|
||||
"no_upgrades": "Aucune mise à niveau en attente",
|
||||
"ok": "OK",
|
||||
"overwrite": "En faisant cela, cela l'écrasera.",
|
||||
"reload_data": "Cela recharge les données de tous les dépôts dont HACS a connaissance, cela prendra un certain temps à terminer.",
|
||||
"restart_home_assistant": "Voulez-vous vraiment redémarrer Home Assistant ?",
|
||||
"uninstall": "Êtes-vous sûr de vouloir désinstaller '{item}'?",
|
||||
"upgrade_all": "Cela mettra à niveau tous ces dépôts, assurez-vous d'avoir lu les notes de publication pour chacun d'entre eux avant de continuer.",
|
||||
"yes": "Oui"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Activer la découverte et le suivi des applications AppDaemon",
|
||||
"country": "Filtrer par code pays.",
|
||||
"debug": "Activez le débogage.",
|
||||
"experimental": "Activer les fonctionnalités expérimentales",
|
||||
"netdaemon": "Activer la découverte et le suivi des applications NetDaemon",
|
||||
"not_in_use": "Non utilisé avec YAML",
|
||||
"release_limit": "Nombre de recensés à afficher.",
|
||||
"sidepanel_icon": "Icône de la barre latérale",
|
||||
"sidepanel_title": "Titre de la barre latérale"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Cette intégration prend en charge config_flow, ce qui signifie que vous pouvez maintenant accéder à la section d'intégration de votre interface utilisateur pour le configurer.",
|
||||
"config_flow_title": "Configuration de l'interface utilisateur prise en charge",
|
||||
"integration_not_loaded": "Cette intégration n'est pas chargée dans Home Assistant.",
|
||||
"no_restart_required": "Aucun redémarrage requis",
|
||||
"not_loaded": "Non chargé",
|
||||
"plugin_not_loaded": "Ce plugin n'est pas ajouté à vos ressources Lovelace.",
|
||||
"restart": "Vous devez redémarrer Home Assistant.",
|
||||
"restart_pending": "Redémarrage en attente"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Ajouter à Lovelace",
|
||||
"authors": "Auteurs",
|
||||
"available": "Disponible",
|
||||
"back_to": "Retour",
|
||||
"changelog": "Change log",
|
||||
"downloads": "Téléchargements",
|
||||
"flag_this": "Marquer",
|
||||
"frontend_version": "Version de l'interface",
|
||||
"github_stars": "Étoiles GitHub",
|
||||
"goto_integrations": "Aller aux intégrations",
|
||||
"hide": "Masquer",
|
||||
"hide_beta": "Masquer les bêta",
|
||||
"install": "Installer",
|
||||
"installed": "Installé",
|
||||
"lovelace_copy_example": "Copier cet exemple dans le presse-papier",
|
||||
"lovelace_instruction": "Quand vous l'ajoutez à votre configuration lovelace, utilisez",
|
||||
"lovelace_no_js_type": "Impossible de déterminer le type de plugin, veuillez vérifier le dépôt",
|
||||
"newest": "nouveau",
|
||||
"note_appdaemon": "vous devez toujours l'ajouter à votre fichier 'apps.yaml'",
|
||||
"note_installed": "Une fois installé, il se trouvera dans",
|
||||
"note_integration": "Vous devez toujours l'ajouter à votre fichier 'configuration.yaml'",
|
||||
"note_plugin": "Vous devez toujours l'ajouter à votre configuration lovelace ('ui-lovelace.yaml' ou l'éditeur de configuration de l'interface)",
|
||||
"note_plugin_post_107": "Vous devez toujours l'ajouter à votre configuration lovelace ('configuration.yaml' ou l'éditeur de configuration de l'interface '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Ouvrir un ticket",
|
||||
"open_plugin": "Ouvrir le plugin",
|
||||
"reinstall": "Réinstaller",
|
||||
"repository": "Dépôt",
|
||||
"restart_home_assistant": "Redémarrer Home Assistant",
|
||||
"show_beta": "Afficher les bêta",
|
||||
"uninstall": "Désinstaller",
|
||||
"update_information": "Mettre à jour les informations",
|
||||
"upgrade": "Mettre à jour"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "AJOUTER UN DÉPÔT PERSONNALISÉ",
|
||||
"adding_new_repo": "Ajout d'un nouveau dépôt '{repo}'",
|
||||
"adding_new_repo_category": "Avec la catégorie '{category}'.",
|
||||
"bg_task_custom": "Les dépôts personnalisés sont masqués pendant l'exécution de tâches en arrière-plan.",
|
||||
"category": "Catégorie",
|
||||
"compact_mode": "Mode compact",
|
||||
"custom_repositories": "DÉPÔTS PERSONNALISÉS",
|
||||
"delete": "Supprimer",
|
||||
"display": "Affichage",
|
||||
"grid": "Grille",
|
||||
"hacs_repo": "Dépôt HACS",
|
||||
"hidden_repositories": "dépôts cachés",
|
||||
"missing_category": "Vous devez sélectionner une catégorie",
|
||||
"open_repository": "Ouvrir dépôt",
|
||||
"reload_data": "Recharger les données",
|
||||
"reload_window": "Recharger la fenêtre",
|
||||
"repository_configuration": "Configuration de dépôt",
|
||||
"save": "Enregistrer",
|
||||
"table": "Tableau",
|
||||
"table_view": "Vue table",
|
||||
"unhide": "Afficher",
|
||||
"upgrade_all": "Tout mettre à jour"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascendant",
|
||||
"clear_new": "Effacer tous les nouveaux dépôts",
|
||||
"descending": "descendant",
|
||||
"last_updated": "Dernière mise à jour",
|
||||
"name": "Nom",
|
||||
"new_repositories": "Nouveaux dépôts",
|
||||
"pending_upgrades": "Mises à niveau en attente",
|
||||
"placeholder_search": "Veuillez entrer un terme de recherche...",
|
||||
"sort": "Trier",
|
||||
"stars": "Étoiles",
|
||||
"status": "Statut"
|
||||
},
|
||||
"time": {
|
||||
"ago": "il y a",
|
||||
"day": "jour",
|
||||
"days": "jours",
|
||||
"hour": "heure",
|
||||
"hours": "heures",
|
||||
"minute": "minute",
|
||||
"minutes": "minutes",
|
||||
"month": "mois",
|
||||
"months": "mois",
|
||||
"one": "Un",
|
||||
"one_day_ago": "il y a 1 jour",
|
||||
"one_hour_ago": "il y a 1 heure",
|
||||
"one_minute_ago": "il y a 1 minute",
|
||||
"one_month_ago": "il y a 1 mois",
|
||||
"one_second_ago": "il y a 1 seconde",
|
||||
"one_year_ago": "il y a 1 an",
|
||||
"second": "seconde",
|
||||
"seconds": "secondes",
|
||||
"x_days_ago": "il y a {x} jours",
|
||||
"x_hours_ago": "il y a {x} heures",
|
||||
"x_minutes_ago": "il y a {x} minutes",
|
||||
"x_months_ago": "il y a {x} mois",
|
||||
"x_seconds_ago": "il y a {x} secondes",
|
||||
"x_years_ago": "il y a {x} ans",
|
||||
"year": "an",
|
||||
"years": "ans"
|
||||
}
|
||||
}
|
|
@ -1,323 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Névjegy",
|
||||
"add": "hozzáadás",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Appok",
|
||||
"appdaemon_plural": "AppDaemon appok",
|
||||
"background_task": "Éppen háttérfeladat fut, ez az oldal frissülni fog, ha kész.",
|
||||
"check_log_file": "További részletekért ellenőrizd a naplófájlt.",
|
||||
"continue": "Folytatás",
|
||||
"disabled": "Tiltva",
|
||||
"documentation": "Dokumentáció",
|
||||
"element": "bővítmény",
|
||||
"hacs_is_disabled": "A HACS le van tiltva",
|
||||
"install": "Telepítés",
|
||||
"installed": "Telepített",
|
||||
"integration": "Integráció",
|
||||
"integration_plural": "Integrációk",
|
||||
"integrations": "Integrációk",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace bővítmény",
|
||||
"lovelace_elements": "Lovelace bővítmények",
|
||||
"manage": "kezelés",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Appok",
|
||||
"netdaemon_plural": "NetDaemon appok",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace bővítmények",
|
||||
"plugins": "Lovelace bővítmények",
|
||||
"python_script": "Python Szkript",
|
||||
"python_script_plural": "Python szkriptek",
|
||||
"python_scripts": "Python Szkriptek",
|
||||
"repositories": "Tárolók",
|
||||
"repository": "Tároló",
|
||||
"settings": "beállítások",
|
||||
"theme": "Téma",
|
||||
"theme_plural": "Témák",
|
||||
"themes": "Témák",
|
||||
"uninstall": "Eltávolítás",
|
||||
"update": "Frissítés",
|
||||
"version": "Verzió"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Csak egyetlen HACS-konfiguráció megengedett."
|
||||
},
|
||||
"error": {
|
||||
"auth": "A Személyes Hozzáférési Token nem megfelelő."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "AppDaemon appok felfedezésének és nyomon követésének engedélyezése",
|
||||
"netdaemon": "NetDaemon appok felfedezésének és nyomon követésének engedélyezése",
|
||||
"python_script": "Python szkriptek felfedezésének és nyomon követésének engedélyezése",
|
||||
"sidepanel_icon": "Oldalsó panel ikon",
|
||||
"sidepanel_title": "Oldalsó panel cím",
|
||||
"theme": "Témák felfedezésének és nyomon követésének engedélyezése",
|
||||
"token": "GitHub Személyes Hozzáférési Token"
|
||||
},
|
||||
"description": "Ha segítségre van szükséged a konfigurációval kapcsolatban, akkor tekintsd meg ezt az oldalt: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Biztosan hozzá szeretnéd ezt adni a Lovelace erőforrásokhoz?",
|
||||
"bg_task": "A művelet le van tiltva, amíg háttérfeladat fut.",
|
||||
"cancel": "Mégse",
|
||||
"continue": "Biztosan folytatni szeretnéd?",
|
||||
"delete": "Biztosan törölni szeretnéd a(z) '{item}'-t?",
|
||||
"delete_installed": "A(z) '{item}' telepítve van, törlés előtt el kell távolítanod.",
|
||||
"exist": "{item} már létezik",
|
||||
"generic": "Biztos vagy benne?",
|
||||
"home_assistant_is_restarting": "Várj, a Home Assistant éppen újraindul.",
|
||||
"home_assistant_version_not_correct": "A Home Assistant '{haversion}' verzióját használod, de ehhez a tárolóhoz legalább a(z) '{minversion}' verzióra van szükség.",
|
||||
"no": "Nem",
|
||||
"no_upgrades": "Nincsenek elérhető frissítések",
|
||||
"ok": "OK",
|
||||
"overwrite": "Ezzel felül fogod írni.",
|
||||
"reload_data": "Ez újratölti a HACS által ismert összes tároló adatát, ami némi időbe telhet.",
|
||||
"restart_home_assistant": "Biztosan újraindítod a Home Assistant programot?",
|
||||
"uninstall": "Biztosan el szeretnéd távolítani a(z) '{item}'-t?",
|
||||
"upgrade_all": "Ez frissíteni fogja az összes tárolót. Győzödj meg róla, hogy elolvastad az összes kiadási megjegyzést, mielőtt továbblépnél.",
|
||||
"yes": "Igen"
|
||||
},
|
||||
"dialog_about": {
|
||||
"frontend_version": "Frontend verzió",
|
||||
"installed_repositories": "Telepített tárolók",
|
||||
"integration_version": "Integráció verzió",
|
||||
"useful_links": "Hasznos linkek"
|
||||
},
|
||||
"dialog_add_repo": {
|
||||
"limit": "Csak az első 100 tároló jelenik meg, használd a keresőt a találatok szűkítéséhez",
|
||||
"no_match": "Nincs a szűrésnek megfelelő tároló",
|
||||
"sort_by": "Rendezés",
|
||||
"title": "Tároló hozzáadása"
|
||||
},
|
||||
"dialog_custom_repositories": {
|
||||
"category": "Kategória",
|
||||
"no_category": "Hiányzó kategória",
|
||||
"no_repository": "Hiányzó tároló",
|
||||
"title": "Egyéni tárolók",
|
||||
"url_placeholder": "Egyéni tároló URL címének hozzáadása"
|
||||
},
|
||||
"dialog_info": {
|
||||
"author": "Szerző",
|
||||
"downloads": "Letöltések",
|
||||
"install": "Tároló telepítése HACS-ben",
|
||||
"loading": "Információ betöltése...",
|
||||
"no_info": "A fejlesztő nem adott meg több információt ehhez a tárolóhoz",
|
||||
"open_issues": "Jelentett problémák",
|
||||
"open_repo": "Tároló megnyitása",
|
||||
"stars": "Csillagok",
|
||||
"version_installed": "Telepített verzió"
|
||||
},
|
||||
"dialog_install": {
|
||||
"restart": "Ne feledd, hogy az egyéni integrációk (custom_components) módosításainak alkalmazásához újra kell indítanod a Home Assistant alkalmazást.",
|
||||
"select_version": "Verzió kiválasztása",
|
||||
"show_beta": "Béta verziók megjelenítése",
|
||||
"type": "Típus",
|
||||
"url": "URL"
|
||||
},
|
||||
"dialog_update": {
|
||||
"available_version": "Elérhető verzió",
|
||||
"changelog": "Változási napló",
|
||||
"installed_version": "Telepített verzió",
|
||||
"title": "Frissítés érhető el"
|
||||
},
|
||||
"entry": {
|
||||
"information": "Információ",
|
||||
"intro": "A frissítések és a fontos üzenetek itt jelennek meg, ha vannak",
|
||||
"messages": {
|
||||
"disabled": {
|
||||
"content": "További részletek a naplófájlban",
|
||||
"title": "A HACS le van tiltva"
|
||||
},
|
||||
"has_pending_tasks": {
|
||||
"content": "Előfordulhat, hogy egyes tárolók nem jelennek meg, amíg ez be nem fejeződik",
|
||||
"title": "Függőben lévő háttérfeladatok"
|
||||
},
|
||||
"startup": {
|
||||
"content": "A HACS éppen indul, ezidő alatt egyes információk hiányozhatnak vagy helytelenek lehetnek",
|
||||
"title": "A HACS éppen indul"
|
||||
}
|
||||
},
|
||||
"pending_updates": "Frissítések érhetők el"
|
||||
},
|
||||
"menu": {
|
||||
"about": "HACS névjegye",
|
||||
"clear": "Új jelölések törlése",
|
||||
"custom_repositories": "Egyéni tárolók",
|
||||
"dismiss": "Minden új tároló elvetése",
|
||||
"documentation": "Dokumentáció",
|
||||
"open_issue": "Probléma jelentése",
|
||||
"reload": "Ablak újratöltése"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "AppDaemon appok felfedezésének és nyomon követésének engedélyezése",
|
||||
"country": "Szűrés országkóddal.",
|
||||
"debug": "Hibakeresés engedélyezése.",
|
||||
"experimental": "Kísérleti funkciók engedélyezése",
|
||||
"netdaemon": "NetDaemon appok felfedezésének és nyomon követésének engedélyezése",
|
||||
"not_in_use": "YAML-lel nem használható",
|
||||
"release_limit": "Megjelenítendő kiadások száma.",
|
||||
"sidepanel_icon": "Oldalsó panel ikon",
|
||||
"sidepanel_title": "Oldalsó panel cím"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Ez az integráció támogatja a config_flow-t, vagyis a felhasználói felületen az integrációk menüben lehet konfigurálni.",
|
||||
"config_flow_title": "A felhasználói felület konfigurációja támogatott",
|
||||
"integration_not_loaded": "Ez az integráció nincs betöltve a Home Assistantban.",
|
||||
"no_restart_required": "Nincs szükség újraindításra",
|
||||
"not_loaded": "Nincs betöltve",
|
||||
"plugin_not_loaded": "Ez a bővítmény nincs hozzáadva a Lovelace erőforrásaidhoz.",
|
||||
"restart": "Indítsd újra a Home Assistant programot.",
|
||||
"restart_pending": "Újraindítás függőben"
|
||||
},
|
||||
"repository_card": {
|
||||
"dismiss": "elvetés",
|
||||
"hide": "Elrejtés",
|
||||
"information": "Információ",
|
||||
"new_repository": "Új tároló",
|
||||
"open_issue": "Probléma jelentése",
|
||||
"open_source": "Forrás megnyitása",
|
||||
"pending_update": "Frissítés érhető el",
|
||||
"reinstall": "Újratelepítés",
|
||||
"report": "Jelentés eltávolításra",
|
||||
"update_information": "Frissítési információ"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Hozzáadás a Lovelace-hez",
|
||||
"authors": "Szerzők",
|
||||
"available": "Elérhető",
|
||||
"back_to": "Vissza -",
|
||||
"changelog": "Változási napló",
|
||||
"downloads": "Letöltések",
|
||||
"flag_this": "Megjelölés",
|
||||
"frontend_version": "Frontend verzió",
|
||||
"github_stars": "GitHub csillagok",
|
||||
"goto_integrations": "Ugrás az integrációkhoz",
|
||||
"hide": "Elrejtés",
|
||||
"hide_beta": "Béta elrejtése",
|
||||
"install": "Telepítés",
|
||||
"installed": "Telepített",
|
||||
"lovelace_copy_example": "Példa másolása a vágólapra",
|
||||
"lovelace_instruction": "Amikor hozzáadod ezt a lovelace konfigurációdhoz, használd ezt",
|
||||
"lovelace_no_js_type": "Nem sikerült meghatározni a bővítmény típusát, ellenőrizd a tárolót.",
|
||||
"newest": "legújabb",
|
||||
"note_appdaemon": "de még hozzá kell adnod az 'apps.yaml' fájlhoz",
|
||||
"note_installed": "Telepítéskor a következő helyre kerül:",
|
||||
"note_integration": "de még hozzá kell adnod a 'configuration.yaml' fájlhoz",
|
||||
"note_plugin": "de még hozzá kell adnod a lovelace konfigurációhoz (az 'ui-lovelace.yaml' fájlban vagy a Lovelace felületen a konfiguráció szerkesztőben)",
|
||||
"note_plugin_post_107": "de még hozzá kell adnod a lovelace konfigurációhoz ('configuration.yaml' vagy az erőforrás szerkesztőben '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Probléma jelentése",
|
||||
"open_plugin": "Bővítmény megnyitása",
|
||||
"reinstall": "Újratelepítés",
|
||||
"repository": "Tároló",
|
||||
"restart_home_assistant": "Home Assistant újraindítása",
|
||||
"show_beta": "Béta megjelenítése",
|
||||
"uninstall": "Eltávolítás",
|
||||
"update_information": "Frissítési információk",
|
||||
"upgrade": "Frissítés"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Tároló keresése"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Információk megjelenítése a HACS-ről",
|
||||
"title": "Névjegy"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Itt Python szkripteket, AppDaemon és NetDaemon appokat találsz",
|
||||
"title": "Automatizálás"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Itt témákat, egyéni kártyákat és más bővítményeket találsz a Lovelace-hez",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Itt találod az egyéni integrációkat (custom_components)",
|
||||
"title": "Integrációk"
|
||||
},
|
||||
"pending_repository_upgrade": "A(z) {installed} verziót futtatod, a(z) {available} verzió már elérhető"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "EGYÉNI TÁROLÓ HOZZÁADÁSA",
|
||||
"adding_new_repo": "Új tároló hozzáadása '{repo}'",
|
||||
"adding_new_repo_category": "A '{category}' kategóriával.",
|
||||
"bg_task_custom": "Az egyéni tárolók rejtve vannak, amíg háttérfeladat fut.",
|
||||
"category": "Kategória",
|
||||
"compact_mode": "Kompakt mód",
|
||||
"custom_repositories": "EGYÉNI TÁROLÓK",
|
||||
"delete": "Törlés",
|
||||
"display": "Megjelenítés",
|
||||
"grid": "Rács",
|
||||
"hacs_repo": "HACS tároló",
|
||||
"hidden_repositories": "rejtett tárolók",
|
||||
"missing_category": "Ki kell választanod egy kategóriát",
|
||||
"open_repository": "Tároló megnyitása",
|
||||
"reload_data": "Adatok újratöltése",
|
||||
"reload_window": "Ablak újratöltése",
|
||||
"repository_configuration": "Tároló konfiguráció",
|
||||
"save": "Mentés",
|
||||
"table": "Táblázat",
|
||||
"table_view": "Táblázat nézet",
|
||||
"unhide": "felfedés",
|
||||
"upgrade_all": "Minden frissítése"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "növekvő",
|
||||
"clear_new": "Új tárolók megjelölése látottként",
|
||||
"descending": "csökkenő",
|
||||
"last_updated": "Utolsó frissítés",
|
||||
"name": "Név",
|
||||
"new_repositories": "Új tárolók",
|
||||
"new_repositories_note": "Több mint 10 új tároló látható. Ha törölni szeretnéd őket, akkor kattints a jobb felső sarokban lévő 3 pontra, és válaszd ki a 'Minden új tároló elvetése' menüpontot.",
|
||||
"no_repositories": "Nincsenek tárolók",
|
||||
"no_repositories_desc1": "Úgy tűnik, még nincsenek telepítve tárolók ebben a szekcióban.",
|
||||
"no_repositories_desc2": "Kattints az alsó sarokban található + jelre az első hozzáadásához!",
|
||||
"pending_upgrades": "Frissítések érhetők el",
|
||||
"placeholder_search": "Kérlek adj meg egy keresési kifejezést...",
|
||||
"sort": "rendezés",
|
||||
"stars": "Csillag",
|
||||
"status": "Állapot"
|
||||
},
|
||||
"time": {
|
||||
"ago": "ezelőtt",
|
||||
"day": "nap",
|
||||
"days": "nap",
|
||||
"hour": "óra",
|
||||
"hours": "óra",
|
||||
"minute": "perc",
|
||||
"minutes": "perc",
|
||||
"month": "hónap",
|
||||
"months": "hónap",
|
||||
"one": "Egy",
|
||||
"one_day_ago": "egy nappal ezelőtt",
|
||||
"one_hour_ago": "egy órával ezelőtt",
|
||||
"one_minute_ago": "egy perccel ezelőtt",
|
||||
"one_month_ago": "egy hónappal ezelőtt",
|
||||
"one_second_ago": "egy másodperccel ezelőtt",
|
||||
"one_year_ago": "egy évvel ezelőtt",
|
||||
"second": "másodperc",
|
||||
"seconds": "másodperc",
|
||||
"x_days_ago": "{x} nappal ezelőtt",
|
||||
"x_hours_ago": "{x} órával ezelőtt",
|
||||
"x_minutes_ago": "{x} perccel ezelőtt",
|
||||
"x_months_ago": "{x} hónappal ezelőtt",
|
||||
"x_seconds_ago": "{x} másodperccel ezelőtt",
|
||||
"x_years_ago": "{x} évvel ezelőtt",
|
||||
"year": "év",
|
||||
"years": "év"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Informazioni su",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Applicazioni AppDaemon",
|
||||
"background_task": "Attività in esecuzione, questa pagina sarà ricaricata al termine.",
|
||||
"check_log_file": "Controlla il tuo file di registro per maggiori dettagli.",
|
||||
"continue": "Continua",
|
||||
"disabled": "Disabilitato",
|
||||
"documentation": "Documentazione",
|
||||
"hacs_is_disabled": "HACS è disabilitato",
|
||||
"installed": "Installati",
|
||||
"integration": "Integrazione",
|
||||
"integrations": "Integrazioni",
|
||||
"manage": "gestione",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "Applicazioni NetDaemon",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Plugin",
|
||||
"python_script": "Script python",
|
||||
"python_scripts": "Script python",
|
||||
"repositories": "Repository",
|
||||
"settings": "Impostazioni",
|
||||
"theme": "Tema",
|
||||
"themes": "Temi",
|
||||
"version": "Versione"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "È consentita una sola configurazione di HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Il token di accesso personale non è corretto."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Abilita il rilevamento e il monitoraggio delle applicazioni AppDaemon",
|
||||
"netdaemon": "Abilita il rilevamento e il monitoraggio delle applicazioni NetDaemon",
|
||||
"python_script": "Abilita il rilevamento e il monitoraggio dei python_scripts",
|
||||
"sidepanel_icon": "Icona nel pannello laterale",
|
||||
"sidepanel_title": "Titolo nel pannello laterale",
|
||||
"theme": "Abilita individuazione e tracciamento dei temi",
|
||||
"token": "Token di accesso personale GitHub"
|
||||
},
|
||||
"description": "Se hai bisogno di aiuto con la configurazione dai un'occhiata qui: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Sei sicuro di voler aggiungerlo alle tue risorse Lovelace?",
|
||||
"bg_task": "L'azione è disabilitata mentre sono in esecuzione attività in background.",
|
||||
"cancel": "Annulla",
|
||||
"continue": "Sei sicuro di voler continuare?",
|
||||
"delete": "Sei sicuro di voler disinstallare '{item}'?",
|
||||
"delete_installed": "'{item}' è installato, è necessario disinstallarlo prima di poterlo eliminare.",
|
||||
"exist": "{item} esiste già",
|
||||
"generic": "Sei sicuro?",
|
||||
"home_assistant_is_restarting": "Aspetta, Home Assistant si sta riavviando.",
|
||||
"home_assistant_version_not_correct": "Stai eseguendo la versione Home Assistant '{haversion}', ma questo repository richiede l'installazione della versione minima '{minversion}'.",
|
||||
"no": "No",
|
||||
"no_upgrades": "Nessun aggiornamento in sospeso",
|
||||
"ok": "OK",
|
||||
"overwrite": "In questo modo lo sovrascriverà.",
|
||||
"reload_data": "Questo ricarica i dati di tutte le repository di cui HACS è a conoscenza, ci vorrà del tempo per finire.",
|
||||
"restart_home_assistant": "Sei sicuro di voler riavviare Home Assistant?",
|
||||
"uninstall": "Sei sicuro di voler disinstallare '{item}'?",
|
||||
"upgrade_all": "Questa azione aggiornerà tutti i repository, assicurati di aver letto le note di rilascio prima di procedere.",
|
||||
"yes": "Sì"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Abilita il rilevamento e il monitoraggio delle applicazioni AppDaemon",
|
||||
"country": "Filtra con prefisso internazionale.",
|
||||
"debug": "Abilita debug.",
|
||||
"experimental": "Abilita funzionalità sperimentali",
|
||||
"netdaemon": "Abilita il rilevamento e il monitoraggio delle applicazioni NetDaemon",
|
||||
"not_in_use": "Non in uso con YAML",
|
||||
"release_limit": "Numero di versioni da mostrare.",
|
||||
"sidepanel_icon": "Icona nel pannello laterale",
|
||||
"sidepanel_title": "Titolo nel pannello laterale"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Questa integrazione supporta config_flow, questo significa che è ora possibile passare alla sezione \"IntegrazionI\" dell'interfaccia utente per la configurazione.",
|
||||
"config_flow_title": "Configurazione dell'interfaccia utente supportata",
|
||||
"integration_not_loaded": "Questa integrazione non è caricata in Home Assistant.",
|
||||
"no_restart_required": "Non è necessario riavviare",
|
||||
"not_loaded": "Non caricato",
|
||||
"plugin_not_loaded": "Questo plugin non è stato aggiunto alle risorse di Lovelace.",
|
||||
"restart": "È necessario riavviare Home Assistant.",
|
||||
"restart_pending": "Riavvio in attesa"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Aggiungi a Lovelace",
|
||||
"authors": "Autori",
|
||||
"available": "Disponibile",
|
||||
"back_to": "Torna a",
|
||||
"changelog": "Change log",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Spunta questo",
|
||||
"frontend_version": "Frontend versione",
|
||||
"github_stars": "GitHub stelle",
|
||||
"goto_integrations": "Vai alle Integrazioni",
|
||||
"hide": "Nascondi",
|
||||
"hide_beta": "Nascondi beta",
|
||||
"install": "Installa",
|
||||
"installed": "Installato",
|
||||
"lovelace_copy_example": "Copia l'esempio negli appunti",
|
||||
"lovelace_instruction": "Quando lo aggiungi nella configurazione di lovelace, usa questo",
|
||||
"lovelace_no_js_type": "Impossibile determinare il tipo di plugin, verificare il repository.",
|
||||
"newest": "Più recente",
|
||||
"note_appdaemon": "dovrai aggiungerlo nel file 'apps.yaml'",
|
||||
"note_installed": "Una volta installato, si troverà in",
|
||||
"note_integration": "dovrai aggiungerlo nel file 'configuration.yaml'",
|
||||
"note_plugin": "devi aggiungere la configurazione nel file 'ui-lovelace.yaml' oppure via Editor RAW della UI.",
|
||||
"note_plugin_post_107": "devi aggiungere la configurazione nel file 'ui-lovelace.yaml' oppure via Editor RAW della UI.",
|
||||
"open_issue": "Segnala anomalia",
|
||||
"open_plugin": "Apri plugin",
|
||||
"reinstall": "Reinstalla",
|
||||
"repository": "Archivio Software (Repository)",
|
||||
"restart_home_assistant": "Riavvia Home Assistant",
|
||||
"show_beta": "Visualizza beta",
|
||||
"uninstall": "Rimuovi",
|
||||
"update_information": "Aggiorna informazioni",
|
||||
"upgrade": "Aggiorna"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "AGGIUNGI REPOSITORY PERSONALIZZATA",
|
||||
"adding_new_repo": "Aggiunta di un nuovo repository '{repo}'",
|
||||
"adding_new_repo_category": "Con la categoria '{category}'.",
|
||||
"bg_task_custom": "I repository personalizzati sono nascosti mentre sono in esecuzione attività in background.",
|
||||
"category": "Categoria",
|
||||
"compact_mode": "Modalità compatta",
|
||||
"custom_repositories": "REPOSITORY PERSONALIZZATE",
|
||||
"delete": "Cancella",
|
||||
"display": "Visualizza",
|
||||
"grid": "Griglia",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "repository nascosti",
|
||||
"missing_category": "Devi selezionare una categoria",
|
||||
"open_repository": "Apri il repository",
|
||||
"reload_data": "Ricarica i dati",
|
||||
"reload_window": "Ricarica la finestra",
|
||||
"repository_configuration": "Configurazione del repository",
|
||||
"save": "Salva",
|
||||
"table": "Tabella",
|
||||
"table_view": "Vista tabella",
|
||||
"unhide": "Mostra",
|
||||
"upgrade_all": "Aggiorna tutto"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascendente",
|
||||
"clear_new": "Ripulisci i nuovi repository",
|
||||
"descending": "discendente",
|
||||
"last_updated": "Ultimo aggiornamento",
|
||||
"name": "Nome",
|
||||
"new_repositories": "Nuovi repository",
|
||||
"pending_upgrades": "Aggiornamenti in sospeso",
|
||||
"placeholder_search": "Inserire un termine di ricerca",
|
||||
"sort": "Ordinare",
|
||||
"stars": "Stelle",
|
||||
"status": "Stato"
|
||||
},
|
||||
"time": {
|
||||
"ago": "fa",
|
||||
"day": "giorno",
|
||||
"days": "giorni",
|
||||
"hour": "ora",
|
||||
"hours": "ore",
|
||||
"minute": "minuto",
|
||||
"minutes": "minuti",
|
||||
"month": "mese",
|
||||
"months": "mesi",
|
||||
"one": "Un",
|
||||
"one_day_ago": "un giorno fa",
|
||||
"one_hour_ago": "un'ora fa",
|
||||
"one_minute_ago": "un minuto fa",
|
||||
"one_month_ago": "un mese fa",
|
||||
"one_second_ago": "un secondo fa",
|
||||
"one_year_ago": "un anno fa",
|
||||
"second": "secondo",
|
||||
"seconds": "secondi",
|
||||
"x_days_ago": "{x} giorni fa",
|
||||
"x_hours_ago": "{x} ore fa",
|
||||
"x_minutes_ago": "{x} minuti fa",
|
||||
"x_months_ago": "{x} mesi fa",
|
||||
"x_seconds_ago": "{x} secondi fa",
|
||||
"x_years_ago": "{x} anni fa",
|
||||
"year": "anno",
|
||||
"years": "anni"
|
||||
}
|
||||
}
|
|
@ -1,317 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Om",
|
||||
"add": "legg til",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apper",
|
||||
"appdaemon_plural": "AppDaemon-apper",
|
||||
"background_task": "Bakgrunnsoppgaven kjører. Denne siden lastes inn på nytt når den er ferdig.",
|
||||
"check_log_file": "Sjekk loggfilen din for mer informasjon.",
|
||||
"continue": "Fortsett",
|
||||
"disabled": "Deaktivert",
|
||||
"documentation": "dokumentasjon",
|
||||
"element": "element",
|
||||
"hacs_is_disabled": "HACS er deaktivert",
|
||||
"install": "Installer",
|
||||
"installed": "Installert",
|
||||
"integration": "Integrasjon",
|
||||
"integration_plural": "Integrasjoner",
|
||||
"integrations": "Integrasjoner",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace-element",
|
||||
"lovelace_elements": "Lovelace-elementer",
|
||||
"manage": "manage",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apper",
|
||||
"netdaemon_plural": "NetDaemon-apper",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace-elementer",
|
||||
"plugins": "Lovelace-elementer",
|
||||
"python_script": "Python-skript",
|
||||
"python_script_plural": "Python-skript",
|
||||
"python_scripts": "Python-skript",
|
||||
"repositories": "Repositories",
|
||||
"repository": "Repository",
|
||||
"settings": "Innstillinger",
|
||||
"theme": "Tema",
|
||||
"theme_plural": "Temaer",
|
||||
"themes": "Temaer",
|
||||
"uninstall": "Avinstaller",
|
||||
"update": "Oppdater",
|
||||
"version": "Versjon"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Bare en konfigurasjon av HACS er tillatt."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Personlig tilgangstoken er ikke korrekt."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver oppdagelse og sporing av AppDaemon-apper",
|
||||
"netdaemon": "Aktiver oppdagelse og sporing av NetDaemon-apper",
|
||||
"python_script": "Aktiver oppdagelse og sporing av python_scripts",
|
||||
"sidepanel_icon": "Sidepanel ikon",
|
||||
"sidepanel_title": "Sidepanel tittel",
|
||||
"theme": "Aktiver oppdagelse og sporing av temaer",
|
||||
"token": "GitHub Personal Access Token"
|
||||
},
|
||||
"description": "Hvis du trenger hjelp med konfigurasjonen, ta en titt her: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Er du sikker på at du vil legge dette til i dine Lovelace resources?",
|
||||
"bg_task": "Handlingen er deaktivert mens bakgrunnsoppgaver kjører.",
|
||||
"cancel": "Avbryt",
|
||||
"continue": "Er du sikker på at du vil fortsette?",
|
||||
"delete": "Er du sikker på at du vil fjerne '{item}'?",
|
||||
"delete_installed": "'{item}' er installert, du må avinstallere det før du kan slette det.",
|
||||
"exist": "{item} eksisterer allerede",
|
||||
"generic": "Er du sikker?",
|
||||
"home_assistant_is_restarting": "Vent, Home Assistant starter nå på nytt.",
|
||||
"home_assistant_version_not_correct": "Du kjører Home Assistant '{haversion}', men denne krever minimum versjon '{minversion}' for å bli installert.",
|
||||
"no": "Nei",
|
||||
"no_upgrades": "Ingen oppgraderinger tilgjengelig",
|
||||
"ok": "OK",
|
||||
"overwrite": "Å gjøre dette vil overskrive det.",
|
||||
"reload_data": "Dette laster inn dataene til alle repositories HACS vet om, dette vil ta litt tid å fullføre.",
|
||||
"restart_home_assistant": "Er du sikker på at du vil starte Home Assistant på nytt?",
|
||||
"uninstall": "Er du sikker på at du vil avinstallere '{item}'?",
|
||||
"upgrade_all": "Dette vil oppgradere alle disse repositorene, sørg for at du har lest utgivelses notatene for dem alle før du fortsetter.",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"dialog_about": {
|
||||
"frontend_version": "Frontend versjon",
|
||||
"installed_repositories": "Installerte repositories",
|
||||
"integration_version": "Integrasjonsversjon",
|
||||
"useful_links": "Nyttige lenker"
|
||||
},
|
||||
"dialog_add_repo": {
|
||||
"limit": "Bare de første 100 elementene vises, bruk søket til å filtrere det du trenger",
|
||||
"no_match": "Ingen elementer funnet som samsvarer med filteret ditt",
|
||||
"title": "Legg til repository"
|
||||
},
|
||||
"dialog_custom_repositories": {
|
||||
"category": "Kategori",
|
||||
"no_category": "Mangler kategori",
|
||||
"no_repository": "Mangler repository",
|
||||
"title": "Custom repositories",
|
||||
"url_placeholder": "Legg til custom repository"
|
||||
},
|
||||
"dialog_info": {
|
||||
"author": "Utgiver",
|
||||
"downloads": "Nedlastinger",
|
||||
"install": "Installer dette elementet i HACS",
|
||||
"loading": "Laster inn informasjon ...",
|
||||
"no_info": "Utvikleren har ikke gitt mer informasjon for dette elementet",
|
||||
"open_issues": "Åpne problemer",
|
||||
"open_repo": "Åpne repository",
|
||||
"stars": "Stjerner",
|
||||
"version_installed": "Versjon installert"
|
||||
},
|
||||
"dialog_install": {
|
||||
"select_version": "Velg versjon",
|
||||
"show_beta": "Vis betaversjoner",
|
||||
"type": "Type",
|
||||
"url": "URL"
|
||||
},
|
||||
"dialog_update": {
|
||||
"available_version": "Tilgjengelig versjon",
|
||||
"changelog": "Endringslogg",
|
||||
"installed_version": "Installert versjon",
|
||||
"title": "Oppdatering venter"
|
||||
},
|
||||
"entry": {
|
||||
"information": "Informasjon",
|
||||
"intro": "Oppdateringer og viktige meldinger vises her hvis det er noen",
|
||||
"messages": {
|
||||
"disabled": {
|
||||
"content": "Sjekk loggfilen din for mer informasjon",
|
||||
"title": "HACS er deaktivert"
|
||||
},
|
||||
"has_pending_tasks": {
|
||||
"content": "Noen elementer vises kanskje ikke før dette er fullført",
|
||||
"title": "Venter på bakgrunnsoppgaver"
|
||||
},
|
||||
"startup": {
|
||||
"content": "HACS starter opp, i løpet av denne tiden kan det hende at noe informasjon mangler eller er feil",
|
||||
"title": "HACS starter opp"
|
||||
}
|
||||
},
|
||||
"pending_updates": "Oppdateringer er klare"
|
||||
},
|
||||
"menu": {
|
||||
"about": "Om HACS",
|
||||
"clear": "Fjern alt nytt",
|
||||
"custom_repositories": "Custom repositories",
|
||||
"documentation": "Dokumentasjon",
|
||||
"open_issue": "Meld et problem",
|
||||
"reload": "Last inn vinduet på nytt"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver oppdagelse og sporing av AppDaemon-apper",
|
||||
"country": "Filtrer med landskode.",
|
||||
"debug": "Aktiver debug",
|
||||
"experimental": "Aktiver eksperimentelle funksjoner",
|
||||
"netdaemon": "Aktiver oppdagelse og sporing av NetDaemon-apper",
|
||||
"not_in_use": "Ikke i bruk med YAML",
|
||||
"release_limit": "Antall utgivelser som skal vises.",
|
||||
"sidepanel_icon": "Sidepanel ikon",
|
||||
"sidepanel_title": "Sidepanel tittel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Denne integrasjonen støtter config_flow, det betyr at du nå kan gå til integrasjoner i brukergrensesnittet for å konfigurere den.",
|
||||
"config_flow_title": "UI konfigurasjon støttet",
|
||||
"integration_not_loaded": "Integrasjonen er ikke lastet inn i Home Assistant.",
|
||||
"no_restart_required": "Ingen omstart kreves",
|
||||
"not_loaded": "Ikke lastet inn",
|
||||
"plugin_not_loaded": "Dette elementet er ikke lagt til i lovelace under \"resource\" delen av konfigurasjonen.",
|
||||
"restart": "Du må restart Home Assistant",
|
||||
"restart_pending": "Restart er nødvendig"
|
||||
},
|
||||
"repository_card": {
|
||||
"hide": "Skjul",
|
||||
"information": "Informasjon",
|
||||
"new_repository": "Ny",
|
||||
"open_issue": "Meld et problem",
|
||||
"open_source": "Åpne kilde",
|
||||
"pending_update": "Oppdatering venter",
|
||||
"reinstall": "Installer på nytt",
|
||||
"report": "Rapporter for fjerning",
|
||||
"update_information": "Oppdater informasjon"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Legg til i Lovelace",
|
||||
"authors": "Laget av",
|
||||
"available": "Tilgjengelig",
|
||||
"back_to": "Tilbake til",
|
||||
"changelog": "Endringslogg",
|
||||
"downloads": "Nedlastinger",
|
||||
"flag_this": "Flag dette",
|
||||
"frontend_version": "Frontend versjon",
|
||||
"github_stars": "GitHub-stjerner",
|
||||
"goto_integrations": "Gå til integrasjoner",
|
||||
"hide": "Skjul",
|
||||
"hide_beta": "Skjul beta",
|
||||
"installed": "Installert",
|
||||
"lovelace_copy_example": "Kopier eksemplet til utklippstavlen",
|
||||
"lovelace_instruction": "Når du legger til dette i lovelace-konfigurasjonen din, bruk dette",
|
||||
"lovelace_no_js_type": "Kunne ikke bestemme typen for dettte elementet, sjekk repository.",
|
||||
"newest": "Nyeste",
|
||||
"note_appdaemon": "du må fortsatt legge den til i 'apps.yaml' filen",
|
||||
"note_installed": "Når det er installert, vil dette ligge i",
|
||||
"note_integration": "du må fortsatt legge den til 'configuration.yaml' filen",
|
||||
"note_plugin": "du må fortsatt legge den til i lovelace-konfigurasjonen ('ui-lovelace.yaml' eller den rå UI-konfigurasjonsredigereren)",
|
||||
"note_plugin_post_107": "du må fortsatt legge den til i lovelace konfigurasjonen ('configuration.yaml' eller via resource behanleren i grensesnittet '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Meld et problem",
|
||||
"open_plugin": "Åpne kilde",
|
||||
"reinstall": "Installer på nytt",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Start Home Assistant på nytt",
|
||||
"show_beta": "Vis beta",
|
||||
"uninstall": "Avinstaller",
|
||||
"update_information": "Oppdater informasjon",
|
||||
"upgrade": "Oppdater"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Søk etter repository"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Vis informasjon om HACS",
|
||||
"title": "Om"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Det er her du finner python_scripts, AppDaemon-apper og NetDaemon-apper",
|
||||
"title": "Automasjon"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Det er her du finner temaer, tilpassede kort og andre elementer for lovelace",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Det er her du finner tilpassede integrasjoner (custom_components)",
|
||||
"title": "Integrasjoner"
|
||||
},
|
||||
"pending_repository_upgrade": "Du kjører versjon {installed} , versjon {available} er tilgjengelig"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "LEGG TIL REPOSITORY",
|
||||
"adding_new_repo": "Legger til ny repository '{repo}'",
|
||||
"adding_new_repo_category": "Med kategori '{category}'.",
|
||||
"bg_task_custom": "Custom repositories er skjult mens bakgrunnsoppgaver kjører.",
|
||||
"category": "Kategori",
|
||||
"compact_mode": "Kompakt modus",
|
||||
"custom_repositories": "TILPASSEDE REPOSITORIER",
|
||||
"delete": "Slett",
|
||||
"display": "Vise",
|
||||
"grid": "Nett",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "Gjemte repositories",
|
||||
"missing_category": "Du må velge en kategori",
|
||||
"open_repository": "Åpne repository",
|
||||
"reload_data": "Last inn data på nytt",
|
||||
"reload_window": "Last inn vinduet på nytt",
|
||||
"repository_configuration": "Repository konfigurasjon",
|
||||
"save": "Lagre",
|
||||
"table": "Tabell",
|
||||
"table_view": "Tabellvisning",
|
||||
"unhide": "Vis igjen",
|
||||
"upgrade_all": "Oppgradere alle"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "stigende",
|
||||
"clear_new": "Tøm nye repositories",
|
||||
"descending": "synkende",
|
||||
"last_updated": "Sist oppdatert",
|
||||
"name": "Navn",
|
||||
"new_repositories": "Nye repositories",
|
||||
"no_repositories": "Ingen repositories",
|
||||
"no_repositories_desc1": "Det virker som om du ikke har noen elementer installert i denne delen ennå.",
|
||||
"no_repositories_desc2": "Klikk på + i nederste hjørne for å legge til din første!",
|
||||
"pending_upgrades": "Venter på oppgradering",
|
||||
"placeholder_search": "Skriv inn et søkeord ...",
|
||||
"sort": "sorter",
|
||||
"stars": "Stjerner",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "siden",
|
||||
"day": "dag",
|
||||
"days": "dager",
|
||||
"hour": "time",
|
||||
"hours": "timer",
|
||||
"minute": "minutt",
|
||||
"minutes": "minutter",
|
||||
"month": "måned",
|
||||
"months": "måneder",
|
||||
"one": "En",
|
||||
"one_day_ago": "for en dag siden",
|
||||
"one_hour_ago": "en time siden",
|
||||
"one_minute_ago": "ett minutt siden",
|
||||
"one_month_ago": "en måned siden",
|
||||
"one_second_ago": "ett sekund siden",
|
||||
"one_year_ago": "ett år siden",
|
||||
"second": "sekund",
|
||||
"seconds": "sekunder",
|
||||
"x_days_ago": "{x} dager siden",
|
||||
"x_hours_ago": "{x} timer siden",
|
||||
"x_minutes_ago": "{x} minutter siden",
|
||||
"x_months_ago": "{x} måneder siden",
|
||||
"x_seconds_ago": "{x} sekunder siden",
|
||||
"x_years_ago": "{x} år siden",
|
||||
"year": "år",
|
||||
"years": "år"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Over",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"background_task": "Achtergrond taak is draaiende, de pagina herhaalt zichzelf wanneer dit klaar is.",
|
||||
"check_log_file": "Controleer het logbestand voor meer details.",
|
||||
"continue": "Doorgaan",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"documentation": "Documentatie",
|
||||
"hacs_is_disabled": "HACS is uitgeschakeld",
|
||||
"installed": "geinstalleerd",
|
||||
"integration": "Integratie",
|
||||
"integrations": "Integraties",
|
||||
"manage": "beheer",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Plugins",
|
||||
"python_script": "Python Script",
|
||||
"python_scripts": "Python Scripts",
|
||||
"repositories": "Repositories",
|
||||
"settings": "instellingen",
|
||||
"theme": "Thema",
|
||||
"themes": "Themas",
|
||||
"version": "Versie"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Je kunt maar een enkele configuratie van HACS tegelijk hebben."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Persoonlijke Toegang Token is niet correct."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Zet AppDaemon apps ontdekken & traceren aan",
|
||||
"netdaemon": "Zet NetDaemon apps ontdekken & traceren aan",
|
||||
"python_script": "Zet python_scripts ontdekken & traceren aan",
|
||||
"sidepanel_icon": "Zijpaneel icoon",
|
||||
"sidepanel_title": "Zijpaneel titel",
|
||||
"theme": "Zet Themes ontdekken & traceren aan",
|
||||
"token": "GitHub Persoonlijke Toegang Token"
|
||||
},
|
||||
"description": "Als je hulp nodig hebt met de configuratie, kun je hier verder kijken: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Weet u zeker dat u dit wilt toevoegen aan uw Lovelace bronnen?",
|
||||
"bg_task": "Actie is geblokkeerd terwijl achtergrondtaken actief zijn.",
|
||||
"cancel": "Annuleer",
|
||||
"continue": "Weet je zeker dat je wilt doorgaan?",
|
||||
"delete": "Weet u zeker dat u '{item}' wilt verwijderen?",
|
||||
"delete_installed": "'{item}' is geïnstalleerd, je dient het eerst te deïnstalleren voordat je het kan verwijderen.",
|
||||
"exist": "{item} bestaat al.",
|
||||
"generic": "Weet je het zeker?",
|
||||
"home_assistant_is_restarting": "Een moment alstublieft, Home Assistant is aan het herstarten.",
|
||||
"home_assistant_version_not_correct": "Je gebruikt Home Assistant versie '{haversion}', echter deze repository vereist dat minimaal versie '{minversion}' is geïnstalleerd.",
|
||||
"no": "Nee",
|
||||
"no_upgrades": "Geen upgrades in afwachting.",
|
||||
"ok": "Oké",
|
||||
"overwrite": "Door dit te doen, wordt het overschreven.",
|
||||
"reload_data": "Dit zal alle bekende data herladen van alle repositories van HACS. Dit kan even duren",
|
||||
"restart_home_assistant": "Weet u zeker dat u Home Assistant opnieuw wilt starten?",
|
||||
"uninstall": "Weet u zeker dat u '{item}' wilt verwijderen?",
|
||||
"upgrade_all": "Hiermee worden al deze repositories geüpgraded. Zorg ervoor dat u de release-opmerkingen van allen heeft gelezen voordat u doorgaat.",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Zet AppDaemon apps ontdekken & traceren aan",
|
||||
"country": "Filter met land code.",
|
||||
"debug": "Schakel debug in.",
|
||||
"experimental": "Zet experimentele functies aan",
|
||||
"netdaemon": "Zet NetDaemon apps ontdekken & traceren aan",
|
||||
"not_in_use": "Niet in gebruik met YAML",
|
||||
"release_limit": "Aantal releases om te laten zien.",
|
||||
"sidepanel_icon": "Zijpaneel icoon",
|
||||
"sidepanel_title": "Zijpaneel titel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Deze integratie ondersteunt config_flow, wat betekent dat u via uw \"Instellingen\" naar \"Integraties\" kunt gaan om het te configureren.",
|
||||
"config_flow_title": "UI-configuratie ondersteund",
|
||||
"integration_not_loaded": "Deze integratie wordt niet geladen in Home Assistant.",
|
||||
"no_restart_required": "Geen herstart vereist",
|
||||
"not_loaded": "Niet geladen",
|
||||
"plugin_not_loaded": "Deze plugin wordt niet toegevoegd aan je Lovelace resources.",
|
||||
"restart": "U moet Home Assistant opnieuw starten.",
|
||||
"restart_pending": "Wachten op herstart"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Toevoegen aan Lovelace",
|
||||
"authors": "Auteurs",
|
||||
"available": "Beschikbaar",
|
||||
"back_to": "Terug naar",
|
||||
"changelog": "Changelog",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Vlag dit",
|
||||
"frontend_version": "Frontend versie",
|
||||
"github_stars": "GitHub-sterren",
|
||||
"goto_integrations": "Ga naar integraties",
|
||||
"hide": "Verberg",
|
||||
"hide_beta": "Verberg beta",
|
||||
"install": "Installeer",
|
||||
"installed": "Geinstalleerd",
|
||||
"lovelace_copy_example": "Kopier het voorbeeld naar je klembord",
|
||||
"lovelace_instruction": "Wanneer je dit gaat toevoegen aan je lovelace configuratie gebruik dit",
|
||||
"lovelace_no_js_type": "Kon niet achterhalen welk type plugin dit is, controleer de repository van de plugin.",
|
||||
"newest": "nieuwste",
|
||||
"note_appdaemon": "je moet het nog steeds toevoegen aan je 'apps.yaml' bestand",
|
||||
"note_installed": "Wanneer geïnstalleerd, staat het in",
|
||||
"note_integration": "je moet het nog steeds toevoegen aan je 'configuration.yaml' bestand",
|
||||
"note_plugin": "je moet het nog steeds toevoegen aan je lovelace configuratie ('ui-lovelace.yaml') of raw UI config editor.",
|
||||
"note_plugin_post_107": "je moet het nog steeds toevoegen aan je lovelace configuratie ('configuration.yaml' of de resource editor '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Meld probleem",
|
||||
"open_plugin": "Open plugin",
|
||||
"reinstall": "Herinstalleer",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Start Home Assistant opnieuw",
|
||||
"show_beta": "Laat beta zien",
|
||||
"uninstall": "Verwijder",
|
||||
"update_information": "Update informatie",
|
||||
"upgrade": "Update"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "VOEG EIGEN REPOSITORY TOE",
|
||||
"adding_new_repo": "Nieuwe repository '{repo}' toevoegen",
|
||||
"adding_new_repo_category": "Met categorie '{category}'.",
|
||||
"bg_task_custom": "Aangepaste repositories zijn verborgen terwijl de achtergrondtaken actief zijn.",
|
||||
"category": "Categorie",
|
||||
"compact_mode": "Compacte modus",
|
||||
"custom_repositories": "EIGEN REPOSITORIES",
|
||||
"delete": "Verwijder",
|
||||
"display": "Weergave",
|
||||
"grid": "Rooster",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "verborgen repositories",
|
||||
"missing_category": "Je moet een categorie selecteren.",
|
||||
"open_repository": "Open repository",
|
||||
"reload_data": "Herlaad data",
|
||||
"reload_window": "Herlaad venster",
|
||||
"repository_configuration": "Repository configuratie",
|
||||
"save": "Opslaan",
|
||||
"table": "Tabel",
|
||||
"table_view": "Tabelweergave",
|
||||
"unhide": "zichtbaar maken",
|
||||
"upgrade_all": "Upgrade alles"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "oplopend",
|
||||
"clear_new": "Wissen van alle nieuwe repositories",
|
||||
"descending": "Aflopend",
|
||||
"last_updated": "Laatste update",
|
||||
"name": "Naam",
|
||||
"new_repositories": "Nieuwe Repositories",
|
||||
"pending_upgrades": "Upgrades in afwachting",
|
||||
"placeholder_search": "Typ iets om te zoeken...",
|
||||
"sort": "sorteer",
|
||||
"stars": "Sterren",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "geleden",
|
||||
"day": "dag",
|
||||
"days": "dagen",
|
||||
"hour": "uur",
|
||||
"hours": "uren",
|
||||
"minute": "minuut",
|
||||
"minutes": "minuten",
|
||||
"month": "maand",
|
||||
"months": "maanden",
|
||||
"one": "Eén",
|
||||
"one_day_ago": "een dag geleden",
|
||||
"one_hour_ago": "een uur geleden",
|
||||
"one_minute_ago": "een minuut geleden",
|
||||
"one_month_ago": "een maand geleden",
|
||||
"one_second_ago": "een seconde geleden",
|
||||
"one_year_ago": "een jaar geleden",
|
||||
"second": "seconde",
|
||||
"seconds": "seconden",
|
||||
"x_days_ago": "{x} dagen geleden",
|
||||
"x_hours_ago": "{x} uur geleden",
|
||||
"x_minutes_ago": "{x} minuten geleden",
|
||||
"x_months_ago": "{x} maanden geleden",
|
||||
"x_seconds_ago": "{x} seconden geleden",
|
||||
"x_years_ago": "{x} jaar geleden",
|
||||
"year": "jaar",
|
||||
"years": "jaren"
|
||||
}
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Om",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDeamon-appar",
|
||||
"appdaemon_plural": "AppDaemon-appar",
|
||||
"background_task": "Bakgrunnsoppgåve køyrer. Denne sida kjem til å laste seg omatt når ho er ferdig.",
|
||||
"check_log_file": "Sjå i loggfila di for meir detaljar.",
|
||||
"continue": "Hald fram",
|
||||
"disabled": "Deaktivert",
|
||||
"documentation": "Dokumentasjon",
|
||||
"element": "element",
|
||||
"hacs_is_disabled": "HACS er deaktivert",
|
||||
"installed": "Installert",
|
||||
"integration": "Integrasjon",
|
||||
"integration_plural": "Integrasjonar",
|
||||
"integrations": "Integrasjonar",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Lovelace-element",
|
||||
"lovelace_elements": "Lovelace-element",
|
||||
"manage": "Handtere",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDeamon-appar",
|
||||
"netdaemon_plural": "NetDaemon-appar",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Lovelace-element",
|
||||
"plugins": "Lovelace-element",
|
||||
"python_script": "Pythonskript",
|
||||
"python_script_plural": "Pythonskript",
|
||||
"python_scripts": "Pythonskript",
|
||||
"repositories": "Repositories",
|
||||
"settings": "innstillingar",
|
||||
"theme": "Tema",
|
||||
"theme_plural": "Tema",
|
||||
"themes": "Tema",
|
||||
"version": "Versjon"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Berre éin enkelt konfigurasjon av HACS er tillete."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Personleg tilgangsnøkkel er ikkje korrekt."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver AppDeamon-appar-oppdaging og sporing",
|
||||
"netdaemon": "Aktiver NetDeamon-appar-oppdaging og sporing",
|
||||
"python_script": "Aktiver pythonscript-oppdaging og sporing",
|
||||
"sidepanel_icon": "Sidepanelikon",
|
||||
"sidepanel_title": "Sidepaneltittel",
|
||||
"theme": "Aktiver tema-oppdaging og sporing",
|
||||
"token": "Personleg GitHub tilgangsnøkkel"
|
||||
},
|
||||
"description": "Dersom du treng hjelp med konfigurasjonen, ta ein kik her: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Er du sikker på at du vil legge til dette i Lovelace-ressursane dine?",
|
||||
"bg_task": "Handlinga er deaktivert medan bakgrunnsoppgåveene køyrer.",
|
||||
"cancel": "Avbryt",
|
||||
"continue": "Er du sikker på at du vil halde fram?",
|
||||
"delete": "Er du sikker på at du vil slette '{item}'?",
|
||||
"delete_installed": "'{item}' er installert. Du må avinstallere det før du kan slette det.",
|
||||
"exist": "{item} eksisterer allereie",
|
||||
"generic": "Er du sikker?",
|
||||
"home_assistant_is_restarting": "Vent... Home Assistant starter på nytt no.",
|
||||
"home_assistant_version_not_correct": "Du køyrer Home Assistant-versjonen '{haversion}', men dette kodedepoet krev minst versjon '{minversion}' for å bli installert.",
|
||||
"no": "Nei",
|
||||
"no_upgrades": "Ingen ventande oppgradringer",
|
||||
"ok": "OK",
|
||||
"overwrite": "Ved å gjere dette kjem du til å overskrive.",
|
||||
"reload_data": "Dette laster inn dataa til depota HACS veit om, og dette vil ta litt tid å fullføre.",
|
||||
"restart_home_assistant": "Er du sikker på at du vil starte Home Assistant på nytt?",
|
||||
"uninstall": "Er du sikker på at du vil avinstallere '{item}'?",
|
||||
"upgrade_all": "Dette kjem til å oppgradere alle depota. Ver sikker på at du har lest alle versjonsmerknadene før du held fram.",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Aktiver AppDeamon-appar-oppdaging og sporing",
|
||||
"country": "Filterer med landskode",
|
||||
"debug": "Aktiver debug.",
|
||||
"experimental": "Aktiver ekspreimentelle funksjonar",
|
||||
"netdaemon": "Aktiver NetDeamon-appar-oppdaging og sporing",
|
||||
"not_in_use": "Kan ikkje brukast saman med YAML",
|
||||
"release_limit": "Talet på utgivingar",
|
||||
"sidepanel_icon": "Sidepanelikon",
|
||||
"sidepanel_title": "Sidepaneltittel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Denne integrasjonen støttar config_flow, som betyr at du no kan gå til integrasjonssida i brukargrensesnittet for å konfigurere den.",
|
||||
"config_flow_title": "UI-konfigurasjon støtta",
|
||||
"integration_not_loaded": "Integrasjonen er ikkje lasta inn i Home Assistant.",
|
||||
"no_restart_required": "Ingen omstart kravd",
|
||||
"not_loaded": "Ikkje lasta",
|
||||
"plugin_not_loaded": "Tillegget er ikkje lagt til i Lovelace-ressursane dine.",
|
||||
"restart": "Du må starte Home Assistant på nytt",
|
||||
"restart_pending": "Omstart venter"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Legg til i Lovelace",
|
||||
"authors": "Forfatter(e)",
|
||||
"available": "Tilgjengeleg",
|
||||
"back_to": "Tilbake til",
|
||||
"changelog": "Endre logg",
|
||||
"downloads": "Nedlastinger",
|
||||
"flag_this": "Marker dette",
|
||||
"frontend_version": "Frontend-versjon",
|
||||
"github_stars": "GitHub-stjerner",
|
||||
"goto_integrations": "Gå til integrasjonar",
|
||||
"hide": "Gøym",
|
||||
"hide_beta": "Gøym beta",
|
||||
"install": "Installer",
|
||||
"installed": "Installert",
|
||||
"lovelace_copy_example": "Kopier eksempelet til utklippsbreittet ditt",
|
||||
"lovelace_instruction": "Når du legg til dette i Lovelace-konfigurasjonen din, bruk dette",
|
||||
"lovelace_no_js_type": "Kunne ikkje slå fast typen til dette tilegget. Sjå i repositoryet.",
|
||||
"newest": "nyaste",
|
||||
"note_appdaemon": "du må framleis legge dette til i \"apps.yaml\"-fila di",
|
||||
"note_installed": "Når dette er installert, kjem den til å vere plassert i",
|
||||
"note_integration": "du må framleis legge dette til i \"configuration.yaml\"-fila di",
|
||||
"note_plugin": "du må framleis dette til i Lovelace-konfigurasjonen (\"ui-lovelace.yaml\" eller i rå-brukargrensesnittredigeraren",
|
||||
"note_plugin_post_107": "du må framleis legge dette til i lovelace-konfigurasjonen ('configuration.yaml' eller i kjelderedigeraren ''\/config\/lovelace\/resources')",
|
||||
"open_issue": "Opne problem",
|
||||
"open_plugin": "Opne tillegg",
|
||||
"reinstall": "Installer på nytt",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Start Home Assistant på nytt",
|
||||
"show_beta": "Vis beta",
|
||||
"uninstall": "Avinstaller",
|
||||
"update_information": "Oppdater informasjonen",
|
||||
"upgrade": "Oppdater"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Vis informasjon om HACS",
|
||||
"title": "Om"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Her finn du python_scripts, AppDaemon-appar og NetDaemon-appar",
|
||||
"title": "Automasjon"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Her finn du tema, eigendefinerte kort og andre element for lovelace",
|
||||
"title": "Frontend"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Her finn du eigendefinerte ingtegrasjonar (custom_components)",
|
||||
"title": "Integrasjonar"
|
||||
},
|
||||
"pending_repository_upgrade": "Du køyrer versjon {installed}, og versjon {available} er tilgjengeleg"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "LEGG TIL EIN ANNAN REPOSITORY",
|
||||
"adding_new_repo": "Legger til ny repository '{repo}'",
|
||||
"adding_new_repo_category": "Med kategori '{category}'.",
|
||||
"bg_task_custom": "Custom repositories er skjult medan bakgrunnsoppgaver køyrer.",
|
||||
"category": "Kategori",
|
||||
"compact_mode": "Kompaktmodus",
|
||||
"custom_repositories": "VANLEG REPOSITORY",
|
||||
"delete": "Slett",
|
||||
"display": "Vis",
|
||||
"grid": "rutenett",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "gøymde repositories",
|
||||
"missing_category": "Du må velje éin kategori",
|
||||
"open_repository": "Opne repository",
|
||||
"reload_data": "Last om dataa",
|
||||
"reload_window": "Last inn vindauget på nytt",
|
||||
"repository_configuration": "Repository-konfigurasjon",
|
||||
"save": "Lagre",
|
||||
"table": "Tavle",
|
||||
"table_view": "Tabellvisning",
|
||||
"unhide": "vis",
|
||||
"upgrade_all": "Oppdater alle"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "stigande",
|
||||
"clear_new": "Fjern alle nye repositories",
|
||||
"descending": "synkande",
|
||||
"last_updated": "Sist oppdatert",
|
||||
"name": "Namn",
|
||||
"new_repositories": "Ny repository",
|
||||
"pending_upgrades": "Ventande oppgraderinger",
|
||||
"placeholder_search": "Ver vennleg og skriv inn ei søkefrase",
|
||||
"sort": "Sorter",
|
||||
"stars": "Stjerner",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "sidan",
|
||||
"day": "dag",
|
||||
"days": "dagar",
|
||||
"hour": "time",
|
||||
"hours": "timar",
|
||||
"minute": "minutt",
|
||||
"minutes": "minutt",
|
||||
"month": "månad",
|
||||
"months": "månadar",
|
||||
"one": "Éin",
|
||||
"one_day_ago": "for éin dag sidan",
|
||||
"one_hour_ago": "éin time sidan",
|
||||
"one_minute_ago": "eitt minutt sidan",
|
||||
"one_month_ago": "ein månad sidan",
|
||||
"one_second_ago": "eitt sekund sidan",
|
||||
"one_year_ago": "eitt år sidan",
|
||||
"second": "sekund",
|
||||
"seconds": "sekund",
|
||||
"x_days_ago": "{x} dagar siden",
|
||||
"x_hours_ago": "{x} timer sidan",
|
||||
"x_minutes_ago": "{x} minutt sidan",
|
||||
"x_months_ago": "{x} månadar sidan",
|
||||
"x_seconds_ago": "{x} sekund sidan",
|
||||
"x_years_ago": "{x} år sidan",
|
||||
"year": "år",
|
||||
"years": "år"
|
||||
}
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "O",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Aplikacje AppDaemon",
|
||||
"appdaemon_plural": "Aplikacje AppDaemon",
|
||||
"background_task": "Wykonywanie zadania w tle, ta strona zostanie odświeżona, gdy zadanie zostanie ukończone.",
|
||||
"check_log_file": "Sprawdź plik dziennika, aby uzyskać więcej informacji.",
|
||||
"continue": "Kontynuuj",
|
||||
"disabled": "Wyłączony",
|
||||
"documentation": "Dokumentacja",
|
||||
"hacs_is_disabled": "HACS jest wyłączony",
|
||||
"installed": "zainstalowane",
|
||||
"integration": "Integracja",
|
||||
"integration_plural": "Integracje",
|
||||
"integrations": "Integracje",
|
||||
"lovelace": "Lovelace",
|
||||
"lovelace_element": "Element Lovelace",
|
||||
"lovelace_elements": "Elementy Lovelace",
|
||||
"manage": "zarządzaj",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "Aplikacje NetDaemon",
|
||||
"netdaemon_plural": "Aplikacje NetDaemon",
|
||||
"plugin": "Lovelace",
|
||||
"plugin_plural": "Elementy Lovelace",
|
||||
"plugins": "Elementy Lovelace",
|
||||
"python_script": "Skrypt Python",
|
||||
"python_script_plural": "Skrypty języka Python",
|
||||
"python_scripts": "Skrypty Python",
|
||||
"repositories": "Repozytoria",
|
||||
"settings": "ustawienia",
|
||||
"theme": "Motyw",
|
||||
"theme_plural": "Motywy",
|
||||
"themes": "Motywy",
|
||||
"version": "Wersja"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Dozwolona jest tylko jedna konfiguracja HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Osobisty token dostępu jest nieprawidłowy."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Włącz wykrywanie i śledzenie aplikacji AppDaemon",
|
||||
"netdaemon": "Włącz wykrywanie i śledzenie aplikacji NetDaemon",
|
||||
"python_script": "Włącz wykrywanie i śledzenie skryptów Python",
|
||||
"sidepanel_icon": "Ikona w panelu bocznym",
|
||||
"sidepanel_title": "Tytuł w panelu bocznym",
|
||||
"theme": "Włącz wykrywanie i śledzenie motywów",
|
||||
"token": "Osobisty token dostępu GitHub"
|
||||
},
|
||||
"description": "Jeśli potrzebujesz pomocy w konfiguracji, przejdź na stronę: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Na pewno chcesz dodać to do swoich zasobów Lovelace?",
|
||||
"bg_task": "Akcja jest wyłączona podczas wykonywania zadań w tle.",
|
||||
"cancel": "Anuluj",
|
||||
"continue": "Na pewno chcesz kontynuować?",
|
||||
"delete": "Na pewno chcesz usunąć '{item}'?",
|
||||
"delete_installed": "'{item}' jest zainstalowany, musisz go odinstalować zanim będziesz mógł go usunąć.",
|
||||
"exist": "{item} już istnieje",
|
||||
"generic": "Jesteś pewny?",
|
||||
"home_assistant_is_restarting": "Poczekaj, Home Assistant jest teraz ponownie uruchamiany.",
|
||||
"home_assistant_version_not_correct": "Używasz Home Assistant'a w wersji '{haversion}', a to repozytorium wymaga wersji minimum '{minversion}'.",
|
||||
"no": "Nie",
|
||||
"no_upgrades": "Brak oczekujących aktualizacji",
|
||||
"ok": "Ok",
|
||||
"overwrite": "Spowoduje to zastąpienie istniejącej kopii.",
|
||||
"reload_data": "To przeładowuje dane wszystkich repozytoriów, o których wie HACS, może to trochę potrwać.",
|
||||
"restart_home_assistant": "Na pewno chcesz ponownie uruchomić Home Assistant'a?",
|
||||
"uninstall": "Na pewno chcesz odinstalować '{item}'?",
|
||||
"upgrade_all": "To uaktualni wszystkie te repozytoria, upewnij się, że przeczytałeś uwagi do wydania dla wszystkich z nich przed kontynuacją.",
|
||||
"yes": "Tak"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Włącz wykrywanie i śledzenie aplikacji AppDaemon",
|
||||
"country": "Filtruj według kodu kraju",
|
||||
"debug": "Włącz debugowanie.",
|
||||
"experimental": "Włącz funkcje eksperymentalne",
|
||||
"netdaemon": "Włącz wykrywanie i śledzenie aplikacji NetDaemon",
|
||||
"not_in_use": "Nieużywany z YAML",
|
||||
"release_limit": "Liczba wydań do wyświetlenia",
|
||||
"sidepanel_icon": "Ikona w panelu bocznym",
|
||||
"sidepanel_title": "Tytuł w panelu bocznym"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Ta integracja obsługuje config_flow, co oznacza, że możesz teraz przejść do sekcji integracji w interfejsie użytkownika, aby ją skonfigurować.",
|
||||
"config_flow_title": "Obsługiwana konfiguracja poprzez interfejs użytkownika",
|
||||
"integration_not_loaded": "Ta integracja nie jest załadowana do Home Assistant'a.",
|
||||
"no_restart_required": "Ponowne uruchomienie nie jest wymagane",
|
||||
"not_loaded": "Nie załadowano",
|
||||
"plugin_not_loaded": "Ta wtyczka nie jest dodana do zasobów Lovelace.",
|
||||
"restart": "Musisz ponownie uruchomić Home Assistant'a.",
|
||||
"restart_pending": "Oczekiwanie na ponowne uruchomienie"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Dodaj do Lovelace",
|
||||
"authors": "Autorzy",
|
||||
"available": "Dostępna",
|
||||
"back_to": "Wróć do",
|
||||
"changelog": "Lista zmian",
|
||||
"downloads": "Ilość pobrań",
|
||||
"flag_this": "Oflaguj",
|
||||
"frontend_version": "Wersja frontendu",
|
||||
"github_stars": "Gwiazdki GitHub",
|
||||
"goto_integrations": "Przejdź do integracji",
|
||||
"hide": "Ukryj",
|
||||
"hide_beta": "Ukryj wydania beta",
|
||||
"install": "Zainstaluj",
|
||||
"installed": "Zainstalowano",
|
||||
"lovelace_copy_example": "Skopiuj przykład do schowka",
|
||||
"lovelace_instruction": "Interfejs użytkownika użyje tej wtyczki po dodaniu konfiguracji",
|
||||
"lovelace_no_js_type": "Nie można określić typu tej wtyczki, sprawdź repozytorium.",
|
||||
"newest": "najnowsza",
|
||||
"note_appdaemon": "musisz jeszcze dodać aplikację do pliku 'apps.yaml'",
|
||||
"note_installed": "Po zainstalowaniu dodatek będzie znajdować się w",
|
||||
"note_integration": "musisz jeszcze dodać integrację do pliku 'configuration.yaml'",
|
||||
"note_plugin": "musisz jeszcze dodać wtyczkę do konfiguracji interfejsu użytkownika (plik 'ui-lovelace.yaml' lub edytor interfejsu użytkownika)",
|
||||
"note_plugin_post_107": "nadal musisz dodać go do konfiguracji Lovelace ('configuration.yaml' lub edytora zasobów '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Powiadom o problemie",
|
||||
"open_plugin": "Otwórz element",
|
||||
"reinstall": "Przeinstaluj",
|
||||
"repository": "Repozytorium",
|
||||
"restart_home_assistant": "Uruchom ponownie Home Assistant'a",
|
||||
"show_beta": "Wyświetl wydania beta",
|
||||
"uninstall": "Odinstaluj",
|
||||
"update_information": "Uaktualnij informacje",
|
||||
"upgrade": "Uaktualnij"
|
||||
},
|
||||
"sections": {
|
||||
"about": {
|
||||
"description": "Pokaż informacje o HACS"
|
||||
},
|
||||
"automation": {
|
||||
"description": "Tutaj znajdziesz skrypty Pythona, aplikacje AppDaemon i NetDaemon",
|
||||
"title": "Automatyzacja"
|
||||
},
|
||||
"frontend": {
|
||||
"description": "Tutaj znajdziesz motywy, niestandardowe karty i inne elementy dla Lovelace"
|
||||
},
|
||||
"integrations": {
|
||||
"description": "Tutaj znajdziesz niestandardowe integracje (custom_components)",
|
||||
"title": "Integracje"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "DODAJ REPOZYTORIUM NIESTANDARDOWE",
|
||||
"adding_new_repo": "Dodawanie nowego repozytorium '{repo}'",
|
||||
"adding_new_repo_category": "Z kategorią '{category}'.",
|
||||
"bg_task_custom": "Niestandardowe repozytoria są ukryte podczas wykonywania zadań w tle.",
|
||||
"category": "Kategoria",
|
||||
"compact_mode": "Tryb kompaktowy",
|
||||
"custom_repositories": "REPOZYTORIA NIESTANDARDOWE",
|
||||
"delete": "Usuń",
|
||||
"display": "Sposób wyświetlania",
|
||||
"grid": "Siatka",
|
||||
"hacs_repo": "Repozytorium HACS",
|
||||
"hidden_repositories": "ukryte repozytoria",
|
||||
"missing_category": "Musisz wybrać kategorię",
|
||||
"open_repository": "Otwórz repozytorium",
|
||||
"reload_data": "Wczytaj ponownie dane",
|
||||
"reload_window": "Załaduj ponownie okno",
|
||||
"repository_configuration": "Konfiguracja repozytorium",
|
||||
"save": "Zapisz",
|
||||
"table": "tabela",
|
||||
"table_view": "Widok tabeli",
|
||||
"unhide": "pokaż",
|
||||
"upgrade_all": "Uaktualnij wszystkie"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "rosnąco",
|
||||
"clear_new": "Wyczyść wszystkie nowe repozytoria",
|
||||
"descending": "malejąco",
|
||||
"last_updated": "Ostatnia aktualizacja",
|
||||
"name": "Nazwa",
|
||||
"new_repositories": "Nowe repozytoria",
|
||||
"pending_upgrades": "Oczekujące aktualizacje",
|
||||
"placeholder_search": "Wprowadź wyszukiwane hasło...",
|
||||
"sort": "sortowanie",
|
||||
"stars": "Gwiazdki",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "temu",
|
||||
"day": "dzień",
|
||||
"days": "dni",
|
||||
"hour": "godzina",
|
||||
"hours": "godziny",
|
||||
"minute": "minuta",
|
||||
"minutes": "minuty",
|
||||
"month": "miesiąc",
|
||||
"months": "miesięcy",
|
||||
"one": "Jeden",
|
||||
"one_day_ago": "jeden dzień temu",
|
||||
"one_hour_ago": "jedna godzina temu",
|
||||
"one_minute_ago": "jedna minuta temu",
|
||||
"one_month_ago": "jeden miesiąc temu",
|
||||
"one_second_ago": "jedna sekunda temu",
|
||||
"one_year_ago": "jeden rok temu",
|
||||
"second": "sekunda",
|
||||
"seconds": "sekundy",
|
||||
"x_days_ago": "{x} dni temu",
|
||||
"x_hours_ago": "{x} godzin(y) temu",
|
||||
"x_minutes_ago": "{x} minut(y) temu",
|
||||
"x_months_ago": "{x} miesi(ące\/ęcy) temu",
|
||||
"x_seconds_ago": "{x} sekund(y) temu",
|
||||
"x_years_ago": "{x} lat(a) temu",
|
||||
"year": "rok",
|
||||
"years": "lata"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Sobre",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Apps",
|
||||
"background_task": "Tarefa em segundo plano em execução, esta página será recarregada quando terminar.",
|
||||
"check_log_file": "Verifique seu arquivo de log para obter mais detalhes.",
|
||||
"continue": "Continuar",
|
||||
"disabled": "Desativado",
|
||||
"documentation": "Documentação",
|
||||
"hacs_is_disabled": "HACS está desativado",
|
||||
"installed": "instalado",
|
||||
"integration": "Integração",
|
||||
"integrations": "Integrações",
|
||||
"manage": "gerenciar",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Apps",
|
||||
"plugin": "Plugin",
|
||||
"plugins": "Plugins",
|
||||
"python_script": "Python Script",
|
||||
"python_scripts": "Python Scripts",
|
||||
"repositories": "Repositórios",
|
||||
"settings": "configurações",
|
||||
"theme": "Tema",
|
||||
"themes": "Temas",
|
||||
"version": "Versão"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Apenas uma configuração do HACS é permitida."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Token de acesso pessoal incorreto."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Habilitar AppDaemon apps descoberta & rastreamento",
|
||||
"netdaemon": "Habilitar NetDaemon apps descoberta & rastreamento",
|
||||
"python_script": "Habilitar python_scripts descoberta & rastreamento",
|
||||
"sidepanel_icon": "Icone do painel lateral",
|
||||
"sidepanel_title": "Titulo do painel lateral",
|
||||
"theme": "Habilitar temas descoberta & rastreamento",
|
||||
"token": "GitHub Token de acesso pessoal"
|
||||
},
|
||||
"description": "Se você preciar de ajuda com a configuração olhe aqui: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Tem certeza de que deseja adicionar isso aos seus recursos do Lovelace?",
|
||||
"bg_task": "A ação é desativada enquanto as tarefas de fundo estão sendo executadas.",
|
||||
"cancel": "Cancelar",
|
||||
"continue": "Tem certeza que quer continuar?",
|
||||
"delete": "Tem certeza de que deseja excluir '{item}'?",
|
||||
"delete_installed": "'{item}' está instalado, é necessário desinstalá-lo para poder excluí-lo.",
|
||||
"exist": "{item} já existe",
|
||||
"generic": "Tem certeza?",
|
||||
"home_assistant_is_restarting": "Espere, o Home Assistant está agora a reiniciar.",
|
||||
"home_assistant_version_not_correct": "Você está executando a versão Home Assistant '{haversion}', mas este repositório requer que a versão mínima '{minversion}' esteja instalada.",
|
||||
"no": "Não",
|
||||
"no_upgrades": "Não há atualizações pendentes",
|
||||
"ok": "OK",
|
||||
"overwrite": "Fazer isso irá substituí-lo.",
|
||||
"reload_data": "Isso recarrega os dados de todos os repositórios que o HACS conhece e levará algum tempo para concluir.",
|
||||
"restart_home_assistant": "Tem certeza de que deseja reiniciar o Home Assistant?",
|
||||
"uninstall": "Tem certeza de que deseja desinstalar '{item}'?",
|
||||
"upgrade_all": "Isso atualizará todos esses repositórios, verifique se você leu as notas de versão de todos eles antes de continuar.",
|
||||
"yes": "Sim"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Habilitar AppDaemon apps descoberta & rastreamento",
|
||||
"country": "Filtro pelo código do país.",
|
||||
"debug": "Ative a depuração.",
|
||||
"experimental": "Ativar recursos experimentais",
|
||||
"netdaemon": "Habilitar NetDaemon apps descoberta & rastreamento",
|
||||
"not_in_use": "Não está em uso com o YAML",
|
||||
"release_limit": "Número de lançamentos a serem exibidos.",
|
||||
"sidepanel_icon": "Icone do painel lateral",
|
||||
"sidepanel_title": "Titulo do painel lateral"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Essa integração oferece suporte ao config_flow, o que significa que agora você pode acessar a seção de integração da sua interface do usuário para configurá-lo.",
|
||||
"config_flow_title": "Configuração de interface do usuário suportada",
|
||||
"integration_not_loaded": "Esta integração não é carregada no Home Assistant.",
|
||||
"no_restart_required": "Não é necessário reiniciar",
|
||||
"not_loaded": "Não carregado",
|
||||
"plugin_not_loaded": "Este plugin não foi adicionado aos seus recursos do Lovelace.",
|
||||
"restart": "Você precisa reiniciar o Home Assistant.",
|
||||
"restart_pending": "Reiniciar pendente"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Adicionar a Lovelace",
|
||||
"authors": "Autores",
|
||||
"available": "Disponível",
|
||||
"back_to": "Voltar para",
|
||||
"changelog": "Changelog",
|
||||
"downloads": "Downloads",
|
||||
"flag_this": "Sinalizar isso",
|
||||
"frontend_version": "Versão Frontend",
|
||||
"github_stars": "Estrelas de GitHub",
|
||||
"goto_integrations": "Ir para integrações",
|
||||
"hide": "Esconder",
|
||||
"hide_beta": "Esconder beta",
|
||||
"install": "Instalar",
|
||||
"installed": "Instalado",
|
||||
"lovelace_copy_example": "Copie este exemplo para seu clipboard",
|
||||
"lovelace_instruction": "Quando você adicionar isso à sua configuração do lovelace, use este",
|
||||
"lovelace_no_js_type": "Não foi possível determinar o tipo deste plug-in, verifique o repositório.",
|
||||
"newest": "O mais novo",
|
||||
"note_appdaemon": "Você ainda precisa adicioná-lo ao seu arquivo 'apps.yaml'",
|
||||
"note_installed": "Quando instalado, ele estará localizado em",
|
||||
"note_integration": "Você ainda precisa adicioná-lo ao seu arquivo 'configuration.yaml'",
|
||||
"note_plugin": "você ainda precisará adicioná-lo à sua configuração do lovelace ('ui-lovelace.yaml' ou o editor de configuração da interface do usuário)",
|
||||
"note_plugin_post_107": "você ainda precisará adicioná-lo à sua configuração do lovelace ('configuration.yaml' ou o editor de recursos '\/config \/lovelace\/resources')",
|
||||
"open_issue": "Open issue",
|
||||
"open_plugin": "Plugin aberto",
|
||||
"reinstall": "Reinstalar",
|
||||
"repository": "Repositório",
|
||||
"restart_home_assistant": "Reiniciar Home Assistant",
|
||||
"show_beta": "Mostrar beta",
|
||||
"uninstall": "Desinstalar",
|
||||
"update_information": "Atualizar informação",
|
||||
"upgrade": "Melhorar"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "ADICIONAR REPOSITÓRIO PERSONALIZADO",
|
||||
"adding_new_repo": "Adicionando novo repositório '{repo}'",
|
||||
"adding_new_repo_category": "Com a categoria '{category}'.",
|
||||
"bg_task_custom": "Os repositórios personalizados ficam ocultas enquanto as tarefas de fundo estão em execução.",
|
||||
"category": "Categoria",
|
||||
"compact_mode": "Modo compacto",
|
||||
"custom_repositories": "REPOSITÓRIOS PERSONALIZADOS",
|
||||
"delete": "Deletar",
|
||||
"display": "Display",
|
||||
"grid": "Grade",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "repositórios ocultos",
|
||||
"missing_category": "Você precisa selecionar uma categoria",
|
||||
"open_repository": "Repositório aberto",
|
||||
"reload_data": "Recarregar dados",
|
||||
"reload_window": "Recarregar janela",
|
||||
"repository_configuration": "Configuração do Repositório",
|
||||
"save": "Salvar",
|
||||
"table": "Tabela",
|
||||
"table_view": "Vista de mesa",
|
||||
"unhide": "reexibir",
|
||||
"upgrade_all": "Atualizar tudo"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascendente",
|
||||
"clear_new": "Limpar todos os novos repositórios",
|
||||
"descending": "descendente",
|
||||
"last_updated": "Última atualização",
|
||||
"name": "Nome",
|
||||
"new_repositories": "Novos Repositórios",
|
||||
"pending_upgrades": "Atualizações pendentes",
|
||||
"placeholder_search": "Por favor insira um termo de pesquisa...",
|
||||
"sort": "ordenar",
|
||||
"stars": "Estrelas",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "atrás",
|
||||
"day": "dia",
|
||||
"days": "dias",
|
||||
"hour": "hora",
|
||||
"hours": "horas",
|
||||
"minute": "minuto",
|
||||
"minutes": "minutos",
|
||||
"month": "mês",
|
||||
"months": "meses",
|
||||
"one": "Um",
|
||||
"one_day_ago": "um dia atrás",
|
||||
"one_hour_ago": "uma hora atrás",
|
||||
"one_minute_ago": "um minuto atrás",
|
||||
"one_month_ago": "um mês atrás",
|
||||
"one_second_ago": "um segundo atrás",
|
||||
"one_year_ago": "um ano atrás",
|
||||
"second": "segundo",
|
||||
"seconds": "segundos",
|
||||
"x_days_ago": "{x} dias atrás",
|
||||
"x_hours_ago": "{x} horas atrás",
|
||||
"x_minutes_ago": "{x} minutos atrás",
|
||||
"x_months_ago": "{x} meses atrás",
|
||||
"x_seconds_ago": "{x} segundos atrás",
|
||||
"x_years_ago": "{x} anos atrás",
|
||||
"year": "ano",
|
||||
"years": "anos"
|
||||
}
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Despre",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Aplicații AppDaemon",
|
||||
"background_task": "Activitatea de fundal se execută, această pagină se va reîncărca atunci când este gata.",
|
||||
"check_log_file": "Verificați log-ul pentru mai multe detalii.",
|
||||
"continue": "Continua",
|
||||
"disabled": "Dezactivat",
|
||||
"documentation": "Documentație",
|
||||
"hacs_is_disabled": "HACS este dezactivat",
|
||||
"installed": "instalat",
|
||||
"integration": "Integrare",
|
||||
"integrations": "Integrări",
|
||||
"manage": "administra",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "Aplicații NetDaemon",
|
||||
"plugin": "Plugin",
|
||||
"plugins": "Plugin-uri",
|
||||
"python_script": "Script Python",
|
||||
"python_scripts": "Scripturi Python",
|
||||
"repositories": "Depozite",
|
||||
"settings": "setări",
|
||||
"theme": "Temă",
|
||||
"themes": "Teme",
|
||||
"version": "Versiune"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Doar o singură configurație pentru HACS este permisă."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Token-ul de acces personal nu este corect."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Activați descoperirea și urmărirea aplicațiilor AppDaemon",
|
||||
"netdaemon": "Activați descoperirea și urmărirea aplicațiilor NetDaemon",
|
||||
"python_script": "Activați descoperirea și urmărirea python_scripts",
|
||||
"sidepanel_icon": "Pictogramă Panou lateral",
|
||||
"sidepanel_title": "Titlu panou lateral",
|
||||
"theme": "Activați descoperirea și urmărirea temelor",
|
||||
"token": "Token de acces personal GitHub"
|
||||
},
|
||||
"description": "Dacă aveți nevoie de ajutor pentru configurare, uitați-vă aici: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Ești sigur că vrei să adaugi asta la resursele tale Lovelace?",
|
||||
"bg_task": "Acțiunea este dezactivată în timp ce activitățile de fundal se execută.",
|
||||
"cancel": "Anulare",
|
||||
"continue": "Esti sigur ca vrei sa continui?",
|
||||
"delete": "Sigur doriți să ștergeți '{item}'?",
|
||||
"exist": "{item} există deja",
|
||||
"generic": "Ești sigur?",
|
||||
"home_assistant_is_restarting": "Asteptati, Home Assistant repornește.",
|
||||
"no": "Nu",
|
||||
"no_upgrades": "Nu există actualizări în curs",
|
||||
"ok": "OK",
|
||||
"overwrite": "Făcând acest lucru, îl va suprascrie.",
|
||||
"restart_home_assistant": "Sigur doriți să reporniți Home Assistant?",
|
||||
"uninstall": "Sigur doriți să dezinstalați '{item}'?",
|
||||
"yes": "Da"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Activați descoperirea și urmărirea aplicațiilor AppDaemon",
|
||||
"country": "Filtrează cu codul țării.",
|
||||
"debug": "Activează depanarea.",
|
||||
"experimental": "Activați funcțiile experimentale",
|
||||
"netdaemon": "Activați descoperirea și urmărirea aplicațiilor NetDaemon",
|
||||
"not_in_use": "Nu este utilizat cu YAML",
|
||||
"release_limit": "Număr de versiuni afișate.",
|
||||
"sidepanel_icon": "Pictogramă Panou lateral",
|
||||
"sidepanel_title": "Titlu panou lateral"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"integration_not_loaded": "Această integrare nu este încărcată în Home Assistant.",
|
||||
"no_restart_required": "Nu este necesară repornirea",
|
||||
"not_loaded": "Neîncărcat",
|
||||
"plugin_not_loaded": "Acest plugin nu este adăugat la resursele Lovelace.",
|
||||
"restart": "Trebuie să reporniți Home Assistant.",
|
||||
"restart_pending": "Reporniți în așteptare"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Adăugați la Lovelace",
|
||||
"authors": "Autori",
|
||||
"available": "Disponibil",
|
||||
"back_to": "Înapoi la",
|
||||
"changelog": "Jurnal modificari",
|
||||
"downloads": "Descărcări",
|
||||
"flag_this": "Semnalizează",
|
||||
"frontend_version": "Versiune frontend",
|
||||
"github_stars": "Stele GitHub",
|
||||
"goto_integrations": "Mergi la integrări",
|
||||
"hide": "Ascunde",
|
||||
"hide_beta": "Ascundere beta",
|
||||
"install": "Instalează",
|
||||
"installed": "Instalat",
|
||||
"lovelace_copy_example": "Copiați exemplul în clipboard",
|
||||
"lovelace_instruction": "Când adăugați acest lucru la configurația lovelace, folosiți acest",
|
||||
"lovelace_no_js_type": "Nu s-a putut determina tipul acestui plugin, verificați \"repository\".",
|
||||
"newest": "cele mai noi",
|
||||
"note_appdaemon": "mai trebuie să o adăugați in fișierul „apps.yaml”",
|
||||
"note_installed": "Când este instalat, acesta va fi localizat în",
|
||||
"note_integration": "mai trebuie să o adăugați in fișierul „configuration.yaml”",
|
||||
"note_plugin": "mai trebuie să o adăugați la configurația lovelace ('ui-lovelace.yaml' sau in editorul UI)",
|
||||
"open_issue": "Deschidere problemă",
|
||||
"open_plugin": "Deschide plugin",
|
||||
"reinstall": "Reinstalare",
|
||||
"repository": "Depozit",
|
||||
"restart_home_assistant": "Reporniți Home Assistant",
|
||||
"show_beta": "Afișare beta",
|
||||
"uninstall": "Dezinstalare",
|
||||
"update_information": "Actualizare informație",
|
||||
"upgrade": "Actualizare"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "ADĂUGARE DEPOZIT PERSONALIZAT",
|
||||
"adding_new_repo": "Adăugarea unui depozit nou '{repo}'",
|
||||
"adding_new_repo_category": "Cu categoria '{categoria}'.",
|
||||
"category": "Categorie",
|
||||
"compact_mode": "Modul compact",
|
||||
"custom_repositories": "DEPOZITE PERSONALIZATE",
|
||||
"delete": "Șterge",
|
||||
"display": "Afişeaza",
|
||||
"grid": "Grilă",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "depozite ascunse",
|
||||
"missing_category": "Trebuie să selectați o categorie",
|
||||
"open_repository": "Deschideți depozitul",
|
||||
"reload_data": "Reîncărcați datele",
|
||||
"reload_window": "Reîncărcați fereastra",
|
||||
"repository_configuration": "Configurația depozitului",
|
||||
"save": "Salveaza",
|
||||
"table": "Tabel",
|
||||
"table_view": "Vizualizare tabel",
|
||||
"unhide": "Unhide",
|
||||
"upgrade_all": "Actualizați toate"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "ascendent",
|
||||
"clear_new": "Ștergeți toate depozitele noi",
|
||||
"descending": "descendent",
|
||||
"last_updated": "Ultima actualizare",
|
||||
"name": "Nume",
|
||||
"new_repositories": "Noi depozite",
|
||||
"pending_upgrades": "Actualizări în așteptare",
|
||||
"placeholder_search": "Vă rugăm să introduceți un termen de căutare ...",
|
||||
"sort": "fel",
|
||||
"stars": "Stele",
|
||||
"status": "Starea"
|
||||
},
|
||||
"time": {
|
||||
"ago": "în urmă",
|
||||
"day": "zi",
|
||||
"days": "zi",
|
||||
"hour": "oră",
|
||||
"hours": "ore",
|
||||
"minute": "minut",
|
||||
"minutes": "minute",
|
||||
"month": "lună",
|
||||
"months": "luni",
|
||||
"one": "Unu",
|
||||
"one_day_ago": "acum o zi",
|
||||
"one_hour_ago": "acum o oră",
|
||||
"one_minute_ago": "acum un minut",
|
||||
"one_month_ago": "acum o luna",
|
||||
"one_second_ago": "acum o secunda",
|
||||
"one_year_ago": "acum un an",
|
||||
"second": "al doilea",
|
||||
"seconds": "secunde",
|
||||
"x_days_ago": "{x} zile în urmă",
|
||||
"x_hours_ago": "{x} ore în urmă",
|
||||
"x_minutes_ago": "{x} minute în urmă",
|
||||
"x_months_ago": "{x} luni în urmă",
|
||||
"x_seconds_ago": "{x} secunde în urmă",
|
||||
"x_years_ago": "{x} ani în urmă",
|
||||
"year": "an",
|
||||
"years": "ani"
|
||||
}
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "О проекте",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Приложения AppDaemon",
|
||||
"background_task": "Выполняется фоновая задача, страница перезагрузится по готовности.",
|
||||
"check_log_file": "Проверьте логи для получения более подробной информации.",
|
||||
"continue": "Продолжить",
|
||||
"disabled": "Отключено",
|
||||
"documentation": "Документация",
|
||||
"hacs_is_disabled": "HACS отключен",
|
||||
"installed": "установлено",
|
||||
"integration": "Интеграция",
|
||||
"integrations": "Интеграции",
|
||||
"manage": "управлять",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "Приложения NetDaemon",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Плагины",
|
||||
"python_script": "Скрипт Python",
|
||||
"python_scripts": "Скрипты Python",
|
||||
"repositories": "Репозитории",
|
||||
"settings": "настройки",
|
||||
"theme": "Тема",
|
||||
"themes": "Темы",
|
||||
"version": "Версия"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Разрешена только одна настройка HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Неверный токен персонального доступа."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Включить поиск и отслеживание приложений AppDaemon",
|
||||
"netdaemon": "Включить поиск и отслеживание приложений NetDaemon",
|
||||
"python_script": "Включить поиск и отслеживание скриптов Python",
|
||||
"sidepanel_icon": "Иконка в боковом меню",
|
||||
"sidepanel_title": "Название в боковом меню",
|
||||
"theme": "Включить поиск и отслеживание тем",
|
||||
"token": "Персональный токен доступа GitHub"
|
||||
},
|
||||
"description": "Если вам нужна помощь с настройкой, посмотрите: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Вы уверены, что хотите добавить это в ресурсы Lovelace?",
|
||||
"bg_task": "Действие отключено во время выполнения фоновых задач.",
|
||||
"cancel": "Отмена",
|
||||
"continue": "Вы уверены, что хотите продолжить?",
|
||||
"delete": "Вы уверены, что хотите удалить '{item}'?",
|
||||
"delete_installed": "'{item}' установлен, вам нужно нажать 'Удалить', чтобы удалить его.",
|
||||
"exist": "{item} уже существует.",
|
||||
"generic": "Вы уверены?",
|
||||
"home_assistant_is_restarting": "Подожди, теперь Home Assistant перезагружается.",
|
||||
"no": "Нет",
|
||||
"no_upgrades": "Нет обновлений",
|
||||
"ok": "ОК",
|
||||
"overwrite": "После подтверждения файлы будут перезаписаны.",
|
||||
"reload_data": "Выполняется перезагрузка данных всех репозиториев в HACS, это займет некоторое время.",
|
||||
"restart_home_assistant": "Вы уверены, что хотите перезапустить Home Assistant?",
|
||||
"uninstall": "Вы уверены, что хотите удалить '{item}'?",
|
||||
"yes": "Да"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Включить поиск и отслеживание приложений AppDaemon",
|
||||
"country": "Фильтр по стране.",
|
||||
"debug": "Включить отладку.",
|
||||
"experimental": "Вкл. экспериментальные функции",
|
||||
"netdaemon": "Включить поиск и отслеживание приложений NetDaemon",
|
||||
"not_in_use": "Не используется с YAML",
|
||||
"release_limit": "Число доступных версий.",
|
||||
"sidepanel_icon": "Иконка в боковом меню",
|
||||
"sidepanel_title": "Название в боковом меню"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"integration_not_loaded": "Эта интеграция не загружена в Home Assistant.",
|
||||
"no_restart_required": "Перезагрузка не требуется",
|
||||
"not_loaded": "Не загружено",
|
||||
"plugin_not_loaded": "Этот плагин не добавлен к ресурсам Lovelace.",
|
||||
"restart": "Вам нужно перезапустить Home Assistant.",
|
||||
"restart_pending": "Ожидается перезапуск"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Добавить в Lovelace",
|
||||
"authors": "Авторы",
|
||||
"available": "Доступно",
|
||||
"back_to": "Назад к",
|
||||
"changelog": "Изменения",
|
||||
"downloads": "Загрузки",
|
||||
"flag_this": "Пожаловаться",
|
||||
"frontend_version": "Версия",
|
||||
"github_stars": "Звезды GitHub",
|
||||
"goto_integrations": "Перейти к интеграции",
|
||||
"hide": "Скрыть",
|
||||
"hide_beta": "Скрыть бета",
|
||||
"install": "Установить",
|
||||
"installed": "Установлено",
|
||||
"lovelace_copy_example": "Скопируйте пример в буфер обмена",
|
||||
"lovelace_instruction": "Для добавления в конфигурацию Lovelace, используйте",
|
||||
"lovelace_no_js_type": "Не удалось определить тип этого плагина, проверьте репозиторий.",
|
||||
"newest": "новейшая",
|
||||
"note_appdaemon": "вам всё ещё нужно добавить код для настройки приложения в файл 'apps.yaml'",
|
||||
"note_installed": "После установки, файлы будут расположены в",
|
||||
"note_integration": "вам всё ещё нужно добавить код для настройки интеграции в файл 'configuration.yaml'",
|
||||
"note_plugin": "вам всё ещё нужно добавить код для настройки плагина в конфигурацию Lovelace ('ui-lovelace.yaml')",
|
||||
"open_issue": "Сообщить о проблеме",
|
||||
"open_plugin": "Открыть плагин",
|
||||
"reinstall": "Переустановить",
|
||||
"repository": "Репозиторий",
|
||||
"restart_home_assistant": "Перезагрузка Home Assistant",
|
||||
"show_beta": "Показать бета",
|
||||
"uninstall": "Удалить",
|
||||
"update_information": "Обновить информацию",
|
||||
"upgrade": "Обновить"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "ДОБАВИТЬ СВОЙ РЕПОЗИТОРИЙ",
|
||||
"adding_new_repo": "Добавление нового репозитория '{repo}'",
|
||||
"adding_new_repo_category": "С категорией '{category}'.",
|
||||
"bg_task_custom": "Свои репозитории скрыты во время выполнения фоновых задач.",
|
||||
"category": "Категория",
|
||||
"compact_mode": "Компактный режим",
|
||||
"custom_repositories": "СВОИ РЕПОЗИТОРИИ",
|
||||
"delete": "Удалить",
|
||||
"display": "Вид",
|
||||
"grid": "Сетка",
|
||||
"hacs_repo": "Репозиторий HACS",
|
||||
"hidden_repositories": "Скрытые репозитории",
|
||||
"missing_category": "Вы должны выбрать категорию",
|
||||
"open_repository": "Открыть репозиторий",
|
||||
"reload_data": "Перезагрузить",
|
||||
"reload_window": "Перезагрузить окно",
|
||||
"repository_configuration": "Конфигурация репозитория",
|
||||
"save": "Сохранить",
|
||||
"table": "Таблица",
|
||||
"table_view": "Таблица",
|
||||
"unhide": "Показать",
|
||||
"upgrade_all": "Обновить всё"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "по возрастанию",
|
||||
"clear_new": "Очистить все новые репозитории",
|
||||
"descending": "по убыванию",
|
||||
"last_updated": "Последнее обновление",
|
||||
"name": "Название",
|
||||
"new_repositories": "Новые репозитории",
|
||||
"pending_upgrades": "Ожидается обновление",
|
||||
"placeholder_search": "Пожалуйста, введите условие для поиска...",
|
||||
"sort": "Сортировка",
|
||||
"stars": "Звезды",
|
||||
"status": "Статус"
|
||||
},
|
||||
"time": {
|
||||
"ago": "назад",
|
||||
"day": "день",
|
||||
"days": "дней",
|
||||
"hour": "час",
|
||||
"hours": "часов",
|
||||
"minute": "минута",
|
||||
"minutes": "минут",
|
||||
"month": "месяц",
|
||||
"months": "месяца",
|
||||
"one": "Одна",
|
||||
"one_day_ago": "один день назад",
|
||||
"one_hour_ago": "час назад",
|
||||
"one_minute_ago": "минуту назад",
|
||||
"one_month_ago": "месяц назад",
|
||||
"one_second_ago": "одну секунду назад",
|
||||
"one_year_ago": "один год назад",
|
||||
"second": "секунда",
|
||||
"seconds": "секунд",
|
||||
"x_days_ago": "{x} дней назад",
|
||||
"x_hours_ago": "{x} часов назад",
|
||||
"x_minutes_ago": "{x} минут назад",
|
||||
"x_months_ago": "{x} месяцев назад",
|
||||
"x_seconds_ago": "{x} секунд назад",
|
||||
"x_years_ago": "{x} лет назад",
|
||||
"year": "год",
|
||||
"years": "лет"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "O tem",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon Aplikacije",
|
||||
"background_task": "V ozadju se izvaja naloga, ko se konča, se bo stran osvežila.",
|
||||
"check_log_file": "Za več podrobnosti preverite datoteko dnevnika.",
|
||||
"continue": "Nadaljuj",
|
||||
"disabled": "Onemogočeno",
|
||||
"documentation": "Dokumentacija",
|
||||
"hacs_is_disabled": "HACS je onemogočen",
|
||||
"installed": "Nameščeno",
|
||||
"integration": "Integracija",
|
||||
"integrations": "Integracije",
|
||||
"manage": "upravljanje",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Aplikacije",
|
||||
"plugin": "Vtičnik",
|
||||
"plugins": "Vtičniki",
|
||||
"python_script": "Python skripta",
|
||||
"python_scripts": "Python skripte",
|
||||
"repositories": "Repozitoriji",
|
||||
"settings": "nastavitve",
|
||||
"theme": "Tema",
|
||||
"themes": "Teme",
|
||||
"version": "Različica"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Dovoljena je samo ena konfiguracija HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Osebni dostopni žeton ni pravilen."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Omogoči odkrivanje in sledenje aplikacij AppDaemon",
|
||||
"netdaemon": "Omogoči odkrivanje in sledenje aplikacij NetDaemon",
|
||||
"python_script": "Omogoči odkrivanje in sledenje python_scripts",
|
||||
"sidepanel_icon": "Ikona stranske plošče",
|
||||
"sidepanel_title": "Naslov stranske plošče",
|
||||
"theme": "Omogoči odkrivanje in sledenje tem",
|
||||
"token": "GitHub žeton za osebni dostop"
|
||||
},
|
||||
"description": "Če potrebujete pomoč pri konfiguraciji, poglejte tukaj: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Ali si prepričan, da želiš to dodati med svoje vire Lovelace?",
|
||||
"bg_task": "Dejanje je onemogočeno, medtem ko se izvajajo opravila v ozadju.",
|
||||
"cancel": "Prekliči",
|
||||
"continue": "Ali ste prepričani, da želite nadaljevati?",
|
||||
"delete": "Ali ste prepričani, da želite izbrisati '{item}'?",
|
||||
"delete_installed": "'{item}' je nameščen, pred odstranitvijo ga morate odstraniti.",
|
||||
"exist": "{item} že obstaja",
|
||||
"generic": "Ali si prepričan?",
|
||||
"home_assistant_is_restarting": "Počakaj, Home Assistant se zdaj znova zaganja.",
|
||||
"home_assistant_version_not_correct": "Uporabljate Home Assistant verzije '{haversion}', vendar to skladišče zahteva nameščeno najmanj različico '{minversion}'.",
|
||||
"no": "Ne",
|
||||
"no_upgrades": "Ni nadgradenj",
|
||||
"ok": "V redu",
|
||||
"overwrite": "Če to storite, bo to prepisano.",
|
||||
"reload_data": "Ponovno se naložijo podatki vseh shramb HA, to bo trajalo nekaj časa.",
|
||||
"restart_home_assistant": "Ali ste prepričani, da želite znova zagnati Home Assistant?",
|
||||
"uninstall": "Ali ste prepričani, da želite odstraniti '{item}'?",
|
||||
"upgrade_all": "To bo nadgradil vse te repozitorije, preden nadaljujete poskrbite, da ste prebrali vse opombe ob izdaji.",
|
||||
"yes": "Da"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Omogoči odkrivanje in sledenje aplikacij AppDaemon",
|
||||
"country": "Filtrirajte s kodo države.",
|
||||
"debug": "Omogoči odpravljanje napak.",
|
||||
"experimental": "Omogočite poskusne funkcije",
|
||||
"netdaemon": "Omogoči odkrivanje in sledenje aplikacij NetDaemon",
|
||||
"not_in_use": "Ni v uporabi z YAML",
|
||||
"release_limit": "Število izdaj, ki jih želite prikazati.",
|
||||
"sidepanel_icon": "Ikona stranske plošče",
|
||||
"sidepanel_title": "Naslov stranske plošče"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Ta integracija podpira config_flow, kar pomeni, da lahko zdaj greste na odsek integracije vašega uporabniškega vmesnika, da ga konfigurirate.",
|
||||
"config_flow_title": "Konfiguracija uporabniškega vmesnika je podprta",
|
||||
"integration_not_loaded": "Ta integracija ni naložena v programu Home Assistant.",
|
||||
"no_restart_required": "Ponovni zagon ni potreben",
|
||||
"not_loaded": "Ni naloženo",
|
||||
"plugin_not_loaded": "Ta vtičnik ni dodan vašim virom Lovelace.",
|
||||
"restart": "Znova morate zagnati Home Assistant.",
|
||||
"restart_pending": "Vnovični zagon v čakanju"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Dodaj v Lovelace",
|
||||
"authors": "Avtorji",
|
||||
"available": "Na voljo",
|
||||
"back_to": "Nazaj na",
|
||||
"changelog": "Dnevnik sprememb",
|
||||
"downloads": "Prenosi",
|
||||
"flag_this": "Označite to",
|
||||
"frontend_version": "Frontend različica",
|
||||
"github_stars": "GitHub zvezde",
|
||||
"goto_integrations": "Pojdite na integracije",
|
||||
"hide": "Skrij",
|
||||
"hide_beta": "Skrij različico beta",
|
||||
"install": "Namestite",
|
||||
"installed": "Nameščeno",
|
||||
"lovelace_copy_example": "Kopirajte primer v odložišče",
|
||||
"lovelace_instruction": "Ko ga boste dodajali v svojo lovelace konfiguracijo uporabite to:",
|
||||
"lovelace_no_js_type": "Ni bilo mogoče določiti vrsto tega vtičnika, preverite repozitorij.",
|
||||
"newest": "najnovejše",
|
||||
"note_appdaemon": "Še vedno ga morate dodati v svojo 'apps.yaml' datoteko",
|
||||
"note_installed": "Ko bo nameščen, se bo nahajal v",
|
||||
"note_integration": "Še vedno ga morate dodati v svojo 'configuration.yaml' datoteko",
|
||||
"note_plugin": "vendar ga še vedno morate dodati v svojo lovelace konfiguracijo ('ui-lovelace.yaml' ali \"raw\" UI config urejevalnik)",
|
||||
"note_plugin_post_107": "še vedno ga morate dodati v svojo konfiguracijo lovelace ('config.yaml' ali urejevalnik virov '\/config\/lovelace\/resources')",
|
||||
"open_issue": "Odprite težavo",
|
||||
"open_plugin": "Odprite vtičnik",
|
||||
"reinstall": "Znova namestite",
|
||||
"repository": "Repozitorij",
|
||||
"restart_home_assistant": "Znova zaženite Home Assistant",
|
||||
"show_beta": "Pokaži različico beta",
|
||||
"uninstall": "Odstranite",
|
||||
"update_information": "Posodobite podatke",
|
||||
"upgrade": "Nadgradnja"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "DODAJTE SVOJ REPOZITORIJ",
|
||||
"adding_new_repo": "Dodajanje novega repozitorija '{repo}'",
|
||||
"adding_new_repo_category": "S kategorijo '{category}'.",
|
||||
"bg_task_custom": "Med izvajanjem nalog v ozadju so repozitoriji po meri skriti.",
|
||||
"category": "Kategorija",
|
||||
"compact_mode": "Kompaktni način",
|
||||
"custom_repositories": "VAŠI REPOZITORIJI",
|
||||
"delete": "Izbriši",
|
||||
"display": "Prikaz",
|
||||
"grid": "Mreža",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "skriti repozitoriji",
|
||||
"missing_category": "Izbrati moraš kategorijo",
|
||||
"open_repository": "Odprite skladišče",
|
||||
"reload_data": "Ponovno naloži podatke",
|
||||
"reload_window": "Ponovno naloži okno",
|
||||
"repository_configuration": "Konfiguracija skladišč",
|
||||
"save": "Shranite",
|
||||
"table": "Tabela",
|
||||
"table_view": "Pogled tabele",
|
||||
"unhide": "Razkrij",
|
||||
"upgrade_all": "Nadgradite vse"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "naraščajoče",
|
||||
"clear_new": "Počisti vse nove repozitorije",
|
||||
"descending": "padajoče",
|
||||
"last_updated": "Nazadnje posodobljeno",
|
||||
"name": "Ime",
|
||||
"new_repositories": "Novi repozitoriji",
|
||||
"pending_upgrades": "Nadgradnje na čakanju",
|
||||
"placeholder_search": "Prosim vnesite iskalni izraz ...",
|
||||
"sort": "razvrsti",
|
||||
"stars": "Zvezd",
|
||||
"status": "Stanje"
|
||||
},
|
||||
"time": {
|
||||
"ago": "nazaj",
|
||||
"day": "dan",
|
||||
"days": "Dni",
|
||||
"hour": "ura",
|
||||
"hours": "Ur",
|
||||
"minute": "minuta",
|
||||
"minutes": "minut",
|
||||
"month": "mesec",
|
||||
"months": "mesecev",
|
||||
"one": "Eno",
|
||||
"one_day_ago": "pred enim dnevom",
|
||||
"one_hour_ago": "pred eno uro",
|
||||
"one_minute_ago": "pred eno minuto",
|
||||
"one_month_ago": "pred enim mesecem",
|
||||
"one_second_ago": "pred sekundo",
|
||||
"one_year_ago": "pred enim letom",
|
||||
"second": "drugič",
|
||||
"seconds": "sekund",
|
||||
"x_days_ago": "{x} dni nazaj",
|
||||
"x_hours_ago": "{x} ur nazaj",
|
||||
"x_minutes_ago": "{x} minut nazaj",
|
||||
"x_months_ago": "{x} mesecev nazaj",
|
||||
"x_seconds_ago": "{x} sekund nazaj",
|
||||
"x_years_ago": "{x} let nazaj",
|
||||
"year": "leto",
|
||||
"years": "Let"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "Om",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "Appdaemon Applikationer",
|
||||
"background_task": "Bakgrundsjobb körs, denna sida kommer att laddas igen när det är klart.",
|
||||
"check_log_file": "Kontrollera din loggfil för mer information.",
|
||||
"continue": "Fortsätta",
|
||||
"disabled": "Inaktiverad",
|
||||
"documentation": "Dokumentation",
|
||||
"hacs_is_disabled": "HACS är inaktiverat",
|
||||
"installed": "installerad",
|
||||
"integration": "Integration",
|
||||
"integrations": "Integrationer",
|
||||
"manage": "hantera",
|
||||
"netdaemon": "NetDaemon",
|
||||
"netdaemon_apps": "NetDaemon Applikationer",
|
||||
"plugin": "Lovelace",
|
||||
"plugins": "Plugins",
|
||||
"python_script": "Python skript",
|
||||
"python_scripts": "Python skript",
|
||||
"repositories": "Repositories",
|
||||
"settings": "inställningar",
|
||||
"theme": "Tema",
|
||||
"themes": "Teman",
|
||||
"version": "Version"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Endast en konfiguration kan användas i HACS."
|
||||
},
|
||||
"error": {
|
||||
"auth": "Personal Access Token är inte korrekt."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Upptäck och följ Appdaemon applikationer",
|
||||
"netdaemon": "Upptäck och följ NetDaemon applikationer",
|
||||
"python_script": "Upptäck och följ python_scripts",
|
||||
"sidepanel_icon": "Ikon för sidpanel",
|
||||
"sidepanel_title": "Rubrik för sidpanel",
|
||||
"theme": "Upptäck och följ teman",
|
||||
"token": "GitHub Personal Access Token"
|
||||
},
|
||||
"description": "Om du behöver hjälp med konfigurationen, se här: https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "Är du säker på att du vill lägga till detta till dina Lovelace-resurser?",
|
||||
"bg_task": "Åtgärden är inaktiverad medan aktiviteter i bakgrunden körs",
|
||||
"cancel": "Avbryt",
|
||||
"continue": "Är du säker på att du vill fortsätta?",
|
||||
"delete": "Är du säker på att du vill ta bort '{item}'?",
|
||||
"delete_installed": "'{item}' är installerat, du måste avinstallera det innan du kan ta bort det.",
|
||||
"exist": "{item} existerar redan",
|
||||
"generic": "Är du säker?",
|
||||
"home_assistant_is_restarting": "Vänta, Home Assistant startar nu om.",
|
||||
"home_assistant_version_not_correct": "Du kör Home Assistant-versionen '{haversion}', men detta repository kräver att lägsta versionen '{minversion}' måste installeras.",
|
||||
"no": "Nej",
|
||||
"no_upgrades": "Inga uppgraderingar väntar",
|
||||
"ok": "OK",
|
||||
"overwrite": "Detta kommer att skriva över den.",
|
||||
"reload_data": "Detta laddar om data för alla repositories HACS vet om, kommer detta att ta lite tid att slutföra.",
|
||||
"restart_home_assistant": "Är du säker på att du vill starta om Home Assistant?",
|
||||
"uninstall": "Är du säker på att du vill avinstallera '{item}'?",
|
||||
"upgrade_all": "Detta kommer uppgradera alla dessa repositories, säkerhetsställ att du läst release anteckningarna för dem alla innan du fortsätter",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "Upptäck och följ Appdaemon applikationer",
|
||||
"country": "Filtrera på landskod.",
|
||||
"debug": "Aktivera felsökning",
|
||||
"experimental": "Använd experimentella funktioner",
|
||||
"netdaemon": "Upptäck och följ NetDaemon applikationer",
|
||||
"not_in_use": "Används inte med YAML",
|
||||
"release_limit": "Antalet releaser som visas.",
|
||||
"sidepanel_icon": "Ikon för sidpanel",
|
||||
"sidepanel_title": "Rubrik för sidpanel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "Den här integreringen stöder config_flow, det innebär att du nu kan gå till integrationsdelen i användargränssnittet för att konfigurera det.",
|
||||
"config_flow_title": "UI-konfiguration stöds",
|
||||
"integration_not_loaded": "Denna integration inte laddats i Hem Assistent.",
|
||||
"no_restart_required": "Ingen omstart krävs",
|
||||
"not_loaded": "Ej laddad",
|
||||
"plugin_not_loaded": "Detta plugin är inte tillagt till din Lovelaceresurs.",
|
||||
"restart": "Du måste starta om Home Assistant.",
|
||||
"restart_pending": "Omstart väntar"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "Lägg till i Lovelace",
|
||||
"authors": "Författare",
|
||||
"available": "Tillgänglig",
|
||||
"back_to": "Tillbaka till",
|
||||
"changelog": "Ändringslogg",
|
||||
"downloads": "Nedladdningar",
|
||||
"flag_this": "Flagga denna",
|
||||
"frontend_version": "Frontend-version",
|
||||
"github_stars": "GitHub stjärnor",
|
||||
"goto_integrations": "Gå till integrationer",
|
||||
"hide": "Göm",
|
||||
"hide_beta": "Göm betaversioner",
|
||||
"install": "Installera",
|
||||
"installed": "Installerad",
|
||||
"lovelace_copy_example": "Kopiera exemplet till urklipp",
|
||||
"lovelace_instruction": "När du lägger till denna till din lovelace konfiguration, använd",
|
||||
"lovelace_no_js_type": "Kan inte avgöra villken typ av plugin, kontrollera i GIT \nrepository",
|
||||
"newest": "nyaste",
|
||||
"note_appdaemon": "du behöver fortfarande lägga till den till filen 'apps.yaml'",
|
||||
"note_installed": "När den är installerad kommer den finnas i",
|
||||
"note_integration": "du behöver fortfarande lägga den till filen 'configuration.yaml'",
|
||||
"note_plugin": "du behöver fortfarande lägga till den till din lovelace konfiguration ('ui-lovelace.yaml' eller raw UI config redigerare)",
|
||||
"note_plugin_post_107": "du behöver fortfarande lägga till den i din lovelace-konfiguration ('configuration.yaml' eller resursredigeraren \/config\/lovelace\/resources')",
|
||||
"open_issue": "Rapportera problem",
|
||||
"open_plugin": "Öppna plugin",
|
||||
"reinstall": "Ominstallera",
|
||||
"repository": "Repository",
|
||||
"restart_home_assistant": "Starta om Home Assistant",
|
||||
"show_beta": "Visa betaversioner",
|
||||
"uninstall": "Avinstallera",
|
||||
"update_information": "Uppdatera information",
|
||||
"upgrade": "Uppdatera"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "LÄGG TILL ETT REPOSITORY",
|
||||
"adding_new_repo": "Lägger till nytt repository '{repo}'",
|
||||
"adding_new_repo_category": "Med kategori '{kategori}'.",
|
||||
"bg_task_custom": "Anpassade repositories är dolda under tiden aktiviteter i bakgrunden körs",
|
||||
"category": "Kategori",
|
||||
"compact_mode": "Kompakt läge",
|
||||
"custom_repositories": "REPOSITORIES",
|
||||
"delete": "Ta bort",
|
||||
"display": "Visa",
|
||||
"grid": "Rutnät",
|
||||
"hacs_repo": "HACS repo",
|
||||
"hidden_repositories": "dolda förråd",
|
||||
"missing_category": "Du behöver välja en kategori",
|
||||
"open_repository": "Öppna Repository",
|
||||
"reload_data": "Ladda om data",
|
||||
"reload_window": "Ladda om fönstret",
|
||||
"repository_configuration": "Konfiguration av repository",
|
||||
"save": "Spara",
|
||||
"table": "Tabell",
|
||||
"table_view": "Tabellvy",
|
||||
"unhide": "ta fram",
|
||||
"upgrade_all": "Uppgradera alla"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "stigande",
|
||||
"clear_new": "Rensa alla nya förvar",
|
||||
"descending": "fallande",
|
||||
"last_updated": "Senast uppdaterad",
|
||||
"name": "Namn",
|
||||
"new_repositories": "Nya förvar",
|
||||
"pending_upgrades": "Väntande uppgraderingar",
|
||||
"placeholder_search": "Skriv ett sökord...",
|
||||
"sort": "sortera",
|
||||
"stars": "Stjärnor",
|
||||
"status": "Status"
|
||||
},
|
||||
"time": {
|
||||
"ago": "sedan",
|
||||
"day": "dag",
|
||||
"days": "dagar",
|
||||
"hour": "timme",
|
||||
"hours": "timmar",
|
||||
"minute": "minut",
|
||||
"minutes": "minuter",
|
||||
"month": "månad",
|
||||
"months": "månader",
|
||||
"one": "Ett",
|
||||
"one_day_ago": "för en dag sedan",
|
||||
"one_hour_ago": "för en timme sedan",
|
||||
"one_minute_ago": "en minut sedan",
|
||||
"one_month_ago": "en månad sedan",
|
||||
"one_second_ago": "för en sekund sedan",
|
||||
"one_year_ago": "ett år sedan",
|
||||
"second": "andra",
|
||||
"seconds": "sekunder",
|
||||
"x_days_ago": "{x} dagar sedan",
|
||||
"x_hours_ago": "{x} timmar sedan",
|
||||
"x_minutes_ago": "{x} minuter sedan",
|
||||
"x_months_ago": "{x} månader sedan",
|
||||
"x_seconds_ago": "{x} sekunder sedan",
|
||||
"x_years_ago": "{x} år sedan",
|
||||
"year": "år",
|
||||
"years": "år"
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{
|
||||
"common": {
|
||||
"about": "关于",
|
||||
"appdaemon": "AppDaemon",
|
||||
"appdaemon_apps": "AppDaemon应用",
|
||||
"background_task": "后台任务正在运行,完成后将重新加载此页面。",
|
||||
"check_log_file": "请查看日志文件以了解更多信息。",
|
||||
"continue": "继续",
|
||||
"disabled": "禁用",
|
||||
"documentation": "文档",
|
||||
"hacs_is_disabled": "HACS已禁用",
|
||||
"installed": "已安装",
|
||||
"integration": "自定义组件",
|
||||
"integrations": "自定义组件",
|
||||
"manage": "管理",
|
||||
"netdaemon": "NetDaemon应用",
|
||||
"netdaemon_apps": "NetDaemon应用",
|
||||
"plugin": "Lovelace插件",
|
||||
"plugins": "Lovelace插件",
|
||||
"python_script": "Python脚本",
|
||||
"python_scripts": "Python脚本",
|
||||
"repositories": "仓库数量",
|
||||
"settings": "设置",
|
||||
"theme": "主题",
|
||||
"themes": "主题",
|
||||
"version": "版本"
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "仅允许单个HACS配置。"
|
||||
},
|
||||
"error": {
|
||||
"auth": "个人访问令牌不正确。"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "启用AppDaemon应用发现和跟踪",
|
||||
"netdaemon": "启用NetDaemon应用发现和跟踪",
|
||||
"python_script": "启用python_scripts发现和跟踪",
|
||||
"sidepanel_icon": "侧面板图标",
|
||||
"sidepanel_title": "侧面板标题",
|
||||
"theme": "启用主题发现和跟踪",
|
||||
"token": "GitHub个人访问令牌"
|
||||
},
|
||||
"description": "如果您需要有关配置的帮助,请在此处查看:https:\/\/hacs.xyz\/docs\/configuration\/start",
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
}
|
||||
},
|
||||
"title": "HACS (Home Assistant Community Store)"
|
||||
},
|
||||
"confirm": {
|
||||
"add_to_lovelace": "您确定要将此添加到Lovelace资源中吗?",
|
||||
"bg_task": "后台任务正在运行时,操作被禁用。",
|
||||
"cancel": "取消",
|
||||
"continue": "你确定你要继续吗?",
|
||||
"delete": "是否确实要删除\"{item}\"?",
|
||||
"delete_installed": "已安装 '{item}',需要先将其卸载,然后才能将其删除。",
|
||||
"exist": "{item}已经存在",
|
||||
"generic": "你确定吗?",
|
||||
"home_assistant_is_restarting": "请等待,Home Assistant现在正在重新启动。",
|
||||
"home_assistant_version_not_correct": "您正在运行Home Assistant的版本为'{haversion}',但是这个需要安装最低版本是'{minversion}'。",
|
||||
"no": "取消",
|
||||
"no_upgrades": "暂无升级",
|
||||
"ok": "确定",
|
||||
"overwrite": "这样做会覆盖它。",
|
||||
"reload_data": "这将重新加载HACS知道的所有仓库的数据,这需要一些时间才能完成。",
|
||||
"restart_home_assistant": "您确定要重新启动Home Assistant吗?",
|
||||
"uninstall": "您确定要卸载 '{item}' 吗?",
|
||||
"upgrade_all": "这将升级所有这些仓库,请确保在继续之前已阅读所有仓库的发行说明。",
|
||||
"yes": "确定"
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"appdaemon": "启用AppDaemon应用发现和跟踪",
|
||||
"country": "用国家代码过滤。",
|
||||
"debug": "启用调试。",
|
||||
"experimental": "启用实验功能",
|
||||
"netdaemon": "启用NetDaemon应用发现和跟踪",
|
||||
"not_in_use": "不适用于 YAML",
|
||||
"release_limit": "要显示的发行数量。",
|
||||
"sidepanel_icon": "侧面板图标",
|
||||
"sidepanel_title": "侧面板标题"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository_banner": {
|
||||
"config_flow": "此组件支持config_flow,这意味着您现在可以转到UI的“集成”部分进行配置。",
|
||||
"config_flow_title": "支持UI配置",
|
||||
"integration_not_loaded": "此集成未加载到Home Assistant中。",
|
||||
"no_restart_required": "无需重启",
|
||||
"not_loaded": "未加载",
|
||||
"plugin_not_loaded": "该插件未添加到您的Lovelace资源中。",
|
||||
"restart": "您需要重新启动Home Assistant。",
|
||||
"restart_pending": "重新启动待处理"
|
||||
},
|
||||
"repository": {
|
||||
"add_to_lovelace": "添加到Lovelace",
|
||||
"authors": "作者",
|
||||
"available": "版本号",
|
||||
"back_to": "返回",
|
||||
"changelog": "更新日志",
|
||||
"downloads": "下载",
|
||||
"flag_this": "标记",
|
||||
"frontend_version": "前端版本",
|
||||
"github_stars": "GitHub星级",
|
||||
"goto_integrations": "转到组件",
|
||||
"hide": "隐藏",
|
||||
"hide_beta": "隐藏测试版",
|
||||
"install": "安装",
|
||||
"installed": "已安装版本",
|
||||
"lovelace_copy_example": "复制样例代码到你的剪贴板",
|
||||
"lovelace_instruction": "您仍然需要将下列代码添加到lovelace配置中(“ ui-lovelace.yaml”或原始配置编辑器):",
|
||||
"lovelace_no_js_type": "无法确定此插件的类型,请检查仓库。",
|
||||
"newest": "最新",
|
||||
"note_appdaemon": "您仍然需要将其添加到“ apps.yaml”文件中",
|
||||
"note_installed": "安装后,它将位于",
|
||||
"note_integration": "您仍然需要将其添加到“ configuration.yaml”文件中",
|
||||
"note_plugin": "您仍然需要将其添加到lovelace配置中(“ ui-lovelace.yaml”或原始配置编辑器)ui-lovelace.yaml",
|
||||
"note_plugin_post_107": "您仍然需要将其添加到lovelace配置中(“ configuration.yaml”或资源编辑器“\/config\/lovelace\/resources”)",
|
||||
"open_issue": "提交问题",
|
||||
"open_plugin": "打开插件",
|
||||
"reinstall": "重新安装",
|
||||
"repository": "仓库",
|
||||
"restart_home_assistant": "重新启动Home Assistant",
|
||||
"show_beta": "显示测试版",
|
||||
"uninstall": "卸载",
|
||||
"update_information": "更新信息",
|
||||
"upgrade": "升级"
|
||||
},
|
||||
"settings": {
|
||||
"add_custom_repository": "添加自定义仓库",
|
||||
"adding_new_repo": "添加新的仓库 '{repo}'",
|
||||
"adding_new_repo_category": "类别为 '{category}'。",
|
||||
"bg_task_custom": "自定义仓库在后台任务运行时被隐藏。",
|
||||
"category": "类别",
|
||||
"compact_mode": "紧凑模式",
|
||||
"custom_repositories": "自定义仓库",
|
||||
"delete": "删除",
|
||||
"display": "视图方式",
|
||||
"grid": "网格",
|
||||
"hacs_repo": "HACS仓库",
|
||||
"hidden_repositories": "隐藏的仓库",
|
||||
"missing_category": "您需要选择一个类别",
|
||||
"open_repository": "打开仓库",
|
||||
"reload_data": "重载数据",
|
||||
"reload_window": "重新加载窗口",
|
||||
"repository_configuration": "仓库数据配置",
|
||||
"save": "保存",
|
||||
"table": "列表",
|
||||
"table_view": "表视图",
|
||||
"unhide": "取消隐藏",
|
||||
"upgrade_all": "升级全部"
|
||||
},
|
||||
"store": {
|
||||
"ascending": "升序",
|
||||
"clear_new": "清除所有新仓库标记",
|
||||
"descending": "降序",
|
||||
"last_updated": "最近更新时间",
|
||||
"name": "名称",
|
||||
"new_repositories": "新仓库",
|
||||
"pending_upgrades": "待升级",
|
||||
"placeholder_search": "搜索项目...",
|
||||
"sort": "排序",
|
||||
"stars": "星级",
|
||||
"status": "状态"
|
||||
},
|
||||
"time": {
|
||||
"ago": "过去",
|
||||
"day": "天",
|
||||
"days": "天",
|
||||
"hour": "小时",
|
||||
"hours": "小时",
|
||||
"minute": "分",
|
||||
"minutes": "分",
|
||||
"month": "月",
|
||||
"months": "月",
|
||||
"one": "一",
|
||||
"one_day_ago": "一天前",
|
||||
"one_hour_ago": "一个小时之前",
|
||||
"one_minute_ago": "一分钟前",
|
||||
"one_month_ago": "一个月前",
|
||||
"one_second_ago": "一秒钟前",
|
||||
"one_year_ago": "一年前",
|
||||
"second": "秒",
|
||||
"seconds": "秒",
|
||||
"x_days_ago": "{x}天前",
|
||||
"x_hours_ago": "{x}小时前",
|
||||
"x_minutes_ago": "{x}分钟前",
|
||||
"x_months_ago": "{x}个月前",
|
||||
"x_seconds_ago": "{x}秒前",
|
||||
"x_years_ago": "{x}年前",
|
||||
"year": "年",
|
||||
"years": "年"
|
||||
}
|
||||
}
|
|
@ -1,231 +0,0 @@
|
|||
"""
|
||||
Custom element manager for community created elements.
|
||||
|
||||
For more details about this integration, please refer to the documentation at
|
||||
https://hacs.xyz/
|
||||
"""
|
||||
|
||||
import voluptuous as vol
|
||||
from aiogithubapi import GitHub, AIOGitHubAPIException
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.const import __version__ as HAVERSION
|
||||
from homeassistant.components.lovelace import system_health_info
|
||||
from homeassistant.exceptions import ConfigEntryNotReady, ServiceNotFound
|
||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from custom_components.hacs.configuration_schema import hacs_config_combined, FRONTEND_REPO, FRONTEND_REPO_URL
|
||||
from custom_components.hacs.const import DOMAIN, ELEMENT_TYPES, STARTUP, VERSION
|
||||
from custom_components.hacs.constrains import check_constrains
|
||||
from custom_components.hacs.helpers.remaining_github_calls import get_fetch_updates_for
|
||||
from custom_components.hacs.hacsbase.configuration import Configuration
|
||||
from custom_components.hacs.hacsbase.data import HacsData
|
||||
from custom_components.hacs.setup import (
|
||||
clear_storage,
|
||||
add_sensor,
|
||||
load_hacs_repository,
|
||||
setup_frontend,
|
||||
)
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
|
||||
from custom_components.hacs.helpers.network import internet_connectivity_check
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({DOMAIN: hacs_config_combined()}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up this integration using yaml."""
|
||||
hacs = get_hacs()
|
||||
if DOMAIN not in config:
|
||||
return True
|
||||
if hacs.configuration and hacs.configuration.config_type == "flow":
|
||||
return True
|
||||
|
||||
configuration = config[DOMAIN]
|
||||
|
||||
if configuration.get(FRONTEND_REPO) and configuration.get(FRONTEND_REPO_URL):
|
||||
hacs.logger.critical("Could not setup HACS, set only one of ('frontend_repo', 'frontend_repo_url)")
|
||||
|
||||
return False
|
||||
|
||||
hass.data[DOMAIN] = config
|
||||
hacs.hass = hass
|
||||
hacs.session = async_create_clientsession(hass)
|
||||
hacs.configuration = Configuration.from_dict(configuration)
|
||||
hacs.configuration.config = config
|
||||
hacs.configuration.config_type = "yaml"
|
||||
await startup_wrapper_for_yaml()
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry):
|
||||
"""Set up this integration using UI."""
|
||||
hacs = get_hacs()
|
||||
conf = hass.data.get(DOMAIN)
|
||||
if conf is not None:
|
||||
return False
|
||||
if config_entry.source == config_entries.SOURCE_IMPORT:
|
||||
hass.async_create_task(hass.config_entries.async_remove(config_entry.entry_id))
|
||||
return False
|
||||
hacs.hass = hass
|
||||
hacs.session = async_create_clientsession(hass)
|
||||
hacs.configuration = Configuration.from_dict(
|
||||
config_entry.data, config_entry.options
|
||||
)
|
||||
hacs.configuration.config_type = "flow"
|
||||
hacs.configuration.config_entry = config_entry
|
||||
config_entry.add_update_listener(reload_hacs)
|
||||
try:
|
||||
startup_result = await hacs_startup()
|
||||
except AIOGitHubAPIException:
|
||||
startup_result = False
|
||||
if not startup_result:
|
||||
hacs.system.disabled = True
|
||||
raise ConfigEntryNotReady
|
||||
hacs.system.disabled = False
|
||||
return startup_result
|
||||
|
||||
|
||||
async def startup_wrapper_for_yaml():
|
||||
"""Startup wrapper for yaml config."""
|
||||
hacs = get_hacs()
|
||||
try:
|
||||
startup_result = await hacs_startup()
|
||||
except AIOGitHubAPIException:
|
||||
startup_result = False
|
||||
if not startup_result:
|
||||
hacs.system.disabled = True
|
||||
hacs.hass.components.frontend.async_remove_panel(
|
||||
hacs.configuration.sidepanel_title.lower()
|
||||
.replace(" ", "_")
|
||||
.replace("-", "_")
|
||||
)
|
||||
hacs.logger.info("Could not setup HACS, trying again in 15 min")
|
||||
async_call_later(hacs.hass, 900, startup_wrapper_for_yaml())
|
||||
return
|
||||
hacs.system.disabled = False
|
||||
|
||||
|
||||
async def hacs_startup():
|
||||
"""HACS startup tasks."""
|
||||
hacs = get_hacs()
|
||||
|
||||
if hacs.configuration.debug:
|
||||
try:
|
||||
await hacs.hass.services.async_call(
|
||||
"logger", "set_level", {"hacs": "debug"}
|
||||
)
|
||||
await hacs.hass.services.async_call(
|
||||
"logger", "set_level", {"queueman": "debug"}
|
||||
)
|
||||
await hacs.hass.services.async_call(
|
||||
"logger", "set_level", {"AioGitHub": "debug"}
|
||||
)
|
||||
except ServiceNotFound:
|
||||
hacs.logger.error(
|
||||
"Could not set logging level to debug, logger is not enabled"
|
||||
)
|
||||
|
||||
lovelace_info = await system_health_info(hacs.hass)
|
||||
hacs.logger.debug(f"Configuration type: {hacs.configuration.config_type}")
|
||||
hacs.version = VERSION
|
||||
hacs.logger.info(STARTUP)
|
||||
hacs.system.config_path = hacs.hass.config.path()
|
||||
hacs.system.ha_version = HAVERSION
|
||||
|
||||
await hacs.hass.async_add_executor_job(clear_storage)
|
||||
|
||||
hacs.system.lovelace_mode = lovelace_info.get("mode", "yaml")
|
||||
hacs.system.disabled = False
|
||||
hacs.github = GitHub(
|
||||
hacs.configuration.token, async_create_clientsession(hacs.hass)
|
||||
)
|
||||
hacs.data = HacsData()
|
||||
|
||||
can_update = await get_fetch_updates_for(hacs.github)
|
||||
if can_update == 0:
|
||||
hacs.logger.info("HACS is ratelimited, repository updates will resume in 1h.")
|
||||
else:
|
||||
hacs.logger.debug(f"Can update {can_update} repositories")
|
||||
|
||||
# Check HACS Constrains
|
||||
if not await hacs.hass.async_add_executor_job(check_constrains):
|
||||
if hacs.configuration.config_type == "flow":
|
||||
if hacs.configuration.config_entry is not None:
|
||||
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||||
return False
|
||||
|
||||
# Set up frontend
|
||||
await setup_frontend()
|
||||
|
||||
if not await hacs.hass.async_add_executor_job(internet_connectivity_check):
|
||||
hacs.logger.critical("No network connectivity")
|
||||
return False
|
||||
|
||||
# Load HACS
|
||||
if not await load_hacs_repository():
|
||||
if hacs.configuration.config_type == "flow":
|
||||
if hacs.configuration.config_entry is not None:
|
||||
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||||
return False
|
||||
|
||||
# Restore from storefiles
|
||||
if not await hacs.data.restore():
|
||||
hacs_repo = hacs.get_by_name("hacs/integration")
|
||||
hacs_repo.pending_restart = True
|
||||
if hacs.configuration.config_type == "flow":
|
||||
if hacs.configuration.config_entry is not None:
|
||||
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||||
return False
|
||||
|
||||
# Add aditional categories
|
||||
hacs.common.categories = ELEMENT_TYPES
|
||||
if hacs.configuration.appdaemon:
|
||||
hacs.common.categories.append("appdaemon")
|
||||
if hacs.configuration.netdaemon:
|
||||
hacs.common.categories.append("netdaemon")
|
||||
|
||||
# Setup startup tasks
|
||||
if hacs.configuration.config_type == "yaml":
|
||||
hacs.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, hacs.startup_tasks())
|
||||
else:
|
||||
async_call_later(hacs.hass, 5, hacs.startup_tasks())
|
||||
|
||||
# Show the configuration
|
||||
hacs.configuration.print()
|
||||
|
||||
# Set up sensor
|
||||
await hacs.hass.async_add_executor_job(add_sensor)
|
||||
|
||||
# Mischief managed!
|
||||
return True
|
||||
|
||||
|
||||
async def async_remove_entry(hass, config_entry):
|
||||
"""Handle removal of an entry."""
|
||||
hacs = get_hacs()
|
||||
hacs.logger.info("Disabling HACS")
|
||||
hacs.logger.info("Removing recuring tasks")
|
||||
for task in hacs.recuring_tasks:
|
||||
task()
|
||||
if config_entry.state == "loaded":
|
||||
hacs.logger.info("Removing sensor")
|
||||
try:
|
||||
await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")
|
||||
except ValueError:
|
||||
pass
|
||||
hacs.logger.info("Removing sidepanel")
|
||||
try:
|
||||
hass.components.frontend.async_remove_panel("hacs")
|
||||
except AttributeError:
|
||||
pass
|
||||
hacs.system.disabled = True
|
||||
hacs.logger.info("HACS is now disabled")
|
||||
|
||||
|
||||
async def reload_hacs(hass, config_entry):
|
||||
"""Reload HACS."""
|
||||
await async_remove_entry(hass, config_entry)
|
||||
await async_setup_entry(hass, config_entry)
|
|
@ -1,97 +0,0 @@
|
|||
"""Adds config flow for HACS."""
|
||||
# pylint: disable=dangerous-default-value
|
||||
import logging
|
||||
import voluptuous as vol
|
||||
from aiogithubapi import AIOGitHubAPIException, AIOGitHubAPIAuthenticationException
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
|
||||
from .const import DOMAIN
|
||||
from .configuration_schema import hacs_base_config_schema, hacs_config_option_schema
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.helpers.information import get_repository
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Config flow for HACS."""
|
||||
|
||||
VERSION = 1
|
||||
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize."""
|
||||
self._errors = {}
|
||||
|
||||
async def async_step_user(self, user_input={}):
|
||||
"""Handle a flow initialized by the user."""
|
||||
self._errors = {}
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
if self.hass.data.get(DOMAIN):
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
if user_input is not None:
|
||||
if await self._test_token(user_input["token"]):
|
||||
return self.async_create_entry(title="", data=user_input)
|
||||
|
||||
self._errors["base"] = "auth"
|
||||
return await self._show_config_form(user_input)
|
||||
|
||||
return await self._show_config_form(user_input)
|
||||
|
||||
async def _show_config_form(self, user_input):
|
||||
"""Show the configuration form to edit location data."""
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=vol.Schema(hacs_base_config_schema(user_input)),
|
||||
errors=self._errors,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry):
|
||||
return HacsOptionsFlowHandler(config_entry)
|
||||
|
||||
async def _test_token(self, token):
|
||||
"""Return true if token is valid."""
|
||||
try:
|
||||
session = aiohttp_client.async_get_clientsession(self.hass)
|
||||
await get_repository(session, token, "hacs/org")
|
||||
return True
|
||||
except (
|
||||
AIOGitHubAPIException,
|
||||
AIOGitHubAPIAuthenticationException,
|
||||
) as exception:
|
||||
_LOGGER.error(exception)
|
||||
return False
|
||||
|
||||
|
||||
class HacsOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""HACS config flow options handler."""
|
||||
|
||||
def __init__(self, config_entry):
|
||||
"""Initialize HACS options flow."""
|
||||
self.config_entry = config_entry
|
||||
|
||||
async def async_step_init(self, user_input=None):
|
||||
"""Manage the options."""
|
||||
return await self.async_step_user()
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle a flow initialized by the user."""
|
||||
hacs = get_hacs()
|
||||
if user_input is not None:
|
||||
return self.async_create_entry(title="", data=user_input)
|
||||
|
||||
if hacs.configuration.config_type == "yaml":
|
||||
schema = {vol.Optional("not_in_use", default=""): str}
|
||||
else:
|
||||
schema = hacs_config_option_schema(self.config_entry.options)
|
||||
del schema["frontend_repo"]
|
||||
del schema["frontend_repo_url"]
|
||||
|
||||
return self.async_show_form(step_id="user", data_schema=vol.Schema(schema))
|
|
@ -1,70 +0,0 @@
|
|||
"""HACS Configuration Schemas."""
|
||||
# pylint: disable=dangerous-default-value
|
||||
import voluptuous as vol
|
||||
from .const import LOCALE
|
||||
|
||||
# Configuration:
|
||||
TOKEN = "token"
|
||||
SIDEPANEL_TITLE = "sidepanel_title"
|
||||
SIDEPANEL_ICON = "sidepanel_icon"
|
||||
FRONTEND_REPO = "frontend_repo"
|
||||
FRONTEND_REPO_URL = "frontend_repo_url"
|
||||
APPDAEMON = "appdaemon"
|
||||
NETDAEMON = "netdaemon"
|
||||
|
||||
# Options:
|
||||
COUNTRY = "country"
|
||||
DEBUG = "debug"
|
||||
RELEASE_LIMIT = "release_limit"
|
||||
EXPERIMENTAL = "experimental"
|
||||
|
||||
|
||||
def hacs_base_config_schema(config: dict = {}) -> dict:
|
||||
"""Return a shcema configuration dict for HACS."""
|
||||
if not config:
|
||||
config = {
|
||||
TOKEN: "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
}
|
||||
return {
|
||||
vol.Required(TOKEN, default=config.get(TOKEN)): str,
|
||||
}
|
||||
|
||||
|
||||
def hacs_config_option_schema(options: dict = {}) -> dict:
|
||||
"""Return a shcema for HACS configuration options."""
|
||||
if not options:
|
||||
options = {
|
||||
APPDAEMON: False,
|
||||
COUNTRY: "ALL",
|
||||
DEBUG: False,
|
||||
EXPERIMENTAL: False,
|
||||
NETDAEMON: False,
|
||||
RELEASE_LIMIT: 5,
|
||||
SIDEPANEL_ICON: "hacs:hacs",
|
||||
SIDEPANEL_TITLE: "HACS",
|
||||
FRONTEND_REPO: "",
|
||||
FRONTEND_REPO_URL: "",
|
||||
}
|
||||
return {
|
||||
vol.Optional(SIDEPANEL_TITLE, default=options.get(SIDEPANEL_TITLE)): str,
|
||||
vol.Optional(SIDEPANEL_ICON, default=options.get(SIDEPANEL_ICON)): str,
|
||||
vol.Optional(RELEASE_LIMIT, default=options.get(RELEASE_LIMIT)): int,
|
||||
vol.Optional(COUNTRY, default=options.get(COUNTRY)): vol.In(LOCALE),
|
||||
vol.Optional(APPDAEMON, default=options.get(APPDAEMON)): bool,
|
||||
vol.Optional(NETDAEMON, default=options.get(NETDAEMON)): bool,
|
||||
vol.Optional(DEBUG, default=options.get(DEBUG)): bool,
|
||||
vol.Optional(EXPERIMENTAL, default=options.get(EXPERIMENTAL)): bool,
|
||||
vol.Optional(FRONTEND_REPO, default=options.get(FRONTEND_REPO)): str,
|
||||
vol.Optional(FRONTEND_REPO_URL, default=options.get(FRONTEND_REPO_URL)): str,
|
||||
}
|
||||
|
||||
|
||||
def hacs_config_combined() -> dict:
|
||||
"""Combine the configuration options."""
|
||||
base = hacs_base_config_schema()
|
||||
options = hacs_config_option_schema()
|
||||
|
||||
for option in options:
|
||||
base[option] = options[option]
|
||||
|
||||
return base
|
|
@ -1,293 +0,0 @@
|
|||
"""Constants for HACS"""
|
||||
NAME_LONG = "HACS (Home Assistant Community Store)"
|
||||
NAME_SHORT = "HACS"
|
||||
VERSION = "1.1.0"
|
||||
DOMAIN = "hacs"
|
||||
PROJECT_URL = "https://github.com/hacs/integration/"
|
||||
CUSTOM_UPDATER_LOCATIONS = [
|
||||
"{}/custom_components/custom_updater.py",
|
||||
"{}/custom_components/custom_updater/__init__.py",
|
||||
]
|
||||
|
||||
ISSUE_URL = f"{PROJECT_URL}issues"
|
||||
DOMAIN_DATA = f"{NAME_SHORT.lower()}_data"
|
||||
|
||||
ELEMENT_TYPES = ["integration", "plugin"]
|
||||
|
||||
IFRAME = {
|
||||
"title": "HACS",
|
||||
"icon": "hacs:hacs",
|
||||
"url": "/community_overview",
|
||||
"path": "community",
|
||||
"require_admin": True,
|
||||
}
|
||||
|
||||
|
||||
# Messages
|
||||
CUSTOM_UPDATER_WARNING = """
|
||||
This cannot be used with custom_updater.
|
||||
To use this you need to remove custom_updater form {}
|
||||
"""
|
||||
|
||||
STARTUP = f"""
|
||||
-------------------------------------------------------------------
|
||||
HACS (Home Assistant Community Store)
|
||||
|
||||
Version: {VERSION}
|
||||
This is a custom integration
|
||||
If you have any issues with this you need to open an issue here:
|
||||
https://github.com/hacs/integration/issues
|
||||
-------------------------------------------------------------------
|
||||
"""
|
||||
|
||||
LOCALE = [
|
||||
"ALL",
|
||||
"AF",
|
||||
"AL",
|
||||
"DZ",
|
||||
"AS",
|
||||
"AD",
|
||||
"AO",
|
||||
"AI",
|
||||
"AQ",
|
||||
"AG",
|
||||
"AR",
|
||||
"AM",
|
||||
"AW",
|
||||
"AU",
|
||||
"AT",
|
||||
"AZ",
|
||||
"BS",
|
||||
"BH",
|
||||
"BD",
|
||||
"BB",
|
||||
"BY",
|
||||
"BE",
|
||||
"BZ",
|
||||
"BJ",
|
||||
"BM",
|
||||
"BT",
|
||||
"BO",
|
||||
"BQ",
|
||||
"BA",
|
||||
"BW",
|
||||
"BV",
|
||||
"BR",
|
||||
"IO",
|
||||
"BN",
|
||||
"BG",
|
||||
"BF",
|
||||
"BI",
|
||||
"KH",
|
||||
"CM",
|
||||
"CA",
|
||||
"CV",
|
||||
"KY",
|
||||
"CF",
|
||||
"TD",
|
||||
"CL",
|
||||
"CN",
|
||||
"CX",
|
||||
"CC",
|
||||
"CO",
|
||||
"KM",
|
||||
"CG",
|
||||
"CD",
|
||||
"CK",
|
||||
"CR",
|
||||
"HR",
|
||||
"CU",
|
||||
"CW",
|
||||
"CY",
|
||||
"CZ",
|
||||
"CI",
|
||||
"DK",
|
||||
"DJ",
|
||||
"DM",
|
||||
"DO",
|
||||
"EC",
|
||||
"EG",
|
||||
"SV",
|
||||
"GQ",
|
||||
"ER",
|
||||
"EE",
|
||||
"ET",
|
||||
"FK",
|
||||
"FO",
|
||||
"FJ",
|
||||
"FI",
|
||||
"FR",
|
||||
"GF",
|
||||
"PF",
|
||||
"TF",
|
||||
"GA",
|
||||
"GM",
|
||||
"GE",
|
||||
"DE",
|
||||
"GH",
|
||||
"GI",
|
||||
"GR",
|
||||
"GL",
|
||||
"GD",
|
||||
"GP",
|
||||
"GU",
|
||||
"GT",
|
||||
"GG",
|
||||
"GN",
|
||||
"GW",
|
||||
"GY",
|
||||
"HT",
|
||||
"HM",
|
||||
"VA",
|
||||
"HN",
|
||||
"HK",
|
||||
"HU",
|
||||
"IS",
|
||||
"IN",
|
||||
"ID",
|
||||
"IR",
|
||||
"IQ",
|
||||
"IE",
|
||||
"IM",
|
||||
"IL",
|
||||
"IT",
|
||||
"JM",
|
||||
"JP",
|
||||
"JE",
|
||||
"JO",
|
||||
"KZ",
|
||||
"KE",
|
||||
"KI",
|
||||
"KP",
|
||||
"KR",
|
||||
"KW",
|
||||
"KG",
|
||||
"LA",
|
||||
"LV",
|
||||
"LB",
|
||||
"LS",
|
||||
"LR",
|
||||
"LY",
|
||||
"LI",
|
||||
"LT",
|
||||
"LU",
|
||||
"MO",
|
||||
"MK",
|
||||
"MG",
|
||||
"MW",
|
||||
"MY",
|
||||
"MV",
|
||||
"ML",
|
||||
"MT",
|
||||
"MH",
|
||||
"MQ",
|
||||
"MR",
|
||||
"MU",
|
||||
"YT",
|
||||
"MX",
|
||||
"FM",
|
||||
"MD",
|
||||
"MC",
|
||||
"MN",
|
||||
"ME",
|
||||
"MS",
|
||||
"MA",
|
||||
"MZ",
|
||||
"MM",
|
||||
"NA",
|
||||
"NR",
|
||||
"NP",
|
||||
"NL",
|
||||
"NC",
|
||||
"NZ",
|
||||
"NI",
|
||||
"NE",
|
||||
"NG",
|
||||
"NU",
|
||||
"NF",
|
||||
"MP",
|
||||
"NO",
|
||||
"OM",
|
||||
"PK",
|
||||
"PW",
|
||||
"PS",
|
||||
"PA",
|
||||
"PG",
|
||||
"PY",
|
||||
"PE",
|
||||
"PH",
|
||||
"PN",
|
||||
"PL",
|
||||
"PT",
|
||||
"PR",
|
||||
"QA",
|
||||
"RO",
|
||||
"RU",
|
||||
"RW",
|
||||
"RE",
|
||||
"BL",
|
||||
"SH",
|
||||
"KN",
|
||||
"LC",
|
||||
"MF",
|
||||
"PM",
|
||||
"VC",
|
||||
"WS",
|
||||
"SM",
|
||||
"ST",
|
||||
"SA",
|
||||
"SN",
|
||||
"RS",
|
||||
"SC",
|
||||
"SL",
|
||||
"SG",
|
||||
"SX",
|
||||
"SK",
|
||||
"SI",
|
||||
"SB",
|
||||
"SO",
|
||||
"ZA",
|
||||
"GS",
|
||||
"SS",
|
||||
"ES",
|
||||
"LK",
|
||||
"SD",
|
||||
"SR",
|
||||
"SJ",
|
||||
"SZ",
|
||||
"SE",
|
||||
"CH",
|
||||
"SY",
|
||||
"TW",
|
||||
"TJ",
|
||||
"TZ",
|
||||
"TH",
|
||||
"TL",
|
||||
"TG",
|
||||
"TK",
|
||||
"TO",
|
||||
"TT",
|
||||
"TN",
|
||||
"TR",
|
||||
"TM",
|
||||
"TC",
|
||||
"TV",
|
||||
"UG",
|
||||
"UA",
|
||||
"AE",
|
||||
"GB",
|
||||
"US",
|
||||
"UM",
|
||||
"UY",
|
||||
"UZ",
|
||||
"VU",
|
||||
"VE",
|
||||
"VN",
|
||||
"VG",
|
||||
"VI",
|
||||
"WF",
|
||||
"EH",
|
||||
"YE",
|
||||
"ZM",
|
||||
"ZW",
|
||||
]
|
|
@ -1,56 +0,0 @@
|
|||
"""HACS Startup constrains."""
|
||||
# pylint: disable=bad-continuation
|
||||
import os
|
||||
|
||||
from .const import CUSTOM_UPDATER_LOCATIONS, CUSTOM_UPDATER_WARNING
|
||||
from .helpers.misc import version_left_higher_then_right
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
|
||||
MINIMUM_HA_VERSION = "0.110.0"
|
||||
|
||||
|
||||
def check_constrains():
|
||||
"""Check HACS constrains."""
|
||||
if not constrain_translations():
|
||||
return False
|
||||
if not constrain_custom_updater():
|
||||
return False
|
||||
if not constrain_version():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def constrain_custom_updater():
|
||||
"""Check if custom_updater exist."""
|
||||
hacs = get_hacs()
|
||||
for location in CUSTOM_UPDATER_LOCATIONS:
|
||||
if os.path.exists(location.format(hacs.system.config_path)):
|
||||
msg = CUSTOM_UPDATER_WARNING.format(
|
||||
location.format(hacs.system.config_path)
|
||||
)
|
||||
hacs.logger.critical(msg)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def constrain_version():
|
||||
"""Check if the version is valid."""
|
||||
hacs = get_hacs()
|
||||
if not version_left_higher_then_right(hacs.system.ha_version, MINIMUM_HA_VERSION):
|
||||
hacs.logger.critical(
|
||||
f"You need HA version {MINIMUM_HA_VERSION} or newer to use this integration."
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def constrain_translations():
|
||||
"""Check if traslations exist."""
|
||||
hacs = get_hacs()
|
||||
if not os.path.exists(
|
||||
f"{hacs.system.config_path}/custom_components/hacs/translations"
|
||||
):
|
||||
hacs.logger.critical("You are missing the translations directory.")
|
||||
return False
|
||||
return True
|
|
@ -1,30 +0,0 @@
|
|||
# pylint: disable=invalid-name, missing-docstring
|
||||
hacs = []
|
||||
removed_repositories = []
|
||||
rules = {}
|
||||
|
||||
|
||||
def get_hacs():
|
||||
if not hacs:
|
||||
from custom_components.hacs.hacsbase import Hacs
|
||||
|
||||
hacs.append(Hacs())
|
||||
|
||||
return hacs[0]
|
||||
|
||||
|
||||
def is_removed(repository):
|
||||
return repository in [x.repository for x in removed_repositories]
|
||||
|
||||
|
||||
def get_removed(repository):
|
||||
if not is_removed(repository):
|
||||
from custom_components.hacs.repositories.removed import RemovedRepository
|
||||
|
||||
removed_repo = RemovedRepository()
|
||||
removed_repo.repository = repository
|
||||
removed_repositories.append(removed_repo)
|
||||
filter_repos = [
|
||||
x for x in removed_repositories if x.repository.lower() == repository.lower()
|
||||
]
|
||||
return filter_repos[0]
|
|
@ -1,377 +0,0 @@
|
|||
"""Initialize the HACS base."""
|
||||
# pylint: disable=unused-argument, bad-continuation
|
||||
import json
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
|
||||
from homeassistant.helpers.event import async_call_later, async_track_time_interval
|
||||
|
||||
from aiogithubapi import AIOGitHubAPIException, AIOGitHubAPIRatelimitException
|
||||
from integrationhelper import Logger
|
||||
from queueman import QueueManager
|
||||
|
||||
from custom_components.hacs.hacsbase.task_factory import HacsTaskFactory
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
|
||||
from custom_components.hacs.const import ELEMENT_TYPES
|
||||
from custom_components.hacs.setup import setup_extra_stores
|
||||
from custom_components.hacs.store import async_load_from_store, async_save_to_store
|
||||
from custom_components.hacs.helpers.get_defaults import (
|
||||
get_default_repos_lists,
|
||||
get_default_repos_orgs,
|
||||
)
|
||||
|
||||
from custom_components.hacs.helpers.register_repository import register_repository
|
||||
from custom_components.hacs.helpers.remaining_github_calls import get_fetch_updates_for
|
||||
from custom_components.hacs.globals import removed_repositories, get_removed, is_removed
|
||||
from custom_components.hacs.repositories.removed import RemovedRepository
|
||||
|
||||
|
||||
class HacsStatus:
|
||||
"""HacsStatus."""
|
||||
|
||||
startup = True
|
||||
new = False
|
||||
background_task = False
|
||||
reloading_data = False
|
||||
upgrading_all = False
|
||||
|
||||
|
||||
class HacsFrontend:
|
||||
"""HacsFrontend."""
|
||||
|
||||
version_running = None
|
||||
version_available = None
|
||||
version_expected = None
|
||||
update_pending = False
|
||||
|
||||
|
||||
class HacsCommon:
|
||||
"""Common for HACS."""
|
||||
|
||||
categories = []
|
||||
default = []
|
||||
installed = []
|
||||
skip = []
|
||||
|
||||
|
||||
class System:
|
||||
"""System info."""
|
||||
|
||||
status = HacsStatus()
|
||||
config_path = None
|
||||
ha_version = None
|
||||
disabled = False
|
||||
lovelace_mode = "storage"
|
||||
|
||||
|
||||
class Developer:
|
||||
"""Developer settings/tools."""
|
||||
|
||||
template_id = "Repository ID"
|
||||
template_content = ""
|
||||
template_raw = ""
|
||||
|
||||
@property
|
||||
def devcontainer(self):
|
||||
"""Is it a devcontainer?"""
|
||||
import os
|
||||
|
||||
if "DEVCONTAINER" in os.environ:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Hacs:
|
||||
"""The base class of HACS, nested thoughout the project."""
|
||||
|
||||
token = f"{str(uuid.uuid4())}-{str(uuid.uuid4())}"
|
||||
action = False
|
||||
hacsweb = f"/hacsweb/{token}"
|
||||
hacsapi = f"/hacsapi/{token}"
|
||||
repositories = []
|
||||
frontend = HacsFrontend()
|
||||
repo = None
|
||||
data_repo = None
|
||||
developer = Developer()
|
||||
data = None
|
||||
configuration = None
|
||||
logger = Logger("hacs")
|
||||
github = None
|
||||
hass = None
|
||||
version = None
|
||||
session = None
|
||||
factory = HacsTaskFactory()
|
||||
queue = QueueManager()
|
||||
system = System()
|
||||
recuring_tasks = []
|
||||
common = HacsCommon()
|
||||
|
||||
@staticmethod
|
||||
def init(hass, github_token):
|
||||
"""Return a initialized HACS object."""
|
||||
return Hacs()
|
||||
|
||||
def get_by_id(self, repository_id):
|
||||
"""Get repository by ID."""
|
||||
try:
|
||||
for repository in self.repositories:
|
||||
if str(repository.data.id) == str(repository_id):
|
||||
return repository
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_by_name(self, repository_full_name):
|
||||
"""Get repository by full_name."""
|
||||
try:
|
||||
for repository in self.repositories:
|
||||
if repository.data.full_name.lower() == repository_full_name.lower():
|
||||
return repository
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
return None
|
||||
|
||||
def is_known(self, repository_id):
|
||||
"""Return a bool if the repository is known."""
|
||||
return str(repository_id) in [str(x.data.id) for x in self.repositories]
|
||||
|
||||
@property
|
||||
def sorted_by_name(self):
|
||||
"""Return a sorted(by name) list of repository objects."""
|
||||
return sorted(self.repositories, key=lambda x: x.display_name)
|
||||
|
||||
@property
|
||||
def sorted_by_repository_name(self):
|
||||
"""Return a sorted(by repository_name) list of repository objects."""
|
||||
return sorted(self.repositories, key=lambda x: x.data.full_name)
|
||||
|
||||
async def register_repository(self, full_name, category, check=True):
|
||||
"""Register a repository."""
|
||||
await register_repository(full_name, category, check=True)
|
||||
|
||||
async def startup_tasks(self):
|
||||
"""Tasks tha are started after startup."""
|
||||
self.system.status.background_task = True
|
||||
await self.hass.async_add_executor_job(setup_extra_stores)
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
|
||||
await self.handle_critical_repositories_startup()
|
||||
await self.handle_critical_repositories()
|
||||
await self.load_known_repositories()
|
||||
await self.clear_out_removed_repositories()
|
||||
|
||||
self.recuring_tasks.append(
|
||||
async_track_time_interval(
|
||||
self.hass, self.recuring_tasks_installed, timedelta(minutes=30)
|
||||
)
|
||||
)
|
||||
self.recuring_tasks.append(
|
||||
async_track_time_interval(
|
||||
self.hass, self.recuring_tasks_all, timedelta(minutes=800)
|
||||
)
|
||||
)
|
||||
self.recuring_tasks.append(
|
||||
async_track_time_interval(
|
||||
self.hass, self.prosess_queue, timedelta(minutes=10)
|
||||
)
|
||||
)
|
||||
|
||||
self.hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
await self.recuring_tasks_installed()
|
||||
|
||||
await self.prosess_queue()
|
||||
|
||||
self.system.status.startup = False
|
||||
self.system.status.background_task = False
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
await self.data.async_write()
|
||||
|
||||
async def handle_critical_repositories_startup(self):
|
||||
"""Handled critical repositories during startup."""
|
||||
alert = False
|
||||
critical = await async_load_from_store(self.hass, "critical")
|
||||
if not critical:
|
||||
return
|
||||
for repo in critical:
|
||||
if not repo["acknowledged"]:
|
||||
alert = True
|
||||
if alert:
|
||||
self.logger.critical("URGENT!: Check the HACS panel!")
|
||||
self.hass.components.persistent_notification.create(
|
||||
title="URGENT!", message="**Check the HACS panel!**"
|
||||
)
|
||||
|
||||
async def handle_critical_repositories(self):
|
||||
"""Handled critical repositories during runtime."""
|
||||
# Get critical repositories
|
||||
instored = []
|
||||
critical = []
|
||||
was_installed = False
|
||||
|
||||
try:
|
||||
critical = await self.data_repo.get_contents("critical")
|
||||
critical = json.loads(critical.content)
|
||||
except AIOGitHubAPIException:
|
||||
pass
|
||||
|
||||
if not critical:
|
||||
self.logger.debug("No critical repositories")
|
||||
return
|
||||
|
||||
stored_critical = await async_load_from_store(self.hass, "critical")
|
||||
|
||||
for stored in stored_critical or []:
|
||||
instored.append(stored["repository"])
|
||||
|
||||
stored_critical = []
|
||||
|
||||
for repository in critical:
|
||||
removed_repo = get_removed(repository["repository"])
|
||||
removed_repo.removal_type = "critical"
|
||||
repo = self.get_by_name(repository["repository"])
|
||||
|
||||
stored = {
|
||||
"repository": repository["repository"],
|
||||
"reason": repository["reason"],
|
||||
"link": repository["link"],
|
||||
"acknowledged": True,
|
||||
}
|
||||
if repository["repository"] not in instored:
|
||||
if repo is not None and repo.installed:
|
||||
self.logger.critical(
|
||||
f"Removing repository {repository['repository']}, it is marked as critical"
|
||||
)
|
||||
was_installed = True
|
||||
stored["acknowledged"] = False
|
||||
# Uninstall from HACS
|
||||
repo.remove()
|
||||
await repo.uninstall()
|
||||
stored_critical.append(stored)
|
||||
removed_repo.update_data(stored)
|
||||
|
||||
# Save to FS
|
||||
await async_save_to_store(self.hass, "critical", stored_critical)
|
||||
|
||||
# Resart HASS
|
||||
if was_installed:
|
||||
self.logger.critical("Resarting Home Assistant")
|
||||
self.hass.async_create_task(self.hass.async_stop(100))
|
||||
|
||||
async def prosess_queue(self, notarealarg=None):
|
||||
"""Recuring tasks for installed repositories."""
|
||||
if not self.queue.has_pending_tasks:
|
||||
self.logger.debug("Nothing in the queue")
|
||||
return
|
||||
if self.queue.running:
|
||||
self.logger.debug("Queue is already running")
|
||||
return
|
||||
|
||||
can_update = await get_fetch_updates_for(self.github)
|
||||
if can_update == 0:
|
||||
self.logger.info(
|
||||
"HACS is ratelimited, repository updates will resume later."
|
||||
)
|
||||
else:
|
||||
self.system.status.background_task = True
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
await self.queue.execute(can_update)
|
||||
self.system.status.background_task = False
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
|
||||
async def recuring_tasks_installed(self, notarealarg=None):
|
||||
"""Recuring tasks for installed repositories."""
|
||||
self.logger.debug(
|
||||
"Starting recuring background task for installed repositories"
|
||||
)
|
||||
self.system.status.background_task = True
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
|
||||
for repository in self.repositories:
|
||||
if (
|
||||
repository.data.installed
|
||||
and repository.data.category in self.common.categories
|
||||
):
|
||||
self.queue.add(self.factory.safe_update(repository))
|
||||
|
||||
await self.handle_critical_repositories()
|
||||
self.system.status.background_task = False
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
await self.data.async_write()
|
||||
self.logger.debug("Recuring background task for installed repositories done")
|
||||
|
||||
async def recuring_tasks_all(self, notarealarg=None):
|
||||
"""Recuring tasks for all repositories."""
|
||||
self.logger.debug("Starting recuring background task for all repositories")
|
||||
await self.hass.async_add_executor_job(setup_extra_stores)
|
||||
self.system.status.background_task = True
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
|
||||
for repository in self.repositories:
|
||||
if repository.data.category in self.common.categories:
|
||||
self.queue.add(self.factory.safe_common_update(repository))
|
||||
|
||||
await self.load_known_repositories()
|
||||
await self.clear_out_removed_repositories()
|
||||
self.system.status.background_task = False
|
||||
await self.data.async_write()
|
||||
self.hass.bus.async_fire("hacs/status", {})
|
||||
self.hass.bus.async_fire("hacs/repository", {"action": "reload"})
|
||||
self.logger.debug("Recuring background task for all repositories done")
|
||||
|
||||
async def clear_out_removed_repositories(self):
|
||||
"""Clear out blaclisted repositories."""
|
||||
need_to_save = False
|
||||
for removed in removed_repositories:
|
||||
repository = self.get_by_name(removed.repository)
|
||||
if repository is not None:
|
||||
if repository.data.installed and removed.removal_type != "critical":
|
||||
self.logger.warning(
|
||||
f"You have {repository.data.full_name} installed with HACS "
|
||||
+ f"this repository has been removed, please consider removing it. "
|
||||
+ f"Removal reason ({removed.removal_type})"
|
||||
)
|
||||
else:
|
||||
need_to_save = True
|
||||
repository.remove()
|
||||
|
||||
if need_to_save:
|
||||
await self.data.async_write()
|
||||
|
||||
async def get_repositories(self):
|
||||
"""Return a list of repositories."""
|
||||
repositories = {}
|
||||
for category in self.common.categories:
|
||||
repositories[category] = await get_default_repos_lists(
|
||||
self.session, self.configuration.token, category
|
||||
)
|
||||
org = await get_default_repos_orgs(self.github, category)
|
||||
for repo in org:
|
||||
repositories[category].append(repo)
|
||||
return repositories
|
||||
|
||||
async def load_known_repositories(self):
|
||||
"""Load known repositories."""
|
||||
self.logger.info("Loading known repositories")
|
||||
repositories = await self.get_repositories()
|
||||
|
||||
for item in await get_default_repos_lists(
|
||||
self.session, self.configuration.token, "removed"
|
||||
):
|
||||
removed = get_removed(item["repository"])
|
||||
removed.reason = item.get("reason")
|
||||
removed.link = item.get("link")
|
||||
removed.removal_type = item.get("removal_type")
|
||||
|
||||
for category in repositories:
|
||||
for repo in repositories[category]:
|
||||
if is_removed(repo):
|
||||
continue
|
||||
repository = self.get_by_name(repo)
|
||||
if repository is not None:
|
||||
if str(repository.data.id) not in self.common.default:
|
||||
self.common.default.append(str(repository.data.id))
|
||||
else:
|
||||
continue
|
||||
continue
|
||||
self.queue.add(self.factory.safe_register(repo, category))
|
|
@ -1,117 +0,0 @@
|
|||
"""Backup."""
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from time import sleep
|
||||
|
||||
from integrationhelper import Logger
|
||||
|
||||
BACKUP_PATH = tempfile.gettempdir() + "/hacs_backup/"
|
||||
|
||||
|
||||
class Backup:
|
||||
"""Backup."""
|
||||
|
||||
def __init__(self, local_path, backup_path=BACKUP_PATH):
|
||||
"""initialize."""
|
||||
self.logger = Logger("hacs.backup")
|
||||
self.local_path = local_path
|
||||
self.backup_path = backup_path
|
||||
self.backup_path_full = f"{self.backup_path}{self.local_path.split('/')[-1]}"
|
||||
|
||||
def create(self):
|
||||
"""Create a backup in /tmp"""
|
||||
if not os.path.exists(self.local_path):
|
||||
return
|
||||
if os.path.exists(self.backup_path):
|
||||
shutil.rmtree(self.backup_path)
|
||||
while os.path.exists(self.backup_path):
|
||||
sleep(0.1)
|
||||
os.makedirs(self.backup_path, exist_ok=True)
|
||||
|
||||
try:
|
||||
if os.path.isfile(self.local_path):
|
||||
shutil.copyfile(self.local_path, self.backup_path_full)
|
||||
os.remove(self.local_path)
|
||||
else:
|
||||
shutil.copytree(self.local_path, self.backup_path_full)
|
||||
shutil.rmtree(self.local_path)
|
||||
while os.path.exists(self.local_path):
|
||||
sleep(0.1)
|
||||
self.logger.debug(
|
||||
f"Backup for {self.local_path}, created in {self.backup_path_full}"
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
|
||||
def restore(self):
|
||||
"""Restore from backup."""
|
||||
if not os.path.exists(self.backup_path_full):
|
||||
return
|
||||
|
||||
if os.path.isfile(self.backup_path_full):
|
||||
if os.path.exists(self.local_path):
|
||||
os.remove(self.local_path)
|
||||
shutil.copyfile(self.backup_path_full, self.local_path)
|
||||
else:
|
||||
if os.path.exists(self.local_path):
|
||||
shutil.rmtree(self.local_path)
|
||||
while os.path.exists(self.local_path):
|
||||
sleep(0.1)
|
||||
shutil.copytree(self.backup_path_full, self.local_path)
|
||||
self.logger.debug(
|
||||
f"Restored {self.local_path}, from backup {self.backup_path_full}"
|
||||
)
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup backup files."""
|
||||
if os.path.exists(self.backup_path):
|
||||
shutil.rmtree(self.backup_path)
|
||||
while os.path.exists(self.backup_path):
|
||||
sleep(0.1)
|
||||
self.logger.debug(f"Backup dir {self.backup_path} cleared")
|
||||
|
||||
|
||||
class BackupNetDaemon:
|
||||
"""BackupNetDaemon."""
|
||||
|
||||
def __init__(self, repository):
|
||||
"""Initialize."""
|
||||
self.repository = repository
|
||||
self.logger = Logger("hacs.backup")
|
||||
self.backup_path = (
|
||||
tempfile.gettempdir() + "/hacs_persistent_netdaemon/" + repository.data.name
|
||||
)
|
||||
|
||||
def create(self):
|
||||
"""Create a backup in /tmp"""
|
||||
if os.path.exists(self.backup_path):
|
||||
shutil.rmtree(self.backup_path)
|
||||
while os.path.exists(self.backup_path):
|
||||
sleep(0.1)
|
||||
os.makedirs(self.backup_path, exist_ok=True)
|
||||
|
||||
for filename in os.listdir(self.repository.content.path.local):
|
||||
if filename.endswith(".yaml"):
|
||||
source_file_name = f"{self.repository.content.path.local}/{filename}"
|
||||
target_file_name = f"{self.backup_path}/{filename}"
|
||||
shutil.copyfile(source_file_name, target_file_name)
|
||||
|
||||
def restore(self):
|
||||
"""Create a backup in /tmp"""
|
||||
if os.path.exists(self.backup_path):
|
||||
for filename in os.listdir(self.backup_path):
|
||||
if filename.endswith(".yaml"):
|
||||
source_file_name = f"{self.backup_path}/{filename}"
|
||||
target_file_name = (
|
||||
f"{self.repository.content.path.local}/{filename}"
|
||||
)
|
||||
shutil.copyfile(source_file_name, target_file_name)
|
||||
|
||||
def cleanup(self):
|
||||
"""Create a backup in /tmp"""
|
||||
if os.path.exists(self.backup_path):
|
||||
shutil.rmtree(self.backup_path)
|
||||
while os.path.exists(self.backup_path):
|
||||
sleep(0.1)
|
||||
self.logger.debug(f"Backup dir {self.backup_path} cleared")
|
|
@ -1,75 +0,0 @@
|
|||
"""HACS Configuration."""
|
||||
import attr
|
||||
from integrationhelper import Logger
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class Configuration:
|
||||
"""Configuration class."""
|
||||
|
||||
# Main configuration:
|
||||
appdaemon_path: str = "appdaemon/apps/"
|
||||
appdaemon: bool = False
|
||||
netdaemon_path: str = "netdaemon/apps/"
|
||||
netdaemon: bool = False
|
||||
config: dict = {}
|
||||
config_entry: dict = {}
|
||||
config_type: str = None
|
||||
debug: bool = False
|
||||
dev: bool = False
|
||||
frontend_mode: str = "Grid"
|
||||
frontend_compact: bool = False
|
||||
frontend_repo: str = ""
|
||||
frontend_repo_url: str = ""
|
||||
options: dict = {}
|
||||
onboarding_done: bool = False
|
||||
plugin_path: str = "www/community/"
|
||||
python_script_path: str = "python_scripts/"
|
||||
python_script: bool = False
|
||||
sidepanel_icon: str = "hacs:hacs"
|
||||
sidepanel_title: str = "HACS"
|
||||
theme_path: str = "themes/"
|
||||
theme: bool = False
|
||||
token: str = None
|
||||
|
||||
# Config options:
|
||||
country: str = "ALL"
|
||||
experimental: bool = False
|
||||
release_limit: int = 5
|
||||
|
||||
def to_json(self):
|
||||
"""Return a dict representation of the configuration."""
|
||||
return self.__dict__
|
||||
|
||||
def print(self):
|
||||
"""Print the current configuration to the log."""
|
||||
logger = Logger("hacs.configuration")
|
||||
config = self.to_json()
|
||||
for key in config:
|
||||
if key in ["config", "config_entry", "options", "token"]:
|
||||
continue
|
||||
logger.debug(f"{key}: {config[key]}")
|
||||
|
||||
@staticmethod
|
||||
def from_dict(configuration: dict, options: dict = None):
|
||||
"""Set attributes from dicts."""
|
||||
if isinstance(options, bool) or isinstance(configuration.get("options"), bool):
|
||||
raise HacsException("Configuration is not valid.")
|
||||
|
||||
if options is None:
|
||||
options = {}
|
||||
|
||||
if not configuration:
|
||||
raise HacsException("Configuration is not valid.")
|
||||
|
||||
config = Configuration()
|
||||
|
||||
config.config = configuration
|
||||
config.options = options
|
||||
|
||||
for conf_type in [configuration, options]:
|
||||
for key in conf_type:
|
||||
setattr(config, key, conf_type[key])
|
||||
|
||||
return config
|
|
@ -1,10 +0,0 @@
|
|||
"""Constants for HACS"""
|
||||
# pylint: disable=unused-import
|
||||
STORAGE_VERSION = "6"
|
||||
STORENAME = "hacs"
|
||||
|
||||
# Messages
|
||||
NOT_SUPPORTED_HA_VERSION = "You have version '{}' of Home Assistant, but version '{}' of '{}' require version '{}' of Home Assistant, install and upgrades are disabled for this integration untill you upgrade Home Assistant."
|
||||
|
||||
|
||||
NO_ELEMENTS = "No elements to show, open the store to install some awesome stuff."
|
|
@ -1,175 +0,0 @@
|
|||
"""Data handler for HACS."""
|
||||
from integrationhelper import Logger
|
||||
from ..const import VERSION
|
||||
from ..repositories.repository import HacsRepository
|
||||
from ..repositories.manifest import HacsManifest
|
||||
from ..store import async_save_to_store, async_load_from_store
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.helpers.register_repository import register_repository
|
||||
|
||||
|
||||
class HacsData:
|
||||
"""HacsData class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize."""
|
||||
self.logger = Logger("hacs.data")
|
||||
self.hacs = get_hacs()
|
||||
|
||||
async def async_write(self):
|
||||
"""Write content to the store files."""
|
||||
if self.hacs.system.status.background_task or self.hacs.system.disabled:
|
||||
return
|
||||
|
||||
self.logger.debug("Saving data")
|
||||
|
||||
# Hacs
|
||||
await async_save_to_store(
|
||||
self.hacs.hass,
|
||||
"hacs",
|
||||
{
|
||||
"view": self.hacs.configuration.frontend_mode,
|
||||
"compact": self.hacs.configuration.frontend_compact,
|
||||
"onboarding_done": self.hacs.configuration.onboarding_done,
|
||||
},
|
||||
)
|
||||
|
||||
# Repositories
|
||||
content = {}
|
||||
for repository in self.hacs.repositories:
|
||||
if repository.repository_manifest is not None:
|
||||
repository_manifest = repository.repository_manifest.manifest
|
||||
else:
|
||||
repository_manifest = None
|
||||
data = {
|
||||
"authors": repository.data.authors,
|
||||
"category": repository.data.category,
|
||||
"description": repository.data.description,
|
||||
"domain": repository.data.domain,
|
||||
"downloads": repository.data.downloads,
|
||||
"full_name": repository.data.full_name,
|
||||
"first_install": repository.status.first_install,
|
||||
"installed_commit": repository.data.installed_commit,
|
||||
"installed": repository.data.installed,
|
||||
"last_commit": repository.data.last_commit,
|
||||
"last_release_tag": repository.data.last_version,
|
||||
"last_updated": repository.data.last_updated,
|
||||
"name": repository.data.name,
|
||||
"new": repository.data.new,
|
||||
"repository_manifest": repository_manifest,
|
||||
"selected_tag": repository.data.selected_tag,
|
||||
"show_beta": repository.data.show_beta,
|
||||
"stars": repository.data.stargazers_count,
|
||||
"topics": repository.data.topics,
|
||||
"version_installed": repository.data.installed_version,
|
||||
}
|
||||
if data:
|
||||
if repository.data.installed and (
|
||||
repository.data.installed_commit
|
||||
or repository.data.installed_version
|
||||
):
|
||||
await async_save_to_store(
|
||||
self.hacs.hass,
|
||||
f"hacs/{repository.data.id}.hacs",
|
||||
repository.data.to_json(),
|
||||
)
|
||||
content[str(repository.data.id)] = data
|
||||
|
||||
await async_save_to_store(self.hacs.hass, "repositories", content)
|
||||
self.hacs.hass.bus.async_fire("hacs/repository", {})
|
||||
self.hacs.hass.bus.fire("hacs/config", {})
|
||||
|
||||
async def restore(self):
|
||||
"""Restore saved data."""
|
||||
hacs = await async_load_from_store(self.hacs.hass, "hacs")
|
||||
repositories = await async_load_from_store(self.hacs.hass, "repositories")
|
||||
try:
|
||||
if not hacs and not repositories:
|
||||
# Assume new install
|
||||
self.hacs.system.status.new = True
|
||||
return True
|
||||
self.logger.info("Restore started")
|
||||
self.hacs.system.status.new = False
|
||||
|
||||
# Hacs
|
||||
self.hacs.configuration.frontend_mode = hacs.get("view", "Grid")
|
||||
self.hacs.configuration.frontend_compact = hacs.get("compact", False)
|
||||
self.hacs.configuration.onboarding_done = hacs.get("onboarding_done", False)
|
||||
|
||||
# Repositories
|
||||
for entry in repositories:
|
||||
repo = repositories[entry]
|
||||
if not self.hacs.is_known(entry):
|
||||
await register_repository(
|
||||
repo["full_name"], repo["category"], False
|
||||
)
|
||||
repository = [
|
||||
x
|
||||
for x in self.hacs.repositories
|
||||
if str(x.data.id) == str(entry)
|
||||
or x.data.full_name == repo["full_name"]
|
||||
]
|
||||
if not repository:
|
||||
self.logger.error(f"Did not find {repo['full_name']} ({entry})")
|
||||
continue
|
||||
|
||||
repository = repository[0]
|
||||
|
||||
# Restore repository attributes
|
||||
repository.data.id = entry
|
||||
await self.hacs.hass.async_add_executor_job(
|
||||
restore_repository_data, repository, repo
|
||||
)
|
||||
|
||||
restored = await async_load_from_store(
|
||||
self.hacs.hass, f"hacs/{entry}.hacs"
|
||||
)
|
||||
|
||||
if restored:
|
||||
repository.data.update_data(restored)
|
||||
if not repository.data.installed:
|
||||
repository.logger.debug(
|
||||
"Should be installed but is not... Fixing that!"
|
||||
)
|
||||
repository.data.installed = True
|
||||
|
||||
self.logger.info("Restore done")
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
self.logger.critical(f"[{exception}] Restore Failed!")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def restore_repository_data(
|
||||
repository: type(HacsRepository), repository_data: dict
|
||||
) -> None:
|
||||
"""Restore Repository Data"""
|
||||
repository.data.authors = repository_data.get("authors", [])
|
||||
repository.data.description = repository_data.get("description")
|
||||
repository.releases.last_release_object_downloads = repository_data.get("downloads")
|
||||
repository.data.last_updated = repository_data.get("last_updated")
|
||||
repository.data.topics = repository_data.get("topics", [])
|
||||
repository.data.domain = repository_data.get("domain", None)
|
||||
repository.data.stargazers_count = repository_data.get("stars", 0)
|
||||
repository.releases.last_release = repository_data.get("last_release_tag")
|
||||
repository.data.hide = repository_data.get("hide", False)
|
||||
repository.data.installed = repository_data.get("installed", False)
|
||||
repository.data.new = repository_data.get("new", True)
|
||||
repository.data.selected_tag = repository_data.get("selected_tag")
|
||||
repository.data.show_beta = repository_data.get("show_beta", False)
|
||||
repository.data.last_version = repository_data.get("last_release_tag")
|
||||
repository.data.last_commit = repository_data.get("last_commit")
|
||||
repository.data.installed_version = repository_data.get("version_installed")
|
||||
repository.data.installed_commit = repository_data.get("installed_commit")
|
||||
|
||||
repository.repository_manifest = HacsManifest.from_dict(
|
||||
repository_data.get("repository_manifest", {})
|
||||
)
|
||||
|
||||
if repository.data.installed:
|
||||
repository.status.first_install = False
|
||||
|
||||
if repository_data["full_name"] == "hacs/integration":
|
||||
repository.data.installed_version = VERSION
|
||||
repository.data.installed = True
|
|
@ -1,9 +0,0 @@
|
|||
"""Custom Exceptions."""
|
||||
|
||||
|
||||
class HacsException(Exception):
|
||||
"""Super basic."""
|
||||
|
||||
|
||||
class HacsExpectedException(HacsException):
|
||||
"""For stuff that are expected."""
|
|
@ -1,75 +0,0 @@
|
|||
# pylint: disable=missing-docstring,invalid-name
|
||||
import logging
|
||||
import time
|
||||
from datetime import timedelta
|
||||
import asyncio
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.register_repository import register_repository
|
||||
|
||||
|
||||
max_concurrent_tasks = asyncio.Semaphore(15)
|
||||
sleeper = 5
|
||||
|
||||
logger = logging.getLogger("hacs.factory")
|
||||
|
||||
|
||||
class HacsTaskFactory:
|
||||
def __init__(self):
|
||||
self.tasks = []
|
||||
self.running = False
|
||||
|
||||
async def execute(self):
|
||||
if not self.tasks:
|
||||
logger.debug("No tasks to execute")
|
||||
return
|
||||
if self.running:
|
||||
logger.debug("Allready executing tasks")
|
||||
return
|
||||
try:
|
||||
self.running = True
|
||||
logger.info("Processing %s tasks", len(self.tasks))
|
||||
start = time.time()
|
||||
await asyncio.gather(*self.tasks)
|
||||
logger.info(
|
||||
"Task processing of %s tasks completed in %s seconds",
|
||||
len(self.tasks),
|
||||
timedelta(seconds=round(time.time() - start)).seconds,
|
||||
)
|
||||
self.tasks = []
|
||||
self.running = False
|
||||
except RuntimeError:
|
||||
logger.warning("RuntimeError, Clearing current tasks")
|
||||
self.tasks = []
|
||||
self.running = False
|
||||
|
||||
async def safe_common_update(self, repository):
|
||||
async with max_concurrent_tasks:
|
||||
try:
|
||||
await repository.common_update()
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
logger.error("%s - %s", repository.data.full_name, exception)
|
||||
|
||||
# Due to GitHub ratelimits we need to sleep a bit
|
||||
await asyncio.sleep(sleeper)
|
||||
|
||||
async def safe_update(self, repository):
|
||||
async with max_concurrent_tasks:
|
||||
try:
|
||||
await repository.update_repository()
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
logger.error("%s - %s", repository.data.full_name, exception)
|
||||
|
||||
# Due to GitHub ratelimits we need to sleep a bit
|
||||
await asyncio.sleep(sleeper)
|
||||
|
||||
async def safe_register(self, repo, category):
|
||||
async with max_concurrent_tasks:
|
||||
try:
|
||||
await register_repository(repo, category)
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
logger.error("%s - %s", repo, exception)
|
||||
|
||||
# Due to GitHub ratelimits we need to sleep a bit
|
||||
await asyncio.sleep(sleeper)
|
|
@ -1 +0,0 @@
|
|||
"""Initialize handlers."""
|
|
@ -1,90 +0,0 @@
|
|||
"""Download."""
|
||||
import os
|
||||
import gzip
|
||||
import shutil
|
||||
|
||||
import aiofiles
|
||||
import async_timeout
|
||||
from integrationhelper import Logger
|
||||
import backoff
|
||||
from ..hacsbase.exceptions import HacsException
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
|
||||
|
||||
@backoff.on_exception(backoff.expo, Exception, max_tries=5)
|
||||
async def async_download_file(url):
|
||||
"""
|
||||
Download files, and return the content.
|
||||
"""
|
||||
hacs = get_hacs()
|
||||
logger = Logger("hacs.download.downloader")
|
||||
if url is None:
|
||||
return
|
||||
|
||||
# There is a bug somewhere... TODO: Find that bug....
|
||||
if "tags/" in url:
|
||||
url = url.replace("tags/", "")
|
||||
|
||||
logger.debug(f"Downloading {url}")
|
||||
|
||||
result = None
|
||||
|
||||
with async_timeout.timeout(60, loop=hacs.hass.loop):
|
||||
request = await hacs.session.get(url)
|
||||
|
||||
# Make sure that we got a valid result
|
||||
if request.status == 200:
|
||||
result = await request.read()
|
||||
else:
|
||||
raise HacsException(
|
||||
"Got status code {} when trying to download {}".format(
|
||||
request.status, url
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
async def async_save_file(location, content):
|
||||
"""Save files."""
|
||||
logger = Logger("hacs.download.save")
|
||||
logger.debug(f"Saving {location}")
|
||||
mode = "w"
|
||||
encoding = "utf-8"
|
||||
errors = "ignore"
|
||||
|
||||
if not isinstance(content, str):
|
||||
mode = "wb"
|
||||
encoding = None
|
||||
errors = None
|
||||
|
||||
try:
|
||||
async with aiofiles.open(
|
||||
location, mode=mode, encoding=encoding, errors=errors
|
||||
) as outfile:
|
||||
await outfile.write(content)
|
||||
outfile.close()
|
||||
|
||||
# Create gz for .js files
|
||||
if os.path.isfile(location):
|
||||
if location.endswith(".js") or location.endswith(".css"):
|
||||
with open(location, "rb") as f_in:
|
||||
with gzip.open(location + ".gz", "wb") as f_out:
|
||||
shutil.copyfileobj(f_in, f_out)
|
||||
|
||||
# Remove with 2.0
|
||||
if "themes" in location and location.endswith(".yaml"):
|
||||
filename = location.split("/")[-1]
|
||||
base = location.split("/themes/")[0]
|
||||
combined = f"{base}/themes/{filename}"
|
||||
if os.path.exists(combined):
|
||||
logger.info(f"Removing old theme file {combined}")
|
||||
os.remove(combined)
|
||||
|
||||
except Exception as error: # pylint: disable=broad-except
|
||||
msg = "Could not write data to {} - {}".format(location, error)
|
||||
logger.error(msg)
|
||||
return False
|
||||
|
||||
return os.path.exists(location)
|
|
@ -1,29 +0,0 @@
|
|||
"""Custom template support."""
|
||||
# pylint: disable=broad-except
|
||||
from jinja2 import Template
|
||||
from integrationhelper import Logger
|
||||
|
||||
|
||||
def render_template(content, context):
|
||||
"""Render templates in content."""
|
||||
# Fix None issues
|
||||
if context.releases.last_release_object is not None:
|
||||
prerelease = context.releases.last_release_object.prerelease
|
||||
else:
|
||||
prerelease = False
|
||||
|
||||
# Render the template
|
||||
try:
|
||||
render = Template(content)
|
||||
render = render.render(
|
||||
installed=context.data.installed,
|
||||
pending_update=context.pending_upgrade,
|
||||
prerelease=prerelease,
|
||||
selected_tag=context.data.selected_tag,
|
||||
version_available=context.releases.last_release,
|
||||
version_installed=context.display_installed_version,
|
||||
)
|
||||
return render
|
||||
except Exception as exception:
|
||||
Logger("hacs.template").debug(exception)
|
||||
return content
|
|
@ -1,192 +0,0 @@
|
|||
"""Helpers to download repository content."""
|
||||
import os
|
||||
import pathlib
|
||||
import tempfile
|
||||
import zipfile
|
||||
from queueman import QueueManager, concurrent
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.handler.download import async_download_file, async_save_file
|
||||
from custom_components.hacs.helpers.filters import filter_content_return_one_of_type
|
||||
|
||||
|
||||
class FileInformation:
|
||||
def __init__(self, url, path, name):
|
||||
self.download_url = url
|
||||
self.path = path
|
||||
self.name = name
|
||||
|
||||
|
||||
def should_try_releases(repository):
|
||||
"""Return a boolean indicating whether to download releases or not."""
|
||||
if repository.data.zip_release:
|
||||
if repository.data.filename.endswith(".zip"):
|
||||
if repository.ref != repository.data.default_branch:
|
||||
return True
|
||||
if repository.ref == repository.data.default_branch:
|
||||
return False
|
||||
if repository.data.category not in ["plugin", "theme"]:
|
||||
return False
|
||||
if not repository.data.releases:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def gather_files_to_download(repository):
|
||||
"""Return a list of file objects to be downloaded."""
|
||||
files = []
|
||||
tree = repository.tree
|
||||
ref = f"{repository.ref}".replace("tags/", "")
|
||||
releaseobjects = repository.releases.objects
|
||||
category = repository.data.category
|
||||
remotelocation = repository.content.path.remote
|
||||
|
||||
if should_try_releases(repository):
|
||||
for release in releaseobjects or []:
|
||||
if ref == release.tag_name:
|
||||
for asset in release.assets or []:
|
||||
files.append(asset)
|
||||
if files:
|
||||
return files
|
||||
|
||||
if repository.content.single:
|
||||
for treefile in tree:
|
||||
if treefile.filename == repository.data.file_name:
|
||||
files.append(
|
||||
FileInformation(
|
||||
treefile.download_url, treefile.full_path, treefile.filename
|
||||
)
|
||||
)
|
||||
return files
|
||||
|
||||
if category == "plugin":
|
||||
for treefile in tree:
|
||||
if treefile.path in ["", "dist"]:
|
||||
if remotelocation == "dist" and not treefile.filename.startswith(
|
||||
"dist"
|
||||
):
|
||||
continue
|
||||
if not remotelocation:
|
||||
if not treefile.filename.endswith(".js"):
|
||||
continue
|
||||
if treefile.path != "":
|
||||
continue
|
||||
if not treefile.is_directory:
|
||||
files.append(
|
||||
FileInformation(
|
||||
treefile.download_url, treefile.full_path, treefile.filename
|
||||
)
|
||||
)
|
||||
if files:
|
||||
return files
|
||||
|
||||
if repository.data.content_in_root:
|
||||
if not repository.data.filename:
|
||||
if category == "theme":
|
||||
tree = filter_content_return_one_of_type(
|
||||
repository.tree, "", "yaml", "full_path"
|
||||
)
|
||||
|
||||
for path in tree:
|
||||
if path.is_directory:
|
||||
continue
|
||||
if path.full_path.startswith(repository.content.path.remote):
|
||||
files.append(
|
||||
FileInformation(path.download_url, path.full_path, path.filename)
|
||||
)
|
||||
return files
|
||||
|
||||
|
||||
async def download_zip(repository, validate):
|
||||
"""Download ZIP archive from repository release."""
|
||||
contents = []
|
||||
try:
|
||||
for release in repository.releases.objects:
|
||||
repository.logger.info(
|
||||
f"ref: {repository.ref} --- tag: {release.tag_name}"
|
||||
)
|
||||
if release.tag_name == repository.ref.split("/")[1]:
|
||||
contents = release.assets
|
||||
|
||||
if not contents:
|
||||
return validate
|
||||
|
||||
for content in contents:
|
||||
filecontent = await async_download_file(content.download_url)
|
||||
|
||||
if filecontent is None:
|
||||
validate.errors.append(f"[{content.name}] was not downloaded.")
|
||||
continue
|
||||
|
||||
result = await async_save_file(
|
||||
f"{tempfile.gettempdir()}/{repository.data.filename}", filecontent
|
||||
)
|
||||
with zipfile.ZipFile(
|
||||
f"{tempfile.gettempdir()}/{repository.data.filename}", "r"
|
||||
) as zip_file:
|
||||
zip_file.extractall(repository.content.path.local)
|
||||
|
||||
os.remove(f"{tempfile.gettempdir()}/{repository.data.filename}")
|
||||
|
||||
if result:
|
||||
repository.logger.info(f"download of {content.name} complete")
|
||||
continue
|
||||
validate.errors.append(f"[{content.name}] was not downloaded.")
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
validate.errors.append(f"Download was not complete [{exception}]")
|
||||
|
||||
return validate
|
||||
|
||||
|
||||
async def download_content(repository):
|
||||
"""Download the content of a directory."""
|
||||
queue = QueueManager()
|
||||
contents = gather_files_to_download(repository)
|
||||
repository.logger.debug(repository.data.filename)
|
||||
if not contents:
|
||||
raise HacsException("No content to download")
|
||||
|
||||
for content in contents:
|
||||
if repository.data.content_in_root and repository.data.filename:
|
||||
if content.name != repository.data.filename:
|
||||
continue
|
||||
queue.add(dowload_repository_content(repository, content))
|
||||
await queue.execute()
|
||||
|
||||
|
||||
@concurrent(10)
|
||||
async def dowload_repository_content(repository, content):
|
||||
"""Download content."""
|
||||
repository.logger.debug(f"Downloading {content.name}")
|
||||
|
||||
filecontent = await async_download_file(content.download_url)
|
||||
|
||||
if filecontent is None:
|
||||
repository.validate.errors.append(f"[{content.name}] was not downloaded.")
|
||||
return
|
||||
|
||||
# Save the content of the file.
|
||||
if repository.content.single or content.path is None:
|
||||
local_directory = repository.content.path.local
|
||||
|
||||
else:
|
||||
_content_path = content.path
|
||||
if not repository.data.content_in_root:
|
||||
_content_path = _content_path.replace(
|
||||
f"{repository.content.path.remote}", ""
|
||||
)
|
||||
|
||||
local_directory = f"{repository.content.path.local}/{_content_path}"
|
||||
local_directory = local_directory.split("/")
|
||||
del local_directory[-1]
|
||||
local_directory = "/".join(local_directory)
|
||||
|
||||
# Check local directory
|
||||
pathlib.Path(local_directory).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
local_file_path = (f"{local_directory}/{content.name}").replace("//", "/")
|
||||
|
||||
result = await async_save_file(local_file_path, filecontent)
|
||||
if result:
|
||||
repository.logger.info(f"download of {content.name} complete")
|
||||
return
|
||||
repository.validate.errors.append(f"[{content.name}] was not downloaded.")
|
|
@ -1,55 +0,0 @@
|
|||
"""Filter functions."""
|
||||
|
||||
|
||||
def filter_content_return_one_of_type(
|
||||
content, namestartswith, filterfiltype, attr="name"
|
||||
):
|
||||
"""Only match 1 of the filter."""
|
||||
contents = []
|
||||
filetypefound = False
|
||||
for filename in content:
|
||||
if isinstance(filename, str):
|
||||
if filename.startswith(namestartswith):
|
||||
if filename.endswith(f".{filterfiltype}"):
|
||||
if not filetypefound:
|
||||
contents.append(filename)
|
||||
filetypefound = True
|
||||
continue
|
||||
else:
|
||||
contents.append(filename)
|
||||
else:
|
||||
if getattr(filename, attr).startswith(namestartswith):
|
||||
if getattr(filename, attr).endswith(f".{filterfiltype}"):
|
||||
if not filetypefound:
|
||||
contents.append(filename)
|
||||
filetypefound = True
|
||||
continue
|
||||
else:
|
||||
contents.append(filename)
|
||||
return contents
|
||||
|
||||
|
||||
def find_first_of_filetype(content, filterfiltype, attr="name"):
|
||||
"""Find the first of the file type."""
|
||||
filename = ""
|
||||
for _filename in content:
|
||||
if isinstance(_filename, str):
|
||||
if _filename.endswith(f".{filterfiltype}"):
|
||||
filename = _filename
|
||||
break
|
||||
else:
|
||||
if getattr(_filename, attr).endswith(f".{filterfiltype}"):
|
||||
filename = getattr(_filename, attr)
|
||||
break
|
||||
return filename
|
||||
|
||||
|
||||
def get_first_directory_in_directory(content, dirname):
|
||||
"""Return the first directory in dirname or None."""
|
||||
directory = None
|
||||
for path in content:
|
||||
if path.full_path.startswith(dirname) and path.full_path != dirname:
|
||||
if path.is_directory:
|
||||
directory = path.filename
|
||||
break
|
||||
return directory
|
|
@ -1,45 +0,0 @@
|
|||
"""Helpers to get default repositories."""
|
||||
import json
|
||||
from aiogithubapi import GitHub, AIOGitHubAPIException
|
||||
from integrationhelper import Logger
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.information import get_repository
|
||||
|
||||
|
||||
async def get_default_repos_orgs(github: type(GitHub), category: str) -> dict:
|
||||
"""Gets default org repositories."""
|
||||
repositories = []
|
||||
logger = Logger("hacs")
|
||||
orgs = {
|
||||
"plugin": "custom-cards",
|
||||
"integration": "custom-components",
|
||||
"theme": "home-assistant-community-themes",
|
||||
}
|
||||
if category not in orgs:
|
||||
return repositories
|
||||
|
||||
try:
|
||||
repos = await github.get_org_repos(orgs[category])
|
||||
for repo in repos:
|
||||
repositories.append(repo.full_name)
|
||||
|
||||
except AIOGitHubAPIException as exception:
|
||||
logger.error(exception)
|
||||
|
||||
return repositories
|
||||
|
||||
|
||||
async def get_default_repos_lists(session, token, default: str) -> dict:
|
||||
"""Gets repositories from default list."""
|
||||
repositories = []
|
||||
logger = Logger("hacs")
|
||||
|
||||
try:
|
||||
repo = await get_repository(session, token, "hacs/default")
|
||||
content = await repo.get_contents(default)
|
||||
repositories = json.loads(content.content)
|
||||
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
logger.error(exception)
|
||||
|
||||
return repositories
|
|
@ -1,223 +0,0 @@
|
|||
"""Return repository information if any."""
|
||||
import json
|
||||
from aiogithubapi import AIOGitHubAPIException, GitHub
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.handler.template import render_template
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
|
||||
|
||||
def info_file(repository):
|
||||
"""get info filename."""
|
||||
if repository.data.render_readme:
|
||||
for filename in ["readme", "readme.md", "README", "README.md", "README.MD"]:
|
||||
if filename in repository.treefiles:
|
||||
return filename
|
||||
return ""
|
||||
for filename in ["info", "info.md", "INFO", "INFO.md", "INFO.MD"]:
|
||||
if filename in repository.treefiles:
|
||||
return filename
|
||||
return ""
|
||||
|
||||
|
||||
async def get_info_md_content(repository):
|
||||
"""Get the content of info.md"""
|
||||
filename = info_file(repository)
|
||||
if not filename:
|
||||
return ""
|
||||
try:
|
||||
info = await repository.repository_object.get_contents(filename, repository.ref)
|
||||
if info is None:
|
||||
return ""
|
||||
info = info.content.replace("<svg", "<disabled").replace("</svg", "</disabled")
|
||||
return render_template(info, repository)
|
||||
except (AIOGitHubAPIException, Exception): # pylint: disable=broad-except
|
||||
if repository.hacs.action:
|
||||
raise HacsException("No info file found")
|
||||
return ""
|
||||
|
||||
|
||||
async def get_repository(session, token, repository_full_name):
|
||||
"""Return a repository object or None."""
|
||||
try:
|
||||
github = GitHub(token, session)
|
||||
repository = await github.get_repo(repository_full_name)
|
||||
return repository
|
||||
except (AIOGitHubAPIException, Exception) as exception:
|
||||
raise HacsException(exception)
|
||||
|
||||
|
||||
async def get_tree(repository, ref):
|
||||
"""Return the repository tree."""
|
||||
try:
|
||||
tree = await repository.get_tree(ref)
|
||||
return tree
|
||||
except AIOGitHubAPIException as exception:
|
||||
raise HacsException(exception)
|
||||
|
||||
|
||||
async def get_releases(repository, prerelease=False, returnlimit=5):
|
||||
"""Return the repository releases."""
|
||||
try:
|
||||
releases = await repository.get_releases(prerelease, returnlimit)
|
||||
return releases
|
||||
except AIOGitHubAPIException as exception:
|
||||
raise HacsException(exception)
|
||||
|
||||
|
||||
def get_frontend_version():
|
||||
"""get the frontend version from the manifest."""
|
||||
manifest = read_hacs_manifest()
|
||||
frontend = 0
|
||||
for requirement in manifest.get("requirements", []):
|
||||
if requirement.startswith("hacs_frontend"):
|
||||
frontend = requirement.split("==")[1]
|
||||
break
|
||||
return frontend
|
||||
|
||||
|
||||
def read_hacs_manifest():
|
||||
"""Reads the HACS manifest file and returns the contents."""
|
||||
hacs = get_hacs()
|
||||
content = {}
|
||||
with open(
|
||||
f"{hacs.system.config_path}/custom_components/hacs/manifest.json"
|
||||
) as manifest:
|
||||
content = json.loads(manifest.read())
|
||||
return content
|
||||
|
||||
|
||||
async def get_integration_manifest(repository):
|
||||
"""Return the integration manifest."""
|
||||
if repository.data.content_in_root:
|
||||
manifest_path = "manifest.json"
|
||||
else:
|
||||
manifest_path = f"{repository.content.path.remote}/manifest.json"
|
||||
if not manifest_path in [x.full_path for x in repository.tree]:
|
||||
raise HacsException(f"No file found '{manifest_path}'")
|
||||
try:
|
||||
manifest = await repository.repository_object.get_contents(
|
||||
manifest_path, repository.ref
|
||||
)
|
||||
manifest = json.loads(manifest.content)
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
raise HacsException(f"Could not read manifest.json [{exception}]")
|
||||
|
||||
try:
|
||||
repository.integration_manifest = manifest
|
||||
repository.data.authors = manifest["codeowners"]
|
||||
repository.data.domain = manifest["domain"]
|
||||
repository.data.manifest_name = manifest["name"]
|
||||
repository.data.config_flow = manifest.get("config_flow", False)
|
||||
|
||||
if repository.hacs.action:
|
||||
if manifest.get("documentation") is None:
|
||||
raise HacsException("manifest.json is missing documentation")
|
||||
if manifest.get("homeassistant") is not None:
|
||||
raise HacsException(
|
||||
"The homeassistant key in manifest.json is no longer valid"
|
||||
)
|
||||
# if manifest.get("issue_tracker") is None:
|
||||
# raise HacsException("The 'issue_tracker' is missing in manifest.json")
|
||||
|
||||
# Set local path
|
||||
repository.content.path.local = repository.localpath
|
||||
|
||||
except KeyError as exception:
|
||||
raise HacsException(f"Missing expected key {exception} in '{manifest_path}'")
|
||||
|
||||
|
||||
def find_file_name(repository):
|
||||
"""Get the filename to target."""
|
||||
if repository.data.category == "plugin":
|
||||
get_file_name_plugin(repository)
|
||||
elif repository.data.category == "integration":
|
||||
get_file_name_integration(repository)
|
||||
elif repository.data.category == "theme":
|
||||
get_file_name_theme(repository)
|
||||
elif repository.data.category == "appdaemon":
|
||||
get_file_name_appdaemon(repository)
|
||||
elif repository.data.category == "python_script":
|
||||
get_file_name_python_script(repository)
|
||||
|
||||
if repository.hacs.action:
|
||||
repository.logger.info(f"filename {repository.data.file_name}")
|
||||
repository.logger.info(f"location {repository.content.path.remote}")
|
||||
|
||||
|
||||
def get_file_name_plugin(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
releases = repository.releases.objects
|
||||
|
||||
if repository.data.content_in_root:
|
||||
possible_locations = [""]
|
||||
else:
|
||||
possible_locations = ["release", "dist", ""]
|
||||
|
||||
# Handler for plug requirement 3
|
||||
if repository.data.filename:
|
||||
valid_filenames = [repository.data.filename]
|
||||
else:
|
||||
valid_filenames = [
|
||||
f"{repository.data.name.replace('lovelace-', '')}.js",
|
||||
f"{repository.data.name}.js",
|
||||
f"{repository.data.name}.umd.js",
|
||||
f"{repository.data.name}-bundle.js",
|
||||
]
|
||||
|
||||
for location in possible_locations:
|
||||
if location == "release":
|
||||
if not releases:
|
||||
continue
|
||||
release = releases[0]
|
||||
if not release.assets:
|
||||
continue
|
||||
asset = release.assets[0]
|
||||
for filename in valid_filenames:
|
||||
if filename == asset.name:
|
||||
repository.data.file_name = filename
|
||||
repository.content.path.remote = "release"
|
||||
break
|
||||
|
||||
else:
|
||||
for filename in valid_filenames:
|
||||
if f"{location+'/' if location else ''}{filename}" in [
|
||||
x.full_path for x in tree
|
||||
]:
|
||||
repository.data.file_name = filename.split("/")[-1]
|
||||
repository.content.path.remote = location
|
||||
break
|
||||
|
||||
|
||||
def get_file_name_integration(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
releases = repository.releases.objects
|
||||
|
||||
|
||||
def get_file_name_theme(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
|
||||
for treefile in tree:
|
||||
if treefile.full_path.startswith(
|
||||
repository.content.path.remote
|
||||
) and treefile.full_path.endswith(".yaml"):
|
||||
repository.data.file_name = treefile.filename
|
||||
|
||||
|
||||
def get_file_name_appdaemon(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
releases = repository.releases.objects
|
||||
|
||||
|
||||
def get_file_name_python_script(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
|
||||
for treefile in tree:
|
||||
if treefile.full_path.startswith(
|
||||
repository.content.path.remote
|
||||
) and treefile.full_path.endswith(".py"):
|
||||
repository.data.file_name = treefile.filename
|
|
@ -1,93 +0,0 @@
|
|||
"""Install helper for repositories."""
|
||||
import os
|
||||
import tempfile
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.hacsbase.backup import Backup, BackupNetDaemon
|
||||
from custom_components.hacs.helpers.download import download_content
|
||||
|
||||
|
||||
async def install_repository(repository):
|
||||
"""Common installation steps of the repository."""
|
||||
persistent_directory = None
|
||||
await repository.update_repository()
|
||||
if repository.content.path.local is None:
|
||||
raise HacsException("repository.content.path.local is None")
|
||||
repository.validate.errors = []
|
||||
|
||||
if not repository.can_install:
|
||||
raise HacsException(
|
||||
"The version of Home Assistant is not compatible with this version"
|
||||
)
|
||||
|
||||
version = version_to_install(repository)
|
||||
if version == repository.data.default_branch:
|
||||
repository.ref = version
|
||||
else:
|
||||
repository.ref = f"tags/{version}"
|
||||
|
||||
if repository.data.installed and repository.data.category == "netdaemon":
|
||||
persistent_directory = BackupNetDaemon(repository)
|
||||
persistent_directory.create()
|
||||
|
||||
elif repository.data.persistent_directory:
|
||||
if os.path.exists(
|
||||
f"{repository.content.path.local}/{repository.data.persistent_directory}"
|
||||
):
|
||||
persistent_directory = Backup(
|
||||
f"{repository.content.path.local}/{repository.data.persistent_directory}",
|
||||
tempfile.gettempdir() + "/hacs_persistent_directory/",
|
||||
)
|
||||
persistent_directory.create()
|
||||
|
||||
if repository.data.installed and not repository.content.single:
|
||||
backup = Backup(repository.content.path.local)
|
||||
backup.create()
|
||||
|
||||
if repository.data.zip_release and version != repository.data.default_branch:
|
||||
await repository.download_zip(repository)
|
||||
else:
|
||||
await download_content(repository)
|
||||
|
||||
if repository.validate.errors:
|
||||
for error in repository.validate.errors:
|
||||
repository.logger.error(error)
|
||||
if repository.data.installed and not repository.content.single:
|
||||
backup.restore()
|
||||
|
||||
if repository.data.installed and not repository.content.single:
|
||||
backup.cleanup()
|
||||
|
||||
if persistent_directory is not None:
|
||||
persistent_directory.restore()
|
||||
persistent_directory.cleanup()
|
||||
|
||||
if repository.validate.success:
|
||||
if repository.data.full_name not in repository.hacs.common.installed:
|
||||
if repository.data.full_name == "hacs/integration":
|
||||
repository.hacs.common.installed.append(repository.data.full_name)
|
||||
repository.data.installed = True
|
||||
repository.data.installed_commit = repository.data.last_commit
|
||||
|
||||
if version == repository.data.default_branch:
|
||||
repository.data.installed_version = None
|
||||
else:
|
||||
repository.data.installed_version = version
|
||||
|
||||
|
||||
def version_to_install(repository):
|
||||
"""Determine which version to isntall."""
|
||||
if repository.data.last_version is not None:
|
||||
if repository.data.selected_tag is not None:
|
||||
if repository.data.selected_tag == repository.data.last_version:
|
||||
repository.data.selected_tag = None
|
||||
return repository.data.last_version
|
||||
return repository.data.selected_tag
|
||||
return repository.data.last_version
|
||||
if repository.data.selected_tag is not None:
|
||||
if repository.data.selected_tag == repository.data.default_branch:
|
||||
return repository.data.default_branch
|
||||
if repository.data.selected_tag in repository.data.published_tags:
|
||||
return repository.data.selected_tag
|
||||
if repository.data.default_branch is None:
|
||||
return "master"
|
||||
return repository.data.default_branch
|
|
@ -1,30 +0,0 @@
|
|||
"""Helper functions: misc"""
|
||||
import semantic_version
|
||||
|
||||
|
||||
def get_repository_name(repository) -> str:
|
||||
"""Return the name of the repository for use in the frontend."""
|
||||
|
||||
if repository.repository_manifest.name is not None:
|
||||
return repository.repository_manifest.name
|
||||
|
||||
if repository.data.category == "integration":
|
||||
if repository.integration_manifest:
|
||||
if "name" in repository.integration_manifest:
|
||||
return repository.integration_manifest["name"]
|
||||
|
||||
return (
|
||||
repository.data.full_name.split("/")[-1]
|
||||
.replace("-", " ")
|
||||
.replace("_", " ")
|
||||
.title()
|
||||
)
|
||||
|
||||
|
||||
def version_left_higher_then_right(new: str, old: str) -> bool:
|
||||
"""Return a bool if source is newer than target, will also be true if identical."""
|
||||
if not isinstance(new, str) or not isinstance(old, str):
|
||||
return False
|
||||
if new == old:
|
||||
return True
|
||||
return semantic_version.Version.coerce(new) > semantic_version.Version.coerce(old)
|
|
@ -1,8 +0,0 @@
|
|||
"""Verify network."""
|
||||
from socket import gaierror
|
||||
from integrationhelper import Logger
|
||||
|
||||
|
||||
def internet_connectivity_check(host="api.github.com"):
|
||||
"""Verify network connectivity."""
|
||||
return True
|
|
@ -1,68 +0,0 @@
|
|||
"""Register a repository."""
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.hacsbase.exceptions import (
|
||||
HacsException,
|
||||
HacsExpectedException,
|
||||
)
|
||||
|
||||
|
||||
# @concurrent(15, 5)
|
||||
async def register_repository(full_name, category, check=True, ref=None, action=False):
|
||||
"""Register a repository."""
|
||||
hacs = get_hacs()
|
||||
hacs.action = action
|
||||
from custom_components.hacs.repositories import (
|
||||
RERPOSITORY_CLASSES,
|
||||
) # To hanle import error
|
||||
|
||||
if full_name in hacs.common.skip:
|
||||
if full_name != "hacs/integration":
|
||||
raise HacsExpectedException(f"Skipping {full_name}")
|
||||
|
||||
if category not in RERPOSITORY_CLASSES:
|
||||
raise HacsException(f"{category} is not a valid repository category.")
|
||||
|
||||
repository = RERPOSITORY_CLASSES[category](full_name)
|
||||
if check:
|
||||
try:
|
||||
await repository.async_registration(ref)
|
||||
if hacs.system.status.new:
|
||||
repository.data.new = False
|
||||
if repository.validate.errors:
|
||||
hacs.common.skip.append(repository.data.full_name)
|
||||
if not hacs.system.status.startup:
|
||||
hacs.logger.error(f"Validation for {full_name} failed.")
|
||||
if hacs.action:
|
||||
raise HacsException(f"Validation for {full_name} failed.")
|
||||
return repository.validate.errors
|
||||
if hacs.action:
|
||||
repository.logger.info("Validation complete")
|
||||
else:
|
||||
repository.logger.info("Registration complete")
|
||||
except AIOGitHubAPIException as exception:
|
||||
hacs.common.skip.append(repository.data.full_name)
|
||||
raise HacsException(f"Validation for {full_name} failed with {exception}.")
|
||||
|
||||
exists = (
|
||||
False
|
||||
if str(repository.data.id) == "0"
|
||||
else [x for x in hacs.repositories if str(x.data.id) == str(repository.data.id)]
|
||||
)
|
||||
|
||||
if exists:
|
||||
if exists[0] in hacs.repositories:
|
||||
hacs.repositories.remove(exists[0])
|
||||
|
||||
else:
|
||||
if hacs.hass is not None:
|
||||
hacs.hass.bus.async_fire(
|
||||
"hacs/repository",
|
||||
{
|
||||
"id": 1337,
|
||||
"action": "registration",
|
||||
"repository": repository.data.full_name,
|
||||
"repository_id": repository.data.id,
|
||||
},
|
||||
)
|
||||
hacs.repositories.append(repository)
|
|
@ -1,92 +0,0 @@
|
|||
"""Helper to do common validation for repositories."""
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from custom_components.hacs.globals import get_hacs, is_removed
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.install import version_to_install
|
||||
from custom_components.hacs.helpers.information import (
|
||||
get_repository,
|
||||
get_tree,
|
||||
get_releases,
|
||||
)
|
||||
|
||||
|
||||
async def common_validate(repository, ignore_issues=False):
|
||||
"""Common validation steps of the repository."""
|
||||
repository.validate.errors = []
|
||||
|
||||
# Make sure the repository exist.
|
||||
repository.logger.debug("Checking repository.")
|
||||
await common_update_data(repository, ignore_issues)
|
||||
|
||||
# Step 6: Get the content of hacs.json
|
||||
await repository.get_repository_manifest_content()
|
||||
|
||||
|
||||
async def common_update_data(repository, ignore_issues=False):
|
||||
"""Common update data."""
|
||||
hacs = get_hacs()
|
||||
try:
|
||||
repository_object = await get_repository(
|
||||
hacs.session, hacs.configuration.token, repository.data.full_name
|
||||
)
|
||||
repository.repository_object = repository_object
|
||||
repository.data.update_data(repository_object.attributes)
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
if not hacs.system.status.startup:
|
||||
repository.logger.error(exception)
|
||||
repository.validate.errors.append("Repository does not exist.")
|
||||
raise HacsException(exception)
|
||||
|
||||
# Make sure the repository is not archived.
|
||||
if repository.data.archived and not ignore_issues:
|
||||
repository.validate.errors.append("Repository is archived.")
|
||||
raise HacsException("Repository is archived.")
|
||||
|
||||
# Make sure the repository is not in the blacklist.
|
||||
if is_removed(repository.data.full_name) and not ignore_issues:
|
||||
repository.validate.errors.append("Repository is in the blacklist.")
|
||||
raise HacsException("Repository is in the blacklist.")
|
||||
|
||||
# Get releases.
|
||||
try:
|
||||
releases = await get_releases(
|
||||
repository.repository_object,
|
||||
repository.data.show_beta,
|
||||
hacs.configuration.release_limit,
|
||||
)
|
||||
if releases:
|
||||
repository.data.releases = True
|
||||
repository.releases.objects = releases
|
||||
repository.data.published_tags = [
|
||||
x.tag_name for x in releases if not x.draft
|
||||
]
|
||||
repository.data.last_version = next(iter(releases)).tag_name
|
||||
|
||||
except (AIOGitHubAPIException, HacsException):
|
||||
repository.data.releases = False
|
||||
|
||||
if not repository.force_branch:
|
||||
repository.ref = version_to_install(repository)
|
||||
if repository.data.releases:
|
||||
for release in releases:
|
||||
if release.tag_name == repository.ref:
|
||||
assets = release.assets
|
||||
if assets:
|
||||
downloads = next(iter(assets)).attributes.get("download_count")
|
||||
repository.data.downloads = downloads
|
||||
|
||||
repository.logger.debug(
|
||||
f"Running checks against {repository.ref.replace('tags/', '')}"
|
||||
)
|
||||
|
||||
try:
|
||||
repository.tree = await get_tree(repository.repository_object, repository.ref)
|
||||
if not repository.tree:
|
||||
raise HacsException("No files in tree")
|
||||
repository.treefiles = []
|
||||
for treefile in repository.tree:
|
||||
repository.treefiles.append(treefile.full_path)
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
if not hacs.system.status.startup:
|
||||
repository.logger.error(exception)
|
||||
raise HacsException(exception)
|
|
@ -1,89 +0,0 @@
|
|||
"""HACS http endpoints."""
|
||||
import os
|
||||
from integrationhelper import Logger
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from aiohttp import web
|
||||
from hacs_frontend import locate_gz, locate_debug_gz
|
||||
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
|
||||
IGNORE = ["class-map.js.map"]
|
||||
|
||||
|
||||
class HacsFrontend(HomeAssistantView):
|
||||
"""Base View Class for HACS."""
|
||||
|
||||
requires_auth = False
|
||||
name = "hacs_files"
|
||||
url = r"/hacsfiles/{requested_file:.+}"
|
||||
|
||||
async def get(self, request, requested_file): # pylint: disable=unused-argument
|
||||
"""Handle HACS Web requests."""
|
||||
return await get_file_response(requested_file)
|
||||
|
||||
|
||||
async def get_file_response(requested_file):
|
||||
"""Get file."""
|
||||
hacs = get_hacs()
|
||||
|
||||
if requested_file in IGNORE:
|
||||
hacs.logger.debug(f"Ignoring request for {requested_file}")
|
||||
return web.Response(status=200)
|
||||
|
||||
if requested_file.startswith("frontend-"):
|
||||
if hacs.configuration.debug:
|
||||
servefile = await hacs.hass.async_add_executor_job(locate_debug_gz)
|
||||
hacs.logger.debug("Serving DEBUG frontend")
|
||||
elif hacs.configuration.frontend_repo_url:
|
||||
hacs.logger.debug("Serving REMOTE DEVELOPMENT frontend")
|
||||
request = await hacs.session.get(f"{hacs.configuration.frontend_repo_url}/main.js")
|
||||
if request.status == 200:
|
||||
result = await request.read()
|
||||
response = web.Response(body=result)
|
||||
response.headers["Cache-Control"] = "no-store, max-age=0"
|
||||
response.headers["Pragma"] = "no-store"
|
||||
return response
|
||||
elif hacs.configuration.frontend_repo:
|
||||
hacs.logger.debug("Serving LOCAL DEVELOPMENT frontend")
|
||||
servefile = f"{hacs.configuration.frontend_repo}/hacs_frontend/main.js"
|
||||
else:
|
||||
servefile = await hacs.hass.async_add_executor_job(locate_gz)
|
||||
|
||||
if os.path.exists(servefile):
|
||||
response = web.FileResponse(servefile)
|
||||
if hacs.configuration.frontend_repo:
|
||||
response.headers["Cache-Control"] = "no-store, max-age=0"
|
||||
response.headers["Pragma"] = "no-store"
|
||||
|
||||
return response
|
||||
|
||||
elif requested_file == "iconset.js":
|
||||
return web.FileResponse(
|
||||
f"{hacs.system.config_path}/custom_components/hacs/iconset.js"
|
||||
)
|
||||
|
||||
try:
|
||||
if requested_file.startswith("themes"):
|
||||
file = f"{hacs.system.config_path}/{requested_file}"
|
||||
else:
|
||||
file = f"{hacs.system.config_path}/www/community/{requested_file}"
|
||||
|
||||
# Serve .gz if it exist
|
||||
if os.path.exists(file + ".gz"):
|
||||
file += ".gz"
|
||||
|
||||
if os.path.exists(file):
|
||||
hacs.logger.debug("Serving {} from {}".format(requested_file, file))
|
||||
response = web.FileResponse(file)
|
||||
response.headers["Cache-Control"] = "no-store, max-age=0"
|
||||
response.headers["Pragma"] = "no-store"
|
||||
return response
|
||||
else:
|
||||
hacs.logger.error(f"Tried to serve up '{file}' but it does not exist")
|
||||
|
||||
except Exception as error: # pylint: disable=broad-except
|
||||
hacs.logger.debug(
|
||||
"there was an issue trying to serve {} - {}".format(requested_file, error)
|
||||
)
|
||||
|
||||
return web.Response(status=404)
|
|
@ -1,7 +0,0 @@
|
|||
window.customIconsets = window.customIconsets || {};
|
||||
window.customIconsets["hacs"] = async () => {
|
||||
return {
|
||||
path:
|
||||
"m 20.064849,22.306912 c -0.0319,0.369835 -0.280561,0.707789 -0.656773,0.918212 -0.280572,0.153036 -0.605773,0.229553 -0.950094,0.229553 -0.0765,0 -0.146661,-0.0064 -0.216801,-0.01275 -0.605774,-0.05739 -1.135016,-0.344329 -1.402827,-0.7588 l 0.784304,-0.516495 c 0.0893,0.146659 0.344331,0.312448 0.707793,0.34433 0.235931,0.02551 0.471852,-0.01913 0.637643,-0.108401 0.101998,-0.05101 0.172171,-0.127529 0.17854,-0.191295 0.0065,-0.08289 -0.0255,-0.369835 -0.733293,-0.439975 -1.013854,-0.09565 -1.645127,-0.688661 -1.568606,-1.460214 0.0319,-0.382589 0.280561,-0.714165 0.663153,-0.930965 0.331571,-0.172165 0.752423,-0.25506 1.166895,-0.210424 0.599382,0.05739 1.128635,0.344329 1.402816,0.7588 l -0.784304,0.510118 c -0.0893,-0.140282 -0.344331,-0.299694 -0.707782,-0.331576 -0.235932,-0.02551 -0.471863,0.01913 -0.637654,0.10202 -0.0956,0.05739 -0.165791,0.133906 -0.17216,0.191295 -0.0255,0.293317 0.465482,0.420847 0.726913,0.439976 v 0.0064 c 1.020234,0.09565 1.638757,0.66953 1.562237,1.460213 z m -7.466854,-0.988354 c 0,-1.192401 0.962855,-2.155249 2.15525,-2.155249 0.599393,0 1.179645,0.25506 1.594117,0.707789 l -0.695033,0.624895 c -0.235931,-0.25506 -0.561133,-0.401718 -0.899084,-0.401718 -0.675903,0 -1.217906,0.542 -1.217906,1.217906 0,0.66953 0.542003,1.217908 1.217906,1.217908 0.337951,0 0.663153,-0.140283 0.899084,-0.401718 l 0.695033,0.631271 c -0.414472,0.452729 -0.988355,0.707788 -1.594117,0.707788 -1.192395,0 -2.15525,-0.969224 -2.15525,-2.148872 z M 8.6573365,23.461054 10.353474,19.14418 h 0.624893 l 1.568618,4.316874 H 11.52037 L 11.265308,22.734136 H 9.964513 l -0.274192,0.726918 z m 1.6833885,-1.68339 h 0.580263 L 10.646796,21.012487 Z M 8.1089536,19.156932 v 4.297745 H 7.1461095 v -1.645131 h -1.606867 v 1.645131 H 4.5763876 v -4.297745 h 0.9628549 v 1.696143 h 1.606867 V 19.156932 Z M 20.115859,4.2997436 C 20.090359,4.159461 19.969198,4.0574375 19.822548,4.0574375 H 14.141102 10.506516 4.8250686 c -0.14665,0 -0.2678112,0.1020202 -0.2933108,0.2423061 L 3.690064,8.8461703 c -0.00651,0.01913 -0.00651,0.03826 -0.00651,0.057391 v 1.5239797 c 0,0.165789 0.133911,0.299694 0.2996911,0.299694 H 4.5762579 20.0711 20.664112 c 0.165781,0 0.299691,-0.133905 0.299691,-0.299694 V 8.8971848 c 0,-0.01913 0,-0.03826 -0.0065,-0.05739 z M 4.5763876,17.358767 c 0,0.184917 0.1466608,0.331577 0.3315819,0.331577 h 5.5985465 3.634586 0.924594 c 0.184911,0 0.331571,-0.14666 0.331571,-0.331577 v -4.744098 c 0,-0.184918 0.146661,-0.331577 0.331582,-0.331577 h 2.894913 c 0.184921,0 0.331582,0.146659 0.331582,0.331577 v 4.744098 c 0,0.184917 0.146661,0.331577 0.331571,0.331577 h 0.446363 c 0.18491,0 0.331571,-0.14666 0.331571,-0.331577 v -5.636804 c 0,-0.184918 -0.146661,-0.331577 -0.331571,-0.331577 H 4.9079695 c -0.1849211,0 -0.3315819,0.146659 -0.3315819,0.331577 z m 1.6578879,-4.852498 h 5.6495565 c 0.15303,0 0.280561,0.12753 0.280561,0.280564 v 3.513438 c 0,0.153036 -0.127531,0.280566 -0.280561,0.280566 H 6.2342755 c -0.1530412,0 -0.2805719,-0.12753 -0.2805719,-0.280566 v -3.513438 c 0,-0.159411 0.1275307,-0.280564 0.2805719,-0.280564 z M 19.790657,3.3879075 H 4.8569594 c -0.1530412,0 -0.2805718,-0.1275296 -0.2805718,-0.2805642 V 1.3665653 C 4.5763876,1.2135296 4.7039182,1.086 4.8569594,1.086 H 19.790657 c 0.153041,0 0.280572,0.1275296 0.280572,0.2805653 v 1.740778 c 0,0.1530346 -0.127531,0.2805642 -0.280572,0.2805642 z",
|
||||
};
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"codeowners": ["@ludeeus"],
|
||||
"config_flow": true,
|
||||
"dependencies": [
|
||||
"websocket_api",
|
||||
"frontend",
|
||||
"persistent_notification",
|
||||
"lovelace"
|
||||
],
|
||||
"documentation": "https://hacs.xyz/docs/configuration/start",
|
||||
"issue_tracker": "https://github.com/hacs/integration/issues",
|
||||
"domain": "hacs",
|
||||
"name": "HACS",
|
||||
"requirements": [
|
||||
"aiofiles==0.5.0",
|
||||
"aiogithubapi==1.0.4",
|
||||
"backoff==1.10.0",
|
||||
"hacs_frontend==202006071141",
|
||||
"integrationhelper==0.2.2",
|
||||
"semantic_version==2.8.5",
|
||||
"queueman==0.5"
|
||||
]
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
"""Initialize repositories."""
|
||||
from custom_components.hacs.repositories.theme import HacsTheme
|
||||
from custom_components.hacs.repositories.integration import HacsIntegration
|
||||
from custom_components.hacs.repositories.python_script import HacsPythonScript
|
||||
from custom_components.hacs.repositories.appdaemon import HacsAppdaemon
|
||||
from custom_components.hacs.repositories.netdaemon import HacsNetdaemon
|
||||
from custom_components.hacs.repositories.plugin import HacsPlugin
|
||||
|
||||
RERPOSITORY_CLASSES = {
|
||||
"theme": HacsTheme,
|
||||
"integration": HacsIntegration,
|
||||
"python_script": HacsPythonScript,
|
||||
"appdaemon": HacsAppdaemon,
|
||||
"netdaemon": HacsNetdaemon,
|
||||
"plugin": HacsPlugin,
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
"""Class for appdaemon apps in HACS."""
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from integrationhelper import Logger
|
||||
|
||||
from .repository import HacsRepository
|
||||
from ..hacsbase.exceptions import HacsException
|
||||
|
||||
|
||||
class HacsAppdaemon(HacsRepository):
|
||||
"""Appdaemon apps in HACS."""
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.category = "appdaemon"
|
||||
self.content.path.local = self.localpath
|
||||
self.content.path.remote = "apps"
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/appdaemon/apps/{self.data.name}"
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
try:
|
||||
addir = await self.repository_object.get_contents("apps", self.ref)
|
||||
except AIOGitHubAPIException:
|
||||
raise HacsException(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
if not isinstance(addir, list):
|
||||
self.validate.errors.append("Repostitory structure not compliant")
|
||||
|
||||
self.content.path.remote = addir[0].path
|
||||
self.content.objects = await self.repository_object.get_contents(
|
||||
self.content.path.remote, self.ref
|
||||
)
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
# Get appdaemon objects.
|
||||
if self.repository_manifest:
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
if self.content.path.remote == "apps":
|
||||
addir = await self.repository_object.get_contents(
|
||||
self.content.path.remote, self.ref
|
||||
)
|
||||
self.content.path.remote = addir[0].path
|
||||
self.content.objects = await self.repository_object.get_contents(
|
||||
self.content.path.remote, self.ref
|
||||
)
|
||||
|
||||
# Set local path
|
||||
self.content.path.local = self.localpath
|
|
@ -1,94 +0,0 @@
|
|||
"""Class for integrations in HACS."""
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
from integrationhelper import Logger
|
||||
|
||||
from homeassistant.loader import async_get_custom_components
|
||||
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.filters import get_first_directory_in_directory
|
||||
from custom_components.hacs.helpers.information import get_integration_manifest
|
||||
from custom_components.hacs.repositories.repository import HacsRepository
|
||||
|
||||
|
||||
class HacsIntegration(HacsRepository):
|
||||
"""Integrations in HACS."""
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.category = "integration"
|
||||
self.content.path.remote = "custom_components"
|
||||
self.content.path.local = self.localpath
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/custom_components/{self.data.domain}"
|
||||
|
||||
async def async_post_installation(self):
|
||||
"""Run post installation steps."""
|
||||
if self.data.config_flow:
|
||||
if self.data.full_name != "hacs/integration":
|
||||
await self.reload_custom_components()
|
||||
if self.data.first_install:
|
||||
self.pending_restart = False
|
||||
return
|
||||
self.pending_restart = True
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
if self.content.path.remote == "custom_components":
|
||||
name = get_first_directory_in_directory(self.tree, "custom_components")
|
||||
if name is None:
|
||||
raise HacsException(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
self.content.path.remote = f"custom_components/{name}"
|
||||
|
||||
try:
|
||||
await get_integration_manifest(self)
|
||||
except HacsException as exception:
|
||||
if self.hacs.action:
|
||||
raise HacsException(exception)
|
||||
self.logger.error(exception)
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
if self.content.path.remote == "custom_components":
|
||||
name = get_first_directory_in_directory(self.tree, "custom_components")
|
||||
self.content.path.remote = f"custom_components/{name}"
|
||||
|
||||
try:
|
||||
await get_integration_manifest(self)
|
||||
except HacsException as exception:
|
||||
self.logger.error(exception)
|
||||
|
||||
# Set local path
|
||||
self.content.path.local = self.localpath
|
||||
|
||||
async def reload_custom_components(self):
|
||||
"""Reload custom_components (and config flows)in HA."""
|
||||
self.logger.info("Reloading custom_component cache")
|
||||
del self.hacs.hass.data["custom_components"]
|
||||
await async_get_custom_components(self.hacs.hass)
|
||||
self.logger.info("Custom_component cache reloaded")
|
|
@ -1,42 +0,0 @@
|
|||
"""
|
||||
Manifest handling of a repository.
|
||||
|
||||
https://hacs.xyz/docs/publish/start#hacsjson
|
||||
"""
|
||||
from typing import List
|
||||
import attr
|
||||
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class HacsManifest:
|
||||
"""HacsManifest class."""
|
||||
|
||||
name: str = None
|
||||
content_in_root: bool = False
|
||||
zip_release: bool = False
|
||||
filename: str = None
|
||||
manifest: dict = {}
|
||||
hacs: str = None
|
||||
hide_default_branch: bool = False
|
||||
domains: List[str] = []
|
||||
country: List[str] = []
|
||||
homeassistant: str = None
|
||||
persistent_directory: str = None
|
||||
iot_class: str = None
|
||||
render_readme: bool = False
|
||||
|
||||
@staticmethod
|
||||
def from_dict(manifest: dict):
|
||||
"""Set attributes from dicts."""
|
||||
if manifest is None:
|
||||
raise HacsException("Missing manifest data")
|
||||
|
||||
manifest_data = HacsManifest()
|
||||
|
||||
manifest_data.manifest = manifest
|
||||
|
||||
for key in manifest:
|
||||
setattr(manifest_data, key, manifest[key])
|
||||
return manifest_data
|
|
@ -1,86 +0,0 @@
|
|||
"""Class for netdaemon apps in HACS."""
|
||||
from integrationhelper import Logger
|
||||
|
||||
from .repository import HacsRepository
|
||||
from ..hacsbase.exceptions import HacsException
|
||||
|
||||
from custom_components.hacs.helpers.filters import get_first_directory_in_directory
|
||||
|
||||
|
||||
class HacsNetdaemon(HacsRepository):
|
||||
"""Netdaemon apps in HACS."""
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.category = "netdaemon"
|
||||
self.content.path.local = self.localpath
|
||||
self.content.path.remote = "apps"
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/netdaemon/apps/{self.data.name}"
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
if self.repository_manifest:
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
if self.content.path.remote == "apps":
|
||||
self.data.domain = get_first_directory_in_directory(
|
||||
self.tree, self.content.path.remote
|
||||
)
|
||||
self.content.path.remote = f"apps/{self.data.name}"
|
||||
|
||||
compliant = False
|
||||
for treefile in self.treefiles:
|
||||
if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(
|
||||
".cs"
|
||||
):
|
||||
compliant = True
|
||||
break
|
||||
if not compliant:
|
||||
raise HacsException(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
# Get appdaemon objects.
|
||||
if self.repository_manifest:
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
if self.content.path.remote == "apps":
|
||||
self.data.domain = get_first_directory_in_directory(
|
||||
self.tree, self.content.path.remote
|
||||
)
|
||||
self.content.path.remote = f"apps/{self.data.name}"
|
||||
|
||||
# Set local path
|
||||
self.content.path.local = self.localpath
|
||||
|
||||
async def async_post_installation(self):
|
||||
"""Run post installation steps."""
|
||||
try:
|
||||
await self.hacs.hass.services.async_call(
|
||||
"hassio", "addon_restart", {"addon": "c6a2317c_netdaemon"}
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
|
@ -1,75 +0,0 @@
|
|||
"""Class for plugins in HACS."""
|
||||
import json
|
||||
from integrationhelper import Logger
|
||||
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.information import find_file_name
|
||||
from custom_components.hacs.repositories.repository import HacsRepository
|
||||
|
||||
|
||||
class HacsPlugin(HacsRepository):
|
||||
"""Plugins in HACS."""
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.file_name = None
|
||||
self.data.category = "plugin"
|
||||
self.information.javascript_type = None
|
||||
self.content.path.local = self.localpath
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/www/community/{self.data.full_name.split('/')[-1]}"
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
# Run common validation steps.
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
find_file_name(self)
|
||||
|
||||
if self.content.path.remote is None:
|
||||
raise HacsException(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
if self.content.path.remote == "release":
|
||||
self.content.single = True
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
# Get plugin objects.
|
||||
find_file_name(self)
|
||||
|
||||
if self.content.path.remote is None:
|
||||
self.validate.errors.append(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
if self.content.path.remote == "release":
|
||||
self.content.single = True
|
||||
|
||||
async def get_package_content(self):
|
||||
"""Get package content."""
|
||||
try:
|
||||
package = await self.repository_object.get_contents("package.json")
|
||||
package = json.loads(package.content)
|
||||
|
||||
if package:
|
||||
self.data.authors = package["author"]
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
|
@ -1,83 +0,0 @@
|
|||
"""Class for python_scripts in HACS."""
|
||||
from integrationhelper import Logger
|
||||
|
||||
from .repository import HacsRepository
|
||||
from ..hacsbase.exceptions import HacsException
|
||||
from ..helpers.information import find_file_name
|
||||
|
||||
|
||||
class HacsPythonScript(HacsRepository):
|
||||
"""python_scripts in HACS."""
|
||||
|
||||
category = "python_script"
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.category = "python_script"
|
||||
self.content.path.remote = "python_scripts"
|
||||
self.content.path.local = self.localpath
|
||||
self.content.single = True
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/python_scripts"
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
# Run common validation steps.
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
compliant = False
|
||||
for treefile in self.treefiles:
|
||||
if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(
|
||||
".py"
|
||||
):
|
||||
compliant = True
|
||||
break
|
||||
if not compliant:
|
||||
raise HacsException(
|
||||
f"Repository structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def async_post_registration(self):
|
||||
"""Registration."""
|
||||
# Set name
|
||||
find_file_name(self)
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
# Get python_script objects.
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
compliant = False
|
||||
for treefile in self.treefiles:
|
||||
if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(
|
||||
".py"
|
||||
):
|
||||
compliant = True
|
||||
break
|
||||
if not compliant:
|
||||
raise HacsException(
|
||||
f"Repository structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
# Update name
|
||||
find_file_name(self)
|
|
@ -1,21 +0,0 @@
|
|||
"""Object for removed repositories."""
|
||||
import attr
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class RemovedRepository:
|
||||
repository: str = None
|
||||
reason: str = None
|
||||
link: str = None
|
||||
removal_type: str = None # archived, not_compliant, critical, dev, broken
|
||||
acknowledged: bool = False
|
||||
|
||||
def update_data(self, data: dict):
|
||||
"""Update data of the repository."""
|
||||
for key in data:
|
||||
if key in self.__dict__:
|
||||
setattr(self, key, data[key])
|
||||
|
||||
def to_json(self):
|
||||
"""Return a JSON representation of the data."""
|
||||
return self.__dict__
|
|
@ -1,395 +0,0 @@
|
|||
"""Repository."""
|
||||
# pylint: disable=broad-except, bad-continuation, no-member
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import zipfile
|
||||
from integrationhelper import Validate
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from .manifest import HacsManifest
|
||||
from ..helpers.misc import get_repository_name
|
||||
from ..handler.download import async_download_file, async_save_file
|
||||
from ..helpers.install import version_to_install
|
||||
|
||||
from custom_components.hacs.repositories.helpers import RepositoryHelpers
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.store import async_remove_store
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.helpers.information import (
|
||||
get_info_md_content,
|
||||
get_repository,
|
||||
)
|
||||
from custom_components.hacs.helpers.validate_repository import (
|
||||
common_validate,
|
||||
common_update_data,
|
||||
)
|
||||
from custom_components.hacs.repositories.repositorydata import RepositoryData
|
||||
|
||||
|
||||
class RepositoryVersions:
|
||||
"""Versions."""
|
||||
|
||||
available = None
|
||||
available_commit = None
|
||||
installed = None
|
||||
installed_commit = None
|
||||
|
||||
|
||||
class RepositoryStatus:
|
||||
"""Repository status."""
|
||||
|
||||
hide = False
|
||||
installed = False
|
||||
last_updated = None
|
||||
new = True
|
||||
selected_tag = None
|
||||
show_beta = False
|
||||
track = True
|
||||
updated_info = False
|
||||
first_install = True
|
||||
|
||||
|
||||
class RepositoryInformation:
|
||||
"""RepositoryInformation."""
|
||||
|
||||
additional_info = None
|
||||
authors = []
|
||||
category = None
|
||||
default_branch = None
|
||||
description = ""
|
||||
state = None
|
||||
full_name = None
|
||||
file_name = None
|
||||
javascript_type = None
|
||||
homeassistant_version = None
|
||||
last_updated = None
|
||||
uid = None
|
||||
stars = 0
|
||||
info = None
|
||||
name = None
|
||||
topics = []
|
||||
|
||||
|
||||
class RepositoryReleases:
|
||||
"""RepositoyReleases."""
|
||||
|
||||
last_release = None
|
||||
last_release_object = None
|
||||
last_release_object_downloads = None
|
||||
published_tags = []
|
||||
objects = []
|
||||
releases = False
|
||||
downloads = None
|
||||
|
||||
|
||||
class RepositoryPath:
|
||||
"""RepositoryPath."""
|
||||
|
||||
local = None
|
||||
remote = None
|
||||
|
||||
|
||||
class RepositoryContent:
|
||||
"""RepositoryContent."""
|
||||
|
||||
path = None
|
||||
files = []
|
||||
objects = []
|
||||
single = False
|
||||
|
||||
|
||||
class HacsRepository(RepositoryHelpers):
|
||||
"""HacsRepository."""
|
||||
|
||||
def __init__(self):
|
||||
"""Set up HacsRepository."""
|
||||
self.hacs = get_hacs()
|
||||
self.data = RepositoryData()
|
||||
self.content = RepositoryContent()
|
||||
self.content.path = RepositoryPath()
|
||||
self.information = RepositoryInformation()
|
||||
self.repository_object = None
|
||||
self.status = RepositoryStatus()
|
||||
self.state = None
|
||||
self.force_branch = False
|
||||
self.integration_manifest = {}
|
||||
self.repository_manifest = HacsManifest.from_dict({})
|
||||
self.validate = Validate()
|
||||
self.releases = RepositoryReleases()
|
||||
self.versions = RepositoryVersions()
|
||||
self.pending_restart = False
|
||||
self.tree = []
|
||||
self.treefiles = []
|
||||
self.ref = None
|
||||
|
||||
@property
|
||||
def display_name(self):
|
||||
"""Return display name."""
|
||||
return get_repository_name(self)
|
||||
|
||||
@property
|
||||
def display_status(self):
|
||||
"""Return display_status."""
|
||||
if self.data.new:
|
||||
status = "new"
|
||||
elif self.pending_restart:
|
||||
status = "pending-restart"
|
||||
elif self.pending_upgrade:
|
||||
status = "pending-upgrade"
|
||||
elif self.data.installed:
|
||||
status = "installed"
|
||||
else:
|
||||
status = "default"
|
||||
return status
|
||||
|
||||
@property
|
||||
def display_status_description(self):
|
||||
"""Return display_status_description."""
|
||||
description = {
|
||||
"default": "Not installed.",
|
||||
"pending-restart": "Restart pending.",
|
||||
"pending-upgrade": "Upgrade pending.",
|
||||
"installed": "No action required.",
|
||||
"new": "This is a newly added repository.",
|
||||
}
|
||||
return description[self.display_status]
|
||||
|
||||
@property
|
||||
def display_installed_version(self):
|
||||
"""Return display_authors"""
|
||||
if self.data.installed_version is not None:
|
||||
installed = self.data.installed_version
|
||||
else:
|
||||
if self.data.installed_commit is not None:
|
||||
installed = self.data.installed_commit
|
||||
else:
|
||||
installed = ""
|
||||
return installed
|
||||
|
||||
@property
|
||||
def display_available_version(self):
|
||||
"""Return display_authors"""
|
||||
if self.data.last_version is not None:
|
||||
available = self.data.last_version
|
||||
else:
|
||||
if self.data.last_commit is not None:
|
||||
available = self.data.last_commit
|
||||
else:
|
||||
available = ""
|
||||
return available
|
||||
|
||||
@property
|
||||
def display_version_or_commit(self):
|
||||
"""Does the repositoriy use releases or commits?"""
|
||||
if self.data.releases:
|
||||
version_or_commit = "version"
|
||||
else:
|
||||
version_or_commit = "commit"
|
||||
return version_or_commit
|
||||
|
||||
@property
|
||||
def main_action(self):
|
||||
"""Return the main action."""
|
||||
actions = {
|
||||
"new": "INSTALL",
|
||||
"default": "INSTALL",
|
||||
"installed": "REINSTALL",
|
||||
"pending-restart": "REINSTALL",
|
||||
"pending-upgrade": "UPGRADE",
|
||||
}
|
||||
return actions[self.display_status]
|
||||
|
||||
async def common_validate(self, ignore_issues=False):
|
||||
"""Common validation steps of the repository."""
|
||||
await common_validate(self, ignore_issues)
|
||||
|
||||
async def common_registration(self):
|
||||
"""Common registration steps of the repository."""
|
||||
# Attach repository
|
||||
if self.repository_object is None:
|
||||
self.repository_object = await get_repository(
|
||||
self.hacs.session, self.hacs.configuration.token, self.data.full_name
|
||||
)
|
||||
self.data.update_data(self.repository_object.attributes)
|
||||
|
||||
# Set topics
|
||||
self.data.topics = self.data.topics
|
||||
|
||||
# Set stargazers_count
|
||||
self.data.stargazers_count = self.data.stargazers_count
|
||||
|
||||
# Set description
|
||||
self.data.description = self.data.description
|
||||
|
||||
if self.hacs.action:
|
||||
if self.data.description is None or len(self.data.description) == 0:
|
||||
raise HacsException("Missing repository description")
|
||||
|
||||
async def common_update(self, ignore_issues=False):
|
||||
"""Common information update steps of the repository."""
|
||||
self.logger.debug("Getting repository information")
|
||||
|
||||
# Attach repository
|
||||
await common_update_data(self, ignore_issues)
|
||||
|
||||
# Update last updaeted
|
||||
self.data.last_updated = self.repository_object.attributes.get("pushed_at", 0)
|
||||
|
||||
# Update last available commit
|
||||
await self.repository_object.set_last_commit()
|
||||
self.data.last_commit = self.repository_object.last_commit
|
||||
|
||||
# Get the content of hacs.json
|
||||
await self.get_repository_manifest_content()
|
||||
|
||||
# Update "info.md"
|
||||
self.information.additional_info = await get_info_md_content(self)
|
||||
|
||||
async def download_zip(self, validate):
|
||||
"""Download ZIP archive from repository release."""
|
||||
try:
|
||||
contents = False
|
||||
|
||||
for release in self.releases.objects:
|
||||
self.logger.info(f"ref: {self.ref} --- tag: {release.tag_name}")
|
||||
if release.tag_name == self.ref.split("/")[1]:
|
||||
contents = release.assets
|
||||
|
||||
if not contents:
|
||||
return validate
|
||||
|
||||
for content in contents or []:
|
||||
filecontent = await async_download_file(content.download_url)
|
||||
|
||||
if filecontent is None:
|
||||
validate.errors.append(f"[{content.name}] was not downloaded.")
|
||||
continue
|
||||
|
||||
result = await async_save_file(
|
||||
f"{tempfile.gettempdir()}/{self.data.filename}", filecontent
|
||||
)
|
||||
with zipfile.ZipFile(
|
||||
f"{tempfile.gettempdir()}/{self.data.filename}", "r"
|
||||
) as zip_file:
|
||||
zip_file.extractall(self.content.path.local)
|
||||
|
||||
if result:
|
||||
self.logger.info(f"download of {content.name} complete")
|
||||
continue
|
||||
validate.errors.append(f"[{content.name}] was not downloaded.")
|
||||
except Exception:
|
||||
validate.errors.append(f"Download was not complete.")
|
||||
|
||||
return validate
|
||||
|
||||
async def download_content(self, validate, directory_path, local_directory, ref):
|
||||
"""Download the content of a directory."""
|
||||
from custom_components.hacs.helpers.download import download_content
|
||||
|
||||
validate = await download_content(self)
|
||||
return validate
|
||||
|
||||
async def get_repository_manifest_content(self):
|
||||
"""Get the content of the hacs.json file."""
|
||||
if not "hacs.json" in [x.filename for x in self.tree]:
|
||||
if self.hacs.action:
|
||||
raise HacsException("No hacs.json file in the root of the repository.")
|
||||
return
|
||||
if self.hacs.action:
|
||||
self.logger.info("Found hacs.json")
|
||||
|
||||
self.ref = version_to_install(self)
|
||||
|
||||
try:
|
||||
manifest = await self.repository_object.get_contents("hacs.json", self.ref)
|
||||
self.repository_manifest = HacsManifest.from_dict(
|
||||
json.loads(manifest.content)
|
||||
)
|
||||
self.data.update_data(json.loads(manifest.content))
|
||||
if self.hacs.action:
|
||||
self.logger.info(json.loads(manifest.content))
|
||||
except (AIOGitHubAPIException, Exception) as exception: # Gotta Catch 'Em All
|
||||
if self.hacs.action:
|
||||
raise HacsException(f"hacs.json file is not valid ({exception}).")
|
||||
if self.hacs.action:
|
||||
self.logger.info("hacs.json is valid")
|
||||
|
||||
def remove(self):
|
||||
"""Run remove tasks."""
|
||||
self.logger.info("Starting removal")
|
||||
|
||||
if self.data.id in self.hacs.common.installed:
|
||||
self.hacs.common.installed.remove(self.data.id)
|
||||
for repository in self.hacs.repositories:
|
||||
if repository.data.id == self.data.id:
|
||||
self.hacs.repositories.remove(repository)
|
||||
|
||||
async def uninstall(self):
|
||||
"""Run uninstall tasks."""
|
||||
self.logger.info("Uninstalling")
|
||||
if not await self.remove_local_directory():
|
||||
raise HacsException("Could not uninstall")
|
||||
self.data.installed = False
|
||||
if self.data.category == "integration":
|
||||
if self.data.config_flow:
|
||||
await self.reload_custom_components()
|
||||
else:
|
||||
self.pending_restart = True
|
||||
elif self.data.category == "theme":
|
||||
try:
|
||||
await self.hacs.hass.services.async_call(
|
||||
"frontend", "reload_themes", {}
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
if self.data.full_name in self.hacs.common.installed:
|
||||
self.hacs.common.installed.remove(self.data.full_name)
|
||||
|
||||
await async_remove_store(self.hacs.hass, f"hacs/{self.data.id}.hacs")
|
||||
|
||||
self.data.installed_version = None
|
||||
self.data.installed_commit = None
|
||||
self.hacs.hass.bus.async_fire(
|
||||
"hacs/repository",
|
||||
{"id": 1337, "action": "uninstall", "repository": self.data.full_name},
|
||||
)
|
||||
|
||||
async def remove_local_directory(self):
|
||||
"""Check the local directory."""
|
||||
import shutil
|
||||
from asyncio import sleep
|
||||
|
||||
try:
|
||||
if self.data.category == "python_script":
|
||||
local_path = "{}/{}.py".format(self.content.path.local, self.data.name)
|
||||
elif self.data.category == "theme":
|
||||
if os.path.exists(
|
||||
f"{self.hacs.system.config_path}/{self.hacs.configuration.theme_path}/{self.data.name}.yaml"
|
||||
):
|
||||
os.remove(
|
||||
f"{self.hacs.system.config_path}/{self.hacs.configuration.theme_path}/{self.data.name}.yaml"
|
||||
)
|
||||
local_path = self.content.path.local
|
||||
elif self.data.category == "integration":
|
||||
if not self.data.domain:
|
||||
self.logger.error("Missing domain")
|
||||
return False
|
||||
local_path = self.content.path.local
|
||||
else:
|
||||
local_path = self.content.path.local
|
||||
|
||||
if os.path.exists(local_path):
|
||||
self.logger.debug(f"Removing {local_path}")
|
||||
|
||||
if self.data.category in ["python_script"]:
|
||||
os.remove(local_path)
|
||||
else:
|
||||
shutil.rmtree(local_path)
|
||||
|
||||
while os.path.exists(local_path):
|
||||
await sleep(1)
|
||||
|
||||
except Exception as exception:
|
||||
self.logger.debug(f"Removing {local_path} failed with {exception}")
|
||||
return False
|
||||
return True
|
|
@ -1,126 +0,0 @@
|
|||
"""Repository data."""
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
import attr
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class RepositoryData:
|
||||
"""RepositoryData class."""
|
||||
|
||||
archived: bool = False
|
||||
authors: List[str] = []
|
||||
category: str = ""
|
||||
content_in_root: bool = False
|
||||
country: List[str] = []
|
||||
config_flow: bool = False
|
||||
default_branch: str = None
|
||||
description: str = ""
|
||||
domain: str = ""
|
||||
domains: List[str] = []
|
||||
downloads: int = 0
|
||||
file_name: str = ""
|
||||
filename: str = ""
|
||||
first_install: bool = False
|
||||
fork: bool = False
|
||||
full_name: str = ""
|
||||
hacs: str = None # Minimum HACS version
|
||||
hide: bool = False
|
||||
hide_default_branch: bool = False
|
||||
homeassistant: str = None # Minimum Home Assistant version
|
||||
id: int = 0
|
||||
iot_class: str = None
|
||||
installed: bool = False
|
||||
installed_commit: str = None
|
||||
installed_version: str = None
|
||||
open_issues: int = 0
|
||||
last_commit: str = None
|
||||
last_version: str = None
|
||||
last_updated: str = 0
|
||||
manifest_name: str = None
|
||||
new: bool = True
|
||||
persistent_directory: str = None
|
||||
pushed_at: str = ""
|
||||
releases: bool = False
|
||||
render_readme: bool = False
|
||||
published_tags: List[str] = []
|
||||
selected_tag: str = None
|
||||
show_beta: bool = False
|
||||
stargazers_count: int = 0
|
||||
topics: List[str] = []
|
||||
zip_release: bool = False
|
||||
|
||||
@property
|
||||
def stars(self):
|
||||
"""Return the stargazers count."""
|
||||
return self.stargazers_count or 0
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
if self.category in ["integration", "netdaemon"]:
|
||||
return self.domain
|
||||
return self.full_name.split("/")[-1]
|
||||
|
||||
def to_json(self):
|
||||
"""Export to json."""
|
||||
return self.__dict__
|
||||
|
||||
@staticmethod
|
||||
def create_from_dict(source: dict):
|
||||
"""Set attributes from dicts."""
|
||||
data = RepositoryData()
|
||||
for key in source:
|
||||
if key in data.__dict__:
|
||||
if key == "pushed_at":
|
||||
if source[key] == "":
|
||||
continue
|
||||
if "Z" in source[key]:
|
||||
setattr(
|
||||
data,
|
||||
key,
|
||||
datetime.strptime(source[key], "%Y-%m-%dT%H:%M:%SZ"),
|
||||
)
|
||||
else:
|
||||
setattr(
|
||||
data,
|
||||
key,
|
||||
datetime.strptime(source[key], "%Y-%m-%dT%H:%M:%S"),
|
||||
)
|
||||
elif key == "id":
|
||||
setattr(data, key, str(source[key]))
|
||||
elif key == "county":
|
||||
if isinstance(source[key], str):
|
||||
setattr(data, key, [source[key]])
|
||||
else:
|
||||
setattr(data, key, source[key])
|
||||
else:
|
||||
setattr(data, key, source[key])
|
||||
return data
|
||||
|
||||
def update_data(self, data: dict):
|
||||
"""Update data of the repository."""
|
||||
for key in data:
|
||||
if key in self.__dict__:
|
||||
if key == "pushed_at":
|
||||
if data[key] == "":
|
||||
continue
|
||||
if "Z" in data[key]:
|
||||
setattr(
|
||||
self,
|
||||
key,
|
||||
datetime.strptime(data[key], "%Y-%m-%dT%H:%M:%SZ"),
|
||||
)
|
||||
else:
|
||||
setattr(
|
||||
self, key, datetime.strptime(data[key], "%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
elif key == "id":
|
||||
setattr(self, key, str(data[key]))
|
||||
elif key == "county":
|
||||
if isinstance(data[key], str):
|
||||
setattr(self, key, [data[key]])
|
||||
else:
|
||||
setattr(self, key, data[key])
|
||||
else:
|
||||
setattr(self, key, data[key])
|
|
@ -1,76 +0,0 @@
|
|||
"""Class for themes in HACS."""
|
||||
from integrationhelper import Logger
|
||||
from .repository import HacsRepository
|
||||
from ..hacsbase.exceptions import HacsException
|
||||
from ..helpers.information import find_file_name
|
||||
|
||||
|
||||
class HacsTheme(HacsRepository):
|
||||
"""Themes in HACS."""
|
||||
|
||||
def __init__(self, full_name):
|
||||
"""Initialize."""
|
||||
super().__init__()
|
||||
self.data.full_name = full_name
|
||||
self.data.category = "theme"
|
||||
self.content.path.remote = "themes"
|
||||
self.content.path.local = self.localpath
|
||||
self.content.single = False
|
||||
self.logger = Logger(f"hacs.repository.{self.data.category}.{full_name}")
|
||||
|
||||
@property
|
||||
def localpath(self):
|
||||
"""Return localpath."""
|
||||
return f"{self.hacs.system.config_path}/themes/{self.data.file_name.replace('.yaml', '')}"
|
||||
|
||||
async def async_post_installation(self):
|
||||
"""Run post installation steps."""
|
||||
try:
|
||||
await self.hacs.hass.services.async_call("frontend", "reload_themes", {})
|
||||
self.logger.info("Themes reloaded")
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
# Run common validation steps.
|
||||
await self.common_validate()
|
||||
|
||||
# Custom step 1: Validate content.
|
||||
compliant = False
|
||||
for treefile in self.treefiles:
|
||||
if treefile.startswith("themes/") and treefile.endswith(".yaml"):
|
||||
compliant = True
|
||||
break
|
||||
if not compliant:
|
||||
raise HacsException(
|
||||
f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant"
|
||||
)
|
||||
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
# Handle potential errors
|
||||
if self.validate.errors:
|
||||
for error in self.validate.errors:
|
||||
if not self.hacs.system.status.startup:
|
||||
self.logger.error(error)
|
||||
return self.validate.success
|
||||
|
||||
async def async_post_registration(self):
|
||||
"""Registration."""
|
||||
# Set name
|
||||
find_file_name(self)
|
||||
self.content.path.local = self.localpath
|
||||
|
||||
async def update_repository(self, ignore_issues=False):
|
||||
"""Update."""
|
||||
await self.common_update(ignore_issues)
|
||||
|
||||
# Get theme objects.
|
||||
if self.data.content_in_root:
|
||||
self.content.path.remote = ""
|
||||
|
||||
# Update name
|
||||
find_file_name(self)
|
||||
self.content.path.local = self.localpath
|
|
@ -1,96 +0,0 @@
|
|||
"""Sensor platform for HACS."""
|
||||
# pylint: disable=unused-argument
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from .hacsbase import Hacs as hacs
|
||||
from .const import DOMAIN, VERSION, NAME_SHORT
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Setup sensor platform."""
|
||||
async_add_entities([HACSSensor()])
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_devices):
|
||||
"""Setup sensor platform."""
|
||||
async_add_devices([HACSSensor()])
|
||||
|
||||
|
||||
class HACSDevice(Entity):
|
||||
"""HACS Device class."""
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device information about HACS."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self.unique_id)},
|
||||
"name": NAME_SHORT,
|
||||
"manufacturer": "hacs.xyz",
|
||||
"model": "",
|
||||
"sw_version": VERSION,
|
||||
}
|
||||
|
||||
|
||||
class HACSSensor(HACSDevice):
|
||||
"""HACS Sensor class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize."""
|
||||
self._state = None
|
||||
self.repositories = []
|
||||
|
||||
async def async_update(self):
|
||||
"""Update the sensor."""
|
||||
if hacs.system.status.background_task:
|
||||
return
|
||||
|
||||
self.repositories = []
|
||||
|
||||
for repository in hacs.repositories:
|
||||
if (
|
||||
repository.pending_upgrade
|
||||
and repository.data.category in hacs.common.categories
|
||||
):
|
||||
self.repositories.append(repository)
|
||||
self._state = len(self.repositories)
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique ID to use for this sensor."""
|
||||
return (
|
||||
"0717a0cd-745c-48fd-9b16-c8534c9704f9-bc944b0f-fd42-4a58-a072-ade38d1444cd"
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return "hacs"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon of the sensor."""
|
||||
return "hacs:hacs"
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return "pending update(s)"
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return attributes for the sensor."""
|
||||
data = []
|
||||
for repository in self.repositories:
|
||||
data.append(
|
||||
{
|
||||
"name": repository.data.full_name,
|
||||
"display_name": repository.display_name,
|
||||
"installed_version": repository.display_installed_version,
|
||||
"available_version": repository.display_available_version,
|
||||
}
|
||||
)
|
||||
return {"repositories": data}
|
|
@ -1,15 +0,0 @@
|
|||
install:
|
||||
description: This is NOT intended to be used here, this is intended for developers!
|
||||
fields:
|
||||
repository:
|
||||
description: The repository ID
|
||||
example: '"123456789"'
|
||||
register:
|
||||
description: This is NOT intended to be used here, this is intended for developers!
|
||||
fields:
|
||||
repository:
|
||||
description: The full name of the repository
|
||||
example: 'developer/repo'
|
||||
repository_type:
|
||||
description: The repository type
|
||||
example: 'plugin'
|
|
@ -1,125 +0,0 @@
|
|||
"""Setup functions for HACS."""
|
||||
# pylint: disable=bad-continuation
|
||||
import os
|
||||
from hacs_frontend.version import VERSION as FE_VERSION
|
||||
from homeassistant.helpers import discovery
|
||||
|
||||
from custom_components.hacs.hacsbase.exceptions import HacsException
|
||||
from custom_components.hacs.const import VERSION, DOMAIN
|
||||
from custom_components.hacs.globals import get_hacs
|
||||
from custom_components.hacs.helpers.information import (
|
||||
get_repository,
|
||||
get_frontend_version,
|
||||
)
|
||||
from custom_components.hacs.helpers.register_repository import register_repository
|
||||
|
||||
|
||||
def clear_storage():
|
||||
"""Clear old files from storage."""
|
||||
hacs = get_hacs()
|
||||
storagefiles = ["hacs"]
|
||||
for s_f in storagefiles:
|
||||
path = f"{hacs.system.config_path}/.storage/{s_f}"
|
||||
if os.path.isfile(path):
|
||||
hacs.logger.info(f"Cleaning up old storage file {path}")
|
||||
os.remove(path)
|
||||
|
||||
|
||||
async def load_hacs_repository():
|
||||
"""Load HACS repositroy."""
|
||||
hacs = get_hacs()
|
||||
|
||||
try:
|
||||
repository = hacs.get_by_name("hacs/integration")
|
||||
if repository is None:
|
||||
await register_repository("hacs/integration", "integration")
|
||||
repository = hacs.get_by_name("hacs/integration")
|
||||
if repository is None:
|
||||
raise HacsException("Unknown error")
|
||||
repository.data.installed = True
|
||||
repository.data.installed_version = VERSION
|
||||
repository.data.new = False
|
||||
hacs.repo = repository.repository_object
|
||||
hacs.data_repo = await get_repository(
|
||||
hacs.session, hacs.configuration.token, "hacs/default"
|
||||
)
|
||||
except HacsException as exception:
|
||||
if "403" in f"{exception}":
|
||||
hacs.logger.critical("GitHub API is ratelimited, or the token is wrong.")
|
||||
else:
|
||||
hacs.logger.critical(f"[{exception}] - Could not load HACS!")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def setup_extra_stores():
|
||||
"""Set up extra stores in HACS if enabled in Home Assistant."""
|
||||
hacs = get_hacs()
|
||||
if "python_script" in hacs.hass.config.components:
|
||||
if "python_script" not in hacs.common.categories:
|
||||
hacs.common.categories.append("python_script")
|
||||
|
||||
if hacs.hass.services.services.get("frontend", {}).get("reload_themes") is not None:
|
||||
if "theme" not in hacs.common.categories:
|
||||
hacs.common.categories.append("theme")
|
||||
|
||||
|
||||
def add_sensor():
|
||||
"""Add sensor."""
|
||||
hacs = get_hacs()
|
||||
|
||||
try:
|
||||
if hacs.configuration.config_type == "yaml":
|
||||
hacs.hass.async_create_task(
|
||||
discovery.async_load_platform(
|
||||
hacs.hass, "sensor", DOMAIN, {}, hacs.configuration.config
|
||||
)
|
||||
)
|
||||
else:
|
||||
hacs.hass.async_add_job(
|
||||
hacs.hass.config_entries.async_forward_entry_setup(
|
||||
hacs.configuration.config_entry, "sensor"
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
async def setup_frontend():
|
||||
"""Configure the HACS frontend elements."""
|
||||
from .http import HacsFrontend
|
||||
from .ws_api_handlers import setup_ws_api
|
||||
|
||||
hacs = get_hacs()
|
||||
|
||||
hacs.hass.http.register_view(HacsFrontend())
|
||||
hacs.frontend.version_running = FE_VERSION
|
||||
hacs.frontend.version_expected = await hacs.hass.async_add_executor_job(
|
||||
get_frontend_version
|
||||
)
|
||||
|
||||
# Add to sidepanel
|
||||
custom_panel_config = {
|
||||
"name": "hacs-frontend",
|
||||
"embed_iframe": False,
|
||||
"trust_external": False,
|
||||
"js_url": f"/hacsfiles/frontend-{hacs.frontend.version_running}.js",
|
||||
}
|
||||
|
||||
config = {}
|
||||
config["_panel_custom"] = custom_panel_config
|
||||
|
||||
hacs.hass.components.frontend.async_register_built_in_panel(
|
||||
component_name="custom",
|
||||
sidebar_title=hacs.configuration.sidepanel_title,
|
||||
sidebar_icon=hacs.configuration.sidepanel_icon,
|
||||
frontend_url_path="hacs",
|
||||
config=config,
|
||||
require_admin=True,
|
||||
)
|
||||
|
||||
if "frontend_extra_module_url" not in hacs.hass.data:
|
||||
hacs.hass.data["frontend_extra_module_url"] = set()
|
||||
hacs.hass.data["frontend_extra_module_url"].add("/hacsfiles/iconset.js")
|
||||
|
||||
await setup_ws_api(hacs.hass)
|
|
@ -1,29 +0,0 @@
|
|||
"""Storage handers."""
|
||||
from homeassistant.helpers.json import JSONEncoder
|
||||
from homeassistant.helpers.storage import Store
|
||||
from .hacsbase.const import STORAGE_VERSION
|
||||
|
||||
|
||||
async def async_load_from_store(hass, key):
|
||||
"""Load the retained data from store and return de-serialized data."""
|
||||
key = key if "/" in key else f"hacs.{key}"
|
||||
store = Store(hass, STORAGE_VERSION, key, encoder=JSONEncoder)
|
||||
restored = await store.async_load()
|
||||
if restored is None:
|
||||
return {}
|
||||
return restored
|
||||
|
||||
|
||||
async def async_save_to_store(hass, key, data):
|
||||
"""Generate dynamic data to store and save it to the filesystem."""
|
||||
key = key if "/" in key else f"hacs.{key}"
|
||||
store = Store(hass, STORAGE_VERSION, key, encoder=JSONEncoder)
|
||||
await store.async_save(data)
|
||||
|
||||
|
||||
async def async_remove_store(hass, key):
|
||||
"""Remove a store element that should no longer be used"""
|
||||
if "/" not in key:
|
||||
return
|
||||
store = Store(hass, STORAGE_VERSION, key, encoder=JSONEncoder)
|
||||
await store.async_remove()
|
|
@ -1,422 +0,0 @@
|
|||
"""WebSocket API for HACS."""
|
||||
# pylint: disable=unused-argument
|
||||
import sys
|
||||
import os
|
||||
import voluptuous as vol
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from .hacsbase.exceptions import HacsException
|
||||
from .store import async_load_from_store, async_save_to_store
|
||||
|
||||
from custom_components.hacs.globals import get_hacs, removed_repositories
|
||||
from custom_components.hacs.helpers.register_repository import register_repository
|
||||
|
||||
|
||||
async def setup_ws_api(hass):
|
||||
"""Set up WS API handlers."""
|
||||
websocket_api.async_register_command(hass, hacs_settings)
|
||||
websocket_api.async_register_command(hass, hacs_config)
|
||||
websocket_api.async_register_command(hass, hacs_repositories)
|
||||
websocket_api.async_register_command(hass, hacs_repository)
|
||||
websocket_api.async_register_command(hass, hacs_repository_data)
|
||||
websocket_api.async_register_command(hass, check_local_path)
|
||||
websocket_api.async_register_command(hass, hacs_status)
|
||||
websocket_api.async_register_command(hass, hacs_removed)
|
||||
websocket_api.async_register_command(hass, acknowledge_critical_repository)
|
||||
websocket_api.async_register_command(hass, get_critical_repositories)
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/settings",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("categories"): cv.ensure_list,
|
||||
}
|
||||
)
|
||||
async def hacs_settings(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
action = msg["action"]
|
||||
hacs.logger.debug(f"WS action '{action}'")
|
||||
|
||||
if action == "set_fe_grid":
|
||||
hacs.configuration.frontend_mode = "Grid"
|
||||
|
||||
elif action == "onboarding_done":
|
||||
hacs.configuration.onboarding_done = True
|
||||
|
||||
elif action == "set_fe_table":
|
||||
hacs.configuration.frontend_mode = "Table"
|
||||
|
||||
elif action == "set_fe_compact_true":
|
||||
hacs.configuration.frontend_compact = False
|
||||
|
||||
elif action == "set_fe_compact_false":
|
||||
hacs.configuration.frontend_compact = True
|
||||
|
||||
elif action == "upgrade_all":
|
||||
hacs.system.status.upgrading_all = True
|
||||
hacs.system.status.background_task = True
|
||||
hass.bus.async_fire("hacs/status", {})
|
||||
for repository in hacs.repositories:
|
||||
if repository.pending_upgrade:
|
||||
repository.data.selected_tag = None
|
||||
await repository.install()
|
||||
hacs.system.status.upgrading_all = False
|
||||
hacs.system.status.background_task = False
|
||||
hass.bus.async_fire("hacs/status", {})
|
||||
hass.bus.async_fire("hacs/repository", {})
|
||||
|
||||
elif action == "clear_new":
|
||||
for repo in hacs.repositories:
|
||||
if repo.data.new and repo.data.category in msg.get("categories", []):
|
||||
hacs.logger.debug(f"Clearing new flag from '{repo.data.full_name}'")
|
||||
repo.data.new = False
|
||||
else:
|
||||
hacs.logger.error(f"WS action '{action}' is not valid")
|
||||
hass.bus.async_fire("hacs/config", {})
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/config"})
|
||||
async def hacs_config(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
config = hacs.configuration
|
||||
|
||||
content = {}
|
||||
content["frontend_mode"] = config.frontend_mode
|
||||
content["frontend_compact"] = config.frontend_compact
|
||||
content["onboarding_done"] = config.onboarding_done
|
||||
content["version"] = hacs.version
|
||||
content["frontend_expected"] = hacs.frontend.version_expected
|
||||
content["frontend_running"] = hacs.frontend.version_running
|
||||
content["dev"] = config.dev
|
||||
content["debug"] = config.debug
|
||||
content["country"] = config.country
|
||||
content["experimental"] = config.experimental
|
||||
content["categories"] = hacs.common.categories
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/status"})
|
||||
async def hacs_status(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
content = {
|
||||
"startup": hacs.system.status.startup,
|
||||
"background_task": hacs.system.status.background_task,
|
||||
"lovelace_mode": hacs.system.lovelace_mode,
|
||||
"reloading_data": hacs.system.status.reloading_data,
|
||||
"upgrading_all": hacs.system.status.upgrading_all,
|
||||
"disabled": hacs.system.disabled,
|
||||
"has_pending_tasks": hacs.queue.has_pending_tasks,
|
||||
}
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/removed"})
|
||||
async def hacs_removed(hass, connection, msg):
|
||||
"""Get information about removed repositories."""
|
||||
content = []
|
||||
for repo in removed_repositories:
|
||||
content.append(repo.to_json())
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/repositories"})
|
||||
async def hacs_repositories(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
repositories = hacs.repositories
|
||||
content = []
|
||||
for repo in repositories:
|
||||
if repo.data.category in hacs.common.categories:
|
||||
data = {
|
||||
"additional_info": repo.information.additional_info,
|
||||
"authors": repo.data.authors,
|
||||
"available_version": repo.display_available_version,
|
||||
"beta": repo.data.show_beta,
|
||||
"can_install": repo.can_install,
|
||||
"category": repo.data.category,
|
||||
"country": repo.data.country,
|
||||
"config_flow": repo.data.config_flow,
|
||||
"custom": repo.custom,
|
||||
"default_branch": repo.data.default_branch,
|
||||
"description": repo.data.description,
|
||||
"domain": repo.data.domain,
|
||||
"downloads": repo.data.downloads,
|
||||
"file_name": repo.data.file_name,
|
||||
"first_install": repo.status.first_install,
|
||||
"full_name": repo.data.full_name,
|
||||
"hide": repo.data.hide,
|
||||
"hide_default_branch": repo.data.hide_default_branch,
|
||||
"homeassistant": repo.data.homeassistant,
|
||||
"id": repo.data.id,
|
||||
"info": repo.information.info,
|
||||
"installed_version": repo.display_installed_version,
|
||||
"installed": repo.data.installed,
|
||||
"issues": repo.data.open_issues,
|
||||
"javascript_type": repo.information.javascript_type,
|
||||
"last_updated": repo.data.last_updated,
|
||||
"local_path": repo.content.path.local,
|
||||
"main_action": repo.main_action,
|
||||
"name": repo.display_name,
|
||||
"new": repo.data.new,
|
||||
"pending_upgrade": repo.pending_upgrade,
|
||||
"releases": repo.data.published_tags,
|
||||
"selected_tag": repo.data.selected_tag,
|
||||
"stars": repo.data.stargazers_count,
|
||||
"state": repo.state,
|
||||
"status_description": repo.display_status_description,
|
||||
"status": repo.display_status,
|
||||
"topics": repo.data.topics,
|
||||
"updated_info": repo.status.updated_info,
|
||||
"version_or_commit": repo.display_version_or_commit,
|
||||
}
|
||||
|
||||
content.append(data)
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
}
|
||||
)
|
||||
async def hacs_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
try:
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
|
||||
if repo_id is None or action is None:
|
||||
return
|
||||
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
hacs.logger.debug(f"Running {action} for {repository.data.full_name}")
|
||||
|
||||
if action == "update":
|
||||
await repository.update_repository(True)
|
||||
repository.status.updated_info = True
|
||||
|
||||
elif action == "install":
|
||||
repository.data.new = False
|
||||
was_installed = repository.data.installed
|
||||
await repository.install()
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "not_new":
|
||||
repository.data.new = False
|
||||
|
||||
elif action == "uninstall":
|
||||
repository.data.new = False
|
||||
await repository.uninstall()
|
||||
|
||||
elif action == "hide":
|
||||
repository.data.hide = True
|
||||
|
||||
elif action == "unhide":
|
||||
repository.data.hide = False
|
||||
|
||||
elif action == "show_beta":
|
||||
repository.data.show_beta = True
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "hide_beta":
|
||||
repository.data.show_beta = False
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "toggle_beta":
|
||||
repository.data.show_beta = not repository.data.show_beta
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "delete":
|
||||
repository.data.show_beta = False
|
||||
repository.remove()
|
||||
|
||||
elif action == "set_version":
|
||||
if msg["version"] == repository.data.default_branch:
|
||||
repository.data.selected_tag = None
|
||||
else:
|
||||
repository.data.selected_tag = msg["version"]
|
||||
await repository.update_repository()
|
||||
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
else:
|
||||
hacs.logger.error(f"WS action '{action}' is not valid")
|
||||
|
||||
await hacs.data.async_write()
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
hacs.logger.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(exception)})
|
||||
|
||||
repository.state = None
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository/data",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
vol.Optional("data"): cv.string,
|
||||
}
|
||||
)
|
||||
async def hacs_repository_data(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
data = msg.get("data")
|
||||
|
||||
if repo_id is None:
|
||||
return
|
||||
|
||||
if action == "add":
|
||||
if "github." in repo_id:
|
||||
repo_id = repo_id.split("github.com/")[1]
|
||||
|
||||
if repo_id in hacs.common.skip:
|
||||
hacs.common.skip.remove(repo_id)
|
||||
|
||||
if not hacs.get_by_name(repo_id):
|
||||
try:
|
||||
registration = await register_repository(repo_id, data.lower())
|
||||
if registration is not None:
|
||||
raise HacsException(registration)
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"exception": str(sys.exc_info()[0].__name__),
|
||||
"message": str(exception),
|
||||
},
|
||||
)
|
||||
else:
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"message": f"Repository '{repo_id}' exists in the store.",
|
||||
},
|
||||
)
|
||||
|
||||
repository = hacs.get_by_name(repo_id)
|
||||
else:
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
|
||||
if repository is None:
|
||||
hass.bus.async_fire("hacs/repository", {})
|
||||
return
|
||||
|
||||
hacs.logger.debug(f"Running {action} for {repository.data.full_name}")
|
||||
try:
|
||||
if action == "set_state":
|
||||
repository.state = data
|
||||
|
||||
elif action == "set_version":
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
|
||||
repository.state = None
|
||||
|
||||
elif action == "install":
|
||||
was_installed = repository.data.installed
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
await repository.install()
|
||||
repository.state = None
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "add":
|
||||
repository.state = None
|
||||
|
||||
else:
|
||||
repository.state = None
|
||||
hacs.logger.error(f"WS action '{action}' is not valid")
|
||||
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except Exception as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
hacs.logger.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(exception)})
|
||||
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "hacs/check_path", vol.Optional("path"): cv.string}
|
||||
)
|
||||
async def check_local_path(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
path = msg.get("path")
|
||||
exist = {"exist": False}
|
||||
|
||||
if path is None:
|
||||
return
|
||||
|
||||
if os.path.exists(path):
|
||||
exist["exist"] = True
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], exist))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/get_critical"})
|
||||
async def get_critical_repositories(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
if not critical:
|
||||
critical = []
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "hacs/critical", vol.Optional("repository"): cv.string}
|
||||
)
|
||||
async def acknowledge_critical_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
repository = msg["repository"]
|
||||
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
for repo in critical:
|
||||
if repository == repo["repository"]:
|
||||
repo["acknowledged"] = True
|
||||
await async_save_to_store(hass, "critical", critical)
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
Loading…
Reference in New Issue