<s> import gc <EOL> import os <EOL> import time <EOL> from datetime import datetime , date , timedelta <EOL> from optparse import make_option <EOL> from django . core . files . storage import get_storage_class <EOL> from django . core . management . base import BaseCommand <EOL> from easy_thumbnails . conf import settings <EOL> from easy_thumbnails . models import Source <EOL> class ThumbnailCollectionCleaner ( object ) : <EOL> """<STR_LIT>""" <EOL> sources = <NUM_LIT:0> <EOL> thumbnails = <NUM_LIT:0> <EOL> thumbnails_deleted = <NUM_LIT:0> <EOL> source_refs_deleted = <NUM_LIT:0> <EOL> execution_time = <NUM_LIT:0> <EOL> def _get_absolute_path ( self , path ) : <EOL> return os . path . join ( settings . MEDIA_ROOT , path ) <EOL> def _get_relative_path ( self , path ) : <EOL> return os . path . relpath ( path , settings . MEDIA_ROOT ) <EOL> def _check_if_exists ( self , storage , path ) : <EOL> try : <EOL> return storage . exists ( path ) <EOL> except Exception as e : <EOL> print ( "<STR_LIT>" % path ) <EOL> print ( str ( e ) ) <EOL> def _delete_sources_by_id ( self , ids ) : <EOL> Source . objects . all ( ) . filter ( id__in = ids ) . delete ( ) <EOL> def clean_up ( self , dry_run = False , verbosity = <NUM_LIT:1> , last_n_days = <NUM_LIT:0> , <EOL> cleanup_path = None , storage = None ) : <EOL> """<STR_LIT>""" <EOL> if dry_run : <EOL> print ( "<STR_LIT>" ) <EOL> if not storage : <EOL> storage = get_storage_class ( settings . THUMBNAIL_DEFAULT_STORAGE ) ( ) <EOL> sources_to_delete = [ ] <EOL> time_start = time . time ( ) <EOL> query = Source . objects . all ( ) <EOL> if last_n_days > <NUM_LIT:0> : <EOL> today = date . today ( ) <EOL> query = query . filter ( <EOL> modified__range = ( today - timedelta ( days = last_n_days ) , today ) ) <EOL> if cleanup_path : <EOL> query = query . filter ( name__startswith = cleanup_path ) <EOL> for source in queryset_iterator ( query ) : <EOL> self . sources += <NUM_LIT:1> <EOL> abs_source_path = self . _get_absolute_path ( source . name ) <EOL> if not self . _check_if_exists ( storage , abs_source_path ) : <EOL> if verbosity > <NUM_LIT:0> : <EOL> print ( "<STR_LIT>" , abs_source_path ) <EOL> self . source_refs_deleted += <NUM_LIT:1> <EOL> sources_to_delete . append ( source . id ) <EOL> for thumb in source . thumbnails . all ( ) : <EOL> self . thumbnails_deleted += <NUM_LIT:1> <EOL> abs_thumbnail_path = self . _get_absolute_path ( thumb . name ) <EOL> if self . _check_if_exists ( storage , abs_thumbnail_path ) : <EOL> if not dry_run : <EOL> storage . delete ( abs_thumbnail_path ) <EOL> if verbosity > <NUM_LIT:0> : <EOL> print ( "<STR_LIT>" , abs_thumbnail_path ) <EOL> if len ( sources_to_delete ) >= <NUM_LIT:1000> and not dry_run : <EOL> self . _delete_sources_by_id ( sources_to_delete ) <EOL> sources_to_delete = [ ] <EOL> if not dry_run : <EOL> self . _delete_sources_by_id ( sources_to_delete ) <EOL> self . execution_time = round ( time . time ( ) - time_start ) <EOL> def print_stats ( self ) : <EOL> """<STR_LIT>""" <EOL> print ( <EOL> "<STR_LIT>" . format ( str ( datetime . now ( ) . strftime ( '<STR_LIT>' ) ) ) ) <EOL> print ( "<STR_LIT>" . format ( "<STR_LIT>" , self . sources ) ) <EOL> print ( "<STR_LIT>" . format ( <EOL> "<STR_LIT>" , self . source_refs_deleted ) ) <EOL> print ( "<STR_LIT>" . format ( "<STR_LIT>" , <EOL> self . thumbnails_deleted ) ) <EOL> print ( "<STR_LIT>" % self . execution_time ) <EOL> def queryset_iterator ( queryset , chunksize = <NUM_LIT:1000> ) : <EOL> """<STR_LIT>""" <EOL> primary_key = <NUM_LIT:0> <EOL> last_pk = queryset . order_by ( '<STR_LIT>' ) [ <NUM_LIT:0> ] . pk <EOL> queryset = queryset . order_by ( '<STR_LIT>' ) <EOL> while primary_key < last_pk : <EOL> for row in queryset . filter ( pk__gt = primary_key ) [ : chunksize ] : <EOL> primary_key = row . pk <EOL> yield row <EOL> gc . collect ( ) <EOL> class Command ( BaseCommand ) : <EOL> help = """<STR_LIT>""" <EOL> option_list = BaseCommand . option_list + ( <EOL> make_option ( <EOL> '<STR_LIT>' , <EOL> action = '<STR_LIT:store_true>' , <EOL> dest = '<STR_LIT>' , <EOL> default = False , <EOL> help = '<STR_LIT>' ) , <EOL> make_option ( <EOL> '<STR_LIT>' , <EOL> action = '<STR_LIT:store>' , <EOL> dest = '<STR_LIT>' , <EOL> default = <NUM_LIT:0> , <EOL> type = '<STR_LIT:int>' , <EOL> help = '<STR_LIT>' ) , <EOL> make_option ( <EOL> '<STR_LIT>' , <EOL> action = '<STR_LIT:store>' , <EOL> dest = '<STR_LIT>' , <EOL> type = '<STR_LIT:string>' , <EOL> help = '<STR_LIT>' ) , <EOL> ) <EOL> def handle ( self , * args , ** options ) : <EOL> tcc = ThumbnailCollectionCleaner ( ) <EOL> tcc . clean_up ( <EOL> dry_run = options . get ( '<STR_LIT>' , False ) , <EOL> verbosity = int ( options . get ( '<STR_LIT>' , <NUM_LIT:1> ) ) , <EOL> last_n_days = int ( options . get ( '<STR_LIT>' , <NUM_LIT:0> ) ) , <EOL> cleanup_path = options . get ( '<STR_LIT>' ) ) <EOL> tcc . print_stats ( ) </s>
