1
1
"""Project views for authenticated users."""
2
2
3
3
import structlog
4
-
5
4
from allauth .socialaccount .models import SocialAccount
6
5
from django .conf import settings
7
6
from django .contrib import messages
40
39
)
41
40
from readthedocs .core .history import UpdateChangeReasonPostView
42
41
from readthedocs .core .mixins import ListViewWithForm , PrivateViewMixin
43
- from readthedocs .core .utils .extend import SettingsOverrideObject
44
42
from readthedocs .integrations .models import HttpExchange , Integration
45
43
from readthedocs .oauth .services import registry
46
44
from readthedocs .oauth .tasks import attach_webhook
79
77
ProjectRelationListMixin ,
80
78
)
81
79
from readthedocs .search .models import SearchQuery
80
+ from readthedocs .subscriptions .models import PlanFeature
81
+
82
82
83
83
log = structlog .get_logger (__name__ )
84
84
@@ -747,6 +747,7 @@ class DomainMixin(ProjectAdminMixin, PrivateViewMixin):
747
747
model = Domain
748
748
form_class = DomainForm
749
749
lookup_url_kwarg = 'domain_pk'
750
+ feature_type = PlanFeature .TYPE_CNAME
750
751
751
752
def get_success_url (self ):
752
753
return reverse ('projects_domains' , args = [self .get_project ().slug ])
@@ -758,11 +759,13 @@ def get_context_data(self, **kwargs):
758
759
return context
759
760
760
761
def _is_enabled (self , project ):
761
- """Should we allow custom domains for this project?"""
762
- return True
762
+ return PlanFeature .objects .has_feature (
763
+ project ,
764
+ type = self .feature_type ,
765
+ )
763
766
764
767
765
- class DomainListBase (DomainMixin , ListViewWithForm ):
768
+ class DomainList (DomainMixin , ListViewWithForm ):
766
769
767
770
def get_context_data (self , ** kwargs ):
768
771
ctx = super ().get_context_data (** kwargs )
@@ -777,12 +780,7 @@ def get_context_data(self, **kwargs):
777
780
return ctx
778
781
779
782
780
- class DomainList (SettingsOverrideObject ):
781
-
782
- _default_class = DomainListBase
783
-
784
-
785
- class DomainCreateBase (DomainMixin , CreateView ):
783
+ class DomainCreate (DomainMixin , CreateView ):
786
784
787
785
def post (self , request , * args , ** kwargs ):
788
786
project = self .get_project ()
@@ -801,12 +799,7 @@ def get_success_url(self):
801
799
)
802
800
803
801
804
- class DomainCreate (SettingsOverrideObject ):
805
-
806
- _default_class = DomainCreateBase
807
-
808
-
809
- class DomainUpdateBase (DomainMixin , UpdateView ):
802
+ class DomainUpdate (DomainMixin , UpdateView ):
810
803
811
804
def post (self , request , * args , ** kwargs ):
812
805
project = self .get_project ()
@@ -815,11 +808,6 @@ def post(self, request, *args, **kwargs):
815
808
return HttpResponse ('Action not allowed' , status = 401 )
816
809
817
810
818
- class DomainUpdate (SettingsOverrideObject ):
819
-
820
- _default_class = DomainUpdateBase
821
-
822
-
823
811
class DomainDelete (DomainMixin , DeleteView ):
824
812
825
813
pass
@@ -1062,10 +1050,11 @@ class RegexAutomationRuleUpdate(RegexAutomationRuleMixin, UpdateView):
1062
1050
pass
1063
1051
1064
1052
1065
- class SearchAnalyticsBase (ProjectAdminMixin , PrivateViewMixin , TemplateView ):
1053
+ class SearchAnalytics (ProjectAdminMixin , PrivateViewMixin , TemplateView ):
1066
1054
1067
1055
template_name = 'projects/projects_search_analytics.html'
1068
1056
http_method_names = ['get' ]
1057
+ feature_type = PlanFeature .TYPE_SEARCH_ANALYTICS
1069
1058
1070
1059
def get (self , request , * args , ** kwargs ):
1071
1060
download_data = request .GET .get ('download' , False )
@@ -1149,21 +1138,25 @@ def _get_csv_data(self):
1149
1138
1150
1139
def _get_retention_days_limit (self , project ):
1151
1140
"""From how many days we need to show data for this project?"""
1152
- return settings .RTD_ANALYTICS_DEFAULT_RETENTION_DAYS
1141
+ return PlanFeature .objects .get_feature_value (
1142
+ project ,
1143
+ type = self .feature_type ,
1144
+ default = settings .RTD_ANALYTICS_DEFAULT_RETENTION_DAYS ,
1145
+ )
1153
1146
1154
1147
def _is_enabled (self , project ):
1155
1148
"""Should we show search analytics for this project?"""
1156
- return True
1157
-
1158
-
1159
- class SearchAnalytics (SettingsOverrideObject ):
1160
- _default_class = SearchAnalyticsBase
1149
+ return PlanFeature .objects .has_feature (
1150
+ project ,
1151
+ type = self .feature_type ,
1152
+ )
1161
1153
1162
1154
1163
- class TrafficAnalyticsViewBase (ProjectAdminMixin , PrivateViewMixin , TemplateView ):
1155
+ class TrafficAnalyticsView (ProjectAdminMixin , PrivateViewMixin , TemplateView ):
1164
1156
1165
1157
template_name = 'projects/project_traffic_analytics.html'
1166
1158
http_method_names = ['get' ]
1159
+ feature_type = PlanFeature .TYPE_PAGEVIEW_ANALYTICS
1167
1160
1168
1161
def get (self , request , * args , ** kwargs ):
1169
1162
download_data = request .GET .get ('download' , False )
@@ -1239,12 +1232,15 @@ def _get_csv_data(self):
1239
1232
1240
1233
def _get_retention_days_limit (self , project ):
1241
1234
"""From how many days we need to show data for this project?"""
1242
- return settings .RTD_ANALYTICS_DEFAULT_RETENTION_DAYS
1235
+ return PlanFeature .objects .get_feature_value (
1236
+ project ,
1237
+ type = self .feature_type ,
1238
+ default = settings .RTD_ANALYTICS_DEFAULT_RETENTION_DAYS ,
1239
+ )
1243
1240
1244
1241
def _is_enabled (self , project ):
1245
1242
"""Should we show traffic analytics for this project?"""
1246
- return True
1247
-
1248
-
1249
- class TrafficAnalyticsView (SettingsOverrideObject ):
1250
- _default_class = TrafficAnalyticsViewBase
1243
+ return PlanFeature .objects .has_feature (
1244
+ project ,
1245
+ type = self .feature_type ,
1246
+ )
0 commit comments