Skip to content

Commit

Permalink
Merge branch 'dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
manzari authored Mar 24, 2022
2 parents 16127ae + 75eddc8 commit 5bdac4c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ These install instructions are constantly tested via CI/CD pipeline on Debian Bu
sudo python3 -m pip install 'https://github.com/motioneye-project/motioneye/archive/dev.tar.gz'
sudo motioneye_init
```
_NB: `motioneye_init` currently assumes either an APT- or RPM-based distribution with `systemd` as init system. For a manual setup, config and service files can be found here: <https://github.com/motioneye-project/motioneye/tree/dev/motioneye/extra> _
_NB: `motioneye_init` currently assumes either an APT- or RPM-based distribution with `systemd` as init system. For a manual setup, config and service files can be found here: <https://github.com/motioneye-project/motioneye/tree/dev/motioneye/extra>_

# Upgrade

Expand Down
64 changes: 38 additions & 26 deletions motioneye/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,18 @@ def motion_camera_ui_to_dict(ui, prev_config=None):

on_event_end.append(line)

if ui['web_hook_end_notifications_enabled']:
url = re.sub(r'\s', '+', ui['web_hook_end_notifications_url'])

on_event_end.append(
"%(script)s '%(method)s' '%(url)s'"
% {
'script': meyectl.find_command('webhook'),
'method': ui['web_hook_end_notifications_http_method'],
'url': url,
}
)

if ui['command_end_notifications_enabled']:
on_event_end += utils.split_semicolon(ui['command_end_notifications_exec'])

Expand Down Expand Up @@ -1346,6 +1358,7 @@ def motion_camera_dict_to_ui(data):
'email_notifications_enabled': False,
'telegram_notifications_enabled': False,
'web_hook_notifications_enabled': False,
'web_hook_end_notifications_enabled': False,
'command_notifications_enabled': False,
'command_end_notifications_enabled': False,
# working schedule
Expand Down Expand Up @@ -1616,10 +1629,8 @@ def motion_camera_dict_to_ui(data):
ui['telegram_notifications_picture_time_span'] = 0
command_notifications = []
for e in on_event_start:
if e.count(' sendmail '):
e = shlex.split(
utils.make_str(e)
) # poor shlex can't deal with unicode properly
if ' sendmail ' in e:
e = shlex.split(e)

if len(e) < 10:
continue
Expand All @@ -1644,10 +1655,8 @@ def motion_camera_dict_to_ui(data):
except:
ui['email_notifications_picture_time_span'] = 0

elif e.count(' sendtelegram '):
e = shlex.split(
utils.make_str(e)
) # poor shlex can't deal with unicode properly
elif ' sendtelegram ' in e:
e = shlex.split(e)

if len(e) < 7:
continue
Expand All @@ -1661,10 +1670,8 @@ def motion_camera_dict_to_ui(data):
except:
ui['telegram_notifications_picture_time_span'] = 0

elif e.count(' webhook '):
e = shlex.split(
utils.make_str(e)
) # poor shlex can't deal with unicode properly
elif ' webhook ' in e:
e = shlex.split(e)

if len(e) < 3:
continue
Expand All @@ -1673,7 +1680,7 @@ def motion_camera_dict_to_ui(data):
ui['web_hook_notifications_http_method'] = e[-2]
ui['web_hook_notifications_url'] = e[-1]

elif e.count('relayevent'):
elif 'relayevent' in e:
continue # ignore internal relay script

else: # custom command
Expand All @@ -1690,7 +1697,17 @@ def motion_camera_dict_to_ui(data):

command_end_notifications = []
for e in on_event_end:
if e.count('relayevent') or e.count('eventrelay.py'):
if ' webhook ' in e:
e = shlex.split(e)

if len(e) < 3:
continue

ui['web_hook_end_notifications_enabled'] = True
ui['web_hook_end_notifications_http_method'] = e[-2]
ui['web_hook_end_notifications_url'] = e[-1]

elif 'relayevent' in e or 'eventrelay.py' in e:
continue # ignore internal relay script

else: # custom command
Expand All @@ -1707,10 +1724,8 @@ def motion_camera_dict_to_ui(data):

command_storage = []
for e in on_movie_end:
if e.count(' webhook '):
e = shlex.split(
utils.make_str(e)
) # poor shlex can't deal with unicode properly
if ' webhook ' in e:
e = shlex.split(e)

if len(e) < 3:
continue
Expand All @@ -1719,7 +1734,7 @@ def motion_camera_dict_to_ui(data):
ui['web_hook_storage_http_method'] = e[-2]
ui['web_hook_storage_url'] = e[-1]

elif e.count('relayevent'):
elif 'relayevent' in e:
continue # ignore internal relay script

else: # custom command
Expand All @@ -1741,9 +1756,8 @@ def motion_camera_dict_to_ui(data):
for name, value in list(data.items()):
if name not in _USED_MOTION_OPTIONS and not name.startswith('@'):
if isinstance(value, bool):
value = ['off', 'on'][
value
] # boolean values should be transferred as on/off
# boolean values should be transferred as on/off
value = ['off', 'on'][value]

extra_options.append((name, value))

Expand Down Expand Up @@ -2072,7 +2086,6 @@ def _dict_to_conf(lines, data, list_names=None):
remaining.pop(name, None)

# add the remaining config values not covered by existing lines

if len(remaining) and len(lines):
conf_lines.append('') # add a blank line

Expand Down Expand Up @@ -2124,9 +2137,8 @@ def _set_default_motion(data):
data.setdefault('webcontrol_port', settings.MOTION_CONTROL_PORT)
data.setdefault('webcontrol_interface', 1)
data.setdefault('webcontrol_localhost', settings.MOTION_CONTROL_LOCALHOST)
data.setdefault(
'webcontrol_parms', 2
) # the advanced list of parameters will be available
# the advanced list of parameters will be available
data.setdefault('webcontrol_parms', 2)


def _set_default_motion_camera(camera_id, data):
Expand Down
18 changes: 9 additions & 9 deletions motioneye/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,16 +644,9 @@ function initUI() {

return true;
}, '');
makeCustomValidator($('#webHookNotificationsUrlEntry'), function (value) {
makeCustomValidator($('#webHookNotificationsUrlEntry, #webHookEndNotificationsUrlEntry'), function (value) {
if (!value.match(webHookUrlValidRegExp)) {
return "use of semicolon (;) or single quote (\') is not allowed in web hook URL";
}

return true;
}, '');
makeCustomValidator($('#webHookNotificationsUrlEntry'), function (value) {
if (!value.match(webHookUrlValidRegExp)) {
return "use of semicolon (;) or single quote (\') is not allowed in web hook URL";
return "use of semicolon (;) or single quote (') is not allowed in web hook URL";
}

return true;
Expand Down Expand Up @@ -2023,6 +2016,9 @@ function cameraUi2Dict() {
'web_hook_notifications_enabled': $('#webHookNotificationsEnabledSwitch')[0].checked,
'web_hook_notifications_url': $('#webHookNotificationsUrlEntry').val(),
'web_hook_notifications_http_method': $('#webHookNotificationsHttpMethodSelect').val(),
'web_hook_end_notifications_enabled': $('#webHookEndNotificationsEnabledSwitch')[0].checked,
'web_hook_end_notifications_url': $('#webHookEndNotificationsUrlEntry').val(),
'web_hook_end_notifications_http_method': $('#webHookEndNotificationsHttpMethodSelect').val(),
'command_notifications_enabled': $('#commandNotificationsEnabledSwitch')[0].checked,
'command_notifications_exec': $('#commandNotificationsEntry').val(),
'command_end_notifications_enabled': $('#commandEndNotificationsEnabledSwitch')[0].checked,
Expand Down Expand Up @@ -2401,6 +2397,10 @@ function dict2CameraUi(dict) {
$('#webHookNotificationsUrlEntry').val(dict['web_hook_notifications_url']);
$('#webHookNotificationsHttpMethodSelect').val(dict['web_hook_notifications_http_method']);

$('#webHookEndNotificationsEnabledSwitch')[0].checked = dict['web_hook_end_notifications_enabled']; markHideIfNull('web_hook_end_notifications_enabled', 'webHookEndNotificationsEnabledSwitch');
$('#webHookEndNotificationsUrlEntry').val(dict['web_hook_end_notifications_url']);
$('#webHookEndNotificationsHttpMethodSelect').val(dict['web_hook_end_notifications_http_method']);

$('#commandNotificationsEnabledSwitch')[0].checked = dict['command_notifications_enabled']; markHideIfNull('command_notifications_enabled', 'commandNotificationsEnabledSwitch');
$('#commandNotificationsEntry').val(dict['command_notifications_exec']);
$('#commandEndNotificationsEnabledSwitch')[0].checked = dict['command_end_notifications_enabled']; markHideIfNull('command_end_notifications_enabled', 'commandEndNotificationsEnabledSwitch');
Expand Down
41 changes: 40 additions & 1 deletion motioneye/templates/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,13 @@
<span class="minimize"></span>
</div>
<table class="settings">
<tr class="settings-item" depends="motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label"><strong>Actions when motion</strong></span></td>
<td class="settings-item-value"><span class="settings-item-label"><strong>has started:</strong></span></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td colspan="100"><div class="settings-item-separator"></div></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Sendi retpoŝton") }}</span></td>
<td class="settings-item-value"><input type="checkbox" class="styled notifications camera-config" id="emailNotificationsEnabledSwitch"></td>
Expand Down Expand Up @@ -1136,7 +1143,39 @@
<td colspan="100"><div class="settings-item-separator"></div></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Lanĉi fina komando") }}</span></td>
<td class="settings-item-label"><span class="settings-item-label"><strong>Actions when motion</strong></span></td>
<td class="settings-item-value"><span class="settings-item-label"><strong>has ended:</strong></span></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td colspan="100"><div class="settings-item-separator"></div></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Alvoki URL") }}</span></td>
<td class="settings-item-value"><input type="checkbox" class="styled notifications camera-config" id="webHookEndNotificationsEnabledSwitch"></td>
<td><span class="help-mark" title="enable this if you want a URL to be requested whenever a motion event ends">?</span></td>
</tr>
<tr class="settings-item" required="true" depends="webHookEndNotificationsEnabled motionDetectionEnabled" strip="true">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Reteja URL") }}</span></td>
<td class="settings-item-value"><input type="text" class="styled notifications camera-config" id="webHookEndNotificationsUrlEntry" placeholder="e.g. http://example.com/notify/"></td>
<td><span class="help-mark" title="a single URL to be requested when motion event ends; the following special tokens are accepted: %Y = year, %m = month, %d = day, %H = hour, %M = minute, %S = second, %q = frame number, %v = event number">?</span></td>
</tr>
<tr class="settings-item" depends="webHookEndNotificationsEnabled motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Metodo HTTP") }}</span></td>
<td class="settings-item-value">
<select class="styled notifications camera-config" id="webHookEndNotificationsHttpMethodSelect">
<option value="GET">GET</option>
<option value="POST">POST (query)</option>
<option value="POSTf">POST (form)</option>
<option value="POSTj">POST (json)</option>
</select>
</td>
<td><span class="help-mark" title="{{ _("La HTTP-metodo por uzi kiam vi petas URL (la donitaj URL-parametroj estos transdonitaj kiel indikite ĉi tie).") }}">?</span></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td colspan="100"><div class="settings-item-separator"></div></td>
</tr>
<tr class="settings-item" depends="motionDetectionEnabled">
<td class="settings-item-label"><span class="settings-item-label">{{ _("Lanĉi komando") }}</span></td>
<td class="settings-item-value"><input type="checkbox" class="styled notifications camera-config" id="commandEndNotificationsEnabledSwitch"></td>
<td><span class="help-mark" title="{{ _("Ebligu ĉi tion, se vi volas lanĉi komandon ĉiufoje kiam movada evento finiĝos.") }}">?</span></td>
</tr>
Expand Down
12 changes: 6 additions & 6 deletions motioneye/utils/dtconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def pretty_date_time(date_time, tzinfo=None, short=False):
tz += '-'
offset = -offset

tz += '%.2d' % (offset / 3600) + ':%.2d' % ((offset % 3600) / 60)
tz += '%.2d' % (offset // 3600) + ':%.2d' % ((offset % 3600) // 60)

text += ' (' + tz + ')'

Expand All @@ -77,8 +77,8 @@ def pretty_time(t: Union[datetime.time, datetime.timedelta]) -> str:
return ''

if isinstance(t, datetime.timedelta):
hour = int(t.seconds / 3600)
minute = int((t.seconds % 3600) / 60)
hour = t.seconds // 3600
minute = (t.seconds % 3600) // 60
t = datetime.time(hour=hour, minute=minute)

return '{hm}'.format(hm=t.strftime('%H:%M'))
Expand All @@ -98,11 +98,11 @@ def pretty_duration(duration):
else:
negative = False

days = int(duration / 86400)
days = duration // 86400
duration %= 86400
hours = int(duration / 3600)
hours = duration // 3600
duration %= 3600
minutes = int(duration / 60)
minutes = duration // 60
duration %= 60
seconds = duration

Expand Down

0 comments on commit 5bdac4c

Please sign in to comment.