Esempio n. 1
0
def _show_schedule_setup_notification():
    """Show a notification hinting to setup a remote backup schedule."""
    from plinth.notification import Notification
    message = gettext_noop(
        'Enable an automatic backup schedule for data safety. Prefer an '
        'encrypted remote backup location or an extra attached disk.')
    data = {
        'app_name': 'translate:' + gettext_noop('Backups'),
        'app_icon': 'fa-files-o'
    }
    title = gettext_noop('Enable a Backup Schedule')
    actions_ = [{
        'type': 'link',
        'class': 'primary',
        'text': gettext_noop('Go to {app_name}'),
        'url': 'backups:index'
    }, {
        'type': 'dismiss'
    }]
    Notification.update_or_create(id='backups-remote-schedule',
                                  app_id='backups',
                                  severity='info',
                                  title=title,
                                  message=message,
                                  actions=actions_,
                                  data=data,
                                  group='admin')
Esempio n. 2
0
def _warn_about_low_ram_space(request):
    """Warn about insufficient RAM space."""
    from plinth.notification import Notification

    memory_info = _get_memory_info()
    if memory_info['free_bytes'] < 1024**3:
        # Translators: This is the unit of computer storage Mebibyte similar to
        # Megabyte.
        memory_available_unit = gettext_noop('MiB')
        memory_available = memory_info['free_bytes'] / 1024**2
    else:
        # Translators: This is the unit of computer storage Gibibyte similar to
        # Gigabyte.
        memory_available_unit = gettext_noop('GiB')
        memory_available = memory_info['free_bytes'] / 1024**3

    show = False
    if memory_info['percent_used'] > 90:
        severity = 'error'
        advice_message = gettext_noop(
            'You should disable some apps to reduce memory usage.')
        show = True
    elif memory_info['percent_used'] > 75:
        severity = 'warning'
        advice_message = gettext_noop(
            'You should not install any new apps on this system.')
        show = True

    if not show:
        try:
            Notification.get('diagnostics-low-ram-space').delete()
        except KeyError:
            pass
        return

    message = gettext_noop(
        # xgettext:no-python-format
        'System is low on memory: {percent_used}% used, {memory_available} '
        '{memory_available_unit} free. {advice_message}')
    title = gettext_noop('Low Memory')
    data = {
        'app_icon': 'fa-heartbeat',
        'app_name': 'translate:' + gettext_noop('Diagnostics'),
        'percent_used': f'{memory_info["percent_used"]:.1f}',
        'memory_available': f'{memory_available:.1f}',
        'memory_available_unit': 'translate:' + memory_available_unit,
        'advice_message': 'translate:' + advice_message
    }
    actions = [{'type': 'dismiss'}]
    Notification.update_or_create(id='diagnostics-low-ram-space',
                                  app_id='diagnostics',
                                  severity=severity,
                                  title=title,
                                  message=message,
                                  actions=actions,
                                  data=data,
                                  group='admin')
Esempio n. 3
0
def warn_about_low_disk_space(request):
    """Warn about insufficient space on root partition."""
    from plinth.notification import Notification

    try:
        root_info = get_disk_info('/')
    except PlinthError as exception:
        logger.exception('Error getting information about root partition: %s',
                         exception)
        return

    show = False
    if root_info['percent_used'] > 90 or root_info['free_gib'] < 1:
        severity = 'error'
        show = True
    elif root_info['percent_used'] > 75 or root_info['free_gib'] < 2:
        severity = 'warning'
        show = True

    if not show:
        try:
            Notification.get('storage-low-disk-space').delete()
        except KeyError:
            pass
    else:
        message = ugettext_noop(
            # xgettext:no-python-format
            'Low space on system partition: {percent_used}% used, '
            '{free_space} free.')
        title = ugettext_noop('Low disk space')
        data = {
            'app_icon': 'fa-hdd-o',
            'app_name': ugettext_noop('Storage'),
            'percent_used': root_info['percent_used'],
            'free_space': format_bytes(root_info['free_bytes'])
        }
        actions = [{
            'type': 'link',
            'class': 'primary',
            'text': 'Go to {app_name}',
            'url': 'storage:index'
        }, {
            'type': 'dismiss'
        }]
        Notification.update_or_create(id='storage-low-disk-space',
                                      app_id='storage',
                                      severity=severity,
                                      title=title,
                                      message=message,
                                      actions=actions,
                                      data=data,
                                      group='admin')
Esempio n. 4
0
def check_dist_upgrade(_):
    """Check for upgrade to new stable release."""
    from plinth.notification import Notification
    if is_dist_upgrade_enabled():
        output = actions.superuser_run('upgrades', ['start-dist-upgrade'])
        result = json.loads(output)
        dist_upgrade_started = result['dist_upgrade_started']
        reason = result['reason']
        if 'found-previous' in reason:
            logger.info(
                'Found previous dist-upgrade. If it was interrupted, it will '
                'be restarted.')
        elif 'already-' in reason:
            logger.info('Skip dist upgrade: System is already up-to-date.')
        elif 'codename-not-found' in reason:
            logger.warning('Skip dist upgrade: Codename not found in release '
                           'file.')
        elif 'upgrades-not-enabled' in reason:
            logger.info('Skip dist upgrade: Automatic updates are not '
                        'enabled.')
        elif 'test-not-set' in reason:
            logger.info('Skip dist upgrade: --test is not set.')
        elif 'not-enough-free-space' in reason:
            logger.warning('Skip dist upgrade: Not enough free space in /.')
            title = gettext_noop('Could not start distribution update')
            message = gettext_noop(
                'There is not enough free space in the root partition to '
                'start the distribution update. Please ensure at least 5 GB '
                'is free. Distribution update will be retried after 24 hours,'
                ' if enabled.')
            Notification.update_or_create(
                id='upgrades-dist-upgrade-free-space', app_id='upgrades',
                severity='warning', title=title, message=message, actions=[{
                    'type': 'dismiss'
                }], group='admin')
        elif 'started-dist-upgrade' in reason:
            logger.info('Started dist upgrade.')
            title = gettext_noop('Distribution update started')
            message = gettext_noop(
                'Started update to next stable release. This may take a long '
                'time to complete.')
            Notification.update_or_create(id='upgrades-dist-upgrade-started',
                                          app_id='upgrades', severity='info',
                                          title=title, message=message,
                                          actions=[{
                                              'type': 'dismiss'
                                          }], group='admin')
        else:
            logger.warning('Unhandled result of start-dist-upgrade: %s, %s',
                           dist_upgrade_started, reason)
Esempio n. 5
0
    def _show_new_release_notification(self):
        """When upgraded to new release, show a notification."""
        from plinth.notification import Notification
        try:
            note = Notification.get('upgrades-new-release')
            if note.data['version'] == plinth.__version__:
                # User already has notification for update to this version. It
                # may be dismissed or not yet dismissed
                return

            # User currently has a notification for an older version, update.
            dismiss = False
        except KeyError:
            # Don't show notification for the first version user runs, create
            # but don't show it.
            dismiss = True

        data = {
            'version': plinth.__version__,
            'app_name': 'Update',
            'app_icon': 'fa-refresh'
        }
        title = ugettext_noop('FreedomBox Updated')
        note = Notification.update_or_create(
            id='upgrades-new-release',
            app_id='upgrades',
            severity='info',
            title=title,
            body_template='upgrades-new-release.html',
            data=data,
            group='admin')
        note.dismiss(should_dismiss=dismiss)
Esempio n. 6
0
def _show_schedule_error_notification(repository, is_error, exception=None):
    """Show or hide a notification related scheduled backup operation."""
    from plinth.notification import Notification
    id_ = 'backups-schedule-error-' + repository.uuid
    try:
        note = Notification.get(id_)
        error_count = note.data['error_count']
    except KeyError:
        error_count = 0

    message = ugettext_noop(
        'A scheduled backup failed. Past {error_count} attempts for backup '
        'did not succeed. The latest error is: {error_message}')
    data = {
        'app_name': 'translate:' + ugettext_noop('Backups'),
        'app_icon': 'fa-files-o',
        'error_count': error_count + 1 if is_error else 0,
        'error_message': str(exception)
    }
    title = ugettext_noop('Error During Backup')
    actions_ = [{
        'type': 'link',
        'class': 'primary',
        'text': ugettext_noop('Go to {app_name}'),
        'url': 'backups:index'
    }, {
        'type': 'dismiss'
    }]
    note = Notification.update_or_create(id=id_, app_id='backups',
                                         severity='error', title=title,
                                         message=message, actions=actions_,
                                         data=data, group='admin')
    note.dismiss(should_dismiss=not is_error)
Esempio n. 7
0
def report_failing_drive(id, is_failing):
    """Show or withdraw notification about failing drive."""
    notification_id = 'storage-disk-failure-' + base64.b32encode(
        id.encode()).decode()

    from plinth.notification import Notification
    title = ugettext_noop('Disk failure imminent')
    message = ugettext_noop(
        'Disk {id} is reporting that it is likely to fail in the near future. '
        'Copy any data while you still can and replace the drive.')
    data = {
        'app_icon': 'fa-hdd-o',
        'app_name': 'translate:' + ugettext_noop('Storage'),
        'id': id
    }
    note = Notification.update_or_create(id=notification_id,
                                         app_id='storage',
                                         severity='error',
                                         title=title,
                                         message=message,
                                         actions=[{
                                             'type': 'dismiss'
                                         }],
                                         data=data,
                                         group='admin')
    note.dismiss(should_dismiss=not is_failing)
Esempio n. 8
0
def fixture_note():
    """Fixture to return a valid notification object."""
    Notification.objects.all().delete()
    return Notification.update_or_create(id='test-notification',
                                         app_id='test-app',
                                         severity='info',
                                         title='Test Title',
                                         data={'test-key': 'test-value'})
Esempio n. 9
0
def test_update(note):
    """Test updating a existing notification."""
    note = Notification.get('test-notification')
    assert note.app_id == 'test-app'
    assert note.severity == 'info'
    assert note.title == 'Test Title'
    assert note.data == {'test-key': 'test-value'}

    Notification.update_or_create(id='test-notification',
                                  app_id='test-app2',
                                  severity='error',
                                  title='Test Title2',
                                  data={'test-key2': 'test-value2'})
    note = Notification.get('test-notification')
    assert note.app_id == 'test-app2'
    assert note.severity == 'error'
    assert note.title == 'Test Title2'
    assert note.data == {'test-key2': 'test-value2'}