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:
Markus 2021-10-02 18:02:52 +02:00 committed by GitHub
parent f269268def
commit eb96553975
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 776 additions and 573 deletions

View File

@ -35,7 +35,7 @@ jobs:
- name: Build package - name: Build package
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version tr -d '\n' < .version > temp && mv temp .version
mkdir -p "${GITHUB_WORKSPACE}/deploy" mkdir -p "${GITHUB_WORKSPACE}/deploy"
docker run --rm \ docker run --rm \
-v "${GITHUB_WORKSPACE}/deploy:/deploy" \ -v "${GITHUB_WORKSPACE}/deploy:/deploy" \
@ -43,7 +43,7 @@ jobs:
ghcr.io/hyperion-project/${{ matrix.architecture }}:$(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]') \ ghcr.io/hyperion-project/${{ matrix.architecture }}:$(echo ${{ matrix.distribution }} | tr '[:upper:]' '[:lower:]') \
/bin/bash -c "cd /source && \ /bin/bash -c "cd /source && \
mkdir -p debian/source && echo '3.0 (quilt)' > debian/source/format && \ 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 && \ 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 && \ 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 . && \ tar cf ../hyperion_2.0.0.orig.tar . && \

View File

@ -36,12 +36,12 @@ jobs:
with: with:
submodules: true submodules: true
# Append PR number to version # Append PR number to .version
- name: Append PR number to version - name: Append PR number to version
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version tr -d '\n' < .version > temp && mv temp .version
echo -n "+PR${{ github.event.pull_request.number }}" >> version echo -n "+PR${{ github.event.pull_request.number }}" >> .version
# Build packages # Build packages
- name: Build packages - name: Build packages
@ -82,12 +82,12 @@ jobs:
with: with:
submodules: true submodules: true
# Append PR number to version # Append PR number to .version
- name: Append PR number to version - name: Append PR number to version
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version tr -d '\n' < .version > temp && mv temp .version
echo -n "+PR${{ github.event.pull_request.number }}" >> version echo -n "+PR${{ github.event.pull_request.number }}" >> .version
# Install dependencies # Install dependencies
- name: Install dependencies - name: Install dependencies
@ -131,12 +131,12 @@ jobs:
with: with:
submodules: true submodules: true
# Append PR number to version # Append PR number to .version
- name: Append PR number to version - name: Append PR number to version
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version tr -d '\n' < .version > temp && mv temp .version
echo -n "+PR${{ github.event.pull_request.number }}" >> version echo -n "+PR${{ github.event.pull_request.number }}" >> .version
- name: Cache Qt - name: Cache Qt
uses: actions/cache@v2 uses: actions/cache@v2
@ -199,27 +199,3 @@ jobs:
with: with:
name: windows name: windows
path: 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 }}

View File

@ -156,31 +156,6 @@ jobs:
with: with:
path: build/Hyperion-* 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 ######## ###### Publish GitHub Releases ########
####################################### #######################################
@ -195,10 +170,10 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
# generate environment variables # generate environment variables
- name: Generate environment variables from version and tag - name: Generate environment variables from .version and tag
run: | run: |
echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 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 echo "preRelease=false" >> $GITHUB_ENV
# If version contains alpha or beta, mark draft release as pre-release # If version contains alpha or beta, mark draft release as pre-release
@ -223,35 +198,3 @@ jobs:
prerelease: ${{ env.preRelease }} prerelease: ${{ env.preRelease }}
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 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

View File

View File

@ -6,7 +6,7 @@ PROJECT(hyperion)
# Parse semantic version of version file and write version to config # Parse semantic version of version file and write version to config
include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cmake) include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cmake)
file (STRINGS "version" HYPERION_VERSION) file (STRINGS ".version" HYPERION_VERSION)
SetVersionNumber(HYPERION ${HYPERION_VERSION}) SetVersionNumber(HYPERION ${HYPERION_VERSION})
set(DEFAULT_JSON_CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/config/hyperion.config.json.default) set(DEFAULT_JSON_CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/config/hyperion.config.json.default)
file(READ ${DEFAULT_JSON_CONFIG_FILE} DEFAULT_JSON_CONFIG_VAR) file(READ ${DEFAULT_JSON_CONFIG_FILE} DEFAULT_JSON_CONFIG_VAR)

View File

@ -299,6 +299,10 @@ select.form-control {
color: #DDDDDD; color: #DDDDDD;
} }
.radio__field:checked ~ .radio__icon::before {
background: #fff;
}
.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) { .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) {
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
border-top-right-radius: 4px; border-top-right-radius: 4px;

View File

@ -764,6 +764,88 @@ li a:active:after {
padding: 15px; 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*/ /*https://github.com/flatlogic/awesome-bootstrap-checkbox slighty edited for our purposes*/
.checkbox { .checkbox {

View File

@ -636,12 +636,17 @@
"edt_eff_flag_header": "Flaggen", "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_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_fps": "Bilder pro Sekunde",
"edt_eff_grayscale": "Graustufen",
"edt_eff_frequency": "Frequenz", "edt_eff_frequency": "Frequenz",
"edt_eff_gif_header": "GIFs", "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_gif_header_desc": "Dieser Effekt spielt .gif Dateien ab. Bietet die Möglichkeit kleine GIF-Videos abzuspielen.",
"edt_eff_height": "Höhe", "edt_eff_height": "Höhe",
"edt_eff_huechange": "Farbänderung", "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_image": "Bilddatei",
"edt_eff_url": "Bildadresse",
"edt_eff_initial_blink": "Blinken beim Start", "edt_eff_initial_blink": "Blinken beim Start",
"edt_eff_interval": "Intervall", "edt_eff_interval": "Intervall",
"edt_eff_knightrider_header": "Knight Rider", "edt_eff_knightrider_header": "Knight Rider",

View File

@ -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_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_fps": "Frames per seconds",
"edt_eff_frequency": "Frequency", "edt_eff_frequency": "Frequency",
"edt_eff_grayscale": "Grayscale",
"edt_eff_gif_header": "GIF's", "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_gif_header_desc": "This effect plays .gif files, provide a simple video like loop as effect.",
"edt_eff_height": "Height", "edt_eff_height": "Height",
"edt_eff_huechange": "Color change", "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_image": "Image file",
"edt_eff_url": "Image adress",
"edt_eff_initial_blink" : "Flash for attention", "edt_eff_initial_blink" : "Flash for attention",
"edt_eff_interval": "Interval", "edt_eff_interval": "Interval",
"edt_eff_knightrider_header": "Knight Rider", "edt_eff_knightrider_header": "Knight Rider",

View File

@ -55,7 +55,11 @@ $(document).ready(function () {
testrun = true; testrun = true;
var args = effects_editor.getEditor('root.args'); var args = effects_editor.getEditor('root.args');
if ($('input[type=radio][value=url]').is(':checked')) {
requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), "");
} else {
requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), imageData); requestTestEffect(effectName, effectPyScript, JSON.stringify(args.getValue()), imageData);
}
}; };
// Specify upload handler for image files // Specify upload handler for image files
@ -133,7 +137,12 @@ $(document).ready(function () {
// Save Effect // Save Effect
$('#btn_write').off().on('click', function () { $('#btn_write').off().on('click', function () {
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); requestWriteEffect(effectName, effectPyScript, JSON.stringify(effects_editor.getValue()), imageData);
}
$(window.hyperion).one("cmd-create-effect", function (event) { $(window.hyperion).one("cmd-create-effect", function (event) {
if (event.response.success) if (event.response.success)
showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName)); showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName));

View File

@ -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 // colorpicker creation and handling, build on top of strings editor
JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.extend({ JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.extend({
getValue: function() { getValue: function() {
@ -7174,7 +7289,12 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
}); });
// Use the `select` editor for dynamic enumSource enums // Use the `select` editor for dynamic enumSource enums
JSONEditor.defaults.resolvers.unshift(function(schema) { 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 // Use the `enum` or `select` editors for schemas with enumerated properties
JSONEditor.defaults.resolvers.unshift(function(schema) { JSONEditor.defaults.resolvers.unshift(function(schema) {
@ -7183,6 +7303,11 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
return "enum"; return "enum";
} }
else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") { else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") {
if(schema.format === "radio") {
return "radio";
}
return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select'; return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
} }
} }

View 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

View File

@ -1,6 +1,10 @@
[Unit] [Unit]
Description=Hyperion ambient light systemd service for user %i 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] [Service]
ExecStart=/usr/bin/hyperiond ExecStart=/usr/bin/hyperiond

View File

@ -158,12 +158,12 @@ macro(DeployUnix TARGET)
endif() 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) if (PYTHON_MODULES_DIR)
install( install(
DIRECTORY ${PYTHON_MODULES_DIR}/ DIRECTORY ${PYTHON_MODULES_DIR}/
DESTINATION "share/hyperion/lib/python" DESTINATION "share/hyperion/lib/python${PYTHON_VERSION_MAJOR_MINOR}"
COMPONENT "Hyperion" COMPONENT "Hyperion"
PATTERN "*.pyc" EXCLUDE # compiled bytecodes PATTERN "*.pyc" EXCLUDE # compiled bytecodes
PATTERN "__pycache__" EXCLUDE # any cache PATTERN "__pycache__" EXCLUDE # any cache

View File

@ -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);

View File

@ -1,5 +1,14 @@
#!/bin/sh #!/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() install_file()
{ {
src="$1" src="$1"
@ -15,13 +24,11 @@ install_file()
fi fi
} }
echo "--- Hyperion ambient light postinstall ---" echo "--- Hyperion ambient light postinstall ---"
#check system #check system
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835\|BCM2836\|BCM2837\|BCM2711' /proc/cpuinfo` 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` 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 #Check for a bootloader as Berryboot
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab) 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 # search for users in system, returns first entry
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root" 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="" start_msg=""
restart_msg="" restart_msg=""
if grep -m1 systemd /proc/1/comm > /dev/null # service registration if no gui is present (only on initial installation and not upgrade)
then if [ "$IS_UPGRADE" = false ]; then
echo "---> init deamon: systemd" 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 # systemd
if [ $OS_HYPERBIAN -eq 1 ]; then echo "---> init deamon: systemd"
# start service only install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperion@.service
echo "--> Service file already exists, skip creation" systemctl enable hyperion"@${FOUND_USR}".service
start_msg="--> systemctl start hyperion" start_msg="--> systemctl start hyperion for user ${FOUND_USR}"
systemctl start hyperion systemctl start hyperion"@${FOUND_USR}"
else elif [ -e /sbin/initctl ]
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service then
# 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
fi
elif [ -e /sbin/initctl ]
then
echo "---> init deamon: upstart"
# upstart # upstart
if [ $ENABLE_SERVICE -eq 1 ]; then echo "---> init deamon: upstart"
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration install_file /usr/share/hyperion/service/hyperion.initctl /etc/init/hyperion.conf && initctl reload-configuration
start_msg="--> initctl start hyperiond" start_msg="--> initctl start hyperion"
initctl start hyperiond initctl start hyperion
fi else
else
echo "---> init deamon: sysV"
# sysV # sysV
if [ $ENABLE_SERVICE -eq 1 ]; then echo "---> init deamon: sysV"
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 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 hyperiond start" start_msg="---> service hyperion start"
service hyperiond start service hyperion start
fi
else
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
fi fi
fi fi
@ -87,25 +78,30 @@ fi
rm -r /usr/share/hyperion/service rm -r /usr/share/hyperion/service
#link binarys and set exec bit #link binarys and set exec bit
BINSP=/usr/share/hyperion/bin BINSP=/usr/share/hyperion
BINTP=/usr/bin BINTP=/usr/bin
chmod +x -R $BINSP chmod +x -R $BINSP/bin
ln -fs $BINSP/hyperiond $BINTP/hyperiond ln -fs $BINSP/bin/hyperiond $BINTP/hyperiond
ln -fs $BINSP/hyperion-remote $BINTP/hyperion-remote ln -fs $BINSP/bin/hyperion-remote $BINTP/hyperion-remote
ln -fs $BINSP/hyperion-v4l2 $BINTP/hyperion-v4l2 ln -fs $BINSP/bin/hyperion-v4l2 $BINTP/hyperion-v4l2
ln -fs $BINSP/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null ln -fs $BINSP/bin/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null ln -fs $BINSP/bin/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null ln -fs $BINSP/bin/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
ln -fs $BINSP/hyperion-xcb $BINTP/hyperion-xcb 2>/dev/null ln -fs $BINSP/bin/hyperion-xcb $BINTP/hyperion-xcb 2>/dev/null
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null ln -fs $BINSP/bin/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
ln -fs $BINSP/hyperion-qt $BINTP/hyperion-qt 2>/dev/null ln -fs $BINSP/bin/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
# install desktop icons / not on HyperBian #create symlink for updateHyperionUser.sh script
if [ $OS_HYPERBIAN -ne 1 ]; then 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" echo "---> Install Hyperion desktop icons"
mkdir /usr/share/pixmaps/hyperion 2>/dev/null mkdir /usr/share/pixmaps/hyperion 2>/dev/null
cp /usr/share/hyperion/desktop/*.png /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 desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
fi
fi fi
# cleanup desktop icons # cleanup desktop icons
@ -133,7 +129,11 @@ fi
echo ${start_msg} echo ${start_msg}
echo "-----------------------------------------------------------------------------" 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 "---> " echo "---> "
$STARTUP_MSG $STARTUP_MSG
echo "---> For configuration, visit with your browser: ${NET_IP}:8090" echo "---> For configuration, visit with your browser: ${NET_IP}:8090"

View 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

View File

@ -2,6 +2,17 @@
echo "---Hyperion ambient light prerm ---" 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 # search for users in system, returns first entry
FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root" FOUND_USR=`who | grep -o -m1 '^\w*\b'` || "root"
@ -13,17 +24,18 @@ if grep -m1 systemd /proc/1/comm > /dev/null
then then
echo "---> stop init deamon: systemd" echo "---> stop init deamon: systemd"
# systemd # systemd
$HYPERION_RUNNING && systemctl stop hyperion hyperiond"@${FOUND_USR}" 2> /dev/null $HYPERION_RUNNING && systemctl stop hyperion hyperiond"@${FOUND_USR}" hyperion"@${FOUND_USR}" 2> /dev/null
# disable user specific symlink / not on HyperBian # disable user specific symlink
echo "---> Disable service and remove entry" echo "---> Disable service and remove entry"
systemctl -q disable hyperiond"@${FOUND_USR}" 2> /dev/null systemctl -q disable hyperion hyperiond"@${FOUND_USR}" hyperion"@${FOUND_USR}" 2> /dev/null
rm -v /etc/systemd/system/hyperiond@.service 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 ] elif [ -e /sbin/initctl ]
then then
echo "---> stop init deamon: upstart" echo "---> stop init deamon: upstart"
# upstart # upstart
$HYPERION_RUNNING && initctl stop hyperiond $HYPERION_RUNNING && initctl stop hyperiond
$HYPERION_RUNNING && initctl stop hyperion
echo "---> Remove upstart service" echo "---> Remove upstart service"
rm -v /etc/init/hyperion* 2>/dev/null rm -v /etc/init/hyperion* 2>/dev/null
initctl reload-configuration initctl reload-configuration
@ -32,6 +44,7 @@ else
echo "---> stop init deamon: sysV" echo "---> stop init deamon: sysV"
# sysV # sysV
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null $HYPERION_RUNNING && service hyperiond stop 2>/dev/null
$HYPERION_RUNNING && service hyperion stop 2>/dev/null
echo "---> Remove sysV service" echo "---> Remove sysV service"
update-rc.d -f hyperion remove update-rc.d -f hyperion remove
rm /etc/init.d/hyperion* 2>/dev/null rm /etc/init.d/hyperion* 2>/dev/null

View File

@ -65,7 +65,7 @@ ENDIF()
# Specific CPack Package Generators # Specific CPack Package Generators
# https://cmake.org/Wiki/CMake:CPackPackageGenerators # https://cmake.org/Wiki/CMake:CPackPackageGenerators
# .deb files for apt # .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_DEPENDS "libcec6 | libcec4" )
SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) 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_LICENSE "MIT" )
SET ( CPACK_RPM_PACKAGE_GROUP "Applications" ) SET ( CPACK_RPM_PACKAGE_GROUP "Applications" )
SET ( CPACK_RPM_PACKAGE_REQUIRES "libcec >= 4.0.0" ) 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_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/preinst" )
SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" ) 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/rpm/prerm" ) SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/package-scripts/prerm" )
# OSX "Bundle" generator TODO Add more osx generators # OSX "Bundle" generator TODO Add more osx generators
# https://cmake.org/cmake/help/v3.10/module/CPackBundle.html # https://cmake.org/cmake/help/v3.10/module/CPackBundle.html

View File

@ -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

View File

@ -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);

View File

@ -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

6
debian/rules vendored
View File

@ -15,11 +15,11 @@ binary-indep:
binary-arch: binary-arch:
cd $(BUILDDIR); cmake -P cmake_install.cmake cd $(BUILDDIR); cmake -P cmake_install.cmake
mkdir debian/tmp/DEBIAN 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 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 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 chmod 0775 debian/tmp/DEBIAN/prerm
dpkg-gencontrol -phyperion dpkg-gencontrol -phyperion
dpkg --build debian/tmp .. dpkg --build debian/tmp ..

View File

@ -14,7 +14,7 @@ include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
mbedtls mbedtls
GIT_REPOSITORY "https://github.com/ARMmbed/mbedtls.git" 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 BUILD_ALWAYS OFF
DOWNLOAD_DIR "${DOWNLOAD_DIR}" DOWNLOAD_DIR "${DOWNLOAD_DIR}"
SOURCE_DIR "${SOURCE_DIR}" SOURCE_DIR "${SOURCE_DIR}"

View File

@ -233,7 +233,7 @@ if (NOT USE_SYSTEM_MBEDTLS_LIBS)
FetchContent_Declare( FetchContent_Declare(
mbedtls mbedtls
GIT_REPOSITORY https://github.com/ARMmbed/mbedtls.git 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 BUILD_ALWAYS OFF
GIT_PROGRESS 1 GIT_PROGRESS 1
DOWNLOAD_DIR "${MBEDTLS_DOWNLOAD_DIR}" DOWNLOAD_DIR "${MBEDTLS_DOWNLOAD_DIR}"

View File

@ -3,8 +3,14 @@
"script" : "gif.py", "script" : "gif.py",
"args" : "args" :
{ {
"image" : ":fire.gif", "cropBottom": 0,
"cropLeft": 0,
"cropRight": 0,
"cropTop": 0,
"file" : ":fire.gif",
"fps" :25, "fps" :25,
"grayscale": false,
"imageSource": "file",
"reverse" : false "reverse" : false
} }
} }

View File

@ -1,18 +1,27 @@
import hyperion, time import hyperion, time
# Get the parameters # 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)) 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 sleepTime = 1./framesPerSecond
imageList = [] imageFrameList = []
if imageFile: if imageData:
imageList = [reversed(hyperion.getImage(imageFile))] if reverse else hyperion.getImage(imageFile) 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 # Start the write data loop
while not hyperion.abort() and imageList: while not hyperion.abort() and imageFrameList:
for image in imageList: for image in imageFrameList:
if not hyperion.abort():
hyperion.setImage(image["imageWidth"], image["imageHeight"], image["imageData"]) hyperion.setImage(image["imageWidth"], image["imageHeight"], image["imageData"])
time.sleep(sleepTime) time.sleep(sleepTime)

View File

@ -3,8 +3,14 @@
"script" : "gif.py", "script" : "gif.py",
"args" : "args" :
{ {
"image" : ":lights.gif", "cropBottom": 0,
"cropLeft": 0,
"cropRight": 0,
"cropTop": 0,
"file" : ":lights.gif",
"fps" :25, "fps" :25,
"reverse" : false "grayscale": false,
"imageSource": "file",
"reverse": false
} }
} }

16
effects/matrix.json Normal file
View 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"
}
}

View File

@ -4,17 +4,79 @@
"title":"edt_eff_gif_header", "title":"edt_eff_gif_header",
"required":true, "required":true,
"properties": { "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", "type": "string",
"title":"edt_eff_image", "title":"edt_eff_image",
"format" : "url", "format" : "url",
"options" : "options" :
{ {
"upload" : true, "upload" : true,
"auto_upload" : true "auto_upload" : true,
"dependencies": {
"imageSource": "file"
}
}, },
"default": "", "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": { "fps": {
"type": "integer", "type": "integer",
@ -23,13 +85,13 @@
"minimum" : 1, "minimum" : 1,
"maximum" : 100, "maximum" : 100,
"step" : 1, "step" : 1,
"propertyOrder" : 2 "propertyOrder" : 9
}, },
"reverse": { "reverse": {
"type": "boolean", "type": "boolean",
"title":"edt_eff_reversedirection", "title":"edt_eff_reversedirection",
"default": false, "default": false,
"propertyOrder" : 3 "propertyOrder" : 10
} }
}, },
"additionalProperties": false "additionalProperties": false

View File

@ -8,8 +8,10 @@
class Effect; class Effect;
class EffectModule class EffectModule: public QObject
{ {
Q_OBJECT
public: public:
// Python 3 module def // Python 3 module def
static struct PyModuleDef moduleDef; static struct PyModuleDef moduleDef;

View File

@ -79,6 +79,15 @@ public:
/// ///
bool open(); 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: private slots:
/// ///

View File

@ -70,9 +70,9 @@ QString EffectFileHandler::deleteEffect(const QString& effectName)
{ {
if (effectConfigurationFile.exists()) 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()) if (effectImageFile.exists())
{ {
QFile::remove(effectImageFile.absoluteFilePath()); QFile::remove(effectImageFile.absoluteFilePath());
@ -159,19 +159,26 @@ QString EffectFileHandler::saveEffect(const QJsonObject& message)
newFileName.setFile(f); 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(); 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); QFileInfo imageFileName(imageFilePath);
if (!FileUtils::writeFile(imageFileName.absoluteFilePath(), QByteArray::fromBase64(message["imageData"].toString("").toUtf8()), _log)) 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 //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; effectJson["args"] = args;
} }

View File

@ -12,6 +12,10 @@
#include <QDateTime> #include <QDateTime>
#include <QImageReader> #include <QImageReader>
#include <QBuffer> #include <QBuffer>
#include <QUrl>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QEventLoop>
// Get the effect from the capsule // Get the effect from the capsule
#define getEffect() static_cast<Effect*>((Effect*)PyCapsule_Import("hyperion.__effectObj", 0)) #define getEffect() static_cast<Effect*>((Effect*)PyCapsule_Import("hyperion.__effectObj", 0))
@ -219,22 +223,46 @@ PyObject* EffectModule::wrapSetImage(PyObject *self, PyObject *args)
PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args) PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
{ {
QString file;
QBuffer buffer; QBuffer buffer;
QImageReader reader; QImageReader reader;
char *source;
int cropLeft = 0, cropTop = 0, cropRight = 0, cropBottom = 0;
bool grayscale = false;
if (getEffect()->_imageData.isEmpty()) if (getEffect()->_imageData.isEmpty())
{ {
Q_INIT_RESOURCE(EffectEngine); Q_INIT_RESOURCE(EffectEngine);
char *source; if(!PyArg_ParseTuple(args, "s|iiiii", &source, &cropLeft, &cropTop, &cropRight, &cropBottom, &grayscale))
if(!PyArg_ParseTuple(args, "s", &source))
{ {
PyErr_SetString(PyExc_TypeError, "String required"); PyErr_SetString(PyExc_TypeError, "String required");
return nullptr; return nullptr;
} }
file = QString::fromUtf8(source); const QUrl url = QUrl(source);
if (url.isValid())
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager();
QNetworkReply * networkReply = networkManager->get(QNetworkRequest(url));
QEventLoop eventLoop;
connect(networkReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
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) == ":") if (file.mid(0, 1) == ":")
file = ":/effects/"+file.mid(1); file = ":/effects/"+file.mid(1);
@ -242,8 +270,10 @@ PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
reader.setDecideFormatFromContent(true); reader.setDecideFormatFromContent(true);
reader.setFileName(file); reader.setFileName(file);
} }
}
else else
{ {
PyArg_ParseTuple(args, "|siiiii", &source, &cropLeft, &cropTop, &cropRight, &cropBottom, &grayscale);
buffer.setData(QByteArray::fromBase64(getEffect()->_imageData.toUtf8())); buffer.setData(QByteArray::fromBase64(getEffect()->_imageData.toUtf8()));
buffer.open(QBuffer::ReadOnly); buffer.open(QBuffer::ReadOnly);
reader.setDecideFormatFromContent(true); reader.setDecideFormatFromContent(true);
@ -260,19 +290,33 @@ PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
if (reader.canRead()) if (reader.canRead())
{ {
QImage qimage = reader.read(); QImage qimage = reader.read();
int width = qimage.width(); int width = qimage.width();
int height = qimage.height(); 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; 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)); 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(!grayscale ? (char) qRed(scanline[0]) : (char) qGray(scanline[0]));
binaryImage.append((char) qGreen(scanline[j])); binaryImage.append(!grayscale ? (char) qGreen(scanline[1]) : (char) qGray(scanline[1]));
binaryImage.append((char) qBlue(scanline[j])); 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()))); 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 nullptr;
} }
} }
return result; return result;
} }
else else

View File

@ -11,6 +11,10 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#ifdef _WIN32
#include <Windows.h>
#endif
// Constants // Constants
namespace { namespace {
const bool verbose = false; const bool verbose = false;
@ -156,6 +160,58 @@ void QtGrabber::geometryChanged(const QRect &geo)
updateScreenDimensions(true); 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 QtGrabber::grabFrame(Image<ColorRgb> & image)
{ {
int rc = 0; int rc = 0;
@ -170,7 +226,11 @@ int QtGrabber::grabFrame(Image<ColorRgb> & image)
if (_isEnabled) 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); QPixmap originalPixmap = _screen->grabWindow(0, _src_x, _src_y, _src_x_max, _src_y_max);
#endif
if (originalPixmap.isNull()) if (originalPixmap.isNull())
{ {
rc = -1; rc = -1;

View File

@ -23,18 +23,27 @@ PythonInit::PythonInit()
// register modules // register modules
EffectModule::registerHyperionExtensionModule(); EffectModule::registerHyperionExtensionModule();
// Set Program name
Py_SetProgramName(L"Hyperion");
// set Python module path when exists // 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"); QString py_file = QDir::cleanPath(qApp->applicationDirPath() + "/python" + STRINGIFY(PYTHON_VERSION_MAJOR_MINOR) + ".zip");
if (QFile(py_file).exists() || QDir(py_patch).exists()) if (QFile(py_file).exists() || QDir(py_patch).exists())
{ {
Py_NoSiteFlag++; Py_NoSiteFlag++;
if (QFile(py_file).exists()) if (QFile(py_file).exists())
{
Py_SetPythonHome(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
Py_SetPath(Py_DecodeLocale(py_file.toLatin1().data(), nullptr)); Py_SetPath(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
}
else if (QDir(py_patch).exists()) else if (QDir(py_patch).exists())
{
Py_SetPythonHome(Py_DecodeLocale(py_file.toLatin1().data(), nullptr));
Py_SetPath(Py_DecodeLocale(py_patch.toLatin1().data(), nullptr)); Py_SetPath(Py_DecodeLocale(py_patch.toLatin1().data(), nullptr));
} }
}
// init Python // init Python
Debug(Logger::getInstance("DAEMON"), "Initializing Python interpreter"); Debug(Logger::getInstance("DAEMON"), "Initializing Python interpreter");

View File

@ -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( 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( FILES ${CMAKE_BINARY_DIR}/symlink_hyperiond DESTINATION "bin" RENAME hyperiond COMPONENT "Hyperion" )
install( CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_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() endif()
# Deploy Qt DLLs into the binary folder. # Deploy Qt DLLs into the binary folder.