class EditorTrackable(db.Model): """Describes objects authored by users of the application. In the admin, on object creation the ``created_by`` field is set according to the editor. Same goes for modifying an object and the ``modified_by`` field. Works best in integration with TimeTrackable. If you would rather link to your user profile instead of the user object directly, use the ``EDITOR_TRACKABLE_MODEL`` (the same ``"app_name.ModelClass"``syntax as ``AUTH_PROFILE_MODULE``) setting. Note: for automatic editor updates in admin, ``lck.django.common.admin.ModelAdmin`` **MUST** be used instead of the vanilla ``ModelAdmin``. As a bonus, the ``created_by`` and ``modified_by`` fields will appear as filters on the side of the change list and those fields will be rendered as read-only on the change form.""" created_by = db.ForeignKey( EDITOR_TRACKABLE_MODEL, verbose_name=_("created by"), null=True, blank=True, default=None, related_name='+', on_delete=db.SET_NULL, limit_choices_to={ 'is_staff' if model_is_user(EDITOR_TRACKABLE_MODEL) else 'user__is_staff': True }) modified_by = db.ForeignKey( EDITOR_TRACKABLE_MODEL, verbose_name=_("modified by"), null=True, blank=True, default=None, related_name='+', on_delete=db.SET_NULL, limit_choices_to={ 'is_staff' if model_is_user(EDITOR_TRACKABLE_MODEL) else 'user__is_staff': True }) class Meta: abstract = True def get_editor_from_request(self, request): """This has to be overriden if you're using a custom editor model. Both ``auth.User`` and ``AUTH_PROFILE_MODULE`` are automatically handled.""" if model_is_user(EDITOR_TRACKABLE_MODEL): return request.user else: return request.user.get_profile() def pre_save_model(self, request, obj, form, change): """Internal method used by ``lck.django.common.ModelAdmin``.""" if not change: if not obj.created_by: obj.created_by = self.get_editor_from_request(request) else: obj.modified_by = self.get_editor_from_request(request)
def update_activity(user_id, address, agent, _now_dt): ip, _ = IP.concurrent_get_or_create( address=address, fast_mode=serial_execution, ) if agent: agent, _ = UserAgent.concurrent_get_or_create( name=agent, fast_mode=serial_execution, ) else: agent = None if user_id: profile = User.objects.get(pk=user_id) if not model_is_user(ACTIVITYLOG_PROFILE_MODEL): profile = profile.get_profile() last_active = profile.last_active if not last_active or CURRENTLY_ONLINE_INTERVAL <= 3 * (_now_dt - last_active).seconds: # we're not using save() to bypass signals etc. profile.__class__.objects.filter(pk=profile.pk).update( last_active=_now_dt) pip, _ = ProfileIP.concurrent_get_or_create( ip=ip, profile=profile, fast_mode=serial_execution, ) ProfileIP.objects.filter(pk=pip.pk).update(modified=_now_dt) if agent: pua, _ = ProfileUserAgent.concurrent_get_or_create( agent=agent, profile=profile, fast_mode=serial_execution, ) ProfileUserAgent.objects.filter(pk=pua.pk).update( modified=_now_dt, ) return ip, agent
def get_editor_from_request(self, request): """This has to be overriden if you're using a custom editor model. Both ``auth.User`` and ``AUTH_PROFILE_MODULE`` are automatically handled.""" if model_is_user(EDITOR_TRACKABLE_MODEL): return request.user else: return request.user.get_profile()
def update_activity(user_id, address, agent, _now_dt): ip, _ = IP.concurrent_get_or_create( address=address, fast_mode=serial_execution, ) if agent: agent, _ = UserAgent.concurrent_get_or_create( name=agent, fast_mode=serial_execution, ) else: agent = None if user_id: profile = User.objects.get(pk=user_id) if not model_is_user(ACTIVITYLOG_PROFILE_MODEL): profile = profile.profile last_active = profile.last_active if not last_active or CURRENTLY_ONLINE_INTERVAL <= 3 * ( _now_dt - last_active).seconds: # we're not using save() to bypass signals etc. profile.__class__.objects.filter(pk=profile.pk).update( last_active=_now_dt) pip, _ = ProfileIP.concurrent_get_or_create( ip=ip, profile=profile, fast_mode=serial_execution, ) ProfileIP.objects.filter(pk=pip.pk).update(modified=_now_dt) if agent: pua, _ = ProfileUserAgent.concurrent_get_or_create( agent=agent, profile=profile, fast_mode=serial_execution, ) ProfileUserAgent.objects.filter(pk=pua.pk).update( modified=_now_dt, ) return ip, agent