<s> import re <EOL> from django . db import models <EOL> from django . db . models import signals , Max <EOL> from django . db . models . fields import TextField <EOL> import oembed <EOL> from oembed . constants import URL_RE <EOL> from oembed . exceptions import OEmbedMissingEndpoint <EOL> from oembed . models import AggregateMedia <EOL> class FieldRegistry ( object ) : <EOL> """<STR_LIT>""" <EOL> _registry = { } <EOL> @ classmethod <EOL> def add_field ( cls , model , field ) : <EOL> reg = cls . _registry . setdefault ( model , [ ] ) <EOL> reg . append ( field ) <EOL> @ classmethod <EOL> def get_fields ( cls , model ) : <EOL> return cls . _registry . get ( model , [ ] ) <EOL> @ classmethod <EOL> def __contains__ ( cls , model ) : <EOL> return model in cls . _registry <EOL> class EmbeddedSignalCreator ( object ) : <EOL> def __init__ ( self , field ) : <EOL> self . field = field <EOL> self . name = '<STR_LIT>' % self . field . name <EOL> def contribute_to_class ( self , cls , name ) : <EOL> register_field ( cls , self . field ) <EOL> class EmbeddedMediaField ( models . ManyToManyField ) : <EOL> def __init__ ( self , media_type = None , to = None , ** kwargs ) : <EOL> if media_type and not isinstance ( media_type , ( basestring , list ) ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> elif isinstance ( media_type , basestring ) : <EOL> media_type = [ media_type ] <EOL> self . media_type = media_type <EOL> super ( EmbeddedMediaField , self ) . __init__ ( AggregateMedia , ** kwargs ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> """<STR_LIT>""" <EOL> super ( EmbeddedMediaField , self ) . contribute_to_class ( cls , name ) <EOL> register_field ( cls , self ) <EOL> cls . _meta . add_virtual_field ( EmbeddedSignalCreator ( self ) ) <EOL> def register_field ( cls , field ) : <EOL> """<STR_LIT>""" <EOL> FieldRegistry . add_field ( cls , field ) <EOL> signals . post_save . connect ( handle_save_embeds , sender = cls , <EOL> dispatch_uid = '<STR_LIT>' % ( cls . _meta . app_label , cls . _meta . module_name , field . name ) ) <EOL> def handle_save_embeds ( sender , instance , ** kwargs ) : <EOL> embedded_media_fields = FieldRegistry . get_fields ( sender ) <EOL> if not embedded_media_fields : <EOL> return <EOL> urls = [ ] <EOL> for field in instance . _meta . fields : <EOL> if isinstance ( field , TextField ) : <EOL> urls . extend ( re . findall ( URL_RE , getattr ( instance , field . name ) ) ) <EOL> urls = set ( urls ) <EOL> for embedded_field in embedded_media_fields : <EOL> m2m = getattr ( instance , embedded_field . name ) <EOL> m2m . clear ( ) <EOL> for url in urls : <EOL> try : <EOL> provider = oembed . site . provider_for_url ( url ) <EOL> except OEmbedMissingEndpoint : <EOL> pass <EOL> else : <EOL> if not embedded_field . media_type or provider . resource_type in embedded_field . media_type : <EOL> media_obj , created = AggregateMedia . objects . get_or_create ( url = url ) <EOL> m2m . add ( media_obj ) <EOL> try : <EOL> from south . modelsinspector import add_introspection_rules <EOL> add_introspection_rules ( [ <EOL> ( <EOL> [ EmbeddedMediaField ] , <EOL> [ ] , <EOL> { <EOL> "<STR_LIT>" : [ "<STR_LIT>" , { } ] , <EOL> } , <EOL> ) , <EOL> ] , [ "<STR_LIT>" ] ) <EOL> except ImportError : <EOL> pass </s>
