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",
|
||||
|
@ -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');
|
||||
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 () {
|
||||
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));
|
||||
|
@ -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() {
|
||||
@ -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"
|
||||
# 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
|
||||
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}"
|
||||
fi
|
||||
fi
|
||||
|
||||
elif [ -e /sbin/initctl ]
|
||||
then
|
||||
echo "---> init deamon: upstart"
|
||||
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
|
||||
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"
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
#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
|
6
debian/rules
vendored
6
debian/rules
vendored
@ -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))
|
||||
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:
|
||||
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,22 +223,46 @@ 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));
|
||||
|
||||
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) == ":")
|
||||
file = ":/effects/"+file.mid(1);
|
||||
@ -242,8 +270,10 @@ PyObject* EffectModule::wrapGetImage(PyObject *self, PyObject *args)
|
||||
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,18 +23,27 @@ 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
|
||||
Debug(Logger::getInstance("DAEMON"), "Initializing Python interpreter");
|
||||
|
@ -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