Time tracking you can host anywhere, built on Django. Full export support in multiple formats and easily extensible.
djangodockerhandcodedpythonself-hostedtime-trackingtimetracker
1from django.contrib.sites.models import Site
2from django.db.models.signals import post_save, post_delete
3from django.dispatch import receiver
4
5from asgiref.sync import async_to_sync
6from channels.layers import get_channel_layer
7
8from conf.utils import current_site_id
9
10
11@receiver(post_save)
12def add_current_site(sender, instance, **kwargs):
13 """
14 Add the current site to a model's sites property after a save. This is
15 required in post save because ManyToManyField fields require an existing
16 key.
17
18 TODO: Don't run this on *every* post_save.
19 """
20 if hasattr(instance, "sites"):
21 if not instance.sites.all():
22 instance.sites.set(Site.objects.filter(id=current_site_id()))
23 instance.save()
24
25
26@receiver(post_save)
27def sync_clients_save(sender, instance, **kwargs):
28 """
29 Use django channels to sync all our current clients.
30 """
31 channel_layer = get_channel_layer()
32 async_to_sync(channel_layer.group_send)(
33 "sync_clients", {"type": "sync_clients.save", "model": sender.__name__}
34 )
35
36
37@receiver(post_delete)
38def sync_clients_delete(sender, instance, **kwargs):
39 """
40 Use django channels to sync all our current clients.
41 """
42 channel_layer = get_channel_layer()
43 async_to_sync(channel_layer.group_send)(
44 "sync_clients", {"type": "sync_clients.delete", "model": sender.__name__}
45 )