PomCli 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2025-06-28
4
+ ### Added
5
+ - Support for multiple Pomodoro repetitions via the `--repetitions` CLI option.
6
+ - Optional progress bar display using `tqdm` with the `--tqdm` CLI flag.
7
+
8
+ ## [0.1.0] - 2025-06-28
9
+ ### Added
10
+ - Initial release: basic Pomodoro timer CLI with work and break durations.
11
+ lo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PomCli
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A simple Pomodoro timer CLI tool.
5
5
  Project-URL: Documentation, https://github.com/YanivGrosskopf/PomCli#readme
6
6
  Project-URL: Issues, https://github.com/YanivGrosskopf/PomCli/issues
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
19
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
20
20
  Requires-Python: >=3.8
21
+ Requires-Dist: tqdm>=4.0.0
21
22
  Description-Content-Type: text/markdown
22
23
 
23
24
  # PomCli
@@ -49,6 +50,7 @@ pomcli --work 25 --break_time 5
49
50
 
50
51
  - `--work`: Work duration in minutes (default: 25)
51
52
  - `--break_time`: Break duration in minutes (default: 5)
53
+ - `--repetitions`: Number of repetitions (default: 1)
52
54
 
53
55
  ## License
54
56
 
@@ -27,6 +27,7 @@ pomcli --work 25 --break_time 5
27
27
 
28
28
  - `--work`: Work duration in minutes (default: 25)
29
29
  - `--break_time`: Break duration in minutes (default: 5)
30
+ - `--repetitions`: Number of repetitions (default: 1)
30
31
 
31
32
  ## License
32
33
 
@@ -0,0 +1,4 @@
1
+ from pomcli.pomodoro import PomodoroTimer
2
+
3
+ if __name__ == "__main__":
4
+ PomodoroTimer(work_minutes=0.1, break_minutes=0.05, repetitions=2, use_tqdm=True).start() # Short times for demo
@@ -24,7 +24,9 @@ classifiers = [
24
24
  "Programming Language :: Python :: Implementation :: CPython",
25
25
  "Programming Language :: Python :: Implementation :: PyPy",
26
26
  ]
27
- dependencies = []
27
+ dependencies = [
28
+ "tqdm>=4.0.0"
29
+ ]
28
30
 
29
31
  [project.urls]
30
32
  Documentation = "https://github.com/YanivGrosskopf/PomCli#readme"
@@ -1,3 +1,2 @@
1
1
  # __about__.py for PomCli
2
- __version__ = "0.1.0"
3
-
2
+ __version__ = "0.2.0"
@@ -0,0 +1,79 @@
1
+ import logging
2
+ import time
3
+
4
+
5
+ class PomodoroTimer:
6
+ def __init__(self, work_minutes=25, break_minutes=5, repetitions=1, logger=None, use_tqdm=False):
7
+ """
8
+ Initializes the Pomodoro timer.
9
+ :param work_minutes: Work duration in minutes.
10
+ :param break_minutes: Break duration in minutes.
11
+ :param repetitions: Number of Pomodoro repetitions.
12
+ :param logger: Logger instance for logging messages. If None, a default logger is created.
13
+ :param use_tqdm: Whether to use tqdm for progress bar display.
14
+ """
15
+ self.work_minutes = work_minutes
16
+ self.break_minutes = break_minutes
17
+ self.repetitions = repetitions
18
+ self.is_running = False
19
+ if logger is None:
20
+ logging.basicConfig(level=logging.INFO, format='%(levelname)s:%(message)s')
21
+ self.logger = logger or logging.getLogger(__name__)
22
+
23
+ self.use_tqdm = use_tqdm
24
+
25
+ def start(self):
26
+ """
27
+ Starts the Pomodoro timer.
28
+ """
29
+ self.is_running = True
30
+ for i in range(self.repetitions):
31
+ self.logger.info(f"Pomodoro round {i + 1} of {self.repetitions}")
32
+ self.logger.info(f"Starting Pomodoro: {self.work_minutes} minutes of work.")
33
+ self._countdown(self.work_minutes * 60, "Work")
34
+ if i < self.repetitions - 1:
35
+ self.logger.info(f"Time for a break: {self.break_minutes} minutes.")
36
+ self.logger.info("Pomodoro session complete!")
37
+ self.is_running = False
38
+
39
+ def _countdown(self, seconds, label):
40
+ if self.use_tqdm:
41
+ try:
42
+ from tqdm import tqdm
43
+ except ImportError:
44
+ self.logger.warning("tqdm is not installed. Progress bar will not be shown.")
45
+ tqdm = None
46
+ else:
47
+ tqdm = None
48
+ seconds = int(seconds)
49
+ iterator = tqdm(range(seconds), desc=f"{label} Timer",
50
+ ncols=70) if self.use_tqdm and 'tqdm' in locals() and tqdm else range(seconds)
51
+ for s in iterator:
52
+ if not self.is_running:
53
+ break
54
+ mins, secs = divmod(int(seconds - s - 1), 60)
55
+ timeformat = f'{mins:02d}:{secs:02d}'
56
+ self.logger.debug(f'{label} Timer: {timeformat}')
57
+ time.sleep(1)
58
+
59
+ def stop(self):
60
+ self.is_running = False
61
+ self.logger.info("Pomodoro stopped.")
62
+
63
+
64
+ def main():
65
+ import argparse
66
+ logging.basicConfig(level=logging.INFO, format='%(message)s')
67
+ parser = argparse.ArgumentParser(description="Simple Pomodoro CLI Timer")
68
+ parser.add_argument('--work', type=float, default=25, help='Work duration in minutes (default: 25)')
69
+ parser.add_argument('--break_time', type=float, default=5, help='Break duration in minutes (default: 5)')
70
+ parser.add_argument('--repetitions', type=int, default=1, help='Number of Pomodoro repetitions (default: 1)')
71
+ parser.add_argument('--tqdm', action='store_true', help='Show progress bar using tqdm')
72
+ args = parser.parse_args()
73
+ timer = PomodoroTimer(work_minutes=args.work, break_minutes=args.break_time, repetitions=args.repetitions,
74
+ use_tqdm=args.tqdm)
75
+ timer.start()
76
+
77
+
78
+ if __name__ == "__main__":
79
+ main()
@@ -1,8 +1,10 @@
1
- import unittest
2
- import time
3
1
  import logging
2
+ import time
3
+ import unittest
4
+
4
5
  from pomcli.pomodoro import PomodoroTimer
5
6
 
7
+
6
8
  class TestPomodoroTimer(unittest.TestCase):
7
9
  def setUp(self):
8
10
  self.logger = logging.getLogger("pomodoro_test")
@@ -15,17 +17,19 @@ class TestPomodoroTimer(unittest.TestCase):
15
17
  class _LogCapture:
16
18
  def __init__(self, output_list):
17
19
  self.output_list = output_list
20
+
18
21
  def write(self, msg):
19
22
  if msg.strip():
20
23
  self.output_list.append(msg.strip())
24
+
21
25
  def flush(self):
22
26
  pass
23
27
 
24
28
  def test_start_and_stop(self):
25
29
  timer = PomodoroTimer(work_minutes=0, break_minutes=0, logger=self.logger)
26
30
  timer.start()
31
+ self.assertIn("INFO:Pomodoro round 1 of 1", self.log_output)
27
32
  self.assertIn("INFO:Starting Pomodoro: 0 minutes of work.", self.log_output)
28
- self.assertIn("INFO:Time for a break: 0 minutes.", self.log_output)
29
33
  self.assertIn("INFO:Pomodoro session complete!", self.log_output)
30
34
  timer.stop()
31
35
  self.assertIn("INFO:Pomodoro stopped.", self.log_output)
@@ -40,6 +44,28 @@ class TestPomodoroTimer(unittest.TestCase):
40
44
  t.join()
41
45
  self.assertIn("INFO:Pomodoro stopped.", self.log_output)
42
46
 
47
+ def test_repetitions(self):
48
+ timer = PomodoroTimer(work_minutes=0, break_minutes=0, repetitions=3, logger=self.logger)
49
+ timer.start()
50
+ rounds = [msg for msg in self.log_output if "Pomodoro round" in msg]
51
+ self.assertEqual(len(rounds), 3)
52
+ self.assertIn("INFO:Pomodoro round 1 of 3", rounds[0])
53
+ self.assertIn("INFO:Pomodoro round 2 of 3", rounds[1])
54
+ self.assertIn("INFO:Pomodoro round 3 of 3", rounds[2])
55
+ self.assertIn("INFO:Pomodoro session complete!", self.log_output)
56
+
57
+ def test_tqdm_usage(self):
58
+ try:
59
+ from tqdm import tqdm
60
+ except ImportError:
61
+ self.skipTest("tqdm is not installed, skipping tqdm usage test.")
62
+
63
+ timer = PomodoroTimer(work_minutes=0.05, break_minutes=0.05, repetitions=2, use_tqdm=True, logger=self.logger)
64
+ timer.start()
65
+ self.assertIn("INFO:Starting Pomodoro: 0.05 minutes of work.", self.log_output)
66
+ self.assertIn("INFO:Time for a break: 0.05 minutes.", self.log_output)
67
+ self.assertIn("INFO:Pomodoro session complete!", self.log_output)
68
+
69
+
43
70
  if __name__ == "__main__":
44
71
  unittest.main()
45
-
@@ -1,5 +0,0 @@
1
- from pomcli.pomodoro import PomodoroTimer
2
-
3
- if __name__ == "__main__":
4
- timer = PomodoroTimer(work_minutes=0.1, break_minutes=0.05) # Short times for demo
5
- timer.start()
@@ -1,43 +0,0 @@
1
- import time
2
- import logging
3
-
4
- class PomodoroTimer:
5
- def __init__(self, work_minutes=25, break_minutes=5, logger=None):
6
- self.work_minutes = work_minutes
7
- self.break_minutes = break_minutes
8
- self.is_running = False
9
- self.logger = logger or logging.getLogger(__name__)
10
-
11
- def start(self):
12
- self.is_running = True
13
- self.logger.info(f"Starting Pomodoro: {self.work_minutes} minutes of work.")
14
- self._countdown(self.work_minutes * 60, "Work")
15
- self.logger.info(f"Time for a break: {self.break_minutes} minutes.")
16
- self._countdown(self.break_minutes * 60, "Break")
17
- self.logger.info("Pomodoro session complete!")
18
- self.is_running = False
19
-
20
- def _countdown(self, seconds, label):
21
- while seconds > 0 and self.is_running:
22
- mins, secs = divmod(int(seconds), 60)
23
- timeformat = f'{mins:02d}:{secs:02d}'
24
- self.logger.debug(f'{label} Timer: {timeformat}')
25
- time.sleep(1)
26
- seconds -= 1
27
-
28
- def stop(self):
29
- self.is_running = False
30
- self.logger.info("Pomodoro stopped.")
31
-
32
- def main():
33
- import argparse
34
- logging.basicConfig(level=logging.INFO, format='%(message)s')
35
- parser = argparse.ArgumentParser(description="Simple Pomodoro CLI Timer")
36
- parser.add_argument('--work', type=float, default=25, help='Work duration in minutes (default: 25)')
37
- parser.add_argument('--break_time', type=float, default=5, help='Break duration in minutes (default: 5)')
38
- args = parser.parse_args()
39
- timer = PomodoroTimer(work_minutes=args.work, break_minutes=args.break_time)
40
- timer.start()
41
-
42
- if __name__ == "__main__":
43
- main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes