Added random order setting, reimplemented queue

This commit is contained in:
nikolay 2021-01-22 11:30:24 +07:00
parent 0ce5c2865b
commit 095501b75a
3 changed files with 85 additions and 72 deletions

View File

@ -1,7 +1,8 @@
{
"meta": {
"config_version": "6.0.2"
"config_version": "6.0.3"
},
"random_order": true,
"allow_postpone": false,
"short_break_interval": 15,
"long_break_interval": 75,
@ -129,4 +130,4 @@
"version": "0.0.1"
}
]
}
}

View File

@ -21,6 +21,7 @@ This module contains the entity classes used by Safe Eyes and its plugins.
"""
import logging
import random
from distutils.version import LooseVersion
from enum import Enum
@ -82,19 +83,21 @@ class BreakQueue:
def __init__(self, config, context):
self.context = context
self.__current_break = None
self.__current_long = 0
self.__current_short = 0
self.__first_break = None
self.__short_break_time = config.get('short_break_interval')
self.__long_break_time = config.get('long_break_interval')
self.__short_pointer = self.__build_queue(BreakType.SHORT_BREAK,
self.__is_random_order = config.get('random_order')
self.__short_queue = self.__build_queue(BreakType.SHORT_BREAK,
config.get('short_breaks'),
self.__short_break_time,
config.get('short_break_duration'))
self.__long_pointer = self.__build_queue(BreakType.LONG_BREAK,
self.__long_queue = self.__build_queue(BreakType.LONG_BREAK,
config.get('long_breaks'),
self.__long_break_time,
config.get('long_break_duration'))
self.__short_header = self.__short_pointer
self.__long_header = self.__long_pointer
# Restore the last break from session
if not self.is_empty():
@ -102,9 +105,16 @@ class BreakQueue:
if last_break is not None:
current_break = self.get_break()
if last_break != current_break.name:
pointer = self.next()
while pointer != current_break and pointer.name != last_break:
pointer = self.next()
brk = self.next()
while brk != current_break and brk.name != last_break:
brk = self.next()
# Get next break randomly if enabled
if self.__is_random_order:
# Double next() because get_break calls it once normally
# Therefore calling self.next() once has no effect
self.next()
self.next()
def get_break(self):
if self.__current_break is None:
@ -115,39 +125,28 @@ class BreakQueue:
return self.__current_break is not None and self.__current_break.type == BreakType.LONG_BREAK
def next(self):
break_obj = None
shorts = self.__short_queue
longs = self.__long_queue
if self.is_empty():
return None
break_obj = None
if self.__short_pointer is None:
# No short breaks
break_obj = self.__long_pointer
self.context['break_type'] = 'long'
# Update the pointer to next
self.__long_pointer = self.__long_pointer.next
elif self.__long_pointer is None:
# No long breaks
break_obj = self.__short_pointer
self.context['break_type'] = 'short'
# Update the pointer to next
self.__short_pointer = self.__short_pointer.next
elif self.__long_pointer.time <= self.__short_pointer.time:
# Time for a long break
break_obj = self.__long_pointer
self.context['break_type'] = 'long'
# Update the pointer to next
self.__long_pointer = self.__long_pointer.next
if shorts is None:
break_obj = self.__next_long()
elif longs is None:
break_obj = self.__next_short(ignore_time=True)
elif longs[self.__current_long].time <= shorts[self.__current_short].time:
break_obj = self.__next_long()
else:
# Time for a short break
break_obj = self.__short_pointer
self.context['break_type'] = 'short'
# Reduce the break time from the next long break
self.__long_pointer.time -= self.__short_pointer.time
# Update the pointer to next
self.__short_pointer = self.__short_pointer.next
break_obj = self.__next_short()
if self.__first_break is None:
self.__first_break = break_obj
self.context['new_cycle'] = self.__first_break == break_obj
if not self.__is_random_order:
self.context['new_cycle'] = self.__first_break == break_obj
if self.__current_break is not None:
# Reset the time of long breaks
if self.__current_break.type == BreakType.LONG_BREAK:
@ -159,38 +158,56 @@ class BreakQueue:
return break_obj
def reset(self):
self.__short_pointer = self.__short_header
self.__long_pointer = self.__long_header
self.__first_break = None
self.__current_break = None
# Reset all break time
short_pointer = self.__short_pointer
long_pointer = self.__long_pointer
short_pointer.time = self.__short_break_time
long_pointer.time = self.__long_break_time
short_pointer = short_pointer.next
long_pointer = long_pointer.next
while short_pointer != self.__short_header:
short_pointer.time = self.__short_break_time
short_pointer = short_pointer.next
while long_pointer != self.__long_header:
long_pointer.time = self.__long_break_time
long_pointer = long_pointer.next
for break_object in self.__short_queue:
break_object.time = self.__short_break_time
for break_object in self.__long_queue:
break_object.time = self.__long_break_time
def is_empty(self):
return self.__short_pointer is None and self.__long_pointer is None
return self.__short_queue is None and self.__long_queue is None
def __next_short(self, ignore_time=False):
longs = self.__long_queue
shorts = self.__short_queue
break_obj = shorts[self.__current_short]
self.context['break_type'] = 'short'
# Reduce the break time from the next long break (default)
if not ignore_time:
longs[self.__current_long].time -= shorts[self.__current_short].time
# Update the index to next
if self.__is_random_order:
self.__current_short = random.randint(0, len(shorts) - 1)
else:
self.__current_short = (self.__current_short + 1) % len(shorts)
return break_obj
def __next_long(self):
longs = self.__long_queue
shorts = self.__short_queue
break_obj = longs[self.__current_long]
self.context['break_type'] = 'long'
# Update the index to next
if self.__is_random_order:
self.__current_long = random.randint(0, len(longs) - 1)
else:
self.__current_long = (self.__current_long + 1) % len(longs)
return break_obj
def __build_queue(self, break_type, break_configs, break_time, break_duration):
"""
Build a circular queue of breaks.
Build a queue of breaks.
"""
head = None
tail = None
for break_config in break_configs:
size = len(break_configs)
if 0 == size:
# No breaks
return None
queue = [None] * size
for i, break_config in enumerate(break_configs):
name = _(break_config['name'])
duration = break_config.get('duration', break_duration)
image = break_config.get('image')
@ -205,17 +222,9 @@ class BreakQueue:
break_obj = Break(break_type, name, interval,
duration, image, plugins)
if head is None:
head = break_obj
tail = break_obj
else:
tail.next = break_obj
tail = break_obj
queue[i] = break_obj
# Connect the tail to the head
if tail is not None:
tail.next = head
return head
return queue
class State(Enum):

View File

@ -71,6 +71,7 @@ class SettingsDialog:
self.spin_postpone_duration = builder.get_object('spin_postpone_duration')
self.spin_disable_keyboard_shortcut = builder.get_object('spin_disable_keyboard_shortcut')
self.switch_strict_break = builder.get_object('switch_strict_break')
self.switch_random_order = builder.get_object('switch_random_order')
self.switch_postpone = builder.get_object('switch_postpone')
self.switch_persist = builder.get_object('switch_persist')
self.switch_rpc_server = builder.get_object('switch_rpc_server')
@ -112,6 +113,7 @@ class SettingsDialog:
self.spin_postpone_duration.set_value(config.get('postpone_duration'))
self.spin_disable_keyboard_shortcut.set_value(config.get('shortcut_disable_time'))
self.switch_strict_break.set_active(config.get('strict_break'))
self.switch_random_order.set_active(config.get('random_order'))
self.switch_postpone.set_active(config.get('allow_postpone'))
self.switch_persist.set_active(config.get('persist_state'))
self.switch_rpc_server.set_active(config.get('use_rpc_server'))
@ -325,6 +327,7 @@ class SettingsDialog:
self.config.set('postpone_duration', self.spin_postpone_duration.get_value_as_int())
self.config.set('shortcut_disable_time', self.spin_disable_keyboard_shortcut.get_value_as_int())
self.config.set('strict_break', self.switch_strict_break.get_active())
self.config.set('random_order', self.switch_random_order.get_active())
self.config.set('allow_postpone', self.switch_postpone.get_active())
self.config.set('persist_state', self.switch_persist.get_active())
self.config.set('use_rpc_server', self.switch_rpc_server.get_active())