class SetListEntity(base.TogglEntity): field = fields.SetField(required=True) # type: set
class TimeEntry(WorkspacedEntity): description = fields.StringField() """ Description of the entry. """ project = fields.MappingField(Project, 'pid') """ Project to which the Time entry is linked to. """ task = fields.MappingField(Task, 'tid', premium=True) """ Task to which the Time entry is linked to. (Available only for Premium workspaces) """ billable = fields.BooleanField(default=False, premium=True) """ If available to be billed. (Default: False) (Available only for Premium workspaces) """ start = TimeEntryDateTimeField(required=True) """ DateTime of start of the time entry. (Required) """ stop = TimeEntryDateTimeField() """ DateTime of end of the time entry. """ duration = fields.PropertyField(get_duration, set_duration, formatter=format_duration) """ Dynamic field of entry's duration in seconds. If the time entry is currently running, the duration attribute contains a negative value, denoting the start of the time entry in seconds since epoch (Jan 1 1970). The correct duration can be calculated as current_time + duration, where current_time is the current time in seconds since epoch. """ created_with = fields.StringField(required=True, default='TogglCLI', read=False) """ Information who created the time entry. """ tags = fields.SetField() """ Set of tags associated with the time entry. """ objects = TimeEntrySet() def __init__(self, start, stop=None, duration=None, **kwargs): if stop is None and duration is None: raise ValueError( 'You can create only finished time entries through this way! ' 'You must supply either \'stop\' or \'duration\' parameter!') super().__init__(start=start, stop=stop, duration=duration, **kwargs) @classmethod def get_url(cls): return 'time_entries' def to_dict(self, serialized=False, changes_only=False): # Enforcing serialize duration when start or stop changes if changes_only and (self.__change_dict__.get('start') or self.__change_dict__.get('stop')): self.__change_dict__['duration'] = None return super().to_dict(serialized=serialized, changes_only=changes_only) @classmethod def start_and_save( cls, start=None, config=None, **kwargs ): # type: (pendulum.DateTime, utils.Config, **typing.Any) -> TimeEntry """ Creates a new running entry. If there is another running time entry in the time of calling this method, then the running entry is stopped. This is handled by Toggl's backend. :param start: The DateTime object representing start of the new TimeEntry. If None than current time is used. :param config: :param kwargs: Other parameters for creating the new TimeEntry :return: New running TimeEntry """ config = config or utils.Config.factory() if start is None: start = pendulum.now(config.timezone) if 'stop' in kwargs or 'duration' in kwargs: raise RuntimeError( 'With start_and_save() method you can not create finished entries!' ) instance = cls.__new__(cls) instance.__change_dict__ = {} instance.is_running = True instance._config = config instance.start = start for key, value in kwargs.items(): setattr(instance, key, value) instance.save() return instance def stop_and_save(self=None, stop=None): """ Stops running the entry. It has to be running entry. :param stop: DateTime which should be set as stop time. If None, then current time is used. :return: Self """ if self is None: # noinspection PyMethodFirstArgAssignment self = TimeEntry.objects.current() if self is None: raise exceptions.TogglValidationException( 'There is no running entry to be stoped!') if not self.is_running: raise exceptions.TogglValidationException( 'You can\'t stop not running entry!') config = self._config or utils.Config.factory() if stop is None: stop = pendulum.now(config.timezone) self.stop = stop self.is_running = False self.save(config=config) return self def continue_and_save(self, start=None): """ Creates new time entry with same description as the self entry and starts running it. :param start: The DateTime object representing start of the new TimeEntry. If None than current time is used. :return: The new TimeEntry. """ if self.is_running: logger.warning( 'Trying to continue time entry {} which is already running!'. format(self)) config = self._config or utils.Config.factory() if start is None: start = pendulum.now(config.timezone) new_entry = copy(self) new_entry.start = start new_entry.stop = None new_entry.is_running = True new_entry.save(config=config) return new_entry def __str__(self): return '{} (#{})'.format(getattr(self, 'description', ''), self.id)
class SetEntity(base.TogglEntity): field = fields.SetField() # type: set
class EvaluateConditionsEntity(base.TogglEntity): string = fields.StringField() integer = fields.IntegerField() boolean = fields.BooleanField() set = fields.SetField()