add DiffusionManager, use it
This commit is contained in:
		@ -147,7 +147,12 @@ class Post (models.Model, Routable):
 | 
			
		||||
    )
 | 
			
		||||
    title = models.CharField (
 | 
			
		||||
        _('title'),
 | 
			
		||||
        max_length = 64,
 | 
			
		||||
    )
 | 
			
		||||
    subtitle = models.CharField (
 | 
			
		||||
        _('subtitle'),
 | 
			
		||||
        max_length = 128,
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
    )
 | 
			
		||||
    content = models.TextField (
 | 
			
		||||
        _('description'),
 | 
			
		||||
@ -192,6 +197,8 @@ class Post (models.Model, Routable):
 | 
			
		||||
        """
 | 
			
		||||
        Return an url to the post detail view.
 | 
			
		||||
        """
 | 
			
		||||
        if not self.pk:
 | 
			
		||||
            return ''
 | 
			
		||||
        return self.reverse(
 | 
			
		||||
            routes.DetailRoute,
 | 
			
		||||
            pk = self.pk, slug = slugify(self.title)
 | 
			
		||||
@ -437,11 +444,6 @@ class RelatedPost (Post, metaclass = RelatedMeta):
 | 
			
		||||
 | 
			
		||||
        note: bound values can be any value, not only Django field.
 | 
			
		||||
        """
 | 
			
		||||
        defaults = None
 | 
			
		||||
        """
 | 
			
		||||
        dict of `post_attr: value` that gives default value for the given
 | 
			
		||||
        fields.
 | 
			
		||||
        """
 | 
			
		||||
        post_to_rel = False
 | 
			
		||||
        """
 | 
			
		||||
        update related object when the post is saved, using bindings
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,7 @@ class DetailRoute(Route):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_object(cl, model, request, pk, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * request is optional
 | 
			
		||||
        * request: optional
 | 
			
		||||
        """
 | 
			
		||||
        return model.objects.get(pk = int(pk))
 | 
			
		||||
 | 
			
		||||
@ -107,7 +107,7 @@ class AllRoute(Route):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset(cl, model, request, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * request is optional
 | 
			
		||||
        * request: optional
 | 
			
		||||
        """
 | 
			
		||||
        return model.objects.all()
 | 
			
		||||
 | 
			
		||||
@ -147,7 +147,7 @@ class ThreadRoute(Route):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset(cl, model, request, thread_model, pk, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * request is optional
 | 
			
		||||
        * request: optional
 | 
			
		||||
        """
 | 
			
		||||
        thread = cl.get_thread(model, thread_model, pk)
 | 
			
		||||
        return model.get_siblings(thread_model = thread, thread_id = pk)
 | 
			
		||||
@ -176,15 +176,17 @@ class DateRoute(Route):
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset(cl, model, request, year, month, day, **kwargs):
 | 
			
		||||
    def get_queryset(cl, model, request, year, month, day,
 | 
			
		||||
                     attr='date', **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * request is optional
 | 
			
		||||
        * request: optional
 | 
			
		||||
        * attr: name of the attribute to check the date against
 | 
			
		||||
        """
 | 
			
		||||
        return model.objects.filter(
 | 
			
		||||
            date__year = int(year),
 | 
			
		||||
            date__month = int(month),
 | 
			
		||||
            date__day = int(day),
 | 
			
		||||
        )
 | 
			
		||||
        return model.objects.filter(**{
 | 
			
		||||
            attr + '__year': int(year),
 | 
			
		||||
            attr + '__month': int(month),
 | 
			
		||||
            attr + '__day': int(day)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_title(cl, model, request, year, month, day, **kwargs):
 | 
			
		||||
@ -208,7 +210,7 @@ class SearchRoute(Route):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset(cl, model, request, q = None, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * request is required if q is None
 | 
			
		||||
        * request: required if q is None
 | 
			
		||||
        """
 | 
			
		||||
        q = request.GET.get('q') or q or ''
 | 
			
		||||
        qs = None
 | 
			
		||||
 | 
			
		||||
@ -285,6 +285,7 @@ class ListItem:
 | 
			
		||||
    behaves like it.
 | 
			
		||||
    """
 | 
			
		||||
    title = None
 | 
			
		||||
    subtitle = None
 | 
			
		||||
    content = None
 | 
			
		||||
    author = None
 | 
			
		||||
    date = None
 | 
			
		||||
@ -332,7 +333,8 @@ class List(Section):
 | 
			
		||||
    """
 | 
			
		||||
    paginate_by = 4
 | 
			
		||||
 | 
			
		||||
    fields = [ 'date', 'time', 'image', 'title', 'content', 'info', 'actions' ]
 | 
			
		||||
    fields = [ 'date', 'time', 'image', 'title', 'subtitle', 'content', 'info',
 | 
			
		||||
               'actions' ]
 | 
			
		||||
    """
 | 
			
		||||
    Fields that must be rendered.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								notes.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								notes.md
									
									
									
									
									
								
							@ -37,6 +37,8 @@
 | 
			
		||||
        - mixcloud
 | 
			
		||||
        - seek bar + timer
 | 
			
		||||
        - remove from playing playlist -> stop
 | 
			
		||||
    - date_by_list:
 | 
			
		||||
        - sections' url
 | 
			
		||||
    - list of played diffusions and tracks when non-stop;
 | 
			
		||||
 | 
			
		||||
# Long term TODO
 | 
			
		||||
 | 
			
		||||
@ -50,13 +50,60 @@ class Program (cms.RelatedPost):
 | 
			
		||||
        auto_create = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Diffusion (cms.RelatedPost):
 | 
			
		||||
class DiffusionManager(models.Manager):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def post_or_default(diff, post, create = True, save = False):
 | 
			
		||||
        if not post and create:
 | 
			
		||||
            post = Diffusion(related = diff.initial or diff)
 | 
			
		||||
            if save:
 | 
			
		||||
                post.save()
 | 
			
		||||
            else:
 | 
			
		||||
                post.rel_to_post()
 | 
			
		||||
        if post:
 | 
			
		||||
            post.date = diff.start
 | 
			
		||||
            post.related = diff
 | 
			
		||||
        return post
 | 
			
		||||
 | 
			
		||||
    def get_for(self, diffs, create = True, save = False):
 | 
			
		||||
        """
 | 
			
		||||
        Get posts for the given related diffusion. Return a list
 | 
			
		||||
        not a Queryset, ordered following the given list.
 | 
			
		||||
 | 
			
		||||
        Update the post objects to make date corresponding to the
 | 
			
		||||
        diffusions.
 | 
			
		||||
 | 
			
		||||
        - diffs: a programs.Diffusion, or iterable of
 | 
			
		||||
            programs.Diffusion. In the first case, return
 | 
			
		||||
            an object instead of a list
 | 
			
		||||
        - create: create a post for each Diffusion if missing
 | 
			
		||||
        - save: save the created posts
 | 
			
		||||
        """
 | 
			
		||||
        if not hasattr(diffs, '__iter__'):
 | 
			
		||||
            qs = self.filter(related = diffs.initial or diff,
 | 
			
		||||
                             published = True)
 | 
			
		||||
            return post_or_default(diffs, post, create, save)
 | 
			
		||||
 | 
			
		||||
        qs = self.filter(related__in = [
 | 
			
		||||
            diff.initial or diff for diff in diffs
 | 
			
		||||
        ], published = True)
 | 
			
		||||
        posts = []
 | 
			
		||||
        for diff in diffs:
 | 
			
		||||
            post = qs.filter(related = diff.initial or diff).first()
 | 
			
		||||
            post = self.post_or_default(diff, post, create, save)
 | 
			
		||||
            if post:
 | 
			
		||||
                posts.append(post)
 | 
			
		||||
        return posts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Diffusion(cms.RelatedPost):
 | 
			
		||||
    objects = DiffusionManager()
 | 
			
		||||
    actions = [actions.Play, actions.AddToPlaylist]
 | 
			
		||||
 | 
			
		||||
    class Relation:
 | 
			
		||||
        model = programs.Diffusion
 | 
			
		||||
        bindings = {
 | 
			
		||||
            'thread': 'program',
 | 
			
		||||
            'title': lambda post, rel: rel.program.name,
 | 
			
		||||
            'date': 'start',
 | 
			
		||||
        }
 | 
			
		||||
        fields_args = {
 | 
			
		||||
@ -69,9 +116,16 @@ class Diffusion (cms.RelatedPost):
 | 
			
		||||
        def auto_create(object):
 | 
			
		||||
            return not object.initial
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
    def __init__(self, *args, rel_to_post = False, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        if rel_to_post and self.related:
 | 
			
		||||
            self.rel_to_post()
 | 
			
		||||
 | 
			
		||||
        self.fill_empty()
 | 
			
		||||
        if not self.subtitle:
 | 
			
		||||
            self.subtitle = _('Diffusion of the %(date)s') % {
 | 
			
		||||
                'date': self.related.start.strftime('%A %d/%m')
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def info(self):
 | 
			
		||||
@ -81,3 +135,14 @@ class Diffusion (cms.RelatedPost):
 | 
			
		||||
            'day': self.related.initial.start.strftime('%A %d/%m')
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def url(self):
 | 
			
		||||
        url = super().url()
 | 
			
		||||
        if url or not self.related.initial:
 | 
			
		||||
            return url
 | 
			
		||||
 | 
			
		||||
        post = Diffusions.objects.filter(related = self.related.initial) \
 | 
			
		||||
                                 .first()
 | 
			
		||||
        return post.url() if post else ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -141,52 +141,9 @@ class Diffusions(sections.List):
 | 
			
		||||
        #                .order_by('-start')[:self.prev_count])
 | 
			
		||||
        #return r
 | 
			
		||||
 | 
			
		||||
    def prepare_list(self, object_list):
 | 
			
		||||
        """
 | 
			
		||||
        This function just prepare the list of object, in order to:
 | 
			
		||||
        - have a good title
 | 
			
		||||
        - given a stream to listen to if needed
 | 
			
		||||
        """
 | 
			
		||||
        for post in object_list:
 | 
			
		||||
            # title
 | 
			
		||||
            if not hasattr(post, 'related') or \
 | 
			
		||||
                    not hasattr(post.related , 'program'):
 | 
			
		||||
                continue
 | 
			
		||||
            name = post.related.program.name
 | 
			
		||||
            if name not in post.title:
 | 
			
		||||
                post.title = ': ' + post.title if post.title else \
 | 
			
		||||
                            ' // ' + post.related.start.strftime('%A %d %B')
 | 
			
		||||
                post.title = name + post.title
 | 
			
		||||
        return object_list
 | 
			
		||||
 | 
			
		||||
    def get_object_list(self):
 | 
			
		||||
        diffs = self.get_diffs()
 | 
			
		||||
 | 
			
		||||
        posts = models.Diffusion.objects.filter(related__in = diffs)
 | 
			
		||||
        r = []
 | 
			
		||||
        for diff in diffs:
 | 
			
		||||
            diff_ = diff.initial if diff.initial else diff
 | 
			
		||||
            post = next((x for x in posts if x.related == diff_), None)
 | 
			
		||||
            if not post:
 | 
			
		||||
                post = sections.ListItem(date = diff.start)
 | 
			
		||||
            else:
 | 
			
		||||
                post = sections.ListItem(post=post)
 | 
			
		||||
                post.date = diff.start
 | 
			
		||||
 | 
			
		||||
            if diff.initial:
 | 
			
		||||
                post.info = _('rerun of %(day)s') % {
 | 
			
		||||
                    'day': diff.initial.start.strftime('%A %d/%m')
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            if self.object:
 | 
			
		||||
                post.update(self.object)
 | 
			
		||||
            else:
 | 
			
		||||
                thread = models.Program.objects. \
 | 
			
		||||
                            filter(related = diff.program, published = True)
 | 
			
		||||
                if thread:
 | 
			
		||||
                    post.update(thread[0])
 | 
			
		||||
            r.append(post)
 | 
			
		||||
        return [ sections.ListItem(post=post) for post in r ]
 | 
			
		||||
        diffs = self.get_diffs().order_by('start')
 | 
			
		||||
        return models.Diffusion.objects.get_for(diffs)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def url(self):
 | 
			
		||||
@ -255,7 +212,6 @@ class Sounds(sections.List):
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListByDate(sections.List):
 | 
			
		||||
    """
 | 
			
		||||
    List that add a navigation by date in its header.
 | 
			
		||||
@ -354,10 +310,11 @@ class Schedule(Diffusions,ListByDate):
 | 
			
		||||
 | 
			
		||||
    def get_object_list(self):
 | 
			
		||||
        date = self.date_or_default()
 | 
			
		||||
        return routes.DateRoute.get_queryset(
 | 
			
		||||
            models.Diffusion, self.request, date.year, date.month,
 | 
			
		||||
            date.day
 | 
			
		||||
        ).order_by('date')
 | 
			
		||||
        diffs = routes.DateRoute.get_queryset(
 | 
			
		||||
            programs.Diffusion, None, date.year, date.month, date.day,
 | 
			
		||||
            attr = 'start'
 | 
			
		||||
        ).order_by('start')
 | 
			
		||||
        return models.Diffusion.objects.get_for(diffs, create = True)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_date_url(date):
 | 
			
		||||
@ -400,6 +357,10 @@ class Logs(ListByDate):
 | 
			
		||||
            )
 | 
			
		||||
        return post
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def make_diff(diff):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_object_list(self):
 | 
			
		||||
        return []
 | 
			
		||||
        station = self.view.website.station
 | 
			
		||||
@ -409,8 +370,11 @@ class Logs(ListByDate):
 | 
			
		||||
            date__year = int(year), date__month = int(month),
 | 
			
		||||
            date__day = int(day)
 | 
			
		||||
        )
 | 
			
		||||
        # TODO for each, exclude if there is a diffusion (that has not been logged)
 | 
			
		||||
        return [ cl.make_item(log) for log in qs ]
 | 
			
		||||
        # TODO for each, exclude if there is a corresponding diffusion
 | 
			
		||||
        #       (that has not been logged)
 | 
			
		||||
        #    if diff and diff != last_diff:
 | 
			
		||||
        #        r.append(cl.make_item
 | 
			
		||||
        # return [ cl.make_item(log) for log in qs ]
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_date_url(date):
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user