From 2829026a66793ae0c94cf7e140ee5c291b6a1cf7 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 23 Sep 2017 15:45:05 +0200 Subject: [PATCH] :tada: Initial version --- .circleci/config.yml | 95 ++++++++++++ .codeclimate.yml | 13 ++ .editorconfig | 19 +++ .github/ISSUE_TEMPLATE.md | 20 +++ .github/PULL_REQUEST_TEMPLATE.md | 9 ++ .gitignore | 0 .mdlrc | 1 + CHANGELOG.md | 20 +++ CODE_OF_CONDUCT.md | 74 +++++++++ CONTRIBUTING.md | 29 ++++ LICENSE.md | 21 +++ README.md | 165 ++++++++++++++++++++ example/Dockerfile | 40 +++++ example/config.json | 27 ++++ example/rootfs/run.sh | 251 +++++++++++++++++++++++++++++++ repository.json | 5 + 16 files changed, 789 insertions(+) create mode 100644 .circleci/config.yml create mode 100644 .codeclimate.yml create mode 100755 .editorconfig create mode 100755 .github/ISSUE_TEMPLATE.md create mode 100755 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .gitignore create mode 100644 .mdlrc create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 example/Dockerfile create mode 100644 example/config.json create mode 100644 example/rootfs/run.sh create mode 100644 repository.json diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..4d515d0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,95 @@ +version: 2 +defaults: &defaults + machine: + image: circleci/classic:edge + steps: + - run: + name: Check docker is running + command: docker info + - run: + name: Pull Community Hass.io Add-ons build environment + command: docker pull hassioaddons/build-env:latest + - run: + name: Log in to Docker Hub + command: | + if [[ "${CIRCLE_BRANCH}" = "master" || ! -z "${CIRCLE_TAG:-}" ]]; + then + docker login -u ${DOCKER_LOGIN} -p ${DOCKER_PASSWORD} + fi + - checkout + - deploy: + name: Build and (maybe) deploy + command: | + if [[ "${CIRCLE_BRANCH}" = "master" || ! -z "${CIRCLE_TAG:-}" ]]; + then + docker run \ + --privileged \ + -v ~/.docker:/root/.docker \ + -v "$PWD":/docker \ + hassioaddons/build-env:latest \ + --git \ + --image "hassioaddons/example-{arch}" \ + --target example \ + --${ARCH} \ + --push + else + docker run \ + --privileged \ + -v ~/.docker:/root/.docker \ + -v "$PWD":/docker \ + hassioaddons/build-env:latest \ + --git \ + --image "hassioaddons/example-{arch}" \ + --target example \ + --${ARCH} + fi + - deploy: + name: Send notification to Microbadger + command: | + if [[ "${CIRCLE_BRANCH}" = "master" || ! -z "${CIRCLE_TAG:-}" ]]; + then + curl -X POST https://hooks.microbadger.com/images/${MICROBADGER_WEBHOOK} + fi + +jobs: + aarch64: + <<: *defaults + environment: + ARCH: aarch64 + MICROBADGER_WEBHOOK: hassioaddons/base-aarch64/xPXzVNfmlHE-TbnO6_v2_G5XVt4= + amd64: + <<: *defaults + environment: + ARCH: amd64 + MICROBADGER_WEBHOOK: hassioaddons/base-amd64/9VpSGXcF3-G8pL-mKXq-0WWvG3g= + armhf: + <<: *defaults + environment: + ARCH: armhf + MICROBADGER_WEBHOOK: hassioaddons/base-armhf/PzdnuORNZ7a76EmFKI1mrby2p74= + i386: + <<: *defaults + environment: + ARCH: i386 + MICROBADGER_WEBHOOK: hassioaddons/base-i386/te8Hu20AiumjGJbSK0Bf99iivhI= + +workflows: + version: 2 + build_and_maybe_deploy: + jobs: + - aarch64: + filters: + tags: + only: /.*/ + - amd64: + filters: + tags: + only: /.*/ + - armhf: + filters: + tags: + only: /.*/ + - i386: + filters: + tags: + only: /.*/ diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..b541f14 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,13 @@ +--- +engines: + fixme: + enabled: true + shellcheck: + enabled: true + markdownlint: + enabled: true +ratings: + paths: + - "**.sh" + - "**.md" +exclude_paths: [] diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 0000000..7a12570 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +ident_size = 4 + +[*.md] +ident_size = 2 +trim_trailing_whitespace = false + +[*.json] +ident_size = 2 + +[{.gitignore,.gitkeep,.editorconfig}] +ident_size = 2 diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100755 index 0000000..544da8f --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,20 @@ +# Problem/Motivation + +> (Why the issue was filed) + +## Expected behavior + +> (What you expected to happen) + +## Actual behavior + +> (What actually happened) + +## Steps to reproduce + +> (How can someone else make/see it happen) + +## Proposed changes + +> (If you have a proposed change, workaround or fix, +> describe the rationale behind it) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100755 index 0000000..cbd529a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +# Proposed Changes + +> (Describe the changes and rationale behind them) + +## Related Issues + +> ([Github link][autolink-references] to related issues or pull requests) + +[autolink-references]: https://help.github.com/articles/autolinked-references-and-urls/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 0000000..2b0128d --- /dev/null +++ b/.mdlrc @@ -0,0 +1 @@ +rules "~MD024" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cb12444 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Community Hass.io Add-ons: Example + +All notable changes to this add-on will be documented in this file. + +The format is based on [Keep a Changelog][keep-a-changelog] +and this project adheres to [Semantic Versioning][semantic-versioning]. + +## Unreleased + +No changes yet + +## [v0.0.1] (2017-09-23) + +### Added + +- Initial version, first release. + +[keep-a-changelog]: http://keepachangelog.com/en/1.0.0/ +[semantic-versioning]: http://semver.org/spec/v2.0.0.html +[v0.0.1]: https://github.com/hassio-addons/addon-example/tree/v0.0.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0ac232b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Code of conduct + +## Our pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention + or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or + electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate + in a professional setting + +## Our responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project lead at frenck@addons.community. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project lead is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..12052d3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish +to make via issue, email, or any other method with the owners of this repository +before making a change. + +Please note we have a code of conduct, please follow it in all your interactions +with the project. + +## Issues and feature requests + +You've found a bug in the source code, a mistake in the documentation or maybe +you'd like a new feature? You can help us by submitting an issue to our +[GitHub Repository][github]. Before you create an issue, make sure you search +the archive, maybe your question was already answered. + +Even better: You could submit a pull request with a fix / new feature! + +## Pull request process + +1. Search our repository for open or closed [pull requests][prs] that relates + to your submission. You don't want to duplicate effort. + +1. You may merge the pull request in once you have the sign-off of two other + developers, or if you do not have permission to do that, you may request + the second reviewer to merge it for you. + +[github]: https://github.com/hassio-addons/addon-example/issues +[prs]: https://github.com/hassio-addons/addon-example/pulls \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e8635ed --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Franck Nijhof + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b10ef7c --- /dev/null +++ b/README.md @@ -0,0 +1,165 @@ +# Community Hass.io Add-ons: Example + +![Project Stage][project-stage-shield] +![Maintenance][maintenance-shield] +![Awesome][awesome-shield] +[![License][license-shield]](LICENSE.md) + +[![Code Climate][codeclimate-shield]][codeclimate] +[![CircleCI][circleci-shield]][circleci] + +Example add-on by Community Hass.io add-ons. + +## Docker status + +[![Docker Architecture][armhf-arch-shield]][armhf-dockerhub] +[![Docker Version][armhf-version-shield]][armhf-microbadger] +[![Docker Layers][armhf-layers-shield]][armhf-microbadger] +[![Docker Pulls][armhf-pulls-shield]][armhf-dockerhub] + +[![Docker Architecture][aarch64-arch-shield]][aarch64-dockerhub] +[![Docker Version][aarch64-version-shield]][aarch64-microbadger] +[![Docker Layers][aarch64-layers-shield]][aarch64-microbadger] +[![Docker Pulls][aarch64-pulls-shield]][aarch64-dockerhub] + +[![Docker Architecture][amd64-arch-shield]][amd64-dockerhub] +[![Docker Version][amd64-version-shield]][amd64-microbadger] +[![Docker Layers][amd64-layers-shield]][amd64-microbadger] +[![Docker Pulls][amd64-pulls-shield]][amd64-dockerhub] + +[![Docker Architecture][i386-arch-shield]][i386-dockerhub] +[![Docker Version][i386-version-shield]][i386-microbadger] +[![Docker Layers][i386-layers-shield]][i386-microbadger] +[![Docker Pulls][i386-pulls-shield]][i386-dockerhub] + +## About + +This is an example add-on for Hass.io. When started, it will display a +random quote every 5 seconds. + +It shows off several features and structures like: + +- Full blown GitHub repository. +- General Dockerfile structure and setup. +- The use of the `config.json` file. +- General shell scripting structure (`run.sh`). +- Quality assurance using CodeClimate. +- Continuous integration and deployment using CircleCI. +- Usage of the Community Hass.io Add-ons build environment. + +## Stuff not yet in this example + +We are still working on adding more cases and examples to this addon. +Things on the short list: + +- Add TravisCI example +- Read and use variables from configuration + +## Changelog + +This repository keeps a [change log](CHANGELOG.md) and adhere to +[Semantic Versioning][semver]. The format of the log is based on +[Keep a Changelog][keepchangelog]. + +## Support + +Got questions? + +You have several options to get them answered: + +- The Home Assistant [Community Forums][forums], we have a + [dedicated topic][forums] on that forum regarding this repository. +- The Home Assistant [Discord Chat Server][discord] for general Home Assistant + discussions and questions. +- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] + +You could also [open an issue here][issue] GitHub. + +## Contributing + +This is an active open-source project. We are always open to people who want to +use the code or contribute to it. + +We've set up a separate document for our [contribution guidelines](CONTRIBUTING.md). + +Thank you for being involved! :heart_eyes: + +## Authors & contributors + +The original setup of this repository is by [Franck Nijhof][frenck]. + +For a full list of all authors and contributors, +check [the contributor's page][contributors]. + +## We've got some Hass.io add-ons for you + +Want some more functionality to your Hass.io Home Assistant instance? + +We have created multiple add-ons for Hass.io. For a full list, check out +our [GitHub Repository][repository]. + +## License + +MIT License + +Copyright (c) 2017 Franck Nijhof + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +[aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg +[aarch64-dockerhub]: https://hub.docker.com/r/hassioaddons/example-aarch64 +[aarch64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/example-aarch64.svg +[aarch64-microbadger]: https://microbadger.com/images/hassioaddons/example-aarch64 +[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/example-aarch64.svg +[aarch64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/example-aarch64.svg +[amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg +[amd64-dockerhub]: https://hub.docker.com/r/hassioaddons/example-amd64 +[amd64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/example-amd64.svg +[amd64-microbadger]: https://microbadger.com/images/hassioaddons/example-amd64 +[amd64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/example-amd64.svg +[amd64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/example-amd64.svg +[armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg +[armhf-dockerhub]: https://hub.docker.com/r/hassioaddons/example-armhf +[armhf-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/example-armhf.svg +[armhf-microbadger]: https://microbadger.com/images/hassioaddons/example-armhf +[armhf-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/example-armhf.svg +[armhf-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/example-armhf.svg +[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg +[circleci-shield]: https://img.shields.io/circleci/project/github/hassio-addons/addon-example.svg +[circleci]: https://circleci.com/gh/hassio-addons/addon-example +[codeclimate-shield]: https://img.shields.io/codeclimate/github/hassio-addons/addon-example.svg +[codeclimate]: https://codeclimate.com/github/hassio-addons/addon-example +[contributors]: https://github.com/hassio-addons/addon-example/graphs/contributors +[discord]: https://discord.gg/c5DvZ4e +[forums]: https://community.home-assistant.io/t/repository-community-hass-io-add-ons/24705?u=frenck +[frenck]: https://github.com/frenck +[i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg +[i386-dockerhub]: https://hub.docker.com/r/hassioaddons/example-i386 +[i386-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/example-i386.svg +[i386-microbadger]: https://microbadger.com/images/hassioaddons/example-i386 +[i386-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/example-i386.svg +[i386-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/example-i386.svg +[issue]: https://github.com/hassio-addons/addon-example/issues +[keepchangelog]: http://keepachangelog.com/en/1.0.0/ +[license-shield]: https://img.shields.io/github/license/hassio-addons/addon-example.svg +[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg +[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Experimental-yellow.svg +[reddit]: https://reddit.com/r/homeassistant +[repository]: https://github.com/hassio-addons/repository +[semver]: http://semver.org/spec/v2.0.0.html diff --git a/example/Dockerfile b/example/Dockerfile new file mode 100644 index 0000000..784bb67 --- /dev/null +++ b/example/Dockerfile @@ -0,0 +1,40 @@ +ARG BUILD_FROM=hassioaddons/base-amd64 +FROM ${BUILD_FROM} + +# Copy root filesystem +COPY rootfs / + +RUN \ + apk add --no-cache coreutils wget \ + && chmod a+x /run.sh + +CMD [ "/run.sh" ] + +# Build arugments +ARG BUILD_ARCH +ARG BUILD_DATE +ARG BUILD_DESCRIPTION +ARG BUILD_DOC_URL +ARG BUILD_GIT_URL +ARG BUILD_MAINTAINER +ARG BUILD_NAME +ARG BUILD_REF +ARG BUILD_URL +ARG BUILD_VENDOR +ARG BUILD_VERSION + +# Labels +LABEL \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="${BUILD_MAINTAINER}" \ + org.label-schema.description="${BUILD_DESCRIPTION}" \ + org.label-schema.build-date=${BUILD_DATE} \ + org.label-schema.name="${BUILD_NAME} for ${BUILD_ARCH}" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.url="${BUILD_URL}" \ + org.label-schema.usage="${BUILD_DOC_URL}" \ + org.label-schema.vcs-ref=${BUILD_REF} \ + org.label-schema.vcs-url="${BUILD_GIT_URL}" \ + org.label-schema.vendor="${BUILD_VENDOR}" \ No newline at end of file diff --git a/example/config.json b/example/config.json new file mode 100644 index 0000000..89a6f00 --- /dev/null +++ b/example/config.json @@ -0,0 +1,27 @@ +{ + "name": "Example", + "slug": "example", + "version": "1.0", + "type": "addon", + + "description": "Example add-on for Hass.io", + "maintainer": "Franck Nijhof ", + "vendor": "Community Hass.io Addons", + "url": "https://addons.community", + "source": "https://github.com/hassio-addons/addon-example", + "documentation": "https://github.com/hassio-addons/addon-example/tree/master/README.md", + + "arch": [ + "aarch64", + "amd64", + "armhf", + "i386" + ], + "from": "hassioaddons/base-{arch}", + "squashs": true, + + "startup": "application", + "boot": "auto", + + "image": "hassioaddons/example-{arch}" + } \ No newline at end of file diff --git a/example/rootfs/run.sh b/example/rootfs/run.sh new file mode 100644 index 0000000..9632860 --- /dev/null +++ b/example/rootfs/run.sh @@ -0,0 +1,251 @@ +#!/usr/bin/env bash +# ============================================================================== +# +# Community Hass.io Add-ons: Example +# +# Example add-on for Hass.io. +# This add-on displays a random quote every 5 seconds. +# +# ============================================================================== +set -o errexit # Exit script when a command exits with non-zero status +set -o errtrace # Exit on error inside any functions or sub-shells +set -o nounset # Exit script on use of an undefined variable +set -o pipefail # Return exit status of the last command in the pipe that failed + +# ============================================================================== +# GLOBALS +# ============================================================================== +readonly EX_OK=0 # Successful termination +readonly EX_UNKNOWN=1 # Unknown error occured + +# Global variables +declare TRAPPED + +# Default values +TRAPPED=false + +# ============================================================================== +# UTILITY +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Displays a simple program header +# +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +display_banner() { + echo '---------------------------------------------------------' + echo 'Community Hass.io Add-ons: Example' + echo '---------------------------------------------------------' +} + +# ------------------------------------------------------------------------------ +# Displays a error message and is able to terminate te script execution +# +# Globals: +# None +# Arguments: +# $1 Error message +# $2 Exit code, script will continue execution when omitted +# Returns: +# None +# ------------------------------------------------------------------------------ +display_error_message() { + local status=${1} + local exitcode=${2:-0} + + echo >&2 + echo " ! ERROR: ${status}" + echo >&2 + + if [[ ${exitcode} -ne 0 ]]; then + exit "${exitcode}" + fi +} + +# ------------------------------------------------------------------------------ +# Displays a notice +# +# Globals: +# None +# Arguments: +# $* Notice message to display +# Returns: +# Exit code +# ------------------------------------------------------------------------------ +display_notice_message() { + local status=$* + + echo + echo "NOTICE: ${status}" + echo +} + +# ------------------------------------------------------------------------------ +# Displays a status message +# +# Globals: +# None +# Arguments: +# $* Status message to display +# Returns: +# Exit code +# ------------------------------------------------------------------------------ +display_status_message() { + local status=$* + + echo + echo "-----> ${status}" + echo +} + +# ============================================================================== +# SCRIPT LOGIC +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Cleanup function after execution is of the script is stopped. (trap) +# +# Globals: +# EX_OK +# TRAPPED +# Arguments: +# $1 Exit code +# Returns: +# None +# ------------------------------------------------------------------------------ +cleanup_on_exit() { + local exit_code=${1} + # Prevent double cleanup. Thx Bash :) + if [[ "${TRAPPED}" != true ]]; then + # Add your cleanup logic here + display_notice_message "Doing a fake cleanup... ;)" + fi + exit "${exit_code}" +} + +# ------------------------------------------------------------------------------ +# Get a random quote from quotationspage.com +# +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +get_quote_online() { + local number + local html + local quote + + number=$(( ( RANDOM % 999 ) + 1 )) + html=$(wget -q -O - "http://www.quotationspage.com/quote/${number}.html") + + quote=$(grep -e "
" -e "" <<< "${html}" \ + | awk -F'[<>]' '{ + if($2 ~ /dt/) + { print $3 } + else if($4 ~ /b/) + { print "-- " $7 " n(" $19 ")"} + }' + ) + + echo "${quote}" +} + +# ------------------------------------------------------------------------------ +# Get a random quote from a prefined set of quotes +# +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +get_quote_offline() { + local -i number + local -a quotes + + quotes+=("Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.\n -Samuel Beckett") + quotes+=("Never give up, for that is just the place and time that the tide will turn.\n -Harriet Beecher Stowe") + quotes+=("Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.\n -Thomas A. Edison") + quotes+=("Life isn't about getting and having, it's about giving and being.\n -Kevin Kruse") + quotes+=("Strive not to be a success, but rather to be of value.\n -Albert Einstein") + quotes+=("You miss 100% of the shots you don't take.\n -Wayne Gretzky") + quotes+=("People who are unable to motivate themselves must be content with mediocrity, no matter how impressive their other talents. \n -Andrew Carnegie") + quotes+=("Design is not just what it looks like and feels like. Design is how it works.\n -Steve Jobs") + quotes+=("Only those who dare to fail greatly can ever achieve greatly.\n -Robert F. Kennedy") + quotes+=("All our dreams can come true, if we have the courage to pursue them.\n -Walt Disney") + quotes+=("Success consists of going from failure to failure without loss of enthusiasm.\n -Winston Churchill") + + number=$(( ( RANDOM % 11 ) + 1 )) + echo "${quotes[$number]}" +} + +# ------------------------------------------------------------------------------ +# Displays a random quote +# +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ----------------------------------------------------------------------------- +display_quote() { + local quote + local timestamp + + if wget -q --spider http://www.quotationspage.com; then + quote=$(get_quote_online) + else + display_notice_message \ + 'Could not connect to quotationspage.com, using an offline quote' + quote=$(get_quote_offline) + fi + + quote=$(sed 's/n()//g' <<< "${quote}" | xargs -0 echo | fmt -40) + timestamp=$(date +"%T") + + display_status_message "Random quote loaded @ ${timestamp}" + echo -e "${quote}" +} + +# ============================================================================== +# RUN LOGIC +# ------------------------------------------------------------------------------ +# Globals: +# EX_OK +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +main() { + trap 'cleanup_on_exit $?' EXIT SIGINT SIGTERM + + # Display program banner + display_banner + + # Display a quote every 5 seconds + while true; do + display_quote + sleep 5 + done + + # Fin + exit "${EX_OK}" +} + +# Bootstrap +if [ "${BASH_SOURCE[0]}" = "${0}" ]; then + # Direct call to file + main "$@" +fi # Else file is included from another script diff --git a/repository.json b/repository.json new file mode 100644 index 0000000..7986cb9 --- /dev/null +++ b/repository.json @@ -0,0 +1,5 @@ +{ + "name": "Development - Community Hass.io add-on: Example", + "url": "https://github.com/hassio-addons/addon-example", + "maintainer": "Franck Nijhof " + } \ No newline at end of file