# Path: aircox/models/page.py
# class Page(BasePage):
#     """ Base Page model used for articles and other dated content. """
#     category = models.ForeignKey(
#         Category, models.SET_NULL,
#         verbose_name=_('category'), blank=True, null=True, db_index=True
#     )
#     pub_date = models.DateTimeField(blank=True, null=True)
#     featured = models.BooleanField(
#         _('featured'), default=False,
#     )
#     allow_comments = models.BooleanField(
#         _('allow comments'), default=True,
#     )
# 
#     class Meta:
#         verbose_name = _('Publication')
#         verbose_name_plural = _('Publications')
# 
#     def save(self, *args, **kwargs):
#         if self.is_published and self.pub_date is None:
#             self.pub_date = tz.now()
#         elif not self.is_published:
#             self.pub_date = None
# 
#         if self.parent and not self.category:
#             self.category = self.parent.category
#         super().save(*args, **kwargs)
# 
# class PageQuerySet(InheritanceQuerySet):
#     def draft(self):
#         return self.filter(status=Page.STATUS_DRAFT)
# 
#     def published(self):
#         return self.filter(status=Page.STATUS_PUBLISHED)
# 
#     def trash(self):
#         return self.filter(status=Page.STATUS_TRASH)
# 
#     def parent(self, parent=None, id=None):
#         """ Return pages having this parent. """
#         return self.filter(parent=parent) if id is None else \
#                self.filter(parent__id=id)
# 
# Path: aircox/models/program.py
# class Program(Page):
#     """
#     A Program can either be a Streamed or a Scheduled program.
# 
#     A Streamed program is used to generate non-stop random playlists when there
#     is not scheduled diffusion. In such a case, a Stream is used to describe
#     diffusion informations.
# 
#     A Scheduled program has a schedule and is the one with a normal use case.
# 
#     Renaming a Program rename the corresponding directory to matches the new
#     name if it does not exists.
#     """
#     # explicit foreign key in order to avoid related name clashes
#     station = models.ForeignKey(Station, models.CASCADE,
#                                 verbose_name=_('station'))
#     active = models.BooleanField(
#         _('active'),
#         default=True,
#         help_text=_('if not checked this program is no longer active')
#     )
#     sync = models.BooleanField(
#         _('syncronise'),
#         default=True,
#         help_text=_('update later diffusions according to schedule changes')
#     )
# 
#     objects = ProgramQuerySet.as_manager()
#     detail_url_name = 'program-detail'
# 
#     @property
#     def path(self):
#         """ Return program's directory path """
#         return os.path.join(settings.AIRCOX_PROGRAMS_DIR,
#                             self.slug.replace('-', '_'))
# 
#     @property
#     def archives_path(self):
#         return os.path.join(self.path, settings.AIRCOX_SOUND_ARCHIVES_SUBDIR)
# 
#     @property
#     def excerpts_path(self):
#         return os.path.join(
#             self.path, settings.AIRCOX_SOUND_ARCHIVES_SUBDIR
#         )
# 
#     def __init__(self, *kargs, **kwargs):
#         super().__init__(*kargs, **kwargs)
#         if self.slug:
#             self.__initial_path = self.path
#             self.__initial_cover = self.cover
# 
#     @classmethod
#     def get_from_path(cl, path):
#         """
#         Return a Program from the given path. We assume the path has been
#         given in a previous time by this model (Program.path getter).
#         """
#         path = path.replace(settings.AIRCOX_PROGRAMS_DIR, '')
# 
#         while path[0] == '/':
#             path = path[1:]
# 
#         path = path[:path.index('/')]
#         return cl.objects.filter(slug=path.replace('_','-')).first()
# 
#     def ensure_dir(self, subdir=None):
#         """
#         Make sur the program's dir exists (and optionally subdir). Return True
#         if the dir (or subdir) exists.
#         """
#         path = os.path.join(self.path, subdir) if subdir else \
#             self.path
#         os.makedirs(path, exist_ok=True)
# 
#         return os.path.exists(path)
# 
#     class Meta:
#         verbose_name = _('Program')
#         verbose_name_plural = _('Programs')
# 
#     def __str__(self):
#         return self.title
# 
#     def save(self, *kargs, **kwargs):
#         from .sound import Sound
# 
#         super().save(*kargs, **kwargs)
# 
#         # TODO: move in signals
#         path_ = getattr(self, '__initial_path', None)
#         if path_ is not None and path_ != self.path and \
#                 os.path.exists(path_) and not os.path.exists(self.path):
#             logger.info('program #%s\'s dir changed to %s - update it.',
#                         self.id, self.title)
# 
#             shutil.move(path_, self.path)
#             Sound.objects.filter(path__startswith=path_) \
#                  .update(path=Concat('path', Substr(F('path'), len(path_))))
# 
# class ProgramChildQuerySet(PageQuerySet):
#     def station(self, station=None, id=None):
#         return self.filter(parent__program__station=station) if id is None else \
#                self.filter(parent__program__station__id=id)
# 
#     def program(self, program=None, id=None):
#         return self.parent(program, id)


from django.db import models
from django.utils.translation import gettext_lazy as _
from .page import Page, PageQuerySet
from .program import Program, ProgramChildQuerySet



class Article(Page):
    detail_url_name = 'article-detail'

    objects = ProgramChildQuerySet.as_manager()


# Path: aircox/models/page.py
# class Page(BasePage):
#     """ Base Page model used for articles and other dated content. """
#     category = models.ForeignKey(
#         Category, models.SET_NULL,
#         verbose_name=_('category'), blank=True, null=True, db_index=True
#     )
#     pub_date = models.DateTimeField(blank=True, null=True)
#     featured = models.BooleanField(
#         _('featured'), default=False,
#     )
#     allow_comments = models.BooleanField(
#         _('allow comments'), default=True,
#     )
# 
#     class Meta:
#         verbose_name = _('Publication')
#         verbose_name_plural = _('Publications')
# 
#     def save(self, *args, **kwargs):
#         if self.is_published and self.pub_date is None:
#             self.pub_date = tz.now()
#         elif not self.is_published:
#             self.pub_date = None
# 
#         if self.parent and not self.category:
#             self.category = self.parent.category
#         super().save(*args, **kwargs)
# 
# class PageQuerySet(InheritanceQuerySet):
#     def draft(self):
#         return self.filter(status=Page.STATUS_DRAFT)
# 
#     def published(self):
#         return self.filter(status=Page.STATUS_PUBLISHED)
# 
#     def trash(self):
#         return self.filter(status=Page.STATUS_TRASH)
# 
#     def parent(self, parent=None, id=None):
#         """ Return pages having this parent. """
#         return self.filter(parent=parent) if id is None else \
#                self.filter(parent__id=id)
# 
# Path: aircox/models/program.py
# class Program(Page):
#     """
#     A Program can either be a Streamed or a Scheduled program.
# 
#     A Streamed program is used to generate non-stop random playlists when there
#     is not scheduled diffusion. In such a case, a Stream is used to describe
#     diffusion informations.
# 
#     A Scheduled program has a schedule and is the one with a normal use case.
# 
#     Renaming a Program rename the corresponding directory to matches the new
#     name if it does not exists.
#     """
#     # explicit foreign key in order to avoid related name clashes
#     station = models.ForeignKey(Station, models.CASCADE,
#                                 verbose_name=_('station'))
#     active = models.BooleanField(
#         _('active'),
#         default=True,
#         help_text=_('if not checked this program is no longer active')
#     )
#     sync = models.BooleanField(
#         _('syncronise'),
#         default=True,
#         help_text=_('update later diffusions according to schedule changes')
#     )
# 
#     objects = ProgramQuerySet.as_manager()
#     detail_url_name = 'program-detail'
# 
#     @property
#     def path(self):
#         """ Return program's directory path """
#         return os.path.join(settings.AIRCOX_PROGRAMS_DIR,
#                             self.slug.replace('-', '_'))
# 
#     @property
#     def archives_path(self):
#         return os.path.join(self.path, settings.AIRCOX_SOUND_ARCHIVES_SUBDIR)
# 
#     @property
#     def excerpts_path(self):
#         return os.path.join(
#             self.path, settings.AIRCOX_SOUND_ARCHIVES_SUBDIR
#         )
# 
#     def __init__(self, *kargs, **kwargs):
#         super().__init__(*kargs, **kwargs)
#         if self.slug:
#             self.__initial_path = self.path
#             self.__initial_cover = self.cover
# 
#     @classmethod
#     def get_from_path(cl, path):
#         """
#         Return a Program from the given path. We assume the path has been
#         given in a previous time by this model (Program.path getter).
#         """
#         path = path.replace(settings.AIRCOX_PROGRAMS_DIR, '')
# 
#         while path[0] == '/':
#             path = path[1:]
# 
#         path = path[:path.index('/')]
#         return cl.objects.filter(slug=path.replace('_','-')).first()
# 
#     def ensure_dir(self, subdir=None):
#         """
#         Make sur the program's dir exists (and optionally subdir). Return True
#         if the dir (or subdir) exists.
#         """
#         path = os.path.join(self.path, subdir) if subdir else \
#             self.path
#         os.makedirs(path, exist_ok=True)
# 
#         return os.path.exists(path)
# 
#     class Meta:
#         verbose_name = _('Program')
#         verbose_name_plural = _('Programs')
# 
#     def __str__(self):
#         return self.title
# 
#     def save(self, *kargs, **kwargs):
#         from .sound import Sound
# 
#         super().save(*kargs, **kwargs)
# 
#         # TODO: move in signals
#         path_ = getattr(self, '__initial_path', None)
#         if path_ is not None and path_ != self.path and \
#                 os.path.exists(path_) and not os.path.exists(self.path):
#             logger.info('program #%s\'s dir changed to %s - update it.',
#                         self.id, self.title)
# 
#             shutil.move(path_, self.path)
#             Sound.objects.filter(path__startswith=path_) \
#                  .update(path=Concat('path', Substr(F('path'), len(path_))))
# 
# class ProgramChildQuerySet(PageQuerySet):
#     def station(self, station=None, id=None):
#         return self.filter(parent__program__station=station) if id is None else \
#                self.filter(parent__program__station__id=id)
# 
#     def program(self, program=None, id=None):
#         return self.parent(program, id)


# Path: aircox/models/article.py
from django.db import models
from django.utils.translation import gettext_lazy as _
from .page import Page, PageQuerySet
from .program import Program, ProgramChildQuerySet




class Article(Page):
    detail_url_name = 'article-detail'

    objects = ProgramChildQuerySet.as_manager()


    class Meta: