<s> from __future__ import unicode_literals <EOL> from django . utils . six import with_metaclass <EOL> from moderation . models import ModeratedObject , MODERATION_STATUS_PENDING , MODERATION_STATUS_APPROVED , MODERATION_DRAFT_STATE <EOL> from django . core . exceptions import ObjectDoesNotExist <EOL> from django import VERSION <EOL> if VERSION >= ( <NUM_LIT:1> , <NUM_LIT:8> ) : <EOL> from django . contrib . contenttypes . fields import GenericRelation <EOL> else : <EOL> from django . contrib . contenttypes . generic import GenericRelation <EOL> from moderation . moderator import GenericModerator <EOL> class RegistrationError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class ModerationManagerSingleton ( type ) : <EOL> def __init__ ( cls , name , bases , dict ) : <EOL> super ( ModerationManagerSingleton , cls ) . __init__ ( name , bases , dict ) <EOL> cls . instance = None <EOL> def __call__ ( cls , * args , ** kw ) : <EOL> if cls . instance is None : <EOL> cls . instance = super ( ModerationManagerSingleton , cls ) . __call__ ( * args , ** kw ) <EOL> return cls . instance <EOL> class ModerationManager ( with_metaclass ( ModerationManagerSingleton , object ) ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . _registered_models = { } <EOL> super ( ModerationManager , self ) . __init__ ( * args , ** kwargs ) <EOL> def register ( self , model_class , moderator_class = None ) : <EOL> """<STR_LIT>""" <EOL> if model_class in self . _registered_models : <EOL> msg = "<STR_LIT>" % model_class <EOL> raise RegistrationError ( msg ) <EOL> if not moderator_class : <EOL> moderator_class = GenericModerator <EOL> if not issubclass ( moderator_class , GenericModerator ) : <EOL> msg = '<STR_LIT>' '<STR_LIT>' % moderator_class <EOL> raise AttributeError ( msg ) <EOL> self . _registered_models [ model_class ] = moderator_class ( model_class ) <EOL> self . _and_fields_to_model_class ( self . _registered_models [ model_class ] ) <EOL> self . _connect_signals ( model_class ) <EOL> def _connect_signals ( self , model_class ) : <EOL> from django . db . models import signals <EOL> signals . pre_save . connect ( self . pre_save_handler , <EOL> sender = model_class ) <EOL> signals . post_save . connect ( self . post_save_handler , <EOL> sender = model_class ) <EOL> def _add_moderated_object_to_class ( self , model_class ) : <EOL> if hasattr ( model_class , '<STR_LIT>' ) : <EOL> relation_object = getattr ( model_class , '<STR_LIT>' ) <EOL> else : <EOL> relation_object = GenericRelation ( <EOL> ModeratedObject , <EOL> object_id_field = '<STR_LIT>' ) <EOL> model_class . add_to_class ( '<STR_LIT>' , relation_object ) <EOL> def get_moderated_object ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> if self . _relation_object . count ( ) > <NUM_LIT:0> : <EOL> self . _moderated_object = getattr ( self , '<STR_LIT>' ) . filter ( ) . order_by ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> else : <EOL> self . _moderated_object = getattr ( self , '<STR_LIT>' ) . get ( ) <EOL> return self . _moderated_object <EOL> model_class . add_to_class ( '<STR_LIT>' , <EOL> property ( get_moderated_object ) ) <EOL> def _and_fields_to_model_class ( self , moderator_class_instance ) : <EOL> """<STR_LIT>""" <EOL> model_class = moderator_class_instance . model_class <EOL> base_managers = moderator_class_instance . base_managers <EOL> moderation_manager_class = moderator_class_instance . moderation_manager_class <EOL> for manager_name , mgr_class in base_managers : <EOL> ModerationObjectsManager = moderation_manager_class ( ) ( mgr_class ) <EOL> manager = ModerationObjectsManager ( ) <EOL> model_class . add_to_class ( '<STR_LIT>' % manager_name , <EOL> mgr_class ( ) ) <EOL> model_class . add_to_class ( manager_name , manager ) <EOL> self . _add_moderated_object_to_class ( model_class ) <EOL> def unregister ( self , model_class ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> moderator_instance = self . _registered_models . pop ( model_class ) <EOL> except KeyError : <EOL> msg = "<STR_LIT>" % model_class <EOL> raise RegistrationError ( msg ) <EOL> self . _remove_fields ( moderator_instance ) <EOL> self . _disconnect_signals ( model_class ) <EOL> def _remove_fields ( self , moderator_class_instance ) : <EOL> """<STR_LIT>""" <EOL> model_class = moderator_class_instance . model_class <EOL> base_managers = moderator_class_instance . base_managers <EOL> for manager_name , manager_class in base_managers : <EOL> manager = manager_class ( ) <EOL> delattr ( model_class , '<STR_LIT>' % manager_name ) <EOL> model_class . add_to_class ( manager_name , manager ) <EOL> delattr ( model_class , '<STR_LIT>' ) <EOL> def _disconnect_signals ( self , model_class ) : <EOL> from django . db . models import signals <EOL> signals . pre_save . disconnect ( self . pre_save_handler , model_class ) <EOL> signals . post_save . disconnect ( self . post_save_handler , model_class ) <EOL> def pre_save_handler ( self , sender , instance , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if kwargs [ '<STR_LIT>' ] : <EOL> return <EOL> unchanged_obj = self . _get_unchanged_object ( instance ) <EOL> moderator = self . get_moderator ( sender ) <EOL> if unchanged_obj : <EOL> moderated_obj = self . _get_or_create_moderated_object ( instance , <EOL> unchanged_obj , <EOL> moderator ) <EOL> if moderated_obj . moderation_status != MODERATION_STATUS_APPROVED and not moderator . bypass_moderation_after_approval : <EOL> moderated_obj . save ( ) <EOL> def _get_unchanged_object ( self , instance ) : <EOL> if instance . pk is None : <EOL> return None <EOL> pk = instance . pk <EOL> try : <EOL> unchanged_obj = instance . __class__ . _default_manager . get ( pk = pk ) <EOL> return unchanged_obj <EOL> except ObjectDoesNotExist : <EOL> return None <EOL> def _get_or_create_moderated_object ( self , instance , <EOL> unchanged_obj , moderator ) : <EOL> """<STR_LIT>""" <EOL> def get_new_instance ( unchanged_obj ) : <EOL> moderated_object = ModeratedObject ( content_object = unchanged_obj ) <EOL> moderated_object . changed_object = unchanged_obj <EOL> return moderated_object <EOL> try : <EOL> moderated_object = ModeratedObject . objects . get_for_instance ( <EOL> instance ) <EOL> if moderated_object is None : <EOL> moderated_object = get_new_instance ( unchanged_obj ) <EOL> elif moderator . keep_history and moderated_object . has_object_been_changed ( <EOL> instance ) : <EOL> moderated_object = get_new_instance ( unchanged_obj ) <EOL> except ObjectDoesNotExist : <EOL> moderated_object = get_new_instance ( unchanged_obj ) <EOL> else : <EOL> if moderated_object . has_object_been_changed ( instance ) : <EOL> if moderator . visible_until_rejected : <EOL> moderated_object . changed_object = instance <EOL> else : <EOL> moderated_object . changed_object = unchanged_obj <EOL> return moderated_object <EOL> def get_moderator ( self , model_class ) : <EOL> try : <EOL> moderator_instance = self . _registered_models [ model_class ] <EOL> except KeyError : <EOL> msg = "<STR_LIT>" % model_class <EOL> raise RegistrationError ( msg ) <EOL> return moderator_instance <EOL> def post_save_handler ( self , sender , instance , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if kwargs [ '<STR_LIT>' ] : <EOL> return <EOL> pk = instance . pk <EOL> moderator = self . get_moderator ( sender ) <EOL> if kwargs [ '<STR_LIT>' ] : <EOL> old_object = sender . _default_manager . get ( pk = pk ) <EOL> moderated_obj = ModeratedObject ( content_object = old_object ) <EOL> if not moderator . visible_until_rejected : <EOL> moderated_obj . moderation_state = MODERATION_DRAFT_STATE <EOL> moderated_obj . save ( ) <EOL> moderator . inform_moderator ( instance ) <EOL> return <EOL> moderated_obj = ModeratedObject . objects . get_for_instance ( instance ) <EOL> if ( moderated_obj . moderation_status == MODERATION_STATUS_APPROVED and <EOL> moderator . bypass_moderation_after_approval ) : <EOL> moderated_obj . changed_object = instance <EOL> moderated_obj . save ( ) <EOL> return <EOL> if moderated_obj . has_object_been_changed ( instance ) : <EOL> copied_instance = self . _copy_model_instance ( instance ) <EOL> if not moderator . visible_until_rejected : <EOL> moderated_obj . changed_object . save_base ( raw = True ) <EOL> moderated_obj . changed_object = copied_instance <EOL> moderated_obj . moderation_status = MODERATION_STATUS_PENDING <EOL> moderated_obj . save ( ) <EOL> moderator . inform_moderator ( instance ) <EOL> instance . _moderated_object = moderated_obj <EOL> def _copy_model_instance ( self , obj ) : <EOL> initial = dict ( <EOL> [ ( f . name , getattr ( obj , f . name ) ) for f in obj . _meta . fields ] ) <EOL> return obj . __class__ ( ** initial ) </s>
