gremmie@1: """
gremmie@1: This file contains the admin definitions for the bio application.
gremmie@1: """
bgneal@147: import datetime
gremmie@1: 
gremmie@1: from django.contrib import admin
bgneal@204: 
bgneal@347: import django.contrib.auth.models
bgneal@347: import django.contrib.auth.admin
bgneal@347: 
bgneal@147: import bio.models
bgneal@207: import bio.badges
bgneal@563: from antispam.utils import deactivate_spammer
bgneal@147: 
gremmie@1: 
bgneal@204: class BadgeOwnerInline(admin.TabularInline):
bgneal@204:     model = bio.models.BadgeOwnership
bgneal@204:     extra = 1
bgneal@204: 
bgneal@204: 
gremmie@1: class UserProfileAdmin(admin.ModelAdmin):
bgneal@663:     search_fields = ['user__username', 'user__first_name', 'user__last_name',
bgneal@663:             'user__email']
bgneal@663:     exclude = ['profile_html', 'signature_html']
bgneal@663:     list_display = ['__unicode__', 'user_is_active', 'get_status_display', 'status_date']
bgneal@663:     readonly_fields = ['status', 'status_date', 'update_date']
bgneal@663:     list_filter = ['status', ]
bgneal@147:     date_hierarchy = 'status_date'
bgneal@663:     inlines = [BadgeOwnerInline, ]
bgneal@663:     actions = [
bgneal@347:         'mark_active',
bgneal@147:         'mark_resigned',
bgneal@147:         'mark_removed',
bgneal@147:         'mark_suspended',
bgneal@147:         'mark_spammer',
bgneal@215:         'mark_stranger',
bgneal@663:         'unsubscribe_forums',
bgneal@663:     ]
bgneal@147: 
bgneal@790:     def has_delete_permission(self, request, object=None):
bgneal@790:         # We don't want to delete a user profile; it is tied to the user object
bgneal@790:         return False
bgneal@790: 
bgneal@790:     def get_actions(self, request):
bgneal@790:         # We don't want to delete a user profile; it is tied to the user object
bgneal@790:         actions = super(UserProfileAdmin, self).get_actions(request)
bgneal@790:         del actions['delete_selected']
bgneal@790:         return actions
bgneal@790: 
bgneal@147:     def get_status_display(self, obj):
bgneal@147:         return obj.get_status_display()
bgneal@147:     get_status_display.short_description = 'Status'
bgneal@147: 
bgneal@147:     def mark_user_status(self, request, qs, status):
bgneal@147:         """
bgneal@347:         Common code for the admin actions. Updates the status field in the
bgneal@347:         profiles to 'status'. Updates the status_date.  Sets the is_active
bgneal@147:         field to True if the status is STA_ACTIVE and False otherwise.
bgneal@147:         """
bgneal@147:         now = datetime.datetime.now()
bgneal@147:         for profile in qs:
bgneal@215:             profile.user.is_active = (status == bio.models.STA_ACTIVE or
bgneal@215:                     status == bio.models.STA_STRANGER)
bgneal@147:             profile.user.save()
bgneal@147:             profile.status = status
bgneal@147:             profile.status_date = now
bgneal@562:             profile.save(content_update=False)
bgneal@147: 
bgneal@398:         count = len(qs)
bgneal@147:         msg = "1 user" if count == 1 else "%d users" % count
bgneal@147:         self.message_user(request, "%s successfully marked as %s." % (msg,
bgneal@147:             bio.models.USER_STATUS_CHOICES[status][1]))
bgneal@147: 
bgneal@147:     def mark_active(self, request, qs):
bgneal@147:         """
bgneal@147:         Marks users as active. Updates their profile status to STA_ACTIVE.
bgneal@147:         """
bgneal@147:         self.mark_user_status(request, qs, bio.models.STA_ACTIVE)
bgneal@147:     mark_active.short_description = "Mark selected users as active"
bgneal@147: 
bgneal@147:     def mark_resigned(self, request, qs):
bgneal@147:         """
bgneal@147:         Marks users as inactive. Updates their profile status to STA_RESIGNED.
bgneal@147:         """
bgneal@147:         self.mark_user_status(request, qs, bio.models.STA_RESIGNED)
bgneal@147:     mark_resigned.short_description = "Mark selected users as resigned"
bgneal@147: 
bgneal@147:     def mark_removed(self, request, qs):
bgneal@147:         """
bgneal@147:         Marks users as inactive. Updates their profile status to STA_REMOVED.
bgneal@147:         """
bgneal@147:         self.mark_user_status(request, qs, bio.models.STA_REMOVED)
bgneal@147:     mark_removed.short_description = "Mark selected users as removed"
bgneal@147: 
bgneal@147:     def mark_suspended(self, request, qs):
bgneal@147:         """
bgneal@147:         Marks users as inactive. Updates their profile status to STA_SUSPENDED.
bgneal@147:         """
bgneal@147:         self.mark_user_status(request, qs, bio.models.STA_SUSPENDED)
bgneal@147:     mark_suspended.short_description = "Mark selected users as suspended"
bgneal@147: 
bgneal@147:     def mark_spammer(self, request, qs):
bgneal@147:         """
bgneal@563:         Calls deactivate_spammer() on each user in the profile queryset.
bgneal@563: 
bgneal@147:         """
bgneal@563:         count = qs.count()
bgneal@147:         for profile in qs:
bgneal@563:             deactivate_spammer(profile.user)
bgneal@563: 
bgneal@563:         self.message_user(request,
bgneal@563:                 "%s profile(s) successfully marked as spammers." % count)
bgneal@563: 
bgneal@147:     mark_spammer.short_description = "Mark selected users as spammers"
gremmie@1: 
bgneal@215:     def mark_stranger(self, request, qs):
bgneal@215:         """
bgneal@215:         Marks users as strangers. Updates their profile status to STA_STRANGER.
bgneal@215:         """
bgneal@215:         self.mark_user_status(request, qs, bio.models.STA_STRANGER)
bgneal@215:     mark_stranger.short_description = "Mark selected users as strangers"
bgneal@215: 
bgneal@663:     def unsubscribe_forums(self, request, qs):
bgneal@663:         """Delete users forum topic subscriptions."""
bgneal@663:         for profile in qs:
bgneal@663:             profile.user.subscriptions.clear()
bgneal@663: 
bgneal@663:         self.message_user(request, "%s subscription(s) deleted." % qs.count())
bgneal@663: 
bgneal@663:     unsubscribe_forums.short_description = "Delete users' forum subscriptions"
bgneal@663: 
bgneal@138: 
bgneal@138: class UserProfileFlagAdmin(admin.ModelAdmin):
bgneal@563:     list_display = ['__unicode__', 'flag_date', 'get_profile_url']
bgneal@563:     actions = ['accept_flags']
bgneal@563:     raw_id_fields = ['user', 'profile']
bgneal@207: 
bgneal@207:     def accept_flags(self, request, qs):
bgneal@207:         """
bgneal@563:         This action awards a security pin to the user that reported the
bgneal@563:         profile, deletes the flags, then deactivates the spammers.
bgneal@563:         """
bgneal@563:         count = qs.count()
bgneal@207:         for flag in qs:
bgneal@563:             deactivate_spammer(flag.profile.user)
bgneal@207:             bio.badges.award_badge(bio.badges.SECURITY_PIN, flag.user)
bgneal@207:             flag.delete()
bgneal@207: 
bgneal@563:         self.message_user(request,
bgneal@563:                 "%s profile(s) successfully marked as spammers." % count)
bgneal@563: 
bgneal@563:     accept_flags.short_description = "Mark selected profiles as spammers"
bgneal@207: 
bgneal@207: 
bgneal@204: class BadgeAdmin(admin.ModelAdmin):
bgneal@204:     list_display = ('name', 'html', 'order', 'numeric_id', 'description')
bgneal@204:     list_editable = ('order', 'numeric_id')
bgneal@204: 
bgneal@204: 
bgneal@347: # We like the User admin but would like a date hierarcy on date_joined.
bgneal@347: class UserAdmin(django.contrib.auth.admin.UserAdmin):
bgneal@347:     date_hierarchy = 'date_joined'
bgneal@347: 
bgneal@347: 
bgneal@204: admin.site.register(bio.models.UserProfile, UserProfileAdmin)
bgneal@204: admin.site.register(bio.models.UserProfileFlag, UserProfileFlagAdmin)
bgneal@204: admin.site.register(bio.models.Badge, BadgeAdmin)
bgneal@347: 
bgneal@347: # Unregister existing ModelAdmin for User, then register ours
bgneal@347: admin.site.unregister(django.contrib.auth.models.User)
bgneal@347: admin.site.register(django.contrib.auth.models.User, UserAdmin)