class Profile(models.Model): """User profile which contains some basic configurable settings.""" user = models.ForeignKey(User, unique=True) # This will redirect new users to the account settings page the first time # they log in (or immediately after creating an account). This allows # people to fix their real name and join groups. first_time_setup_done = models.BooleanField( default=False, verbose_name=_("first time setup done"), help_text=_("Indicates whether the user has already gone through " "the first time setup process by saving their user " "preferences.")) # Whether the user wants to receive emails should_send_email = models.BooleanField( default=True, verbose_name=_("send email"), help_text=_("Indicates whether the user wishes to receive emails.")) should_send_own_updates = models.BooleanField( default=True, verbose_name=_("receive emails about own actions"), help_text=_("Indicates whether the user wishes to receive emails " "about their own activity.")) collapsed_diffs = models.BooleanField( default=True, verbose_name=_("collapsed diffs"), help_text=_("Indicates whether diffs should be shown in their " "collapsed state by default.")) wordwrapped_diffs = models.BooleanField( default=True, help_text=_("This field is unused and will be removed in a future " "version.")) syntax_highlighting = models.BooleanField( default=True, verbose_name=_("syntax highlighting"), help_text=_("Indicates whether the user wishes to see " "syntax highlighting in the diffs.")) is_private = models.BooleanField( default=False, verbose_name=_("profile private"), help_text=_("Indicates whether the user wishes to keep his/her " "profile private.")) open_an_issue = models.BooleanField( default=True, verbose_name=_("opens an issue"), help_text=_("Indicates whether the user wishes to default " "to opening an issue or not.")) default_use_rich_text = models.NullBooleanField( default=None, verbose_name=_('enable Markdown by default'), help_text=_('Indicates whether new posts or comments should default ' 'to being in Markdown format.')) # Indicate whether closed review requests should appear in the # review request lists (excluding the dashboard). show_closed = models.BooleanField(default=True) sort_review_request_columns = models.CharField(max_length=256, blank=True) sort_dashboard_columns = models.CharField(max_length=256, blank=True) sort_submitter_columns = models.CharField(max_length=256, blank=True) sort_group_columns = models.CharField(max_length=256, blank=True) review_request_columns = models.CharField(max_length=256, blank=True) dashboard_columns = models.CharField(max_length=256, blank=True) submitter_columns = models.CharField(max_length=256, blank=True) group_columns = models.CharField(max_length=256, blank=True) # A list of starred review requests. This allows users to monitor a # review request and receive e-mails on updates without actually being # on the reviewer list or commenting on the review. This is similar to # adding yourself to a CC list. starred_review_requests = models.ManyToManyField(ReviewRequest, blank=True, related_name="starred_by") # A list of watched groups. This is so that users can monitor groups # without actually joining them, preventing e-mails being sent to the # user and review requests from entering the Incoming Reviews list. starred_groups = models.ManyToManyField(Group, blank=True, related_name="starred_by") # Allows per-user timezone settings timezone = models.CharField(choices=TIMEZONE_CHOICES, default='UTC', max_length=30) settings = JSONField(null=True, default=dict) extra_data = JSONField(null=True, default=dict) objects = ProfileManager() @property def should_use_rich_text(self): """Get whether rich text should be used by default for this user. If the user has chosen whether or not to use rich text explicitly, then that choice will be respected. Otherwise, the system default is used. """ if self.default_use_rich_text is None: siteconfig = SiteConfiguration.objects.get_current() return siteconfig.get('default_use_rich_text') else: return self.default_use_rich_text @property def should_enable_desktop_notifications(self): """Return whether desktop notifications should be used for this user. If the user has chosen whether or not to use desktop notifications explicitly, then that choice will be respected. Otherwise, we enable desktop notifications by default. Returns: bool: If the user has set whether they wish to recieve desktop notifications, then use their preference. Otherwise, we return ``True``. """ return (not self.settings or self.settings.get('enable_desktop_notifications', True)) def star_review_request(self, review_request): """Mark a review request as starred. This will mark a review request as starred for this user and immediately save to the database. """ self.starred_review_requests.add(review_request) if (review_request.public and review_request.status in (ReviewRequest.PENDING_REVIEW, ReviewRequest.SUBMITTED)): site_profile = \ self.user.get_site_profile(review_request.local_site) site_profile.increment_starred_public_request_count() def unstar_review_request(self, review_request): """Mark a review request as unstarred. This will mark a review request as starred for this user and immediately save to the database. """ self.starred_review_requests.remove(review_request) if (review_request.public and review_request.status in (ReviewRequest.PENDING_REVIEW, ReviewRequest.SUBMITTED)): site_profile = \ self.user.get_site_profile(review_request.local_site) site_profile.decrement_starred_public_request_count() def star_review_group(self, review_group): """Mark a review group as starred. This will mark a review group as starred for this user and immediately save to the database. """ self.starred_groups.add(review_group) def unstar_review_group(self, review_group): """Mark a review group as unstarred. This will mark a review group as starred for this user and immediately save to the database. """ self.starred_groups.remove(review_group) def __str__(self): """Return a string used for the admin site listing.""" return self.user.username @property def avatar_service(self): """The avatar service the user has selected. Returns: djblets.avatars.services.base.AvatarService: The avatar service. """ service_id = self.settings.get('avatars', {}).get('avatar_service_id') return avatar_services.get_or_default(service_id) @avatar_service.setter def avatar_service(self, service): """Set the avatar service. Args: service (djblets.avatars.services.base.AvatarService): The avatar service. """ self.settings.setdefault('avatars', {})['avatar_service_id'] = \ service.avatar_service_id def get_display_name(self, viewing_user): """Return the name to display to the given user. If any of the following is True and the user this profile belongs to has a full name set, the display name will be the the user's full name: * The viewing user is authenticated and this profile is public. * The viewing user is the user this profile belongs to. * The viewing user is an administrator. * The viewing user is a LocalSite administrator on any LocalSite for which the user whose this profile belongs to is a user. Otherwise the display name will be the user's username. Args: viewing_user (django.contrib.auth.models.User): The user who is viewing the profile. Returns: unicode: The name to display. """ if (viewing_user is not None and viewing_user.is_authenticated() and (not self.is_private or viewing_user.pk == self.user_id or viewing_user.is_admin_for_user(self.user))): return self.user.get_full_name() or self.user.username else: return self.user.username def save(self, *args, **kwargs): """Save the profile to the database. The profile will only be saved if the user is not affected by read-only mode. Args: *args (tuple): Positional arguments to pass through to the superclass. **kwargs (dict): Keyword arguments to pass through to the superclass. """ if not is_site_read_only_for(self.user): super(Profile, self).save(*args, **kwargs) class Meta: db_table = 'accounts_profile' verbose_name = _('Profile') verbose_name_plural = _('Profiles')
class Profile(models.Model): """User profile which contains some basic configurable settings.""" user = models.ForeignKey(User, unique=True) # This will redirect new users to the account settings page the first time # they log in (or immediately after creating an account). This allows # people to fix their real name and join groups. first_time_setup_done = models.BooleanField( default=False, verbose_name=_("first time setup done"), help_text=_("Indicates whether the user has already gone through " "the first time setup process by saving their user " "preferences.")) # Whether the user wants to receive emails should_send_email = models.BooleanField( default=True, verbose_name=_("send email"), help_text=_("Indicates whether the user wishes to receive emails.")) should_send_own_updates = models.BooleanField( default=True, verbose_name=_("receive emails about own actions"), help_text=_("Indicates whether the user wishes to receive emails " "about their own activity.")) collapsed_diffs = models.BooleanField( default=True, verbose_name=_("collapsed diffs"), help_text=_("Indicates whether diffs should be shown in their " "collapsed state by default.")) wordwrapped_diffs = models.BooleanField( default=True, help_text=_("This field is unused and will be removed in a future " "version.")) syntax_highlighting = models.BooleanField( default=True, verbose_name=_("syntax highlighting"), help_text=_("Indicates whether the user wishes to see " "syntax highlighting in the diffs.")) is_private = models.BooleanField( default=False, verbose_name=_("profile private"), help_text=_("Indicates whether the user wishes to keep his/her " "profile private.")) open_an_issue = models.BooleanField( default=True, verbose_name=_("opens an issue"), help_text=_("Indicates whether the user wishes to default " "to opening an issue or not.")) default_use_rich_text = models.NullBooleanField( default=None, verbose_name=_('enable Markdown by default'), help_text=_('Indicates whether new posts or comments should default ' 'to being in Markdown format.')) # Indicate whether closed review requests should appear in the # review request lists (excluding the dashboard). show_closed = models.BooleanField(default=True) sort_review_request_columns = models.CharField(max_length=256, blank=True) sort_dashboard_columns = models.CharField(max_length=256, blank=True) sort_submitter_columns = models.CharField(max_length=256, blank=True) sort_group_columns = models.CharField(max_length=256, blank=True) review_request_columns = models.CharField(max_length=256, blank=True) dashboard_columns = models.CharField(max_length=256, blank=True) submitter_columns = models.CharField(max_length=256, blank=True) group_columns = models.CharField(max_length=256, blank=True) # A list of starred review requests. This allows users to monitor a # review request and receive e-mails on updates without actually being # on the reviewer list or commenting on the review. This is similar to # adding yourself to a CC list. starred_review_requests = models.ManyToManyField(ReviewRequest, blank=True, related_name="starred_by") # A list of watched groups. This is so that users can monitor groups # without actually joining them, preventing e-mails being sent to the # user and review requests from entering the Incoming Reviews list. starred_groups = models.ManyToManyField(Group, blank=True, related_name="starred_by") # Allows per-user timezone settings timezone = models.CharField(choices=TIMEZONE_CHOICES, default='UTC', max_length=30) settings = JSONField(null=True, default=dict) extra_data = JSONField(null=True, default=dict) objects = ProfileManager() @property def should_use_rich_text(self): """Get whether rich text should be used by default for this user. If the user has chosen whether or not to use rich text explicitly, then that choice will be respected. Otherwise, the system default is used. """ if self.default_use_rich_text is None: siteconfig = SiteConfiguration.objects.get_current() return siteconfig.get('default_use_rich_text') else: return self.default_use_rich_text @property def should_enable_desktop_notifications(self): """Return whether desktop notifications should be used for this user. If the user has chosen whether or not to use desktop notifications explicitly, then that choice will be respected. Otherwise, we enable desktop notifications by default. Returns: bool: If the user has set whether they wish to recieve desktop notifications, then use their preference. Otherwise, we return ``True``. """ return (not self.settings or self.settings.get('enable_desktop_notifications', True)) def star_review_request(self, review_request): """Mark a review request as starred. This will mark a review request as starred for this user and immediately save to the database. """ self.starred_review_requests.add(review_request) if (review_request.public and (review_request.status == ReviewRequest.PENDING_REVIEW or review_request.status == ReviewRequest.SUBMITTED)): site_profile, is_new = LocalSiteProfile.objects.get_or_create( user=self.user, local_site=review_request.local_site, profile=self) if is_new: site_profile.save() site_profile.increment_starred_public_request_count() self.save() def unstar_review_request(self, review_request): """Mark a review request as unstarred. This will mark a review request as starred for this user and immediately save to the database. """ q = self.starred_review_requests.filter(pk=review_request.pk) if q.count() > 0: self.starred_review_requests.remove(review_request) if (review_request.public and (review_request.status == ReviewRequest.PENDING_REVIEW or review_request.status == ReviewRequest.SUBMITTED)): site_profile, is_new = LocalSiteProfile.objects.get_or_create( user=self.user, local_site=review_request.local_site, profile=self) if is_new: site_profile.save() site_profile.decrement_starred_public_request_count() self.save() def star_review_group(self, review_group): """Mark a review group as starred. This will mark a review group as starred for this user and immediately save to the database. """ if self.starred_groups.filter(pk=review_group.pk).count() == 0: self.starred_groups.add(review_group) def unstar_review_group(self, review_group): """Mark a review group as unstarred. This will mark a review group as starred for this user and immediately save to the database. """ if self.starred_groups.filter(pk=review_group.pk).count() > 0: self.starred_groups.remove(review_group) def __str__(self): """Return a string used for the admin site listing.""" return self.user.username
class Profile(models.Model): """User profile. Contains some basic configurable settings""" user = models.ForeignKey(User, unique=True) # This will redirect new users to the account settings page the first time # they log in (or immediately after creating an account). This allows # people to fix their real name and join groups. first_time_setup_done = models.BooleanField( default=False, verbose_name=_("first time setup done"), help_text=_("Indicates whether the user has already gone through " "the first time setup process by saving their user " "preferences.")) collapsed_diffs = models.BooleanField( default=True, verbose_name=_("collapsed diffs"), help_text=_("Indicates whether diffs should be shown in their " "collapsed state by default.")) wordwrapped_diffs = models.BooleanField( default=True, help_text=_("This field is unused and will be removed in a future " "version.")) syntax_highlighting = models.BooleanField( default=True, verbose_name=_("syntax highlighting"), help_text=_("Indicates whether the user wishes to see " "syntax highlighting in the diffs.")) is_private = models.BooleanField( default=False, verbose_name=_("profile private"), help_text=_("Indicates whether the user wishes to keep his/her " "profile private.")) open_an_issue = models.BooleanField( default=True, verbose_name=_("opens an issue"), help_text=_("Indicates whether the user wishes to default " "to opening an issue or not.")) # Indicate whether closed review requests should appear in the # review request lists (excluding the dashboard). show_closed = models.BooleanField(default=True) sort_review_request_columns = models.CharField(max_length=256, blank=True) sort_dashboard_columns = models.CharField(max_length=256, blank=True) sort_submitter_columns = models.CharField(max_length=256, blank=True) sort_group_columns = models.CharField(max_length=256, blank=True) review_request_columns = models.CharField(max_length=256, blank=True) dashboard_columns = models.CharField(max_length=256, blank=True) submitter_columns = models.CharField(max_length=256, blank=True) group_columns = models.CharField(max_length=256, blank=True) # A list of starred review requests. This allows users to monitor a # review request and receive e-mails on updates without actually being # on the reviewer list or commenting on the review. This is similar to # adding yourself to a CC list. starred_review_requests = models.ManyToManyField(ReviewRequest, blank=True, related_name="starred_by") # A list of watched groups. This is so that users can monitor groups # without actually joining them, preventing e-mails being sent to the # user and review requests from entering the Incoming Reviews list. starred_groups = models.ManyToManyField(Group, blank=True, related_name="starred_by") # Allows per-user timezone settings timezone = models.CharField(choices=TIMEZONE_CHOICES, default='UTC', max_length=30) extra_data = JSONField(null=True) objects = ProfileManager() def star_review_request(self, review_request): """Marks a review request as starred. This will mark a review request as starred for this user and immediately save to the database. """ self.starred_review_requests.add(review_request) if (review_request.public and (review_request.status == ReviewRequest.PENDING_REVIEW or review_request.status == ReviewRequest.SUBMITTED)): site_profile, is_new = LocalSiteProfile.objects.get_or_create( user=self.user, local_site=review_request.local_site, profile=self) if is_new: site_profile.save() site_profile.increment_starred_public_request_count() self.save() def unstar_review_request(self, review_request): """Marks a review request as unstarred. This will mark a review request as starred for this user and immediately save to the database. """ q = self.starred_review_requests.filter(pk=review_request.pk) if q.count() > 0: self.starred_review_requests.remove(review_request) if (review_request.public and (review_request.status == ReviewRequest.PENDING_REVIEW or review_request.status == ReviewRequest.SUBMITTED)): site_profile, is_new = LocalSiteProfile.objects.get_or_create( user=self.user, local_site=review_request.local_site, profile=self) if is_new: site_profile.save() site_profile.decrement_starred_public_request_count() self.save() def star_review_group(self, review_group): """Marks a review group as starred. This will mark a review group as starred for this user and immediately save to the database. """ if self.starred_groups.filter(pk=review_group.pk).count() == 0: self.starred_groups.add(review_group) def unstar_review_group(self, review_group): """Marks a review group as unstarred. This will mark a review group as starred for this user and immediately save to the database. """ if self.starred_groups.filter(pk=review_group.pk).count() > 0: self.starred_groups.remove(review_group) def __str__(self): return self.user.username