ClockAlarm: a cross-platform alarm manager

ClockAlarm is a cross-platform (linux, Windows, macOS) alarm manager that will help you improve your life organization. Define alerts and never miss events again.

Features

  • Simple / Periodic alerts
  • Works on Windows, macOS and Linux
  • Safe, corrupt-free and humanly readable database
  • Fully customizable alerts (sound, color, font, etc)

Installation

You will need a working python environment.

Requirements

  • python => 3.6
  • pygame => 1.9.3
  • PyQt5 => 5.8.2
  • sip => 4.19.2
  • tinydb => 3.2.2

You can install these packages using the following command:

$ pip3 install pygame pyqt5 sip tinydb

Clone the repository:

$ git clone https://github.com/BFH-BTI7301-project1/ClockAlarm.git

Launch ClockAlarm:

$ python3 bin/clockalarm&

Development

Requirements

  • coverage >= 4.4.1
  • pytest >= 3.0.7
  • pytest-cov >= 2.5.1
  • pytest-qt >= 2.1.0
  • pytest-catchlog >= 1.2.2
  • coveralls >= 1.1

You can install these packages using the following command:

$ pip3 install -r stable-req.txt

Run the tests:

$ py.test --cov-report term --cov=. _clockalarm/_tests --no-xvfb

GitHub project page

Bugs/Requests

Please use the GitHub issue tracker to submit bugs or request features.

ClockAlarm API Documentation

_clockalarm

_clockalarm package

Subpackages
_clockalarm.UI package
Submodules
_clockalarm.UI.AlertListWidget module
class _clockalarm.UI.AlertListWidget.AlertListWidget[source]

Bases: PyQt5.QtWidgets.QTableWidget

Visual list displaying the Alerts from the database.

actualize(alert_list)[source]

Actualizes the graphical alert list based on the list given in argument.

alert_list

The list containing all the alerts.

init_ui()[source]

Initialization helper method.

Creates a visual empty grid with column headers ID, Time, Periodicity and Message. If alerts are in the db, fills the list with alerts and sorts them.

_clockalarm.UI.ColorSelectorWidget module
class _clockalarm.UI.ColorSelectorWidget.ColorSelectorWidget(hex_color=None, parent=None)[source]

Bases: PyQt5.QtWidgets.QWidget

Custom widget to selected a color for the notification

button_click()[source]

Called when the color_select_button is clicked.

Choose a color from a palette.

change_event()[source]

Called every times the QLineEdit field is updated.

Update the hex_color value and the color of the QPushButton.

init_ui()[source]

Initialize the GUI of the QWidget

set_hex_color(hex_color)[source]

Set a new hexadecimal color

hex_color

str – The new color.

_clockalarm.UI.MainWindow module
class _clockalarm.UI.MainWindow.MainWindow(application, *args)[source]

Bases: PyQt5.QtWidgets.QMainWindow

Main window interface extending PyQt5.QtWidgets.QMainWindow.

Shows a list of all the alerts retrieved from a JSON file.

application

The main application

*args

The parent pointer or window flags

add_simple_alert()[source]

Creates a SimpleAlertEditWidget and shows it to the user.

closeEvent(event)[source]

Overrides closeEvent() method.

Allows to intercept the window closing event.

delete_alerts()[source]

Deletes the selected alerts.

edit_simple_alert()[source]

Edits the selected alert and shows an SimpleAlertEditWidget to the user.

static export_json_db()[source]

Exports all the Alerts into a JSON file.

static import_json_db()[source]

Imports Alerts from a JSON file into ClockAlarm.

init_ui()[source]

Init helper method to set up the main window.

mute_button_click()[source]

Mutes the alerts and updates the mute button.

tray_icon_click(reason)[source]

Displays the main window when clicking on the app icon in the tray.

_clockalarm.UI.NotificationWidget module
class _clockalarm.UI.NotificationWidget.NotificationWidget(geometry, notification, parent=None)[source]

Bases: PyQt5.QtWidgets.QWidget

Notification widget

geometry

The position and size of the widget on the screen

notification

The notification

init_ui(geom)[source]

Helper method that sets the style of the NotificationWidget.

geom

The position and size of the widget on the screen

mousePressEvent(event)[source]

Override of :class:~PyQt5.QtWidgets.QWidget.mousePressEvent method

popup_close
_clockalarm.UI.SimpleAlertEditWidget module
class _clockalarm.UI.SimpleAlertEditWidget.SimpleAlertEditWidget(alert: _clockalarm.SimpleAlert.SimpleAlert = None)[source]

Bases: PyQt5.QtWidgets.QWidget

Widget allowing to create or edit a SimpleAlert.

alert

A SimpleAlert to edit, default None

init_ui(alert)[source]

Initialization helper method.

alert

The SimpleAlert to edit

_clockalarm.UI.SoundSelectorWidget module
class _clockalarm.UI.SoundSelectorWidget.SoundSelectorWidget(sound_name: str = None, parent=None)[source]

Bases: PyQt5.QtWidgets.QWidget

Costum widget to selected a sound

Select a wave file and import it in the application sound folder.

button_click()[source]

Called when the sound_select_button is clicked. Get a wave sound file path from the file explorer.

init_ui()[source]

Initialize the GUI of the QWidget

load_sound(sound_path: str)[source]

Load the given .wave sound file in the application folder

If the file already exist in the sound folder of the app, nothing append. If a file with the same name already exist in the sound folder, he is overwritten.

sound_path

the full path of the sound file.

Exceptions:
ValueError: If the given sound_path isn’t a valid wave sound.
set_sound(sound: str)[source]

Set a new sound

Modify the name and update the edit field.

sound

str – The new sound basename.

Exceptions:
ValueError: If the sound_name argument isn’t a wave file.
Module contents
_clockalarm.resources package
Module contents
_clockalarm.utils package
Submodules
_clockalarm.utils.importExportUtils module
_clockalarm.utils.importExportUtils.export_alerts_file(dest)[source]

Copy the file at ALERT_DB_PATH into the .json location specified the argument

If existing, the destination file is erased.

Parameters:dest (str) – full path of the destination location
Exceptions:
FileNotFoundException: If the given destination file doesn’t exist or haven’t a json extension shutil.SameFileError: If the src and destination files are the same
_clockalarm.utils.importExportUtils.get_default_config(key, cmd=’str’)[source]

Read the configuration file and return the value for the given key

The cmd attribute defines the type of the value. Default is str.

_clockalarm.utils.importExportUtils.key

The key of the key-value pair in the config file

_clockalarm.utils.importExportUtils.cmd

Type of the desired value. Default is str.

Exceptions:
KeyError: Is the key doesn’t match any key in the config file. configparser.NoSectionError: If the config file or the section doesn’t exist.
_clockalarm.utils.importExportUtils.import_alerts_file(src)[source]

Copy the .json file given as argument into the location specified by ALERT_DB_PATH

If existing, the destination file is erased. All the application is restarted after an import.

Parameters:src (str) – full path of the source json database
Exceptions:
FileNotFoundException: If the given source file doesn’t exist or isn’t a json file SameFileError: If the src and destination files are the same
_clockalarm.utils.importExportUtils.set_default_config(key, value)[source]

Set the given (key,value) pair in the config file.

Preserves the Caps

_clockalarm.utils.importExportUtils.key

the key

_clockalarm.utils.importExportUtils.value

the value

Exceptions:
configparser.NoSectionError: If the config file or the section doesn’t exist.
Module contents
Submodules
_clockalarm.Alert module
class _clockalarm.Alert.Alert(trigger_time)[source]

Bases: PyQt5.QtCore.QObject

Abstract Alert class representing alerts.

trigger_time

The trigger time of the alert.

id

The identification number of the alert in the alert.

Set up when added to the database.
get_id()[source]

Get the Alert identifier.

Returns:The identifier of the alert.
get_trigger_time()[source]

Get the Alert trigger time in seconds since epoch.

Returns:The trigger time
timeout
triggered()[source]

Triggers the alert action.

class _clockalarm.Alert.AlertMeta[source]

Bases: sip.wrappertype, abc.ABC

Abstract Metaclass inheriting QObject’s metaclass

_clockalarm.AlertCollection module
class _clockalarm.AlertCollection.AlertCollection(parent=None)[source]

Bases: object

Collection of all the Alert objects running on the program.

This class contains utilities to load, update and save the alerts in a TinyDB database, and maintain the correct state of all the alerts

add(alert: _clockalarm.SimpleAlert.SimpleAlert)[source]

Add the Alert given in argument to the collection of alerts

If parent is set, the new Alert is connected to the notification center and the list of displayed alerts is updated.

alert

SimpleAlert – The alert to add to the collection

Exceptions:
ValueError: If the alert argument is None or incorrect.
check_timers(trig_time)[source]

Check all the alerts to see if on should be triggered

This function is triggered periodically by the clock.

trig_time

Actual time, in seconds.

clean_db()[source]

Make the TinyDB database consistent

All the outdated alerts without periodicity are removed. New trigger time is calculated for outdated alerts with periodicity.

If the db is corrupted, nothing append.

delete(id_alert: int)[source]

Remove an alert from the collection

id_alert

The id number of the alert to remove.

Exceptions:
KeyError: If the alert to delete doesn’t exist in the database.
display()[source]

Actualize the UI alert list display

If parent is unset, the AlertCollection object isn’t link to any QWindow and nothing append

edit(id_alert: int, notification: _clockalarm.Notification.Notification = None, trigger_time: int = None, periodicity: int = None)[source]

Update an alert with the given modifications

If the trigger_time is in the past, he won’t re updated.

id_alert

int – The id number of the alert to modify

notification

Notification, optional – Default is None. The new notification

trigger_time

int,optional – Default is None. The new trigger time

periodicity(int,optional

Default is None. The new periodicity

Exceptions:
KeyError: If the alert to edit doesn’t exist in the database. ValueError: If the periodicity argument is under zero.
load_db()[source]

Fill the AlertCollection with Alerts form the TinyDB database

Exceptions:
IOError: If a required parameter can’t be found in the database. The database is probably corrupted.
_clockalarm.Clock module
class _clockalarm.Clock.Clock(frequency, parent=None)[source]

Bases: PyQt5.QtCore.QThread

Clock emitting ticks with a given periodicity.

The class extends QThread to allow threading.

frequency

The frequency at which the clock emits a tick.

parent

The parent. Default value is None.

run()[source]

Start the clock.

stop()[source]

Stop the clock.

tick
_clockalarm.Notification module
class _clockalarm.Notification.Notification(message: str, color_hex: str = None, font_family: str = None, font_size: int = None, sound: str = None)[source]

Bases: object

Encapsulate the parameters of a Notification in order to pass it to the NotificationCenter

get_color()[source]

Build a QColor from color_hex parameter

If color_hex parameter is missing, replace it with de default configuration.

Returns:The QColor of the notification
get_font()[source]

Build a QFont from font_family and font_size

If font_family or font_size parameter is missing, replace it with de default configuration.

Returns:The QFont of the notification
get_message()[source]

Getter for message

Returns:The notification text
get_sound()[source]

Build a mixer.Sound object from sound parameter

If the sound path parameter is missing, replace it with de default configuration.

Returns:The mixer.Sound file of the notification
_clockalarm.NotificationCenter module
class _clockalarm.NotificationCenter.NotificationCenter(screen_geometry, parent=None)[source]

Bases: object

Class handling the display of the Notification Widgets

Receives the notifications to display and add it to a queue. If there is free slot on the UI display area, pop the queue and display the notification. If the user clicks on the widget, closes it and compacts the remaining widgets.

add_to_queue(notification)[source]

Add a new notification to the queue

The notification will wait till there is a free spot in the display zone

notification

Notification – The notification to add to enqueue

Exceptions:
ValueError: If the user try to add None or incorrect Notification object to the queue
close_popup(popup: _clockalarm.UI.NotificationWidget.NotificationWidget)[source]

Triggered by a NotificationWidget when closed

Remove the popup from the list and refresh the display zone.

popup

The NotificationWidget to remove from the display zone

Exceptions:
ValueError: If the user pass a None or incorrect popup object as argument. KeyError: If the popup isn’t in the list and can’t be removed
display_popup(geom: PyQt5.QtCore.QRect, notification)[source]

Display a QWidget popup

Play a sound if the program isn’t muted

geom

QRect – position and size of the widget on the screen

notification

Notification – the notification to display

Exceptions:
ValueError: In case of None or invalid QRect object as geom argument ValueError: In case of None or invalid Notification object as notification argument IndexError: If the number of displayed popups is greater or equal to the max number of displayed popups
refresh()[source]

Refresh the display off notifications in the display zone

Compact the remaining notifications in the display zone, if there is free slots, pop the notification queue and display the popup.

_clockalarm.SimpleAlert module
class _clockalarm.SimpleAlert.SimpleAlert(trigger_time, notification, periodicity=None)[source]

Bases: _clockalarm.Alert.Alert

Simple Alert implementation with text message

trigger_time

The time at which the alert is triggered.

notification

The notification to display when the alert is triggered.

periodicity

frequency in which the alert is displayed, in seconds.

get_notification()[source]

Get the Notification

Returns:The Notification of the Alert
get_periodicity()[source]

Get the SimpleAlert periodicity

Returns:The periodicity
triggered()[source]

This method does the same as triggered()

_clockalarm.main module
class _clockalarm.main.App(default_config_path, alert_db_path, *argv)[source]

Bases: PyQt5.QtWidgets.QApplication

Main Application extending QApplication

CLOCK_FREQUENCY = None
MUTE = None
init_alert_collection()[source]

Init AlertCollection object and connect the clock to it

Note

The alerts will be loaded from the default database

init_clock(freq)[source]

Init and start the Clock with the given frequency

freq

frequency of the clock’s ticks

init_config()[source]

Open the config_test.cfg file and use a parser to retrieve default values

init_ui()[source]

Initialisation of the main window GUI

_clockalarm.main.main(argv)[source]

Main function called when application starts

_clockalarm.main.argv

optional – path of the config file and the alertDB file usage: program configFile alrtDBFile If no argument entered, default is config_test.cfg and alertDB.json

Returns:the system exit code
Module contents

Indices and tables