Flowkeeper is an independent Pomodoro Technique desktop timer for power users. It is a simple tool, which focuses on doing one thing well. It is Free Software with open source.
Flowkeeper Core handles the following:
- Reading / writing
flowkeeper-data.txt
files - Data model and corresponding operations ("Strategies")
- Settings
- Pomodoro Timer logic and abstract status displays
- Event handling
- Data encryption
- Import and export
- Integrations executor
It's a library, there's no UI or CLI.
The most basic example, which prints out backlogs in your flowkeeper-data.txt
:
from fk.core.file_event_source import FileEventSource
from fk.core.mock_settings import MockSettings
from fk.core.no_cryptograph import NoCryptograph
from fk.core.tenant import Tenant
from fk.core.user import User
if __name__ == '__main__':
settings = MockSettings(filename='/home/<user>/flowkeeper-data.txt')
source = FileEventSource[Tenant](settings,
NoCryptograph(settings),
Tenant(settings))
source.start() # FileEventSource uses synchronous IO
user: User = source.get_data().get_current_user()
print('Backlogs:')
for backlog in user.values():
print(f' - {backlog.get_name()}')
A more elaborate example, which also prints out current timer state:
from fk.core import events
from fk.core.abstract_event_source import AbstractEventSource
from fk.core.event_source_factory import EventSourceFactory
from fk.core.event_source_holder import EventSourceHolder
from fk.core.file_event_source import FileEventSource
from fk.core.mock_settings import MockSettings
from fk.core.mock_timer import MockTimer
from fk.core.no_cryptograph import NoCryptograph
from fk.core.tenant import Tenant
from fk.core.timer import PomodoroTimer
from fk.core.user import User
def display_state(event: str, source: AbstractEventSource):
user: User = source.get_data().get_current_user()
print('Backlogs:')
for backlog in user.values():
if backlog.get_running_workitem()[0] is not None:
state = '*'
else:
state = '-'
print(f' {state} {backlog.get_name()}')
if timer.is_working() or timer.is_resting():
print(f'Timer is ticking, {timer.format_remaining_duration()} remaining')
else:
print('Timer is idling')
if __name__ == '__main__':
settings = MockSettings(filename='/home/<user>/flowkeeper-data.txt')
EventSourceFactory.get_event_source_factory().register_producer('local',
lambda s, c, r: FileEventSource[Tenant](s, c, r))
holder = EventSourceHolder(settings, NoCryptograph(settings))
timer = PomodoroTimer(MockTimer(), MockTimer(), settings, holder)
src = holder.request_new_source()
src.on(events.SourceMessagesProcessed, display_state)
src.start()
Sample output. Here we started a pomodoro in another Flowkeeper instance:
Backlogs:
- 2024-10-11, venerdì
- 2024-12-01, domenica
- 2025-01-09, giovedì
- 2025-01-11, sabato
* 2025-01-12, domenica
Timer is ticking, 09:59 remaining
Copyright (c) 2023 - 2024 Constantine Kulak.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.