
    fJ:                     D   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ  G d d      Z G d	 d
e      Z G d de      Z G d de      Z G d de      Z G d d      Z G d d      Z G d dee      Z G d dee      Z G d dee      Z G d dee      Zy)    N)models)settings)HttpRequest)serializers)AppliedSeederc                   H    e Zd ZdZd ZddefdZd Zd Zd Z	d	 Z
d
 Zd Zy)Seedera   
    The `Seeder` class provides a minimal class which may be used
    for writing custom seeding implementations.
    
    Required:
        seed:
            `seed()` as <method>

    Additionals:
        priority:
            `priority` as <class attribute>
            or
            `get_priority()` as <method>

        just_debug:
            `just_debug` as <class attribute>
            or
            `get_just_debug()` as <method>:
    c                     t        d      )z) Method that fill the datebase as wanted z`seed()` must be implemented.)NotImplementedErrorselfs    j/var/www/teaching_timetable/msuas_timetable/my_venv/lib/python3.12/site-packages/django_seeding/seeders.pyseedzSeeder.seed   s    !"ABB    Ndebugc                    |t         j                  }| j                         r|sy| j                         }t        j
                  j                  |      j                         ryd}d}d}t        | d| d| d	       | j                          t        j
                  j                  |       t        | d
|        y)zK Inner method that do validation before calling the public `seed()` method N)idz[35mz[32mz[0mz
  Seeding z... )endzSuccessfully ^_^)r   DEBUG_get_just_debug_get_idr   objectsfilterexistsprintr   create)r   r   r   PURPLE_COLORGREEN_COLORWHITE_COLORs         r   _seedzSeeder._seed"   s     =NNE !%\\^   ''2'.557! jC}=2F 			 	$$$+-k];<r   c                 .    t        | dt        d            S )z 
        Method return the `priority` value (smaller will be applied earlier)
        
        if `priority` is passed:
            it will be returned

        if `priority` is not passed:
            float(inf) will be returned 
        priorityinf)getattrfloatr   s    r   get_priorityzSeeder.get_priority@   s     tZu66r   c                 |    | j                         }t        |t              st        |t              st	        d      |S )zI Innder method to validate the value returned by `get_priority()` method z`priority` must be a number)r'   
isinstancer&   int	TypeError)r   r#   s     r   _get_priorityzSeeder._get_priorityL   s4    $$&(E*:h3L9::r   c                     t        | dd      S )a1   
        Method return the `just_debug` value 
        
        just_debug=True means this seeder will be applied just when settings.DEBUG=True
        
        if `just_debug` is passed:
            it will be returned

        if `just_debug` is not passed:
            False will be returned 
        
just_debugF)r%   r   s    r   get_just_debugzSeeder.get_just_debugU   s     t\511r   c                 \    | j                         }t        |t              st        d      |S )zK Innder method to validate the value returned by `get_just_debug()` method z!`just_debug` must be a bool value)r/   r)   boolr+   )r   r.   s     r   r   zSeeder._get_just_debugc   s,    ((*
*d+?@@r   c           	      @    t        | dt        t        |                   S )a   
        Method return the `id` value to be stored in the database `AppliedSeeder` table

        Note: by this id value we can check if this seeder is applied before or not
        
        it is preferred to not change the id 
        because after changing thd id the seeder will be considerd as another seeder
        then it will be apllied even that the old seeder is applied with the old id value

        default value is the name of the class -> str(type(self))

        Note:
        if you changed the class name 
        or changed the seeder-class file name
        or and file in the path from the root to the class the str(type(self)) will return another value
        then the default value of this seeder is changed
        then if it doesnt have a constant id the seeder will be applied again
        and it may cause errors

        so:
        give an `id` class attribute to solv this problem
        r   )r%   strtyper   s    r   get_idzSeeder.get_idl   s    . tT3tDz?33r   c                 \    | j                         }t        |t              st        d      |S )zC Innder method to validate the value returned by `get_id()` method z`id` must be str)r5   r)   r3   r+   )r   r   s     r   r   zSeeder._get_id   s(    [[]"c".//	r   N)__name__
__module____qualname____doc__r   r1   r!   r'   r,   r/   r   r5   r    r   r   r	   r	   
   s7    &C=4 =<
7242r   r	   c                       e Zd ZdZd Zd Zy)
DataSeederz
    The `DataSeeder` class provides a minimal class which may be used
    for writing custom seeding implementations.
    
    Required:
        data:
            `data` as <class attribute>
            or
            `get_data()` as <method>
    c                 :    t        | dd      }|t        d      |S )z. Method return the `data` that will be seeded dataNzVsubclasses of `DataSeeder` must have `data` class attribute or the `get_data()` methodr%   r+   )r   r@   s     r   get_datazDataSeeder.get_data   s&    tVT*<tuur   c                     | j                         }d}t        |t              st        |      |D ]  }t        |t              rt        |       |S )zE Innder method to validate the value returned by `get_data()` method z`data` must be list of dict)rB   r)   listr+   dict)r   r@   error_messagerecord_datas       r   	_get_datazDataSeeder._get_data   sR    }}5$%M** 	/Kk40..	/ r   N)r8   r9   r:   r;   rB   rH   r<   r   r   r>   r>      s    	r   r>   c                   "    e Zd ZdZd Zd Zd Zy)ModelSeedera  
    The `ModelSeeder` class  is a subclasse of `DataSeeder` needs `model` and provides fast `seed()` implementation with `bulk_create()` method.
    
    Required:
        model:
            `model` as <class attribute>
            or
            `get_model()` as <method>
    c                 :    t        | dd      }|t        d      |S )z/ Method return the `model` that will be seeded modelNzYsubclasses of `ModelSeeder` must have `model` class attribute or the `get_model()` methodrA   r   rL   s     r   	get_modelzModelSeeder.get_model   s&    gt,=wxxr   c                     | j                         }t        |t              rt        |t        j
                        st        d      |S )zF Innder method to validate the value returned by `get_model()` method z7`model` must be a subclasse of `django.db.models.Model`)rN   r)   r4   
issubclassr   Modelr+   rM   s     r   
_get_modelzModelSeeder._get_model   s6     %&j.MUVVr   c                     | j                         }| j                         }|D cg c]
  } |di | }}|j                  j                  |       yc c}w )zA Standard Implementation of `seed()` method with `bulk_create()` Nr<   )rH   rR   r   bulk_create)r   r@   rL   rG   new_objectss        r   r   zModelSeeder.seed   sM    ~~!?CDu+{+DD!!+. Es   AN)r8   r9   r:   r;   rN   rR   r   r<   r   r   rJ   rJ      s    /r   rJ   c                   "    e Zd ZdZd Zd Zd Zy)SerializerSeedera  
    The `SerializerSeeder` class  is a subclasse of `DataSeeder` needs `serializer_class` and provides slow `seed()` implementation.

    Note: this class is slow not like `ModelSeeder`, so if you have a big dataset dont use this class
    
    Required:
        serializer_class:
            `serializer_class` as <class attribute>
            or
            `get_serializer_class()` as <method>
    c                 :    t        | dd      }|t        d      |S )zC Method return the `serializer_class` that will be used in seeding serializer_classNzlsubclasses of SerializerSeeder must have serializer_class class attribute or the get_serializer_class methodrA   r   rY   s     r   get_serializer_classz%SerializerSeeder.get_serializer_class   s3    "4);TB#  K  L  Lr   c                     | j                         }t        |t              rt        |t        j
                        st        d      |S )zQ Innder method to validate the value returned by `get_serializer_class()` method zMserializer_class must be a subclasse of rest_framework.serializers.Serializer)r[   r)   r4   rP   r   
Serializerr+   rZ   s     r   _get_serializer_classz&SerializerSeeder._get_serializer_class   s?    446*D1DTVaVlVl9mkllr   c                     | j                         }| j                         }|D ]A  }t               }d|_         ||d|i      }|j	                  d       |j                          C y)zY Slow Implementation of `seed()` method with `serializer.save()` method for every record Nrequest)r@   contextT)raise_exception)rH   r^   r   useris_validsave)r   r@   rY   rG   r`   
serializers         r   r   zSerializerSeeder.seed   sg    ~~557 	K!mGGL){YPWDXYJ5OO	r   N)r8   r9   r:   r;   r[   r^   r   r<   r   r   rW   rW      s    
  	r   rW   c                   "    e Zd ZdZd Zd Zd Zy)EmptySeedera6  
    The `EmptySeeder` class is a subclasse of `ModelSeeder` needs `records_count` and provides fast `seed()` implementation with `bulk_create()` method.
    
    Required:
        records_count:
            `records_count` as <class attribute>
            or
            `get_records_count()` as <method>
    c                 :    t        | dd      }|t        d      |S )z@ Method return the `records_count` that will be used in seeding records_countNzasubclasses of EmptySeeder must have records_count class attribute or the get_records_count methodrA   r   rj   s     r   get_records_countzEmptySeeder.get_records_count  s.    ot<   A  Ar   c                 \    | j                         }t        |t              st        d      |S )zN Innder method to validate the value returned by `get_records_count()` method zrecords_count must be int)rl   r)   r*   r+   rk   s     r   _get_records_countzEmptySeeder._get_records_count  s,    ..0--788r   c                     | j                         }| j                         fdt        |      D        }j                  j	                  |       y)zS Standard Implementation of `seed()` method for empty objects with `bulk_create()` c              3   ,   K   | ]  }          y wr7   r<   ).0_rL   s     r   	<genexpr>z#EmptySeeder.seed.<locals>.<genexpr>!  s     =1uw=s   N)rn   rR   ranger   rT   )r   rj   rU   rL   s      @r   r   zEmptySeeder.seed  s>    //1!=m(<=!!+.r   N)r8   r9   r:   r;   rl   rn   r   r<   r   r   rh   rh     s    /r   rh   c                   "    e Zd ZdZd Zd Zd Zy)CSVFileReaderz
    The `CSVFileReader` class needs `csv_file_path` and provides `get_data()` implementation.
    
    Required:
        csv_file_path:
            `csv_file_path` as <class attribute>
            or
            `get_csv_file_path()` as <method>
    c                 :    t        | dd      }|t        d      |S )z[ Method return the `csv_file_path` that will be used in `get_date()` method implementation csv_file_pathNzksubclasses of `CSVFileReader` must have `csv_file_path` class attribute or the `get_csv_file_path()` methodrA   r   rx   s     r   get_csv_file_pathzCSVFileReader.get_csv_file_path/  s1    ot<   J  K  Kr   c                 \    | j                         }t        |t              st        d      |S )zN Innder method to validate the value returned by `get_csv_file_path()` method z`csv_file_path` must be str)rz   r)   r3   r+   ry   s     r   _get_csv_file_pathz CSVFileReader._get_csv_file_path8  s,    ..0--9::r   c                     g }| j                         }t        j                  |      }|j                         D ]5  \  }}i }|j	                         D ]
  \  }}|||<    |j                  |       7 |S )zx Method (using pandas) read the csv_file that is specified by `csv_file_path` and return the `data` that will be seeded )r|   pandasread_csviterrowsitemsappend)	r   r@   rx   pandas_filerr   rowrG   keyvalues	            r   rB   zCSVFileReader.get_dataA  sz    //1oom4!**, 	%FAsK!iik )
U#(C )KK$		%
 r   N)r8   r9   r:   r;   rz   r|   rB   r<   r   r   rv   rv   %  s    
r   rv   c                   "    e Zd ZdZd Zd Zd Zy)JSONFileReadera   
    The `JSONFileReader` class needs `json_file_path` and provides `get_data()` implementation.
    
    Required:
        json_file_path:
            `json_file_path` as <class attribute>
            or
            `get_json_file_path()` as <method>
    c                 :    t        | dd      }|t        d      |S )z\ Method return the `json_file_path` that will be used in `get_date()` method implementation json_file_pathNznsubclasses of `JSONFileReader` must have `json_file_path` class attribute or the `get_json_file_path()` methodrA   r   r   s     r   get_json_file_pathz!JSONFileReader.get_json_file_pathX  s2     '7>!  M  N  Nr   c                 \    | j                         }t        |t              st        d      |S )zO Innder method to validate the value returned by `get_json_file_path()` method z`json_file_path` must be str)r   r)   r3   r+   r   s     r   _get_json_file_pathz"JSONFileReader._get_json_file_patha  s,    002.#.:;;r   c                     | j                         }t        |dd      5 }t        j                  |      }|cddd       S # 1 sw Y   yxY w)zk Method read the json_file that is specified by `json_file_path` and return the `data` that will be seeded rzutf-8)encodingN)r   openjsonload)r   r   filer@   s       r   rB   zJSONFileReader.get_dataj  sC    113.#8 	D99T?D	 	 	s   A  A	N)r8   r9   r:   r;   r   r   rB   r<   r   r   r   r   N  s    r   r   c                       e Zd ZdZy)CSVFileModelSeedera  
    The `CSVFileModelSeeder` class is a Fast Full implemented class that needs `csv_file_path`, 'model` and provides `seed()` implementation.
    
    Required:
        csv_file_path:
            `csv_file_path` as <class attribute>
            or
            `get_csv_file_path()` as <method>

        model:
            `model` as <class attribute>
            or
            `get_model()` as <method>
    Nr8   r9   r:   r;   r<   r   r   r   r   r       	r   r   c                       e Zd ZdZy)CSVFileSerializerSeedera  
    The `CSVFileSerializerSeeder` class is a Slow Full implemented class that needs `csv_file_path`, 'serializer_class` and provides `seed()` implementation.
    
    Required:
        csv_file_path:
            `csv_file_path` as <class attribute>
            or
            `get_csv_file_path()` as <method>

        serializer_class:
            `serializer_class` as <class attribute>
            or
            `get_serializer_class()` as <method>
    Nr   r<   r   r   r   r     r   r   r   c                       e Zd ZdZy)JSONFileModelSeedera  
    The `JSONFileModelSeeder` class is a Fast Full implemented class that needs `json_file_path`, 'model` and provides `seed()` implementation.
    
    Required:
        json_file_path:
            `json_file_path` as <class attribute>
            or
            `get_json_file_path()` as <method>

        model:
            `model` as <class attribute>
            or
            `get_model()` as <method>
    Nr   r<   r   r   r   r     r   r   r   c                       e Zd ZdZy)JSONFileSerializerSeedera  
    The `JSONFileSerializerSeeder` class is a Slow Full implemented class that needs `json_file_path`, 'serializer_class` and provides `seed()` implementation.
    
    Required:
        json_file_path:
            `json_file_path` as <class attribute>
            or
            `get_json_file_path()` as <method>

        serializer_class:
            `serializer_class` as <class attribute>
            or
            `get_serializer_class()` as <method>
    Nr   r<   r   r   r   r     r   r   r   )r~   r   	django.dbr   django.confr   django.httpr   rest_frameworkr   django_seeding.modelsr   r	   r>   rJ   rW   rh   rv   r   r   r   r   r   r<   r   r   <module>r      s         # & /B BJ! !H!/* !/H'z 'T!/+ !/H& &R! !H	 	$	m-= 	$	.+ 	$	~/? 	r   