Changeset 498

Show
Ignore:
Timestamp:
07/08/08 17:42:02 (6 months ago)
Author:
thomas
Message:

Added Publishable abstract class to handle publish and expire dates, matching custom manager with convenience methods, and tests.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/djedna/catalog2/forms.py

    r496 r498  
    9393            'title', 'slug', 'number', 'length', 'year', 'artist', 
    9494            'new_artist_name', 'album', 'new_album_title', 'trackfiles', 
    95             'image_override' 
     95            'image_override', 'publish', 'expire', 'is_active' 
    9696        ] 
    9797     
  • trunk/djedna/catalog2/models.py

    r497 r498  
    9393 
    9494 
    95 class MediaFileManager(models.Manager): 
     95class PublishableManager(models.Manager): 
     96    def get_published_q(self, now=None): 
     97        if not now: 
     98            now = datetime.datetime.now() 
     99        published_q = \ 
     100            models.Q(publish__isnull=True) | \ 
     101            models.Q(publish__lte=now) 
     102        not_expired_q = \ 
     103            models.Q(expire__isnull=True) | \ 
     104            models.Q(expire__gte=now) 
     105        return published_q & not_expired_q 
     106     
     107    def get_unpublished_q(self, now=None): 
     108        if not now: 
     109            now = datetime.datetime.now() 
     110        published_q = self.get_published_q(now=now) 
     111        return ~published_q 
     112     
     113    def get_active_q(self, now=None): 
     114        if not now: 
     115            now = datetime.datetime.now() 
     116        return models.Q(is_active=True) & self.get_published_q(now=now) 
     117     
     118    def get_inactive_q(self, now=None): 
     119        if not now: 
     120            now = datetime.datetime.now() 
     121        return models.Q(is_active=False) | self.get_unpublished_q(now=now) 
     122     
     123    def get_active_query_set(self, now=None): 
     124        if not now: 
     125            now = datetime.datetime.now() 
     126        return self.get_query_set().filter(self.get_active_q(now=now)) 
     127    active = property(get_active_query_set) 
     128     
     129    def get_inactive_query_set(self, now=None): 
     130        if not now: 
     131            now = datetime.datetime.now() 
     132        return self.get_query_set().filter(self.get_inactive_q(now=now)) 
     133    inactive = property(get_inactive_query_set) 
     134     
     135    def get_site_q(self, site_id=None): 
     136        if site_id == None: 
     137            site_id = settings.SITE_ID 
     138        return models.Q(sites__id__exact=site_id) 
     139     
     140    def get_site_query_set(self, site_id=None): 
     141        if site_id == None: 
     142            site_id = settings.SITE_ID 
     143        return self.get_query_set().filter(self.get_site_q(site_id=site_id)) 
     144    on_site = property(get_site_query_set) 
     145     
     146    def get_active_site_q(self, now=None, site_id=None): 
     147        if not now: 
     148            now = datetime.datetime.now() 
     149        if site_id == None: 
     150            site_id = settings.SITE_ID 
     151        return self.get_active_q(now=now) & self.get_site_q(site_id=site_id) 
     152     
     153    def get_inactive_site_q(self, now=None, site_id=None): 
     154        if not now: 
     155            now = datetime.datetime.now() 
     156        if site_id == None: 
     157            site_id = settings.SITE_ID 
     158        return self.get_inactive_q(now=now) & self.get_site_q(site_id=site_id) 
     159     
     160    def get_active_site_query_set(self, now=None, site_id=None): 
     161        if not now: 
     162            now = datetime.datetime.now() 
     163        if site_id == None: 
     164            site_id = settings.SITE_ID 
     165        return self.get_query_set().filter( 
     166            self.get_active_site_q(now=now, site_id=site_id) 
     167        ) 
     168    active_on_site = property(get_active_site_query_set) 
     169     
     170    def get_inactive_site_query_set(self, now=None, site_id=None): 
     171        if not now: 
     172            now = datetime.datetime.now() 
     173        if site_id == None: 
     174            site_id = settings.SITE_ID 
     175        return self.get_query_set().filter( 
     176            self.get_inactive_site_q(now=now, site_id=site_id) 
     177        ) 
     178    inactive_on_site = property(get_inactive_site_query_set) 
     179 
     180class Publishable(models.Model): 
     181    is_active = models.BooleanField(default=True, blank=True) 
     182    publish = models.DateTimeField(null=True, blank=True) 
     183    expire = models.DateTimeField(null=True, blank=True) 
     184    added = models.DateTimeField(auto_now_add=True) 
     185    updated = models.DateTimeField(auto_now=True) 
     186    sites = models.ManyToManyField(Site) 
     187     
     188    class Meta: 
     189        abstract = True 
     190     
     191 
     192 
     193class MediaFileManager(PublishableManager): 
    96194    def get_or_create_from_path( 
    97195            self, path, sites=None, import_path=None, defaults={} 
     
    131229        return self.get_query_set().filter(mimetype=mimetype) 
    132230     
    133     def _get_active(self): 
    134         return self.get_query_set().filter(is_active=True) 
    135     active = property(_get_active) 
    136      
    137     def _get_inactive(self): 
    138         return self.get_query_set().filter(is_active=False) 
    139     inactive = property(_get_inactive) 
    140      
    141  
    142 class MediaFile(models.Model): 
     231 
     232class MediaFile(Publishable): 
    143233    relative_path = models.CharField(max_length=1000, core=True, unique=True) 
    144234    mimetype = models.CharField(max_length=256, default='', blank=True) 
    145235    file_modified = models.DateTimeField(null=True, blank=True) 
    146     is_active = models.BooleanField(default=True, blank=True) 
    147236    group_hash = models.CharField(max_length=256, default='', blank=True) 
    148     added = models.DateTimeField(auto_now_add=True) 
    149     updated = models.DateTimeField(auto_now=True) 
    150     sites = models.ManyToManyField(Site) 
    151237     
    152238    class Meta: 
     
    781867 
    782868 
    783 class TrackManager(models.Manager): 
     869class TrackManager(PublishableManager): 
    784870    def get_or_create_from_trackfile(self, trackfile): 
    785871        title=trackfile.info['title'] 
     
    819905        return (track, track_created) 
    820906     
    821     def _get_active(self): 
    822         return self.get_query_set().filter(is_active=True) 
    823     active = property(_get_active) 
    824      
    825     def _get_inactive(self): 
    826         return self.get_query_set().filter(is_active=False) 
    827     inactive = property(_get_inactive) 
    828      
    829907 
    830908class TrackCurrentSiteManager(CurrentSiteManager, TrackManager): 
    831909    pass 
    832910 
    833 class Track(models.Model): 
     911class Track(Publishable): 
    834912    slug = models.SlugField( 
    835913        max_length=1000, prepopulate_from=("title",), unique=True 
     
    847925        related_name='track_overrides' 
    848926    ) 
    849     is_active = models.BooleanField(default=True, blank=True) 
    850     added = models.DateTimeField(auto_now_add=True) 
    851     updated = models.DateTimeField(auto_now=True) 
    852     sites = models.ManyToManyField(Site) 
    853927     
    854928    objects = TrackManager() 
     
    913987 
    914988 
    915 class AlbumManager(models.Manager): 
    916     def _get_active(self): 
    917         return self.get_query_set().filter(is_active=True) 
    918     active = property(_get_active) 
    919      
    920     def _get_inactive(self): 
    921         return self.get_query_set().filter(is_active=False) 
    922     inactive = property(_get_inactive) 
    923      
     989class AlbumManager(PublishableManager): 
     990    pass 
    924991 
    925992class AlbumCurrentSiteManager(CurrentSiteManager, AlbumManager): 
    926993    pass 
    927994 
    928 class Album(models.Model): 
     995class Album(Publishable): 
    929996    title = models.CharField(max_length=1000, core=True) 
    930997    artists = models.ManyToManyField('Artist', related_name="albums") 
     
    9371004        related_name='album_overrides' 
    9381005    ) 
    939     is_active = models.BooleanField(default=True, blank=True) 
    940     added = models.DateTimeField(auto_now_add=True) 
    941     updated = models.DateTimeField(auto_now=True) 
    942     sites = models.ManyToManyField(Site) 
    9431006     
    9441007    objects = AlbumManager() 
     
    10361099 
    10371100 
    1038 class ArtistManager(models.Manager): 
    1039     def _get_active(self): 
    1040         return self.get_query_set().filter(is_active=True) 
    1041     active = property(_get_active) 
    1042      
    1043     def _get_inactive(self): 
    1044         return self.get_query_set().filter(is_active=False) 
    1045     inactive = property(_get_inactive) 
    1046      
     1101class ArtistManager(PublishableManager): 
     1102    pass 
    10471103 
    10481104class ArtistCurrentSiteManager(CurrentSiteManager, ArtistManager): 
    10491105    pass 
    10501106 
    1051 class Artist(models.Model): 
     1107class Artist(Publishable): 
    10521108    name = models.CharField(max_length=1000, core=True, unique=True) 
    10531109    slug = models.SlugField( 
     
    10591115        related_name='artist_overrides' 
    10601116    ) 
    1061     is_active = models.BooleanField(default=True, blank=True) 
    1062     added = models.DateTimeField(auto_now_add=True) 
    1063     updated = models.DateTimeField(auto_now=True) 
    1064     sites = models.ManyToManyField(Site) 
    10651117     
    10661118    objects = ArtistManager() 
  • trunk/djedna/catalog2/tests.py

    r496 r498  
    690690    def test_active(self): 
    691691        group_hash = TrackFile.objects.add_from_path(ALBUM1_REL) 
    692         trackfile = TrackFile.objects.filter(group_hash=group_hash)[0] 
     692        trackfile1 = TrackFile.objects.filter(group_hash=group_hash)[0] 
     693        trackfile2 = TrackFile.objects.filter(group_hash=group_hash)[1] 
    693694        bogus = TrackFile.objects.get_or_create_from_path(BOGUS_MP3_REL) 
    694695        self.failUnlessEqual(TrackFile.objects.active.count(), 5) 
    695696        self.failUnlessEqual(TrackFile.on_site.active.count(), 5) 
    696         trackfile.sites.clear() 
     697        self.failUnlessEqual( 
     698            TrackFile.objects.active_on_site.count(), 
     699            TrackFile.on_site.active.count() 
     700        ) 
     701        trackfile1.sites.clear() 
     702        self.failUnlessEqual(TrackFile.objects.active.count(), 5) 
    697703        self.failUnlessEqual(TrackFile.on_site.active.count(), 4) 
     704        self.failUnlessEqual( 
     705            TrackFile.objects.active_on_site.count(), 
     706            TrackFile.on_site.active.count() 
     707        ) 
     708        delta = datetime.timedelta(minutes=10) 
     709        now = datetime.datetime.now() 
     710        past = now - delta 
     711        future = now + delta 
     712        trackfile2.publish = past 
     713        trackfile2.expire = None 
     714        trackfile2.save() 
     715        self.failUnlessEqual(TrackFile.objects.active.count(), 5) 
     716        self.failUnlessEqual(TrackFile.on_site.active.count(), 4) 
     717        self.failUnlessEqual( 
     718            TrackFile.objects.active_on_site.count(), 
     719            TrackFile.on_site.active.count() 
     720        ) 
     721        trackfile2.publish = None 
     722        trackfile2.expire = future 
     723        trackfile2.save() 
     724        self.failUnlessEqual(TrackFile.objects.active.count(), 5) 
     725        self.failUnlessEqual(TrackFile.on_site.active.count(), 4) 
     726        self.failUnlessEqual( 
     727            TrackFile.objects.active_on_site.count(), 
     728            TrackFile.on_site.active.count() 
     729        ) 
     730        trackfile2.publish = future 
     731        trackfile2.expire = None 
     732        trackfile2.save() 
     733        self.failUnlessEqual(TrackFile.objects.active.count(), 4) 
     734        self.failUnlessEqual(TrackFile.on_site.active.count(), 3) 
     735        self.failUnlessEqual( 
     736            TrackFile.objects.active_on_site.count(), 
     737            TrackFile.on_site.active.count() 
     738        ) 
     739        trackfile2.publish = None 
     740        trackfile2.expire = past 
     741        trackfile2.save() 
     742        self.failUnlessEqual(TrackFile.objects.active.count(), 4) 
     743        self.failUnlessEqual(TrackFile.on_site.active.count(), 3) 
     744        self.failUnlessEqual( 
     745            TrackFile.objects.active_on_site.count(), 
     746            TrackFile.on_site.active.count() 
     747        ) 
     748        trackfile2.publish = past 
     749        trackfile2.expire = past 
     750        trackfile2.save() 
     751        self.failUnlessEqual(TrackFile.objects.active.count(), 4) 
     752        self.failUnlessEqual(TrackFile.on_site.active.count(), 3) 
     753        self.failUnlessEqual( 
     754            TrackFile.objects.active_on_site.count(), 
     755            TrackFile.on_site.active.count() 
     756        ) 
     757        trackfile2.publish = future 
     758        trackfile2.expire = future 
     759        trackfile2.save() 
     760        self.failUnlessEqual(TrackFile.objects.active.count(), 4) 
     761        self.failUnlessEqual(TrackFile.on_site.active.count(), 3) 
     762        self.failUnlessEqual( 
     763            TrackFile.objects.active_on_site.count(), 
     764            TrackFile.on_site.active.count() 
     765        ) 
     766        trackfile2.publish = None 
     767        trackfile2.expire = None 
     768        trackfile2.save() 
     769        self.failUnlessEqual(TrackFile.objects.active.count(), 5) 
     770        self.failUnlessEqual(TrackFile.on_site.active.count(), 4) 
     771        self.failUnlessEqual( 
     772            TrackFile.objects.active_on_site.count(), 
     773            TrackFile.on_site.active.count() 
     774        ) 
     775         
    698776     
    699777    def test_inactive(self): 
    700778        group_hash = TrackFile.objects.add_from_path(ALBUM1_REL) 
     779        trackfile = TrackFile.objects.filter(group_hash=group_hash)[0] 
    701780        bogus, created = TrackFile.objects.get_or_create_from_path(BOGUS_MP3_REL) 
    702781        self.failUnlessEqual(TrackFile.objects.inactive.count(), 1) 
    703782        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 1) 
     783        self.failUnlessEqual( 
     784            TrackFile.objects.inactive_on_site.count(), 
     785            TrackFile.on_site.inactive.count() 
     786        ) 
    704787        bogus.sites.clear() 
     788        self.failUnlessEqual(TrackFile.objects.inactive.count(), 1) 
    705789        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 0) 
     790        self.failUnlessEqual( 
     791            TrackFile.objects.inactive_on_site.count(), 
     792            TrackFile.on_site.inactive.count() 
     793        ) 
     794        delta = datetime.timedelta(minutes=10) 
     795        now = datetime.datetime.now() 
     796        past = now - delta 
     797        future = now + delta 
     798        trackfile.publish = past 
     799        trackfile.expire = None 
     800        trackfile.save() 
     801        self.failUnlessEqual(TrackFile.objects.inactive.count(), 1) 
     802        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 0) 
     803        self.failUnlessEqual( 
     804            TrackFile.objects.inactive_on_site.count(), 
     805            TrackFile.on_site.inactive.count() 
     806        ) 
     807        trackfile.publish = None 
     808        trackfile.expire = future 
     809        trackfile.save() 
     810        self.failUnlessEqual(TrackFile.objects.inactive.count(), 1) 
     811        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 0) 
     812        self.failUnlessEqual( 
     813            TrackFile.objects.inactive_on_site.count(), 
     814            TrackFile.on_site.inactive.count() 
     815        ) 
     816        trackfile.publish = future 
     817        trackfile.expire = None 
     818        trackfile.save() 
     819        self.failUnlessEqual(TrackFile.objects.inactive.count(), 2) 
     820        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 1) 
     821        self.failUnlessEqual( 
     822            TrackFile.objects.inactive_on_site.count(), 
     823            TrackFile.on_site.inactive.count() 
     824        ) 
     825        trackfile.publish = None 
     826        trackfile.expire = past 
     827        trackfile.save() 
     828        self.failUnlessEqual(TrackFile.objects.inactive.count(), 2) 
     829        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 1) 
     830        self.failUnlessEqual( 
     831            TrackFile.objects.inactive_on_site.count(), 
     832            TrackFile.on_site.inactive.count() 
     833        ) 
     834        trackfile.publish = past 
     835        trackfile.expire = past 
     836        trackfile.save() 
     837        self.failUnlessEqual(TrackFile.objects.inactive.count(), 2) 
     838        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 1) 
     839        self.failUnlessEqual( 
     840            TrackFile.objects.inactive_on_site.count(), 
     841            TrackFile.on_site.inactive.count() 
     842        ) 
     843        trackfile.publish = future 
     844        trackfile.expire = future 
     845        trackfile.save() 
     846        self.failUnlessEqual(TrackFile.objects.inactive.count(), 2) 
     847        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 1) 
     848        self.failUnlessEqual( 
     849            TrackFile.objects.inactive_on_site.count(), 
     850            TrackFile.on_site.inactive.count() 
     851        ) 
     852        trackfile.publish = None 
     853        trackfile.expire = None 
     854        trackfile.save() 
     855        self.failUnlessEqual(TrackFile.objects.inactive.count(), 1) 
     856        self.failUnlessEqual(TrackFile.on_site.inactive.count(), 0) 
     857        self.failUnlessEqual( 
     858            TrackFile.objects.inactive_on_site.count(), 
     859            TrackFile.on_site.inactive.count() 
     860        )  
    706861     
    707862    def test_mp3s_filter(self):