1 from mygpo
.api
.models
import Podcast
, EpisodeAction
2 from mygpo
.web
.models
import Advertisement
3 from babel
import Locale
, UnknownLocaleError
4 from datetime
import datetime
7 def get_accepted_lang(request
):
8 return list(set([s
[:2] for s
in request
.META
.get('HTTP_ACCEPT_LANGUAGE', '').split(',')]))
10 def get_podcast_languages():
12 Returns all 2-letter language codes that are used by podcasts.
14 It filters obviously invalid strings, but does not check if any
15 of these codes is contained in ISO 639.
18 langs
= [x
['language'] for x
in Podcast
.objects
.values('language').distinct()]
19 sane_lang
= sanitize_language_codes(langs
)
26 def sanitize_language_codes(langs
):
28 expects a list of language codes and returns a unique lost of the first
29 part of all items. obviously invalid entries are skipped
31 >>> sanitize_language_codes(['de-at', 'de-ch'])
34 >>> sanitize_language_codes(['de-at', 'en', 'en-gb', '(asdf', 'Deutsch'])
38 r
= '^[a-zA-Z]{2}[-_]?.*$'
39 return list(set([l
[:2] for l
in langs
if l
and re
.match(r
, l
)]))
42 def get_language_names(lang
):
44 Takes a list of language codes and returns a list of tuples
51 except UnknownLocaleError
:
54 if locale
.display_name
:
55 res
[l
] = locale
.display_name
60 class UpdatedException(Exception):
61 """Base exception with additional payload"""
62 def __init__(self
, data
):
63 Exception.__init
__(self
)
67 def get_played_parts(user
, episode
):
69 return a list of length of alternating unplayed, played parts of the given
70 episode for the given user and the resulting duration of the episode
72 If no information is available, None and the stored duration of the episode
75 actions
= EpisodeAction
.objects
.filter(episode
=episode
, user
=user
, action
='play', playmark__isnull
=False, started__isnull
=False)
77 if actions
.count() == 0:
78 return None, episode
.duration
80 lengths
= [x
.total
for x
in actions
]
81 median_length
= lengths
[len(lengths
)/2]
83 # flatten (merge) all play-parts
84 played_parts
= flatten_intervals(actions
)
86 # if end of last played part exceeds median length, extend episode
88 length
= max(median_length
, played_parts
[len(played_parts
)-1]['end'])
90 return None, episode
.duration
92 #split up the played parts in alternating 'unplayed' and 'played'
93 #sections, starting with an unplayed
97 for played_part
in played_parts
:
98 sections
.append(played_part
['start'] - lastpos
)
99 sections
.append(played_part
['end'] - played_part
['start'])
100 lastpos
= played_part
['end']
102 intsections
= [int(s
) for s
in sections
]
104 return intsections
, length
107 def flatten_intervals(actions
):
109 takes a list of EpisodeActions and returns a sorted
110 list of hashtables with start end elements of the flattened
113 actions
= filter(lambda x
: x
.started
!= None and x
.playmark
!= None, actions
)
114 actions
.sort(key
=lambda x
: x
.started
)
116 if len(actions
) == 0:
120 flat_date
= {'start': first
.started
, 'end': first
.playmark
}
121 for action
in actions
:
122 if action
.started
<= flat_date
['end'] and action
.playmark
>= flat_date
['end']:
123 flat_date
['end'] = action
.playmark
124 elif action
.started
>= flat_date
['start'] and action
.playmark
<= flat_date
['end']:
125 # part already contained
128 played_parts
.append(flat_date
)
129 flat_date
= {'start': action
.started
, 'end': action
.playmark
}
130 played_parts
.append(flat_date
)
134 def get_sponsored_podcast(when
=datetime
.now
):
135 adv
= Advertisement
.objects
.filter(start__lte
=when
, end__gte
=when
)
143 def get_page_list(start
, total
, cur
, show_max
):
145 returns a list of pages to be linked for navigation in a paginated view
148 if show_max
>= (total
- start
):
149 return range(start
, total
+1)
152 if (cur
- start
) > show_max
/ 2:
153 ps
.extend(range(start
, show_max
/ 4))
155 ps
.extend(range(cur
- show_max
/ 4, cur
))
158 ps
.extend(range(start
, cur
))
162 if (total
- cur
) > show_max
/ 2:
163 add
= show_max
/ 2 - len(ps
) # for the first pages, show more pages at the beginning
164 ps
.extend(range(cur
+ 1, cur
+ show_max
/ 4 + add
))
166 ps
.extend(range(total
- show_max
/ 4, total
+ 1))
169 ps
.extend(range(cur
+ 1, total
+ 1))
174 def process_lang_params(request
, url
):
175 if 'lang' in request
.GET
:
176 lang
= list(set([x
for x
in request
.GET
.get('lang').split(',') if x
]))
178 if request
.method
== 'POST':
179 if request
.POST
.get('lang'):
180 lang
= list(set(lang
+ [request
.POST
.get('lang')]))
181 raise UpdatedException(lang
)
183 if not 'lang' in request
.GET
:
184 lang
= get_accepted_lang(request
)
186 return sanitize_language_codes(lang
)