14
14
from pages .models import HomePage , Supporters , PrivacyPolicy , K12Subject , Subject , Subjects , RootPage
15
15
16
16
17
- class HttpSmartRedirectResponse (HttpResponsePermanentRedirect ):
18
- pass
19
-
20
-
21
17
class CommonMiddlewareAppendSlashWithoutRedirect (CommonMiddleware ):
22
- """ This class converts HttpSmartRedirectResponse to the common response
23
- of Django view, without redirect. This is necessary to match status_codes
24
- for urls like /url?q=1 and /url/?q=1. If you don't use it, you will have 302
25
- code always on pages without slash.
18
+ """ This class converts HttpResponsePermanentRedirect to the common response
19
+ of Django view, without redirect. This is necessary to match status_codes
20
+ for urls like /url?q=1 and /url/?q=1. If you don't use it, you will have 302
21
+ code always on pages without slash.
26
22
"""
27
- response_redirect_class = HttpSmartRedirectResponse
23
+ response_redirect_class = HttpResponsePermanentRedirect
28
24
29
- def __init__ (self , * args , ** kwargs ):
30
- # create django request resolver
31
- self .handler = BaseHandler ()
25
+ def __init__ (self , * args , ** kwargs ):
26
+ # create django request resolver
27
+ self .handler = BaseHandler ()
32
28
33
- # prevent recursive includes
34
- old = settings .MIDDLEWARE
35
- name = self .__module__ + '.' + self .__class__ .__name__
36
- settings .MIDDLEWARE = [i for i in settings .MIDDLEWARE if i != name ]
29
+ # prevent recursive includes
30
+ old = settings .MIDDLEWARE
31
+ name = self .__module__ + '.' + self .__class__ .__name__
32
+ settings .MIDDLEWARE = [i for i in settings .MIDDLEWARE if i != name ]
37
33
38
- self .handler .load_middleware ()
34
+ self .handler .load_middleware ()
39
35
40
- settings .MIDDLEWARE = old
41
- super (CommonMiddlewareAppendSlashWithoutRedirect , self ).__init__ (* args , ** kwargs )
36
+ settings .MIDDLEWARE = old
37
+ super ().__init__ (* args , ** kwargs )
42
38
43
- def get_full_path_with_slash (self , request ):
44
- """ Return the full path of the request with a trailing slash appended
45
- without Exception in Debug mode
46
- """
47
- new_path = request . get_full_path ( force_append_slash = True )
48
- # Prevent construction of scheme relative urls.
49
- new_path = escape_leading_slashes (new_path )
50
- return new_path
39
+ def get_full_path_with_slash (self , request ):
40
+ """ Return the full path of the request with a trailing slash appended
41
+ without Exception in Debug mode
42
+ """
43
+ # Prevent construction of scheme relative urls.
44
+ new_path = request . get_full_path ( force_append_slash = True )
45
+ new_path = escape_leading_slashes (new_path )
46
+ return new_path
51
47
52
- def process_response (self , request , response ):
53
- response = super (CommonMiddlewareAppendSlashWithoutRedirect , self ).process_response (request , response )
48
+ def process_response (self , request , response ):
49
+ response = super ().process_response (request , response )
54
50
55
- if isinstance (response , HttpSmartRedirectResponse ):
56
- if not request .path .endswith ('/' ):
57
- request .path = request .path + '/'
58
- # we don't need query string in path_info because it's in request.GET already
59
- request .path_info = request .path
60
- response = self .handler .get_response (request )
51
+ if isinstance (response , HttpResponsePermanentRedirect ):
52
+ if not request .path .endswith ('/' ):
53
+ request .path = request .path + '/'
54
+ # we don't need query string in path_info because it's in request.GET already
55
+ response = self .handler .get_response (request )
61
56
62
- return response
57
+ return response
63
58
64
59
65
60
class CommonMiddlewareOpenGraphRedirect (CommonMiddleware ):
66
- OG_USER_AGENTS = [
67
- 'baiduspider' ,
68
- 'bingbot' ,
69
- 'embedly' ,
70
- 'facebookbot' ,
71
- 'facebookexternalhit/1.1' ,
72
- 'facebookexternalhit' ,
73
- 'facebot' ,
74
- 'google.*snippet' ,
75
- 'googlebot' ,
76
- 'linkedinbot' ,
77
- 'MetadataScraper' ,
78
- 'outbrain' ,
79
- 'pinterest' ,
80
- 'pinterestbot' ,
81
- 'quora' ,
82
- 'quora link preview' ,
83
- 'rogerbot' ,
84
- 'showyoubot' ,
85
- 'slackbot' ,
86
- 'slackbot-linkexpanding' ,
87
- 'twitterbot' ,
88
- 'vkShare' ,
89
- 'W3C_Validator' ,
90
- 'WhatsApp' ,
91
- 'MetadataScraper' ,
92
- 'yandex' ,
93
- 'yahoo' ,
94
- ]
61
+ OG_USER_AGENTS = {
62
+ 'baiduspider' , 'bingbot' , 'embedly' , 'facebookbot' , 'facebookexternalhit/1.1' ,
63
+ 'facebookexternalhit' , 'facebot' , 'google.*snippet' , 'googlebot' , 'linkedinbot' ,
64
+ 'MetadataScraper' , 'outbrain' , 'pinterest' , 'pinterestbot' , 'quora' , 'quora link preview' ,
65
+ 'rogerbot' , 'showyoubot' , 'slackbot' , 'slackbot-linkexpanding' , 'twitterbot' , 'vkShare' ,
66
+ 'W3C_Validator' , 'WhatsApp' , 'yandex' , 'yahoo'
67
+ }
95
68
96
69
def __init__ (self , get_response ):
97
70
self .get_response = get_response
98
71
99
72
def __call__ (self , request , * args , ** kwargs ):
100
73
if 'HTTP_USER_AGENT' in request .META :
101
-
102
74
user_agent = user_agent_parser .ParseUserAgent (request .META ["HTTP_USER_AGENT" ])
103
75
if user_agent ['family' ].lower () in self .OG_USER_AGENTS :
104
- # url path minus the trailing /
105
76
url_path = unquote (request .get_full_path ()[:- 1 ])
106
-
107
77
full_url = unquote (request .build_absolute_uri ())
108
-
109
- # index of last / to find slug, except when there isn't a last /
110
- if url_path == '' :
111
- page_slug = "home"
112
- else :
113
- index = url_path .rindex ('/' )
114
- page_slug = url_path [index + 1 :]
78
+ page_slug = "home" if url_path == '' else url_path .rsplit ('/' , 1 )[- 1 ]
115
79
116
80
if self .redirect_path_found (url_path ):
117
- # supporters page has the wrong slug
118
81
if page_slug == 'foundation' :
119
82
page_slug = 'supporters'
120
83
121
- # look up correct object based on path
122
- if '/details/books/' in url_path :
123
- page = Book .objects .filter (slug = page_slug )
124
- elif '/blog/' in url_path :
125
- page = NewsArticle .objects .filter (slug = page_slug )
126
- elif '/privacy' in url_path :
127
- page = PrivacyPolicy .objects .filter (slug = 'privacy-policy' )
128
- elif '/k12' in url_path :
129
- page = K12Subject .objects .filter (slug = 'k12-' + page_slug )
130
- elif '/subjects' in url_path :
131
- flag = FeatureFlag .objects .filter (name = 'new_subjects' )
132
- if flag [0 ].feature_active :
133
- if page_slug == 'subjects' :
134
- page_slug = 'new-subjects'
135
- page = Subjects .objects .filter (slug = page_slug )
136
- else :
137
- page = Subject .objects .filter (slug = page_slug + '-books' )
138
- else :
139
- page_slug = 'subjects'
140
- page = BookIndex .objects .filter (slug = page_slug )
141
- else :
142
- page = self .page_by_slug (page_slug )
143
-
84
+ page = self .get_page (url_path , page_slug )
144
85
if page :
145
86
template = self .build_template (page [0 ], full_url )
146
87
return HttpResponse (template )
147
- else :
148
- return self .get_response (request )
149
- else :
150
- return self .get_response (request )
151
88
return self .get_response (request )
152
89
90
+ def get_page (self , url_path , page_slug ):
91
+ if '/details/books/' in url_path :
92
+ return Book .objects .filter (slug = page_slug )
93
+ elif '/blog/' in url_path :
94
+ return NewsArticle .objects .filter (slug = page_slug )
95
+ elif '/privacy' in url_path :
96
+ return PrivacyPolicy .objects .filter (slug = 'privacy-policy' )
97
+ elif '/k12' in url_path :
98
+ return K12Subject .objects .filter (slug = 'k12-' + page_slug )
99
+ elif '/subjects' in url_path :
100
+ flag = FeatureFlag .objects .filter (name = 'new_subjects' )
101
+ if flag [0 ].feature_active :
102
+ if page_slug == 'subjects' :
103
+ page_slug = 'new-subjects'
104
+ return Subjects .objects .filter (slug = page_slug )
105
+ else :
106
+ return Subject .objects .filter (slug = page_slug + '-books' )
107
+ else :
108
+ return BookIndex .objects .filter (slug = 'subjects' )
109
+ else :
110
+ return self .page_by_slug (page_slug )
111
+
153
112
def build_template (self , page , page_url ):
113
+ page_url = page_url .rstrip ('/' )
154
114
image_url = self .image_url (page .promote_image )
155
- template = '<!DOCTYPE html> <html> <head> <meta charset="utf-8">\n '
156
- template += ' <title>' + str (page .title ) + '</title>\n '
157
- template += ' <meta name="description" content="{}" >\n ' .format (page .search_description )
158
- template += ' <link rel="canonical" href="{}" />\n ' .format (page_url )
159
- template += ' <meta property="og:url" content="{}" />\n ' .format (page_url )
160
- template += ' <meta property="og:type" content="article" />\n '
161
- template += ' <meta property="og:title" content="{}" />\n ' .format (page .title )
162
- template += ' <meta property="og:description" content="{}" />\n ' .format (page .search_description )
163
- template += ' <meta property="og:image" content="{}" />\n ' .format (image_url )
164
- template += ' <meta property="og:image:alt" content="{}" />\n ' .format (page .title )
165
- template += ' <meta name="twitter:card" content="summary_large_image">\n '
166
- template += ' <meta name="twitter:site" content="@OpenStax">\n '
167
- template += ' <meta name="twitter:title" content="{}">\n ' .format (page .title )
168
- template += ' <meta name="twitter:description" content="{}">\n ' .format (page .search_description )
169
- template += ' <meta name="twitter:image" content="{}">\n ' .format (image_url )
170
- template += ' <meta name="twitter:image:alt" content="OpenStax">\n '
171
- template += '</head><body></body></html>'
172
- return template
115
+ return f'''<!DOCTYPE html>
116
+ <html>
117
+ <head>
118
+ <meta charset="utf-8">
119
+ <title>{ page .title } </title>
120
+ <meta name="description" content="{ page .search_description } ">
121
+ <link rel="canonical" href="{ page_url } ">
122
+ <meta property="og:url" content="{ page_url } ">
123
+ <meta property="og:type" content="article">
124
+ <meta property="og:title" content="{ page .title } ">
125
+ <meta property="og:description" content="{ page .search_description } ">
126
+ <meta property="og:image" content="{ image_url } ">
127
+ <meta property="og:image:alt" content="{ page .title } ">
128
+ <meta name="twitter:card" content="summary_large_image">
129
+ <meta name="twitter:site" content="@OpenStax">
130
+ <meta name="twitter:title" content="{ page .title } ">
131
+ <meta name="twitter:description" content="{ page .search_description } ">
132
+ <meta name="twitter:image" content="{ image_url } ">
133
+ <meta name="twitter:image:alt" content="OpenStax">
134
+ </head>
135
+ <body></body>
136
+ </html>'''
173
137
174
138
def redirect_path_found (self , url_path ):
175
- if '/blog/' in url_path or '/details/books/' in url_path or '/foundation' in url_path or '/privacy' in url_path or '/subjects' in url_path or '' == url_path :
176
- return True
177
- elif '/k12' in url_path :
178
- last_slash = url_path .rfind ('/' )
179
- k12_index = url_path .rfind ('k12' )
180
- if last_slash < k12_index :
181
- return False
182
- else :
183
- return True
184
- else :
185
- return False
139
+ return any (substring in url_path for substring in ['/blog/' , '/details/books/' , '/foundation' , '/privacy' , '/subjects' , '' ]) or '/k12' in url_path
186
140
187
141
def image_url (self , image ):
188
- image_url = build_image_url (image )
189
- if not image_url :
190
- return ''
191
- return image_url
142
+ return build_image_url (image ) or ''
192
143
193
144
def page_by_slug (self , page_slug ):
194
145
if page_slug == 'supporters' :
195
146
return Supporters .objects .all ()
196
147
if page_slug == 'openstax-homepage' :
197
148
return HomePage .objects .filter (locale = 1 )
198
149
if page_slug == 'home' :
199
- return RootPage .objects .filter (locale = 1 )
200
-
201
-
202
-
150
+ return RootPage .objects .filter (locale = 1 )
0 commit comments