mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Systemd changes | root script | URL support for gif effects (#1319)
* Systemd changes and URL option for Gif Effects * Add grayscale to gif effect * WebUI adjustments * Rename version to .version * Copy runHyperionAsRoot.sh to rpi packages * Pack script into all unix packages * Start hyperion only after network is available * Snap builds removed due to poor server connection * Flexible updateHyperionUser.sh * updateHyperionUser script entered in the package * Print help on none sudo execute * Corrected embedded Python location * Replacement for the QWindowsScreen grabWindow function * Updated to latest 2.x mbedtls version 2.27 Co-authored-by: LordGrey <lordgrey.emmel@gmail.com>
This commit is contained in:
parent
f269268def
commit
eb96553975
4
.github/workflows/apt.yml
vendored
4
.github/workflows/apt.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
||||
- name: Build package
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
tr -d '\n' < .version > temp && mv temp .version
|
||||
mkdir -p "${GITHUB_WORKSPACE}/deploy"
|
||||
docker run --rm \
|
||||
-v "${GITHUB_WORKSPACE}/deploy:/deploy" \
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
ghcr.io/hyperion-project/${{ matrix.architecture }}:$(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]') \
|
||||
/bin/bash -c "cd /source && \
|
||||
mkdir -p debian/source && echo '3.0 (quilt)' > debian/source/format && \
|
||||
dch --create --distribution $(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]') --package 'hyperion' -v '$(cat version)~$(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]')' '${{ github.event.commits[0].message }}' && \
|
||||
dch --create --distribution $(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]') --package 'hyperion' -v '$(cat .version)~$(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]')' '${{ github.event.commits[0].message }}' && \
|
||||
cp -fr LICENSE debian/copyright && \
|
||||
sed 's/@BUILD_DEPENDS@/${{ matrix.build-depends }}/g; s/@DEPENDS@/${{ matrix.package-depends }}/g; s/@ARCHITECTURE@/${{ matrix.architecture }}/g' debian/control.in > debian/control && \
|
||||
tar cf ../hyperion_2.0.0.orig.tar . && \
|
||||
|
42
.github/workflows/pull-request.yml
vendored
42
.github/workflows/pull-request.yml
vendored
@ -36,12 +36,12 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
# Append PR number to version
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
tr -d '\n' < .version > temp && mv temp .version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> .version
|
||||
|
||||
# Build packages
|
||||
- name: Build packages
|
||||
@ -82,12 +82,12 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
# Append PR number to version
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
tr -d '\n' < .version > temp && mv temp .version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> .version
|
||||
|
||||
# Install dependencies
|
||||
- name: Install dependencies
|
||||
@ -131,12 +131,12 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
# Append PR number to version
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
tr -d '\n' < .version > temp && mv temp .version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> .version
|
||||
|
||||
- name: Cache Qt
|
||||
uses: actions/cache@v2
|
||||
@ -199,27 +199,3 @@ jobs:
|
||||
with:
|
||||
name: windows
|
||||
path: windows
|
||||
|
||||
##########################
|
||||
#### Snap (x86_64) #######
|
||||
##########################
|
||||
|
||||
snap:
|
||||
name: Snap (x86_64)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Build snap package
|
||||
- name: Build snap
|
||||
id: build
|
||||
uses: snapcore/action-build@v1
|
||||
|
||||
# Upload snap artifact (only on tagged commit)
|
||||
- name: Upload snap artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: snap
|
||||
path: ${{ steps.build.outputs.snap }}
|
||||
|
61
.github/workflows/push-master.yml
vendored
61
.github/workflows/push-master.yml
vendored
@ -156,31 +156,6 @@ jobs:
|
||||
with:
|
||||
path: build/Hyperion-*
|
||||
|
||||
##########################
|
||||
#### Snap (x86_64) #######
|
||||
##########################
|
||||
|
||||
snap:
|
||||
name: Snap (x86_64)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Build snap package
|
||||
- name: Build snap
|
||||
id: build
|
||||
uses: snapcore/action-build@v1
|
||||
|
||||
# Upload snap artifact (only on tagged commit)
|
||||
- name: Upload snap artifact
|
||||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: snap
|
||||
path: ${{ steps.build.outputs.snap }}
|
||||
|
||||
#######################################
|
||||
###### Publish GitHub Releases ########
|
||||
#######################################
|
||||
@ -195,10 +170,10 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# generate environment variables
|
||||
- name: Generate environment variables from version and tag
|
||||
- name: Generate environment variables from .version and tag
|
||||
run: |
|
||||
echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
|
||||
echo "VERSION=$(tr -d '\n' < version)" >> $GITHUB_ENV
|
||||
echo "VERSION=$(tr -d '\n' < .version)" >> $GITHUB_ENV
|
||||
echo "preRelease=false" >> $GITHUB_ENV
|
||||
|
||||
# If version contains alpha or beta, mark draft release as pre-release
|
||||
@ -223,35 +198,3 @@ jobs:
|
||||
prerelease: ${{ env.preRelease }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
############################
|
||||
###### Snap Release ########
|
||||
############################
|
||||
|
||||
snap_publish:
|
||||
name: Publish Snap Release
|
||||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
needs: [snap]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Download snap from snap job
|
||||
- name: Download snap from snap build
|
||||
id: download-artifact
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: snap
|
||||
|
||||
# Get file name of the snap
|
||||
- name: Get file name of the snap
|
||||
run: echo "snap=$(ls ${{ steps.download-artifact.outputs.download-path }}/hyperion-ng_*.snap)" >> $GITHUB_ENV
|
||||
|
||||
# Publish snap build to edge channel
|
||||
- name: Publish snap build to edge channel
|
||||
uses: snapcore/action-publish@v1
|
||||
with:
|
||||
store_login: ${{ secrets.SNAP_STORE_LOGIN }}
|
||||
snap: ${{ env.snap }}
|
||||
release: edge
|
||||
|
@ -6,7 +6,7 @@ PROJECT(hyperion)
|
||||
|
||||
# Parse semantic version of version file and write version to config
|
||||
include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cmake)
|
||||
file (STRINGS "version" HYPERION_VERSION)
|
||||
file (STRINGS ".version" HYPERION_VERSION)
|
||||
SetVersionNumber(HYPERION ${HYPERION_VERSION})
|
||||
set(DEFAULT_JSON_CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/config/hyperion.config.json.default)
|
||||
file(READ ${DEFAULT_JSON_CONFIG_FILE} DEFAULT_JSON_CONFIG_VAR)
|
||||
|
@ -299,6 +299,10 @@ select.form-control {
|
||||
color: #DDDDDD;
|
||||
}
|
||||
|
||||
.radio__field:checked ~ .radio__icon::before {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) {
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
|
@ -764,6 +764,88 @@ li a:active:after {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/*https://github.com/json-editor/json-editor/blob/2e005a2bd34c05803702d8bc1347efde7a4926ce/docs/radio.html#L37 radiobox for Json-Editor*/
|
||||
.radio {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
min-width: 1.625rem;
|
||||
min-height: 1.625rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.radio:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.radio__field {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.radio__icon {
|
||||
position: absolute;
|
||||
top: -0.125rem;
|
||||
left: -0.125rem;
|
||||
width: 1.875rem;
|
||||
height: 1.875rem;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border: 0.125rem solid #616161;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.radio__icon::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 50%;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.radio__icon::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: -0.4375rem;
|
||||
right: -0.4375rem;
|
||||
bottom: -0.4375rem;
|
||||
left: -0.4375rem;
|
||||
}
|
||||
|
||||
.radio__label {
|
||||
line-height: 1.5rem;
|
||||
display: block;
|
||||
padding: 0.0625rem 0 0 2.375rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.radio__field:checked ~ .radio__icon::before {
|
||||
background: #616161;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* disabled state css */
|
||||
.radio__field:disabled:checked ~ .radio__icon,
|
||||
.radio__field:disabled:not(:checked) ~ .radio__icon {
|
||||
cursor: default;
|
||||
border-color: #959899;
|
||||
}
|
||||
|
||||
.radio__field:disabled:checked ~ .radio__label,
|
||||
.radio__field:disabled:not(:checked) ~ .radio__label {
|
||||
cursor: default;
|
||||
color: #959899;
|
||||
}
|
||||
|
||||
.radio__field:disabled:checked ~ .radio__icon::before,
|
||||
.radio__field:disabled:not(:checked) ~ .radio__icon::before {
|
||||
cursor: default;
|
||||
background-color: #959899;
|
||||
}
|
||||
|
||||
/*https://github.com/flatlogic/awesome-bootstrap-checkbox slighty edited for our purposes*/
|
||||
.checkbox {
|
||||
|
@ -636,12 +636,17 @@
|
||||
"edt_eff_flag_header": "Flaggen",
|
||||
"edt_eff_flag_header_desc": "Verpasse deinen LEDs die Farben deines Landes. Du kannst mehr als eine Flagge auswählen, je nach Intervall werden diese dann abwechselnd angezeigt.",
|
||||
"edt_eff_fps": "Bilder pro Sekunde",
|
||||
"edt_eff_grayscale": "Graustufen",
|
||||
"edt_eff_frequency": "Frequenz",
|
||||
"edt_eff_gif_header": "GIFs",
|
||||
"edt_eff_gif_header_desc": "Dieser Effekt spielt .gif Dateien ab. Bietet die Möglichkeit kleine GIF-Videos abzuspielen.",
|
||||
"edt_eff_height": "Höhe",
|
||||
"edt_eff_huechange": "Farbänderung",
|
||||
"edt_eff_image_source": "Bildquelle",
|
||||
"edt_eff_image_source_file": "Lokale Datei",
|
||||
"edt_eff_image_source_url": "URL",
|
||||
"edt_eff_image": "Bilddatei",
|
||||
"edt_eff_url": "Bildadresse",
|
||||
"edt_eff_initial_blink": "Blinken beim Start",
|
||||
"edt_eff_interval": "Intervall",
|
||||
"edt_eff_knightrider_header": "Knight Rider",
|
||||
@ -1018,4 +1023,4 @@
|
||||
"wiz_yeelight_intro1": "Dieser Assistent hilft dir bei der Konfiguration von Hyperion für Yeelight. Zu den Funktionen zählen ein automatisches Finden der Yeelights, die einzelnen Lampen unterschiedlichen Bereichen im Bild zuzuordnen und weitere Einstellungen von Hyperion automatisch anzupassen. Kurz gesagt: Komplette Einrichtung mit ein paar Klicks.",
|
||||
"wiz_yeelight_title": "Yeelight Einrichtungsassistent",
|
||||
"wiz_yeelight_unsupported": "Nicht unterstützt"
|
||||
}
|
||||
}
|
||||
|
@ -643,11 +643,16 @@
|
||||
"edt_eff_flag_header_desc": "Let your LEDs shine bright in the colours of your country. You can select more than one flag and they will change based on the interval time.",
|
||||
"edt_eff_fps": "Frames per seconds",
|
||||
"edt_eff_frequency": "Frequency",
|
||||
"edt_eff_grayscale": "Grayscale",
|
||||
"edt_eff_gif_header": "GIF's",
|
||||
"edt_eff_gif_header_desc": "This effect plays .gif files, provide a simple video like loop as effect.",
|
||||
"edt_eff_height": "Height",
|
||||
"edt_eff_huechange": "Color change",
|
||||
"edt_eff_image_source": "Image source",
|
||||
"edt_eff_image_source_file": "Local file",
|
||||
"edt_eff_image_source_url": "URL",
|
||||
"edt_eff_image": "Image file",
|
||||
"edt_eff_url": "Image adress",
|
||||
"edt_eff_initial_blink" : "Flash for attention",
|
||||
"edt_eff_interval": "Interval",
|
||||
"edt_eff_knightrider_header": "Knight Rider",
|
||||
|
@ -55,7 +55,11 @@ $(document).ready(function () {
|
||||
testrun = true;
|
||||
|
||||
var args = effects_editor.getEditor('root.args');
|
||||
requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), imageData);
|
||||
if ($('input[type=radio][value=url]').is(':checked')) {
|
||||
requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), "");
|
||||
} else {
|
||||
requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), imageData);
|
||||
}
|
||||
};
|
||||
|
||||
// Specify upload handler for image files
|
||||
@ -133,7 +137,12 @@ $(document).ready(function () {
|
||||
|
||||
// Save Effect
|
||||
$('#btn_write').off().on('click', function () {
|
||||
requestWriteEffect(effectName, effectPyScript, JSON.stringify(effects_editor.getValue()), imageData);
|
||||
if ($('input[type=radio][value=url]').is(':checked')) {
|
||||
requestWriteEffect(effectName, effectPyScript, JSON.stringify(effects_editor.getValue()), "");
|
||||
} else {
|
||||
requestWriteEffect(effectName, effectPyScript, JSON.stringify(effects_editor.getValue()), imageData);
|
||||
}
|
||||
|
||||
$(window.hyperion).one("cmd-create-effect", function (event) {
|
||||
if (event.response.success)
|
||||
showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName));
|
||||
|
@ -1421,7 +1421,7 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
this.template_engine = this.jsoneditor.template;
|
||||
this.iconlib = this.jsoneditor.iconlib;
|
||||
this.access = this.jsoneditor.access;
|
||||
|
||||
|
||||
this.translate = this.jsoneditor.translate || JSONEditor.defaults.translate;
|
||||
|
||||
this.original_schema = options.schema;
|
||||
@ -1447,7 +1447,7 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
if (!deps) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var self = this;
|
||||
Object.keys(deps).forEach(function(dependency) {
|
||||
var path = self.path.split('.');
|
||||
@ -1464,13 +1464,13 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
if (this.path === path || !wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var self = this;
|
||||
var editor = this.jsoneditor.getEditor(path);
|
||||
var value = editor ? editor.getValue() : undefined;
|
||||
var previousStatus = this.dependenciesFulfilled;
|
||||
this.dependenciesFulfilled = false;
|
||||
|
||||
|
||||
if (!editor || !editor.dependenciesFulfilled) {
|
||||
this.dependenciesFulfilled = false;
|
||||
} else if (Array.isArray(choices)) {
|
||||
@ -1504,7 +1504,7 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
this.dependenciesFulfilled = !value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.dependenciesFulfilled !== previousStatus) {
|
||||
this.notify();
|
||||
}
|
||||
@ -1535,7 +1535,7 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
this.updateHeaderText();
|
||||
this.register();
|
||||
this.onWatchedFieldChange();
|
||||
|
||||
|
||||
//hide input fields, if they didn't match the current access level
|
||||
var storedAccess = this.access
|
||||
if(this.schema.access){
|
||||
@ -1544,12 +1544,12 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
else if(this.schema.access == 'advanced' && storedAccess == 'default')
|
||||
{
|
||||
this.container.style.display = "none";
|
||||
}
|
||||
}
|
||||
else if(this.schema.access == 'expert' && storedAccess != 'expert')
|
||||
{
|
||||
this.container.style.display = "none";
|
||||
//this.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -2046,7 +2046,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
this.placeholder = this.schema.default;
|
||||
|
||||
|
||||
this.format = this.schema.format;
|
||||
if(!this.format && this.schema.media && this.schema.media.type) {
|
||||
this.format = this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,'');
|
||||
@ -2057,7 +2057,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
|
||||
if(this.options.format) {
|
||||
this.format = this.options.format;
|
||||
}
|
||||
|
||||
|
||||
// Specific format
|
||||
if(this.format) {
|
||||
// Text Area
|
||||
@ -2146,7 +2146,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
|
||||
}
|
||||
// Number or integer adds html5 tag 'number'
|
||||
else if (this.schema.type == "number" || this.schema.type == "integer"){
|
||||
|
||||
|
||||
var min = this.schema.minimum
|
||||
var max = this.schema.maximum
|
||||
var step = this.schema.step
|
||||
@ -2240,7 +2240,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
|
||||
if(this.format) this.input.setAttribute('data-schemaformat',this.format);
|
||||
if(this.defaultValue) this.input.setAttribute('data-schemaformat',this.format);
|
||||
if(this.formname && this.label)this.label.setAttribute('for',this.formname);
|
||||
|
||||
|
||||
this.control = this.theme.getFormControl(this.label, this.input, this.description, this.append, this.placeholder);
|
||||
this.container.appendChild(this.control);
|
||||
|
||||
@ -5104,7 +5104,7 @@ JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
|
||||
if(this.options.compact) this.container.className += ' compact';
|
||||
|
||||
this.input = this.theme.getSelectInput(this.enum_options);
|
||||
@ -5122,7 +5122,7 @@ JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
|
||||
});
|
||||
|
||||
if(this.formname)this.label.setAttribute('for',this.formname);
|
||||
|
||||
|
||||
this.control = this.theme.getFormControl(this.label, this.input, this.description);
|
||||
this.container.appendChild(this.control);
|
||||
|
||||
@ -6227,6 +6227,121 @@ JSONEditor.defaults.editors.arraySelectize = JSONEditor.AbstractEditor.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// Imported from Version 1.4.0.beta.0 | https://cdn.jsdelivr.net/npm/@json-editor/json-editor@1.4.0-beta.0/dist/jsoneditor.js
|
||||
JSONEditor.defaults.editors.radio = JSONEditor.defaults.editors.string.extend({
|
||||
build: function () {
|
||||
var self = this;
|
||||
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.options.infoText) this.infoButton = this.theme.getInfoButton(this.options.infoText);
|
||||
if(this.options.compact) this.container.classList.add('compact');
|
||||
|
||||
this.radioContainer = document.createElement('div');
|
||||
|
||||
this.enum_values = this.schema.enum;
|
||||
this.enum_titles = this.options.enum_titles || [];
|
||||
this.radioGroup = [];
|
||||
|
||||
var radioInputEventhandler = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.setValue(this.value);
|
||||
self.onChange(true);
|
||||
};
|
||||
|
||||
for(var i = 0; i < this.enum_values.length; i++) {
|
||||
|
||||
var id = this.key + '-' + i;
|
||||
|
||||
// form radio elements
|
||||
var radioInput = this.theme.getFormInputField('radio');
|
||||
radioInput.name = this.formname;
|
||||
radioInput.value = this.enum_values[i];
|
||||
radioInput.id = id;
|
||||
radioInput.classList.add('radio__field');
|
||||
radioInput.addEventListener('change', radioInputEventhandler, false);
|
||||
this.radioGroup.push(radioInput);
|
||||
|
||||
// form-label for radio elements
|
||||
var radioLabel = document.createElement('label');
|
||||
radioLabel.htmlFor = id;
|
||||
radioLabel.classList.add('radio');
|
||||
|
||||
// contains the displayed text to the label
|
||||
var radioLabelText = document.createElement('span');
|
||||
radioLabelText.innerText = $.i18n(this.options.enum_titles[i]) || this.enum_values[i];
|
||||
radioLabelText.classList.add('radio__label');
|
||||
|
||||
// permits the addition of styles for the radio itself (if you want it to look differently than browser default)
|
||||
var radioLabelIcon = document.createElement('span');
|
||||
radioLabelIcon.classList.add('radio__icon');
|
||||
|
||||
radioLabel.appendChild(radioInput);
|
||||
radioLabel.appendChild(radioLabelIcon);
|
||||
radioLabel.appendChild(radioLabelText);
|
||||
|
||||
this.radioContainer.appendChild(radioLabel);
|
||||
}
|
||||
|
||||
if(this.schema.readOnly || this.schema.readonly) {
|
||||
this.always_disabled = true;
|
||||
for (var j = 0; j < this.radioGroup.length; j++) {
|
||||
this.radioGroup[j].disabled = true;
|
||||
}
|
||||
this.radioContainer.classList.add('readonly');
|
||||
}
|
||||
|
||||
var radioContainerWrapper = this.theme.getContainer();
|
||||
radioContainerWrapper.appendChild(this.radioContainer);
|
||||
|
||||
this.input = radioContainerWrapper;
|
||||
|
||||
this.control = this.theme.getFormControl(this.label, radioContainerWrapper, this.description, this.infoButton);
|
||||
this.container.appendChild(this.control);
|
||||
},
|
||||
enable: function() {
|
||||
if(!this.always_disabled) {
|
||||
for (var i = 0; i<this.radioGroup.length; i++) {
|
||||
this.radioGroup[i].disabled = false;
|
||||
}
|
||||
this.radioContainer.classList.remove('readonly');
|
||||
this._super();
|
||||
}
|
||||
},
|
||||
disable: function(always_disabled) {
|
||||
if(always_disabled) this.always_disabled = true;
|
||||
for (var i = 0; i<this.radioGroup.length; i++) {
|
||||
this.radioGroup[i].disabled = true;
|
||||
}
|
||||
this.radioContainer.classList.add('readonly');
|
||||
this._super();
|
||||
},
|
||||
destroy: function() {
|
||||
if(this.radioContainer.parentNode && this.radioContainer.parentNode.parentNode) this.radioContainer.parentNode.parentNode.removeChild(this.radioContainer.parentNode);
|
||||
if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
|
||||
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
|
||||
this._super();
|
||||
},
|
||||
getNumColumns: function() {
|
||||
return 2;
|
||||
},
|
||||
setValue: function (val) {
|
||||
for(var i = 0; i < this.radioGroup.length; i++) {
|
||||
|
||||
if(this.radioGroup[i].value == val) {
|
||||
this.radioGroup[i].checked = true;
|
||||
this.value = val;
|
||||
if(this.options.displayValue) {
|
||||
this.displayRating.innerHTML = this.value;
|
||||
}
|
||||
this.onChange();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// colorpicker creation and handling, build on top of strings editor
|
||||
JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.extend({
|
||||
getValue: function() {
|
||||
@ -6253,9 +6368,9 @@ JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.ext
|
||||
$(this.input).colorpicker('updatePicker', rgb2hex(val));
|
||||
$(this.input).colorpicker('updateComponent', 'rgb('+val+')');
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
build: function() {
|
||||
this._super();
|
||||
var myinput = this;
|
||||
@ -6277,12 +6392,12 @@ JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.ext
|
||||
|
||||
$("#event_catcher").detach().insertAfter(myinput.input);
|
||||
$("#event_catcher").attr("id", "selector");
|
||||
|
||||
|
||||
$(this.input).colorpicker().on('changeColor', function(e) {
|
||||
$(myinput).val(e.color.toRGB()).change();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
destroy: function() {
|
||||
$(this.input).colorpicker('destroy');
|
||||
}
|
||||
@ -6306,9 +6421,9 @@ JSONEditor.defaults.editors.colorPickerRGBA = JSONEditor.defaults.editors.string
|
||||
// $(this.input).colorpicker('updatePicker', rgb2hex(val));
|
||||
$(this.input).colorpicker('updateComponent', 'rgba('+val+')');
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
build: function() {
|
||||
this._super();
|
||||
var myinput = this;
|
||||
@ -6333,12 +6448,12 @@ JSONEditor.defaults.editors.colorPickerRGBA = JSONEditor.defaults.editors.string
|
||||
|
||||
$("#event_catcher").detach().insertAfter(myinput.input);
|
||||
$("#event_catcher").attr("id", "selector");
|
||||
|
||||
|
||||
$(this.input).colorpicker().on('changeColor', function(e) {
|
||||
$(myinput).val(e.color.toRGB()).change();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
destroy: function() {
|
||||
$(this.input).colorpicker('destroy');
|
||||
}
|
||||
@ -6508,7 +6623,7 @@ JSONEditor.AbstractTheme = Class.extend({
|
||||
},
|
||||
getRangeInput: function(min,max,step) {
|
||||
if (typeof step == "undefined") step = 1;
|
||||
|
||||
|
||||
var el = this.getFormInputField('number');
|
||||
if (typeof min != "undefined") el.setAttribute('min',min);
|
||||
if (typeof max != "undefined") el.setAttribute('max',max);
|
||||
@ -6748,13 +6863,13 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
|
||||
getFormControl: function(label, input, description, append, placeholder) {
|
||||
var group = document.createElement('div');
|
||||
var subgroup = document.createElement('div');
|
||||
|
||||
|
||||
if(placeholder)
|
||||
input.setAttribute('placeholder',placeholder);
|
||||
|
||||
|
||||
if (input.type === 'checkbox'){
|
||||
var helplabel = document.createElement("label")
|
||||
|
||||
|
||||
group.className += ' form-group';
|
||||
group.style.minHeight = "30px";
|
||||
label.className += ' col-form-label col-sm-5 col-md-3 col-lg-5 col-xxl-4';
|
||||
@ -6790,7 +6905,7 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
|
||||
subgroup.className += ' input-group col-sm-7 col-md-9 col-lg-7 col-xxl-8';
|
||||
subgroup.appendChild(input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(description) group.appendChild(description);
|
||||
|
||||
@ -7096,10 +7211,10 @@ JSONEditor.defaults.template = 'default';
|
||||
JSONEditor.defaults.options = {};
|
||||
|
||||
// String translate function
|
||||
JSONEditor.defaults.translate = function(key, variables) {
|
||||
|
||||
JSONEditor.defaults.translate = function(key, variables) {
|
||||
|
||||
return $.i18n(key, variables);
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Miscellaneous Plugin Settings
|
||||
@ -7174,7 +7289,12 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
|
||||
});
|
||||
// Use the `select` editor for dynamic enumSource enums
|
||||
JSONEditor.defaults.resolvers.unshift(function(schema) {
|
||||
if(schema.enumSource) return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
|
||||
if(schema.enumSource) {
|
||||
if(schema.format === "radio") {
|
||||
return "radio";
|
||||
}
|
||||
return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
|
||||
}
|
||||
});
|
||||
// Use the `enum` or `select` editors for schemas with enumerated properties
|
||||
JSONEditor.defaults.resolvers.unshift(function(schema) {
|
||||
@ -7183,6 +7303,11 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
|
||||
return "enum";
|
||||
}
|
||||
else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") {
|
||||
|
||||
if(schema.format === "radio") {
|
||||
return "radio";
|
||||
}
|
||||
|
||||
return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
|
||||
}
|
||||
}
|
||||
|
92
bin/scripts/updateHyperionUser.sh
Executable file
92
bin/scripts/updateHyperionUser.sh
Executable file
@ -0,0 +1,92 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# help print function
|
||||
function printHelp {
|
||||
echo "The script updates the user Hyperion is executed by system and service manager (after start-up).
|
||||
Without arguments it will configure Hyperion being executed under the current user.
|
||||
The script must be executed as root, i.e. sudo $0
|
||||
|
||||
Options:
|
||||
-u username The user name Hyperion to executed to be with
|
||||
-h Shows this help message and exits"
|
||||
}
|
||||
|
||||
function prompt () {
|
||||
while true; do
|
||||
read -p "$1 " yn
|
||||
if [[ $yn = "" ]]; then
|
||||
echo "Please answer Yes or No."
|
||||
else
|
||||
case "${yn:-Y}" in
|
||||
[Yes]* ) return 1;;
|
||||
[No]* ) return 0;;
|
||||
* ) echo "Please answer Yes or No.";;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Default username
|
||||
USERNAME=${SUDO_USER}
|
||||
|
||||
while getopts u:h option
|
||||
do
|
||||
case "${option}"
|
||||
in
|
||||
u) USERNAME=${OPTARG};;
|
||||
v) _VERBOSE=1;;
|
||||
h) printHelp; exit 0;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "`id -u`" -ne 0 ]; then
|
||||
printHelp
|
||||
exit 99
|
||||
fi
|
||||
|
||||
if ! id ${USERNAME} >/dev/null 2>&1; then
|
||||
echo "The given username \"${USERNAME}\" does not exist. Exiting..."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
echo "Configure the hyperion daemon to be executed under user: ${USERNAME}"
|
||||
|
||||
if [ ${USERNAME} == "root" ]; then
|
||||
echo ''
|
||||
echo 'You asked to run Hyperion with root privileges. This poses a security risk!'
|
||||
echo 'It is recommended not to do so unless there are good reasons (e.g. WS281x usage).'
|
||||
if prompt 'Are you sure you want to run Hyperion under root? [Yes/No]'; then
|
||||
echo 'No updates will be done. Exiting...'
|
||||
exit 99
|
||||
fi
|
||||
fi
|
||||
|
||||
#Disable current service
|
||||
CURRENT_SERVICE=$(systemctl --type service | { grep -o "hyperion.*@.*\.service" || true; })
|
||||
if [[ ! -z ${CURRENT_SERVICE} ]]; then
|
||||
CURRENT_SERVICE_USER=$(expr "${CURRENT_SERVICE}" : 'hyperion.*@\(.*\).service')
|
||||
if [ "${USERNAME}" == "${CURRENT_SERVICE_USER}" ]; then
|
||||
echo "Hyperion is already running under the user: ${USERNAME}. No updates required."
|
||||
exit 0;
|
||||
fi
|
||||
echo "Disable current service: ${CURRENT_SERVICE}"
|
||||
systemctl is-active --quiet ${CURRENT_SERVICE} && systemctl disable --quiet ${CURRENT_SERVICE} --now >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
HYPERION="hyperion"
|
||||
#Downward compatibility
|
||||
if [[ ${CURRENT_SERVICE} == hyperiond* ]]; then
|
||||
HYPERION="hyperiond"
|
||||
fi
|
||||
|
||||
#Enable new service
|
||||
NEW_SERVICE="${HYPERION}@${USERNAME}.service"
|
||||
echo "Restarting Hyperion Service: ${NEW_SERVICE}"
|
||||
systemctl enable --quiet ${NEW_SERVICE} --now >/dev/null 2>&1
|
||||
|
||||
# Update HyperBian splash screen
|
||||
sed -i "s/${CURRENT_SERVICE}/${NEW_SERVICE}/" /etc/update-motd.d/10-hyperbian >/dev/null 2>&1
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
||||
|
@ -1,6 +1,10 @@
|
||||
[Unit]
|
||||
Description=Hyperion ambient light systemd service for user %i
|
||||
After=network.target
|
||||
Documentation=https://docs.hyperion-project.org
|
||||
Requisite=network.target
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
After=systemd-resolved.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/hyperiond
|
||||
|
@ -158,12 +158,12 @@ macro(DeployUnix TARGET)
|
||||
|
||||
endif()
|
||||
|
||||
# Copy Python modules to 'share/hyperion/lib/python' and ignore the unnecessary stuff listed below
|
||||
# Copy Python modules to 'share/hyperion/lib/pythonXX' and ignore the unnecessary stuff listed below
|
||||
if (PYTHON_MODULES_DIR)
|
||||
|
||||
install(
|
||||
DIRECTORY ${PYTHON_MODULES_DIR}/
|
||||
DESTINATION "share/hyperion/lib/python"
|
||||
DESTINATION "share/hyperion/lib/python${PYTHON_VERSION_MAJOR_MINOR}"
|
||||
COMPONENT "Hyperion"
|
||||
PATTERN "*.pyc" EXCLUDE # compiled bytecodes
|
||||
PATTERN "__pycache__" EXCLUDE # any cache
|
||||
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "---Hyperion ambient light preinst ---"
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# stop running daemon before we install
|
||||
if pgrep hyperiond > /dev/null 2>&1
|
||||
then
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "--> stop init deamon: systemd"
|
||||
# systemd
|
||||
systemctl stop hyperion hyperiond"@${FOUND_USR}" 2> /dev/null
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "--> stop init deamon: upstart"
|
||||
# upstart
|
||||
initctl stop hyperiond
|
||||
|
||||
else
|
||||
echo "--> stop init deamon: sysV"
|
||||
# sysV
|
||||
service hyperiond stop 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# In case we don't use a service kill all instances
|
||||
killall hyperiond 2> /dev/null
|
||||
|
||||
# overwrite last return code
|
||||
exit 0
|
||||
|
||||
#$USR=hyperionIS;
|
||||
|
||||
#addToGroup()
|
||||
##{
|
||||
# getent group $1 && adduser $USR $1;
|
||||
#}
|
||||
|
||||
#check if user exists
|
||||
#if id $USR >/dev/null 2>&1; then
|
||||
# echo "--> hyperion user exists, skip creation";
|
||||
#else
|
||||
## create user
|
||||
# echo "--> Create Hyperion user";
|
||||
# adduser --system --group $USR;
|
||||
#fi
|
||||
|
||||
# add user to groups if required
|
||||
## secondary user groups that are required to access system things
|
||||
#addToGroup(dialout);
|
||||
#addToGroup(video);
|
||||
#addToGroup(audio);
|
||||
#addToGroup(systemd-journal);
|
||||
# platform specific groups
|
||||
#addToGroup(i2c);
|
||||
#addToGroup(spi);
|
||||
#addToGroup(gpio);
|
@ -1,5 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "--- postinst called with args= " $1 $2
|
||||
|
||||
# If $1=configure and $2 is set, this is an upgrade
|
||||
if [ "$1" = configure ] && [ "$2" != "" ]; then
|
||||
IS_UPGRADE=true
|
||||
else
|
||||
IS_UPGRADE=false
|
||||
fi
|
||||
|
||||
install_file()
|
||||
{
|
||||
src="$1"
|
||||
@ -15,13 +24,11 @@ install_file()
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
echo "--- Hyperion ambient light postinstall ---"
|
||||
|
||||
#check system
|
||||
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835\|BCM2836\|BCM2837\|BCM2711' /proc/cpuinfo`
|
||||
CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
|
||||
OS_HYPERBIAN=`grep ID /etc/os-release | grep -m1 -c HyperBian`
|
||||
|
||||
#Check for a bootloader as Berryboot
|
||||
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
|
||||
@ -32,54 +39,38 @@ NET_IP=`hostname -I | cut -d " " -f1`
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# determine if we should use a service
|
||||
ENABLE_SERVICE=0
|
||||
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
|
||||
|
||||
if [ $CPU_RPI -eq 1 ]; then
|
||||
ENABLE_SERVICE=1
|
||||
STARTUP_MSG="echo ---> Hyperion has been installed as service, it will start on each system startup"
|
||||
fi
|
||||
|
||||
start_msg=""
|
||||
restart_msg=""
|
||||
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "---> init deamon: systemd"
|
||||
# systemd
|
||||
if [ $OS_HYPERBIAN -eq 1 ]; then
|
||||
# start service only
|
||||
echo "--> Service file already exists, skip creation"
|
||||
start_msg="--> systemctl start hyperion"
|
||||
systemctl start hyperion
|
||||
else
|
||||
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service
|
||||
# service registration just on Raspberry Pi, probably need to ask the user how we should use the service. TODO service start in user login scope eg for x11?!
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
systemctl enable hyperiond"@${FOUND_USR}".service
|
||||
start_msg="--> systemctl start hyperiond for user ${FOUND_USR}"
|
||||
systemctl start hyperiond"@${FOUND_USR}"
|
||||
# service registration if no gui is present (only on initial installation and not upgrade)
|
||||
if [ "$IS_UPGRADE" = false ]; then
|
||||
if [ -z "${DISPLAY}" ] && [ -z "${WAYLAND_DISPLAY}" ] && [ -z "${XDG_CURRENT_DESKTOP}" ]; then
|
||||
STARTUP_MSG="echo ---> Hyperion has been installed as service, it will start on each system startup"
|
||||
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
# systemd
|
||||
echo "---> init deamon: systemd"
|
||||
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperion@.service
|
||||
systemctl enable hyperion"@${FOUND_USR}".service
|
||||
start_msg="--> systemctl start hyperion for user ${FOUND_USR}"
|
||||
systemctl start hyperion"@${FOUND_USR}"
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
# upstart
|
||||
echo "---> init deamon: upstart"
|
||||
install_file /usr/share/hyperion/service/hyperion.initctl /etc/init/hyperion.conf && initctl reload-configuration
|
||||
start_msg="--> initctl start hyperion"
|
||||
initctl start hyperion
|
||||
else
|
||||
# sysV
|
||||
echo "---> init deamon: sysV"
|
||||
install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperion && chmod +x /etc/init.d/hyperion && update-rc.d hyperion defaults 98 02
|
||||
start_msg="---> service hyperion start"
|
||||
service hyperion start
|
||||
fi
|
||||
fi
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "---> init deamon: upstart"
|
||||
# upstart
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
|
||||
start_msg="--> initctl start hyperiond"
|
||||
initctl start hyperiond
|
||||
fi
|
||||
|
||||
else
|
||||
echo "---> init deamon: sysV"
|
||||
# sysV
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperiond && chmod +x /etc/init.d/hyperiond && update-rc.d hyperiond defaults 98 02
|
||||
start_msg="---> service hyperiond start"
|
||||
service hyperiond start
|
||||
else
|
||||
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -87,25 +78,30 @@ fi
|
||||
rm -r /usr/share/hyperion/service
|
||||
|
||||
#link binarys and set exec bit
|
||||
BINSP=/usr/share/hyperion/bin
|
||||
BINSP=/usr/share/hyperion
|
||||
BINTP=/usr/bin
|
||||
chmod +x -R $BINSP
|
||||
ln -fs $BINSP/hyperiond $BINTP/hyperiond
|
||||
ln -fs $BINSP/hyperion-remote $BINTP/hyperion-remote
|
||||
ln -fs $BINSP/hyperion-v4l2 $BINTP/hyperion-v4l2
|
||||
ln -fs $BINSP/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-xcb $BINTP/hyperion-xcb 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
|
||||
chmod +x -R $BINSP/bin
|
||||
ln -fs $BINSP/bin/hyperiond $BINTP/hyperiond
|
||||
ln -fs $BINSP/bin/hyperion-remote $BINTP/hyperion-remote
|
||||
ln -fs $BINSP/bin/hyperion-v4l2 $BINTP/hyperion-v4l2
|
||||
ln -fs $BINSP/bin/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
|
||||
ln -fs $BINSP/bin/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
|
||||
ln -fs $BINSP/bin/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
|
||||
ln -fs $BINSP/bin/hyperion-xcb $BINTP/hyperion-xcb 2>/dev/null
|
||||
ln -fs $BINSP/bin/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
|
||||
ln -fs $BINSP/bin/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
|
||||
|
||||
# install desktop icons / not on HyperBian
|
||||
if [ $OS_HYPERBIAN -ne 1 ]; then
|
||||
echo "---> Install Hyperion desktop icons"
|
||||
mkdir /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
cp /usr/share/hyperion/desktop/*.png /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
|
||||
#create symlink for updateHyperionUser.sh script
|
||||
ln -fs $BINSP/scripts/updateHyperionUser.sh $BINTP/updateHyperionUser 2>/dev/null
|
||||
|
||||
# install desktop icons (only on initial installation and not upgrade)
|
||||
if [ "$IS_UPGRADE" = false ]; then
|
||||
if hash desktop-file-install 2>/dev/null; then
|
||||
echo "---> Install Hyperion desktop icons"
|
||||
mkdir /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
cp /usr/share/hyperion/desktop/*.png /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# cleanup desktop icons
|
||||
@ -133,7 +129,11 @@ fi
|
||||
echo ${start_msg}
|
||||
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
echo "---> Hyperion has been installed/updated!"
|
||||
if [ "$IS_UPGRADE" = true ]; then
|
||||
echo "---> Hyperion has been upgraded!"
|
||||
else
|
||||
echo "---> Hyperion has been installed!"
|
||||
fi
|
||||
echo "---> "
|
||||
$STARTUP_MSG
|
||||
echo "---> For configuration, visit with your browser: ${NET_IP}:8090"
|
33
cmake/package-scripts/preinst
Normal file
33
cmake/package-scripts/preinst
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "---Hyperion ambient light preinst ---"
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# stop running daemon before we install/upgrade
|
||||
if pgrep hyperiond > /dev/null 2>&1
|
||||
then
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "--> stop init deamon: systemd"
|
||||
# systemd
|
||||
systemctl stop hyperion hyperiond"@${FOUND_USR}" hyperion"@${FOUND_USR}" 2> /dev/null
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "--> stop init deamon: upstart"
|
||||
# upstart
|
||||
initctl stop hyperiond 2>/dev/null
|
||||
initctl stop hyperion 2>/dev/null
|
||||
else
|
||||
echo "--> stop init deamon: sysV"
|
||||
# sysV
|
||||
service hyperiond stop 2>/dev/null
|
||||
service hyperion stop 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# In case we don't use a service kill all instances
|
||||
killall hyperiond 2> /dev/null
|
||||
|
||||
exit 0
|
@ -2,6 +2,17 @@
|
||||
|
||||
echo "---Hyperion ambient light prerm ---"
|
||||
|
||||
UPGRADE="$1"
|
||||
if [ "$2" = "in-favour" ]; then
|
||||
# Treat conflict remove as an upgrade.
|
||||
UPGRADE="upgrade"
|
||||
fi
|
||||
|
||||
# Don't clean-up just for an upgrade.`
|
||||
if [ "$action" = "upgrade" ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
@ -13,17 +24,18 @@ if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "---> stop init deamon: systemd"
|
||||
# systemd
|
||||
$HYPERION_RUNNING && systemctl stop hyperion hyperiond"@${FOUND_USR}" 2> /dev/null
|
||||
# disable user specific symlink / not on HyperBian
|
||||
$HYPERION_RUNNING && systemctl stop hyperion hyperiond"@${FOUND_USR}" hyperion"@${FOUND_USR}" 2> /dev/null
|
||||
# disable user specific symlink
|
||||
echo "---> Disable service and remove entry"
|
||||
systemctl -q disable hyperiond"@${FOUND_USR}" 2> /dev/null
|
||||
rm -v /etc/systemd/system/hyperiond@.service 2>/dev/null
|
||||
systemctl -q disable hyperion hyperiond"@${FOUND_USR}" hyperion"@${FOUND_USR}" 2> /dev/null
|
||||
rm -v /etc/systemd/system/hyperion.service /etc/systemd/system/hyperiond@.service /etc/systemd/system/hyperion@.service 2>/dev/null
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "---> stop init deamon: upstart"
|
||||
# upstart
|
||||
$HYPERION_RUNNING && initctl stop hyperiond
|
||||
$HYPERION_RUNNING && initctl stop hyperion
|
||||
echo "---> Remove upstart service"
|
||||
rm -v /etc/init/hyperion* 2>/dev/null
|
||||
initctl reload-configuration
|
||||
@ -32,6 +44,7 @@ else
|
||||
echo "---> stop init deamon: sysV"
|
||||
# sysV
|
||||
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null
|
||||
$HYPERION_RUNNING && service hyperion stop 2>/dev/null
|
||||
echo "---> Remove sysV service"
|
||||
update-rc.d -f hyperion remove
|
||||
rm /etc/init.d/hyperion* 2>/dev/null
|
@ -65,7 +65,7 @@ ENDIF()
|
||||
# Specific CPack Package Generators
|
||||
# https://cmake.org/Wiki/CMake:CPackPackageGenerators
|
||||
# .deb files for apt
|
||||
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/prerm" )
|
||||
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/preinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/prerm" )
|
||||
SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libcec6 | libcec4" )
|
||||
SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" )
|
||||
|
||||
@ -75,9 +75,9 @@ SET ( CPACK_RPM_PACKAGE_RELEASE 1 )
|
||||
SET ( CPACK_RPM_PACKAGE_LICENSE "MIT" )
|
||||
SET ( CPACK_RPM_PACKAGE_GROUP "Applications" )
|
||||
SET ( CPACK_RPM_PACKAGE_REQUIRES "libcec >= 4.0.0" )
|
||||
SET ( CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/preinst" )
|
||||
SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" )
|
||||
SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/prerm" )
|
||||
SET ( CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/preinst" )
|
||||
SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/postinst" )
|
||||
SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/prerm" )
|
||||
|
||||
# OSX "Bundle" generator TODO Add more osx generators
|
||||
# https://cmake.org/cmake/help/v3.10/module/CPackBundle.html
|
||||
|
@ -1,148 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
install_file()
|
||||
{
|
||||
src="$1"
|
||||
dest="$2"
|
||||
|
||||
if [ ! -e "$dest" ]
|
||||
then
|
||||
cp "$src" "${dest}"
|
||||
return 1
|
||||
else
|
||||
echo "--> Service file already exists, skip creation"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
echo "---Hyperion ambient light postinstall ---"
|
||||
|
||||
#check system
|
||||
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo`
|
||||
CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
|
||||
|
||||
#Check for a bootloader as Berryboot
|
||||
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
|
||||
|
||||
#get current system ip
|
||||
NET_IP=`hostname -I | cut -d " " -f1`
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# determine if we should use a service
|
||||
ENABLE_SERVICE=0
|
||||
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
|
||||
|
||||
if [ $CPU_RPI -eq 1 ]; then
|
||||
ENABLE_SERVICE=1
|
||||
STARTUP_MSG="echo ---> Hyperion has been installed as service, it will start on each system startup"
|
||||
fi
|
||||
|
||||
start_msg=""
|
||||
restart_msg=""
|
||||
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "---> init deamon: systemd"
|
||||
# systemd
|
||||
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service
|
||||
# service registration just on Raspberry Pi, probably need to ask the user how we should use the service. TODO service start in user login scope eg for x11?!
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
systemctl enable hyperiond"@${FOUND_USR}".service
|
||||
start_msg="--> systemctl start hyperiond for user ${FOUND_USR}"
|
||||
systemctl start hyperiond"@${FOUND_USR}"
|
||||
fi
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "---> init deamon: upstart"
|
||||
# upstart
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
|
||||
start_msg="--> initctl start hyperiond"
|
||||
initctl start hyperiond
|
||||
fi
|
||||
|
||||
else
|
||||
echo "---> init deamon: sysV"
|
||||
# sysV
|
||||
if [ $ENABLE_SERVICE -eq 1 ]; then
|
||||
install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperiond && chmod +x /etc/init.d/hyperiond && update-rc.d hyperiond defaults 98 02
|
||||
start_msg="---> service hyperiond start"
|
||||
service hyperiond start
|
||||
fi
|
||||
fi
|
||||
|
||||
#cleanup
|
||||
rm -r /usr/share/hyperion/service
|
||||
|
||||
#link binarys and set exec bit
|
||||
BINSP=/usr/share/hyperion/bin
|
||||
BINTP=/usr/bin
|
||||
chmod +x -R $BINSP
|
||||
ln -fs $BINSP/hyperiond $BINTP/hyperiond
|
||||
ln -fs $BINSP/hyperion-remote $BINTP/hyperion-remote
|
||||
ln -fs $BINSP/hyperion-v4l2 $BINTP/hyperion-v4l2
|
||||
ln -fs $BINSP/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-xcb $BINTP/hyperion-xcb 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
|
||||
ln -fs $BINSP/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
|
||||
|
||||
# install desktop icons
|
||||
echo "---> Install Hyperion desktop icons"
|
||||
mkdir /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
cp /usr/share/hyperion/desktop/*.png /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
|
||||
|
||||
# cleanup desktop icons
|
||||
rm -r /usr/share/hyperion/desktop 2>/dev/null
|
||||
|
||||
#Check, if dtparam=spi=on is in place
|
||||
if [ $CPU_RPI -eq 1 ]; then
|
||||
BOOT_DIR="/boot"
|
||||
if [ $BOOT_BERRYBOOT -eq 1 ]; then
|
||||
BOOT_DIR=$(sed -ne "s#/dev/mmcblk0p1 \([^ ]*\) vfat rw,.*#\1#p" /etc/mtab)
|
||||
fi
|
||||
if [ -z "$BOOT_DIR" -o ! -f "$BOOT_DIR/config.txt" ]; then
|
||||
echo '---> Warning: RPi using BERRYBOOT found but can not locate where config.txt is to enable SPI. (BOOT_DIR='"$BOOT_DIR)"
|
||||
SPIOK=1 # Not sure if OK, but don't ask to reboot
|
||||
else
|
||||
SPIOK=`grep '^\dtparam=spi=on' "$BOOT_DIR/config.txt" | wc -l`
|
||||
if [ $SPIOK -ne 1 ]; then
|
||||
echo '---> Raspberry Pi found, but SPI is not set, we write "dtparam=spi=on" to '"$BOOT_DIR/config.txt"
|
||||
sed -i '$a dtparam=spi=on' "$BOOT_DIR/config.txt"
|
||||
REBOOTMESSAGE="echo Please reboot your Raspberry Pi, we inserted dtparam=spi=on to $BOOT_DIR/config.txt"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ${start_msg}
|
||||
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
echo "---> Hyperion has been installed/updated!"
|
||||
echo "---> "
|
||||
$STARTUP_MSG
|
||||
echo "---> For configuration, visit with your browser: ${NET_IP}:8090"
|
||||
echo "---> or if already used by another service try: ${NET_IP}:8091"
|
||||
$REBOOTMESSAGE
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
echo "Webpage: www.hyperion-project.org"
|
||||
echo "Forum: www.hyperion-project.org"
|
||||
echo "Documenation: docs.hyperion-project.org"
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
|
||||
|
||||
if [ -e /opt/hyperion/ ]
|
||||
then
|
||||
echo
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
echo "- It seemd that you have an older version of hyperion installed in /opt/hyperion -"
|
||||
echo "- please remove it to avoid problems -"
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "---Hyperion ambient light preinst ---"
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# stop running daemon before we install
|
||||
if pgrep hyperiond > /dev/null 2>&1
|
||||
then
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "--> stop init deamon: systemd"
|
||||
# systemd
|
||||
systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "--> stop init deamon: upstart"
|
||||
# upstart
|
||||
initctl stop hyperiond
|
||||
|
||||
else
|
||||
echo "--> stop init deamon: sysV"
|
||||
# sysV
|
||||
service hyperiond stop 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# In case we don't use a service kill all instances
|
||||
killall hyperiond 2> /dev/null
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
#$USR=hyperionIS;
|
||||
|
||||
#addToGroup()
|
||||
##{
|
||||
# getent group $1 && adduser $USR $1;
|
||||
#}
|
||||
|
||||
#check if user exists
|
||||
#if id $USR >/dev/null 2>&1; then
|
||||
# echo "--> hyperion user exists, skip creation";
|
||||
#else
|
||||
## create user
|
||||
# echo "--> Create Hyperion user";
|
||||
# adduser --system --group $USR;
|
||||
#fi
|
||||
|
||||
# add user to groups if required
|
||||
## secondary user groups that are required to access system things
|
||||
#addToGroup(dialout);
|
||||
#addToGroup(video);
|
||||
#addToGroup(audio);
|
||||
#addToGroup(systemd-journal);
|
||||
# platform specific groups
|
||||
#addToGroup(i2c);
|
||||
#addToGroup(spi);
|
||||
#addToGroup(gpio);
|
@ -1,50 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "---Hyperion ambient light prerm ---"
|
||||
|
||||
# search for users in system, returns first entry
|
||||
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
|
||||
|
||||
# stop running daemon before we delete it
|
||||
HYPERION_RUNNING=false
|
||||
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
|
||||
|
||||
if grep -m1 systemd /proc/1/comm > /dev/null
|
||||
then
|
||||
echo "---> stop init deamon: systemd"
|
||||
# systemd
|
||||
$HYPERION_RUNNING && systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
|
||||
# disable user specific symlink
|
||||
echo "---> Disable service and remove entry"
|
||||
systemctl -q disable hyperiond"@${FOUND_USR}"
|
||||
rm -v /etc/systemd/system/hyperiond@.service 2>/dev/null
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "---> stop init deamon: upstart"
|
||||
# upstart
|
||||
$HYPERION_RUNNING && initctl stop hyperiond
|
||||
echo "---> Remove upstart service"
|
||||
rm -v /etc/init/hyperion* 2>/dev/null
|
||||
initctl reload-configuration
|
||||
|
||||
else
|
||||
echo "---> stop init deamon: sysV"
|
||||
# sysV
|
||||
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null
|
||||
echo "---> Remove sysV service"
|
||||
update-rc.d -f hyperion remove
|
||||
rm /etc/init.d/hyperion* 2>/dev/null
|
||||
fi
|
||||
|
||||
# In case we don't use a service kill all instances
|
||||
killall hyperiond 2> /dev/null
|
||||
|
||||
# delete desktop icons; desktop-file-edit is a workaround to hide the entry and delete it afterwards manual.
|
||||
# TODO Better way for deletion and keep the desktop in sync without logout/login or desktop dependend cmds?
|
||||
echo "---> Delete Hyperion desktop icons"
|
||||
desktop-file-edit --set-key=NoDisplay --set-value=true /usr/share/applications/hyperiond.desktop 2>/dev/null
|
||||
rm -v /usr/share/applications/hyperion* 2>/dev/null
|
||||
rm -rv /usr/share/pixmaps/hyperion 2>/dev/null
|
||||
|
||||
exit 0
|
8
debian/rules
vendored
8
debian/rules
vendored
@ -3,7 +3,7 @@ export DH_VERBOSE = 1
|
||||
|
||||
BUILDDIR = build
|
||||
|
||||
build:
|
||||
build:
|
||||
mkdir $(BUILDDIR);
|
||||
cd $(BUILDDIR); cmake -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr ..
|
||||
make -j4 -C $(BUILDDIR)
|
||||
@ -15,11 +15,11 @@ binary-indep:
|
||||
binary-arch:
|
||||
cd $(BUILDDIR); cmake -P cmake_install.cmake
|
||||
mkdir debian/tmp/DEBIAN
|
||||
cp cmake/debian/postinst debian/tmp/DEBIAN
|
||||
cp cmake/package-scripts/postinst debian/tmp/DEBIAN
|
||||
chmod 0775 debian/tmp/DEBIAN/postinst
|
||||
cp cmake/debian/preinst debian/tmp/DEBIAN
|
||||
cp cmake/package-scripts/preinst debian/tmp/DEBIAN
|
||||
chmod 0775 debian/tmp/DEBIAN/preinst
|
||||
cp cmake/debian/prerm debian/tmp/DEBIAN
|
||||
cp cmake/package-scripts/prerm debian/tmp/DEBIAN
|
||||
chmod 0775 debian/tmp/DEBIAN/prerm
|
||||
dpkg-gencontrol -phyperion
|
||||
dpkg --build debian/tmp ..
|
||||
|
2
dependencies/CMakeLists-mbedtls.txt.in
vendored
2
dependencies/CMakeLists-mbedtls.txt.in
vendored
@ -14,7 +14,7 @@ include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
mbedtls
|
||||
GIT_REPOSITORY "https://github.com/ARMmbed/mbedtls.git"
|
||||
GIT_TAG "v2.25.0" # Reset to origin/master if issue https://github.com/ARMmbed/mbedtls/issues/4233 if fixed
|
||||
GIT_TAG "v2.27.0" # Latest 2.x Version
|
||||
BUILD_ALWAYS OFF
|
||||
DOWNLOAD_DIR "${DOWNLOAD_DIR}"
|
||||
SOURCE_DIR "${SOURCE_DIR}"
|
||||
|
2
dependencies/CMakeLists.txt
vendored
2
dependencies/CMakeLists.txt
vendored
@ -233,7 +233,7 @@ if (NOT USE_SYSTEM_MBEDTLS_LIBS)
|
||||
FetchContent_Declare(
|
||||
mbedtls
|
||||
GIT_REPOSITORY https://github.com/ARMmbed/mbedtls.git
|
||||
GIT_TAG "v2.25.0" # Reset to origin/master if issue https://github.com/ARMmbed/mbedtls/issues/4233 if fixed
|
||||
GIT_TAG "v2.27.0" # Latest 2.x Version
|
||||
BUILD_ALWAYS OFF
|
||||
GIT_PROGRESS 1
|
||||
DOWNLOAD_DIR "${MBEDTLS_DOWNLOAD_DIR}"
|
||||
|
@ -3,8 +3,14 @@
|
||||
"script" : "gif.py",
|
||||
"args" :
|
||||
{
|
||||
"image" : ":fire.gif",
|
||||
"cropBottom": 0,
|
||||
"cropLeft": 0,
|
||||
"cropRight": 0,
|
||||
"cropTop": 0,
|
||||
"file" : ":fire.gif",
|
||||
"fps" :25,
|
||||
"grayscale": false,
|
||||
"imageSource": "file",
|
||||
"reverse" : false
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,27 @@
|
||||
import hyperion, time
|
||||
|
||||
# Get the parameters
|
||||
imageFile = hyperion.args.get('image')
|
||||
imageData = hyperion.args.get('url') if hyperion.args.get('imageSource', "") == "url" else hyperion.args.get('file')
|
||||
framesPerSecond = float(hyperion.args.get('fps', 25))
|
||||
reverse = bool(hyperion.args.get('reverse', False))
|
||||
reverse = bool(hyperion.args.get('reverse', False))
|
||||
cropLeft = int(hyperion.args.get('cropLeft', 0))
|
||||
cropTop = int(hyperion.args.get('cropTop', 0))
|
||||
cropRight = int(hyperion.args.get('cropRight', 0))
|
||||
cropBottom = int(hyperion.args.get('cropBottom', 0))
|
||||
grayscale = bool(hyperion.args.get('grayscale', False))
|
||||
|
||||
sleepTime = 1./framesPerSecond
|
||||
imageList = []
|
||||
imageFrameList = []
|
||||
|
||||
if imageFile:
|
||||
imageList = [reversed(hyperion.getImage(imageFile))] if reverse else hyperion.getImage(imageFile)
|
||||
if imageData:
|
||||
if reverse:
|
||||
imageFrameList = reversed(hyperion.getImage(imageData, cropLeft, cropTop, cropRight, cropBottom, grayscale))
|
||||
else:
|
||||
imageFrameList = hyperion.getImage(imageData, cropLeft, cropTop, cropRight, cropBottom, grayscale)
|
||||
|
||||
# Start the write data loop
|
||||
while not hyperion.abort() and imageList:
|
||||
for image in imageList:
|
||||
hyperion.setImage(image["imageWidth"], image["imageHeight"], image["imageData"])
|
||||
time.sleep(sleepTime)
|
||||
while not hyperion.abort() and imageFrameList:
|
||||
for image in imageFrameList:
|
||||
if not hyperion.abort():
|
||||
hyperion.setImage(image["imageWidth"], image["imageHeight"], image["imageData"])
|
||||
time.sleep(sleepTime)
|
||||
|
@ -3,8 +3,14 @@
|
||||
"script" : "gif.py",
|
||||
"args" :
|
||||
{
|
||||
"image" : ":lights.gif",
|
||||
"cropBottom": 0,
|
||||
"cropLeft": 0,
|
||||
"cropRight": 0,
|
||||
"cropTop": 0,
|
||||
"file" : ":lights.gif",
|
||||
"fps" :25,
|
||||
"reverse" : false
|
||||
"grayscale": false,
|
||||
"imageSource": "file",
|
||||
"reverse": false
|
||||
}
|
||||
}
|
||||
|
16
effects/matrix.json
Normal file
16
effects/matrix.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name" : "Matrix",
|
||||
"script" : "gif.py",
|
||||
"args" :
|
||||
{
|
||||
"cropBottom": 0,
|
||||
"cropLeft": 0,
|
||||
"cropRight": 0,
|
||||
"cropTop": 0,
|
||||
"fps": 30,
|
||||
"grayscale": false,
|
||||
"imageSource": "url",
|
||||
"reverse": false,
|
||||
"url": "https://i.gifer.com/1j6F.gif"
|
||||
}
|
||||
}
|
@ -4,17 +4,79 @@
|
||||
"title":"edt_eff_gif_header",
|
||||
"required":true,
|
||||
"properties": {
|
||||
"image": {
|
||||
"imageSource": {
|
||||
"type": "string",
|
||||
"title": "edt_eff_image_source",
|
||||
"format": "radio",
|
||||
"enum": ["url", "file"],
|
||||
"options" : {
|
||||
"enum_titles" : ["edt_eff_image_source_url", "edt_eff_image_source_file"]
|
||||
},
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"title":"edt_eff_url",
|
||||
"default": "",
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"imageSource": "url"
|
||||
}
|
||||
},
|
||||
"propertyOrder" : 2
|
||||
},
|
||||
"file": {
|
||||
"type": "string",
|
||||
"title":"edt_eff_image",
|
||||
"format" : "url",
|
||||
"options" :
|
||||
{
|
||||
"upload" : true,
|
||||
"auto_upload" : true
|
||||
"auto_upload" : true,
|
||||
"dependencies": {
|
||||
"imageSource": "file"
|
||||
}
|
||||
},
|
||||
"default": "",
|
||||
"propertyOrder" : 1
|
||||
"propertyOrder" : 3
|
||||
},
|
||||
"cropLeft": {
|
||||
"type": "integer",
|
||||
"title":"edt_conf_v4l2_cropLeft_title",
|
||||
"default": 0,
|
||||
"minimum" : 0,
|
||||
"step" : 1,
|
||||
"propertyOrder" : 4
|
||||
},
|
||||
"cropTop": {
|
||||
"type": "integer",
|
||||
"title":"edt_conf_v4l2_cropTop_title",
|
||||
"default": 0,
|
||||
"minimum" : 0,
|
||||
"step" : 1,
|
||||
"propertyOrder" : 5
|
||||
},
|
||||
"cropRight": {
|
||||
"type": "integer",
|
||||
"title":"edt_conf_v4l2_cropRight_title",
|
||||
"default": 0,
|
||||
"minimum" : 0,
|
||||
"step" : 1,
|
||||
"propertyOrder" : 6
|
||||
},
|
||||
"cropBottom": {
|
||||
"type": "integer",
|
||||
"title":"edt_conf_v4l2_cropBottom_title",
|
||||
"default": 0,
|
||||
"minimum" : 0,
|
||||
"step" : 1,
|
||||
"propertyOrder" : 7
|
||||
},
|
||||
"grayscale": {
|
||||
"type": "boolean",
|
||||
"title":"edt_eff_grayscale",
|
||||
"default": false,
|
||||
"propertyOrder" : 8
|
||||
},
|
||||
"fps": {
|
||||
"type": "integer",
|
||||
@ -23,13 +85,13 @@
|
||||
"minimum" : 1,
|
||||
"maximum" : 100,
|
||||
"step" : 1,
|
||||
"propertyOrder" : 2
|
||||
"propertyOrder" : 9
|
||||
},
|
||||
"reverse": {
|
||||
"type": "boolean",
|
||||
"title":"edt_eff_reversedirection",
|
||||
"default": false,
|
||||
"propertyOrder" : 3
|
||||
"propertyOrder" : 10
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
class Effect;
|
||||
|
||||
class EffectModule
|
||||
class EffectModule: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Python 3 module def
|
||||
static struct PyModuleDef moduleDef;
|
||||
|
@ -79,6 +79,15 @@ public:
|
||||
///
|
||||
bool open();
|
||||
|
||||
#ifdef _WIN32
|
||||
///
|
||||
/// @brief Replacement for the virtual QWindowsScreen Function grabWindow (only on Windows).
|
||||
///
|
||||
/// @return QPixmap
|
||||
///
|
||||
QPixmap grabWindow(quintptr window, int xIn, int yIn, int width, int height) const;
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
|
||||
///
|
||||
|
@ -70,9 +70,9 @@ QString EffectFileHandler::deleteEffect(const QString& effectName)
|
||||
{
|
||||
if (effectConfigurationFile.exists())
|
||||
{
|
||||
if ((it->script == ":/effects/gif.py") && !it->args.value("image").toString("").isEmpty())
|
||||
if ((it->script == ":/effects/gif.py") && !it->args.value("file").toString("").isEmpty())
|
||||
{
|
||||
QFileInfo effectImageFile(it->args.value("image").toString());
|
||||
QFileInfo effectImageFile(it->args.value("file").toString());
|
||||
if (effectImageFile.exists())
|
||||
{
|
||||
QFile::remove(effectImageFile.absoluteFilePath());
|
||||
@ -159,19 +159,26 @@ QString EffectFileHandler::saveEffect(const QJsonObject& message)
|
||||
newFileName.setFile(f);
|
||||
}
|
||||
|
||||
if (!message["imageData"].toString("").isEmpty() && !message["args"].toObject().value("image").toString("").isEmpty())
|
||||
if (!message["imageData"].toString("").isEmpty() && !message["args"].toObject().value("file").toString("").isEmpty())
|
||||
{
|
||||
QJsonObject args = message["args"].toObject();
|
||||
QString imageFilePath = effectArray[0].toString().replace("$ROOT", _rootPath) + '/' + args.value("image").toString();
|
||||
QString imageFilePath = effectArray[0].toString().replace("$ROOT", _rootPath) + '/' + args.value("file").toString();
|
||||
|
||||
QFileInfo imageFileName(imageFilePath);
|
||||
if (!FileUtils::writeFile(imageFileName.absoluteFilePath(), QByteArray::fromBase64(message["imageData"].toString("").toUtf8()), _log))
|
||||
{
|
||||
return "Error while saving image file '" + message["args"].toObject().value("image").toString() + ", please check the Hyperion Log";
|
||||
return "Error while saving image file '" + message["args"].toObject().value("file").toString() + ", please check the Hyperion Log";
|
||||
}
|
||||
|
||||
//Update json with image file location
|
||||
args["image"] = imageFilePath;
|
||||
args["file"] = imageFilePath;
|
||||
effectJson["args"] = args;
|
||||
}
|
||||
|
||||
if (message["args"].toObject().value("imageSource").toString("") == "url" || message["args"].toObject().value("imageSource").toString("") == "file")
|
||||
{
|
||||
QJsonObject args = message["args"].toObject();
|
||||
args.remove(args.value("imageSource").toString("") == "url" ? "file" : "url");
|
||||
effectJson["args"] = args;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include <QDateTime>
|
||||
#include <QImageReader>
|
||||
#include <QBuffer>
|
||||
#include <QUrl>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QEventLoop>
|
||||
|
||||
// Get the effect from the capsule
|
||||
#define getEffect() static_cast<Effect*>((Effect*)PyCapsule_Import("hyperion.__effectObj", 0))
|
||||
@ -219,31 +223,57 @@ PyObject* EffectModule::wrapSetImage(PyObject *self, PyObject *args)
|
||||
|
||||
PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
|
||||
{
|
||||
QString file;
|
||||
QBuffer buffer;
|
||||
QImageReader reader;
|
||||
char *source;
|
||||
int cropLeft = 0, cropTop = 0, cropRight = 0, cropBottom = 0;
|
||||
bool grayscale = false;
|
||||
|
||||
if (getEffect()->_imageData.isEmpty())
|
||||
{
|
||||
Q_INIT_RESOURCE(EffectEngine);
|
||||
|
||||
char *source;
|
||||
if(!PyArg_ParseTuple(args, "s", &source))
|
||||
if(!PyArg_ParseTuple(args, "s|iiiii", &source, &cropLeft, &cropTop, &cropRight, &cropBottom, &grayscale))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "String required");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
file = QString::fromUtf8(source);
|
||||
const QUrl url = QUrl(source);
|
||||
if (url.isValid())
|
||||
{
|
||||
QNetworkAccessManager *networkManager = new QNetworkAccessManager();
|
||||
QNetworkReply * networkReply = networkManager->get(QNetworkRequest(url));
|
||||
|
||||
if (file.mid(0, 1) == ":")
|
||||
file = ":/effects/"+file.mid(1);
|
||||
QEventLoop eventLoop;
|
||||
connect(networkReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
|
||||
eventLoop.exec();
|
||||
|
||||
reader.setDecideFormatFromContent(true);
|
||||
reader.setFileName(file);
|
||||
if (networkReply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
buffer.setData(networkReply->readAll());
|
||||
buffer.open(QBuffer::ReadOnly);
|
||||
reader.setDecideFormatFromContent(true);
|
||||
reader.setDevice(&buffer);
|
||||
}
|
||||
|
||||
delete networkReply;
|
||||
delete networkManager;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString file = QString::fromUtf8(source);
|
||||
|
||||
if (file.mid(0, 1) == ":")
|
||||
file = ":/effects/"+file.mid(1);
|
||||
|
||||
reader.setDecideFormatFromContent(true);
|
||||
reader.setFileName(file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyArg_ParseTuple(args, "|siiiii", &source, &cropLeft, &cropTop, &cropRight, &cropBottom, &grayscale);
|
||||
buffer.setData(QByteArray::fromBase64(getEffect()->_imageData.toUtf8()));
|
||||
buffer.open(QBuffer::ReadOnly);
|
||||
reader.setDecideFormatFromContent(true);
|
||||
@ -260,19 +290,33 @@ PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
|
||||
if (reader.canRead())
|
||||
{
|
||||
QImage qimage = reader.read();
|
||||
|
||||
int width = qimage.width();
|
||||
int height = qimage.height();
|
||||
|
||||
if (cropLeft > 0 || cropTop > 0 || cropRight > 0 || cropBottom > 0)
|
||||
{
|
||||
if (cropLeft + cropRight >= width || cropTop + cropBottom >= height)
|
||||
{
|
||||
QString errorStr = QString("Rejecting invalid crop values: left: %1, right: %2, top: %3, bottom: %4, higher than height/width %5/%6").arg(cropLeft).arg(cropRight).arg(cropTop).arg(cropBottom).arg(height).arg(width);
|
||||
PyErr_SetString(PyExc_RuntimeError, qPrintable(errorStr));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
qimage = qimage.copy(cropLeft, cropTop, width - cropLeft - cropRight, height - cropTop - cropBottom);
|
||||
width = qimage.width();
|
||||
height = qimage.height();
|
||||
}
|
||||
|
||||
QByteArray binaryImage;
|
||||
for (int i = 0; i<height; ++i)
|
||||
for (int i = 0; i<height; i++)
|
||||
{
|
||||
const QRgb *scanline = reinterpret_cast<const QRgb *>(qimage.scanLine(i));
|
||||
for (int j = 0; j< width; ++j)
|
||||
const QRgb *end = scanline + qimage.width();
|
||||
for (; scanline != end; scanline++)
|
||||
{
|
||||
binaryImage.append((char) qRed(scanline[j]));
|
||||
binaryImage.append((char) qGreen(scanline[j]));
|
||||
binaryImage.append((char) qBlue(scanline[j]));
|
||||
binaryImage.append(!grayscale ? (char) qRed(scanline[0]) : (char) qGray(scanline[0]));
|
||||
binaryImage.append(!grayscale ? (char) qGreen(scanline[1]) : (char) qGray(scanline[1]));
|
||||
binaryImage.append(!grayscale ? (char) qBlue(scanline[2]) : (char) qGray(scanline[2]));
|
||||
}
|
||||
}
|
||||
PyList_SET_ITEM(result, i, Py_BuildValue("{s:i,s:i,s:O}", "imageWidth", width, "imageHeight", height, "imageData", PyByteArray_FromStringAndSize(binaryImage.constData(),binaryImage.size())));
|
||||
@ -283,6 +327,7 @@ PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const bool verbose = false;
|
||||
@ -156,6 +160,58 @@ void QtGrabber::geometryChanged(const QRect &geo)
|
||||
updateScreenDimensions(true);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
extern QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int format = 0);
|
||||
|
||||
QPixmap QtGrabber::grabWindow(quintptr window, int xIn, int yIn, int width, int height) const
|
||||
{
|
||||
QSize windowSize;
|
||||
int x = xIn;
|
||||
int y = yIn;
|
||||
HWND hwnd = reinterpret_cast<HWND>(window);
|
||||
if (hwnd)
|
||||
{
|
||||
RECT r;
|
||||
GetClientRect(hwnd, &r);
|
||||
windowSize = QSize(r.right - r.left, r.bottom - r.top);
|
||||
}
|
||||
else
|
||||
{
|
||||
hwnd = GetDesktopWindow();
|
||||
const QRect screenGeometry = _screen->geometry();
|
||||
windowSize = screenGeometry.size();
|
||||
x += screenGeometry.x();
|
||||
y += screenGeometry.y();
|
||||
}
|
||||
|
||||
if (width < 0)
|
||||
width = windowSize.width() - x;
|
||||
|
||||
if (height < 0)
|
||||
height = windowSize.height() - y;
|
||||
|
||||
// Create and setup bitmap
|
||||
HDC display_dc = GetDC(nullptr);
|
||||
HDC bitmap_dc = CreateCompatibleDC(display_dc);
|
||||
HBITMAP bitmap = CreateCompatibleBitmap(display_dc, width, height);
|
||||
HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
|
||||
|
||||
// copy data
|
||||
HDC window_dc = GetDC(hwnd);
|
||||
BitBlt(bitmap_dc, 0, 0, width, height, window_dc, x, y, SRCCOPY);
|
||||
|
||||
// clean up all but bitmap
|
||||
ReleaseDC(hwnd, window_dc);
|
||||
SelectObject(bitmap_dc, null_bitmap);
|
||||
DeleteDC(bitmap_dc);
|
||||
const QPixmap pixmap = qt_pixmapFromWinHBITMAP(bitmap);
|
||||
DeleteObject(bitmap);
|
||||
ReleaseDC(nullptr, display_dc);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
#endif
|
||||
|
||||
int QtGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
int rc = 0;
|
||||
@ -170,7 +226,11 @@ int QtGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
|
||||
if (_isEnabled)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
QPixmap originalPixmap = grabWindow(0, _src_x, _src_y, _src_x_max, _src_y_max);
|
||||
#else
|
||||
QPixmap originalPixmap = _screen->grabWindow(0, _src_x, _src_y, _src_x_max, _src_y_max);
|
||||
#endif
|
||||
if (originalPixmap.isNull())
|
||||
{
|
||||
rc = -1;
|
||||
|
@ -23,17 +23,26 @@ PythonInit::PythonInit()
|
||||
// register modules
|
||||
EffectModule::registerHyperionExtensionModule();
|
||||
|
||||
// Set Program name
|
||||
Py_SetProgramName(L"Hyperion");
|
||||
|
||||
// set Python module path when exists
|
||||
QString py_patch = QDir::cleanPath(qApp->applicationDirPath() + "/../lib/python");
|
||||
QString py_patch = QDir::cleanPath(qApp->applicationDirPath() + "/../lib/python" + STRINGIFY(PYTHON_VERSION_MAJOR_MINOR));
|
||||
QString py_file = QDir::cleanPath(qApp->applicationDirPath() + "/python" + STRINGIFY(PYTHON_VERSION_MAJOR_MINOR) + ".zip");
|
||||
|
||||
if (QFile(py_file).exists() || QDir(py_patch).exists())
|
||||
{
|
||||
Py_NoSiteFlag++;
|
||||
if (QFile(py_file).exists())
|
||||
{
|
||||
Py_SetPythonHome(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
|
||||
Py_SetPath(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
|
||||
}
|
||||
else if (QDir(py_patch).exists())
|
||||
{
|
||||
Py_SetPythonHome(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
|
||||
Py_SetPath(Py_DecodeLocale(py_patch.toLatin1().data(), nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
// init Python
|
||||
|
@ -138,6 +138,7 @@ if(CMAKE_HOST_UNIX)
|
||||
install( CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperion/bin/hyperiond\" \"${CMAKE_BINARY_DIR}/symlink_hyperiond\" )" COMPONENT "Hyperion" )
|
||||
install( FILES ${CMAKE_BINARY_DIR}/symlink_hyperiond DESTINATION "bin" RENAME hyperiond COMPONENT "Hyperion" )
|
||||
install( CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_hyperiond )" COMPONENT "Hyperion" )
|
||||
install ( FILES ${CMAKE_SOURCE_DIR}/bin/scripts/updateHyperionUser.sh DESTINATION "share/hyperion/scripts" COMPONENT "Hyperion" )
|
||||
endif()
|
||||
|
||||
# Deploy Qt DLLs into the binary folder.
|
||||
|
Loading…
Reference in New Issue
Block a user