+
    à)îi“+  ã                  óª   € R t ^ RIHt ^ RIt^ RIHtHt ^ RIt^ RIH	t	 ^ RI
Ht R R ltR R	 ltR
 R ltR R ltR tR t]R8X  d
   ]! 4        R# R# )ar  
One-way sync from PartKeepr schema into parts_inventory schema.

Usage example:
  python scripts/sync_partkeepr.py     --source-host 192.168.50.5 --source-port 3306     --source-db PartKeepr --source-user partkeepr --source-password partkeepr     --target-host 192.168.50.5 --target-port 3306     --target-db parts_inventory --target-user root --target-password secret
)ÚannotationsN)ÚDictÚTuple)Ú
DictCursor)Ú_ensure_tablesc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )é   ÚhostÚstrÚportÚintÚuserÚpasswordÚdatabase© )Úformats   "Úscripts/sync_partkeepr.pyÚ__annotate__r      s/   € ÷ 	ñ 	�#ð 	˜Sð 	¨ð 	°sð 	Àcñ 	ó    c           
     óD   € \         P                  ! V VVVV\        R R7      # )F)r	   r   r   r   r   ÚcursorclassÚ
autocommit)ÚpymysqlÚconnectr   )r	   r   r   r   r   s   &&&&&r   r   r      s(   € Ü�?Š?ØØØØØÜØôð r   c               ó   € V ^8„  d   QhRR/# ©r   ÚreturnúDict[int, int]r   )r   s   "r   r   r   "   s   € ÷ (ñ (¨^ñ (r   c                ój  € / pV P                  4       ;_uu_ 4       q1P                  4       ;_uu_ 4       pVP                  R 4       VP                  4       pV FÒ  pVR,          pVP                  RV34       VP                  4       pV'       dR   VR,          W'&   TP                  RVP	                  R4      ;'       g    RVP	                  R4      VR,          34       Kˆ  TP                  RYvP	                  R4      ;'       g    RVP	                  R4      34       VP
                  W'&   KÔ  	  V FI  pVR,          pVP	                  R4      p	W',          p
VP	                  V	4      pVP                  R	Wº34       KK  	  R
R
R
4       R
R
R
4       V#   + '       g   i     L; i  + '       g   i     T# ; i)zESELECT id, parent_id, name, description FROM PartCategory ORDER BY idÚidz@SELECT id FROM categories WHERE source_partkeepr_id = %s LIMIT 1z‘
                    UPDATE categories
                    SET name = %s, description = %s
                    WHERE id = %s
                    ÚnameÚ Údescriptionz¥
                INSERT INTO categories (parent_id, source_partkeepr_id, name, description, sort_order)
                VALUES (NULL, %s, %s, %s, 0)
                Ú	parent_idz2UPDATE categories SET parent_id = %s WHERE id = %sN©ÚcursorÚexecuteÚfetchallÚfetchoneÚgetÚ	lastrowid)Úsrc_connÚdst_connÚmappingÚsrcÚdstÚrowsÚrowÚsrc_idÚhitÚ
parent_srcÚdst_idÚ
parent_dsts   &&          r   Úupsert_categoriesr7   "   sn  € Ø €GØ	�‰×	Ô	˜c§?¡?×#4Ô#4¸Ø�‰Ð[Ô\Ø�|‰|‹~ˆó ˆCØ˜•YˆFØ�K‰KÐZÐ]cÐ\eÔfØ—,‘,“.ˆCßØ"% d¥)�‘Ø—‘ðð
 —W‘W˜V“_×*Ð*¨¨C¯G©G°MÓ,BÀCÈÅIÐNôñ à�K‰Kðð Ÿ™ ›×.Ð.¨B°·±¸Ó0FÐGôð "Ÿm™mˆG‹Oñ/ ó4 ˆCØ˜•YˆFØŸ™ Ó-ˆJØ•_ˆFØ Ÿ™ ZÓ0ˆJØ�K‰KÐLÈzÐNbÖcñ ÷? $5×	ðL €N÷M $5×#4ú×	Ö	ðL €Nús1   ›F!³B	F	Â=AF	ÄA9F	Å<F!ÆFÆF!Æ!F2	c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   M   s   € ÷ ñ °Nñ r   c                óØ  € / pV P                  4       ;_uu_ 4       q1P                  4       ;_uu_ 4       pVP                  R 4       VP                  4       pV FØ  pVR,          pVP                  RV34       VP                  4       pV'       dU   VR,          W'&   TP                  RVP	                  R4      ;'       g    RRVP	                  R4       2VR,          34       K‹  TP                  RYvP	                  R4      ;'       g    RRVP	                  R4       234       VP
                  W'&   KÚ  	  R	R	R	4       R	R	R	4       V#   + '       g   i     L; i  + '       g   i     T# ; i)
z=SELECT id, category_id, name FROM StorageLocation ORDER BY idr   zGSELECT id FROM storage_locations WHERE source_partkeepr_id = %s LIMIT 1zFUPDATE storage_locations SET name = %s, description = %s WHERE id = %sr    r!   zPartKeepr category_id=Úcategory_idz¬
                INSERT INTO storage_locations (parent_id, source_partkeepr_id, name, description, sort_order)
                VALUES (NULL, %s, %s, %s, 0)
                Nr$   )	r+   r,   r-   r.   r/   r0   r1   r2   r3   s	   &&       r   Úupsert_storage_locationsr;   M   s1  € Ø €GØ	�‰×	Ô	˜c§?¡?×#4Ô#4¸Ø�‰ÐSÔTØ�|‰|‹~ˆãˆCØ˜•YˆFØ�K‰KÐaÐdjÐclÔmØ—,‘,“.ˆCßØ"% d¥)�‘Ø—‘Ø\Ø—W‘W˜V“_×*Ð*¨Ð.DÀSÇWÁWÈ]ÓE[ÐD\Ð,]Ð_bÐcgÕ_hÐiôñ à�K‰Kðð Ÿ™ ›×.Ð.¨BÐ2HÈÏÉÐQ^ÓI_ÐH`Ð0aÐbôð "Ÿm™mˆG‹Oñ' ÷	 $5×	ð2 €N÷3 $5×#4ú×	Ö	ð2 €Nús0   ›E³B	E	Â=AE	Ä-E	Ä3EÅEÅEÅE)	c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úcat_mapr   Úloc_mapr   zTuple[int, int, int]r   )r   s   "r   r   r   k   s'   € ÷ L/ñ L/¨nð L/À~ð L/ÐZnñ L/r   c                ó6  € ^ p^ p^ pV P                  4       ;_uu_ 4       qqP                  4       ;_uu_ 4       pVP                  R4       VP                  4       p	V	 EF  p
V
R,          pVP                  V
P                  R4      4      pVP                  V
P                  R4      4      p. pV
P                  R4      '       d"   VP	                  \        V
R,          4      4       V
P                  R4      '       d"   VP	                  \        V
R,          4      4       RP                  V4      P                  4       pV
P                  R4      ;'       g    R	p\        V
P                  R
4      ;'       g    ^ 4      pV
P                  R4      ;'       g    R	P                  4       pVP                  RV34       VP                  4       pV'       dH   TP                  RTTV
P                  R4      ;'       g    R	VVVVRVR,          3	4       V^,          pEK¸  TP                  RV
P                  R4      ;'       g    R	34       VP                  4       pV'       dÉ   VP                  R4      '       d
   VR,          MTpVP                  R4      R9  d
   VR,          MTpVP                  R4      '       d
   VR,          MTpVP                  R4      '       d
   VR,          MTpTP                  RTTTTT;'       g    R	TT;'       g    R	VR,          34       V^,          pEKÄ  TP                  RTTTV
P                  R4      ;'       g    R	VVVVR3	4       V^,          pEK  	  RRR4       RRR4       WEV3#   + '       g   i     L; i  + '       g   i     L'; i)é    a«  
            SELECT
              p.id,
              p.name,
              p.description,
              p.comment,
              p.internalPartNumber,
              p.stockLevel,
              p.storageLocation_id,
              p.category_id,
              p.partUnit_id,
              u.symbol AS unit_symbol
            FROM Part p
            LEFT JOIN Unit u ON p.partUnit_id = u.id
            ORDER BY p.id
            r   r:   ÚstorageLocation_idr"   Úcommentz

Úunit_symbolr!   Ú
stockLevelÚinternalPartNumberz;SELECT id FROM parts WHERE source_partkeepr_id = %s LIMIT 1a×  
                    UPDATE parts
                    SET category_id = %s,
                        storage_location_id = %s,
                        name = %s,
                        description = %s,
                        part_number = %s,
                        quantity = %s,
                        unit = %s,
                        manufacturer = %s,
                        updated_at = CURRENT_TIMESTAMP
                    WHERE id = %s
                    r    Nzö
                SELECT id, part_number, quantity, unit, description
                FROM parts
                WHERE source_partkeepr_id IS NULL
                  AND name = %s
                ORDER BY id
                LIMIT 1
                Úpart_numberÚquantityÚunita»  
                    UPDATE parts
                    SET category_id = %s,
                        storage_location_id = %s,
                        source_partkeepr_id = %s,
                        description = %s,
                        part_number = %s,
                        quantity = %s,
                        unit = %s,
                        updated_at = CURRENT_TIMESTAMP
                    WHERE id = %s
                    a`  
                INSERT INTO parts
                (
                  category_id, storage_location_id, source_partkeepr_id, name, description,
                  part_number, quantity, unit, barcode, datasheet_url, manufacturer, footprint
                )
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NULL, NULL, %s, NULL)
                )Nr@   )
r%   r&   r'   r)   Úappendr
   ÚjoinÚstripr   r(   )r+   r,   r=   r>   ÚinsertedÚupdatedÚmatched_existingr.   r/   r0   r1   r2   r:   Ústorage_location_idÚdescription_partsr"   rH   rG   rF   r3   Úexisting_name_matchÚmerged_part_numberÚmerged_quantityÚmerged_unitÚmerged_descriptions   &&&&                     r   Úupsert_partsrV   k   sU  € Ø€HØ€GØÐØ	�‰×	Ô	˜c§?¡?×#4Ô#4¸Ø�‰ðô	
ð$ �|‰|‹~ˆäˆCØ˜•YˆFØ!Ÿ+™+ c§g¡g¨mÓ&<Ó=ˆKØ")§+¡+¨c¯g©gÐ6JÓ.KÓ"LÐØ "ÐØ�w‰w�}×%Ò%Ø!×(Ñ(¬¨S°Õ-?Ó)@ÔAØ�w‰w�y×!Ò!Ø!×(Ñ(¬¨S°­^Ó)<Ô=Ø Ÿ+™+Ð&7Ó8×>Ñ>Ó@ˆKØ—7‘7˜=Ó)×/Ð/¨RˆDÜ˜3Ÿ7™7 <Ó0×5Ð5°AÓ6ˆHØŸ7™7Ð#7Ó8×>Ð>¸B×EÑEÓGˆKà�K‰KÐUÐX^ÐW`ÔaØ—,‘,“.ˆCßØ—‘ðð $Ø+ØŸ™ ›×-Ð-¨2Ø#Ø#Ø ØØØ˜D�	ð
ôð4 ˜1•�Úð �K‰Kðð —‘˜“×&Ð& BÐ(ô
ð #&§,¡,£.Ðß"ØK^×KbÑKbÐcp×KqÒKqÐ%8¸Ö%Gð  xCÐ"ØEX×E\ÑE\Ð]gÓEhÐpyÔEyÐ"5°jÖ"Að  @H�Ø=P×=TÑ=TÐU[×=\Ò=\Ð1°&Ö9Ðbf�ØK^×KbÑKbÐcp×KqÒKqÐ%8¸Ö%Gð  xCÐ"Ø—‘ðð $Ø+ØØ*Ø*×0Ð0¨bØ'Ø#×)Ð) rØ+¨DÕ1ð	ôð0 ! AÕ%Ð Úà�K‰Kðð  Ø'ØØ—G‘G˜F“O×)Ð) rØØØØØð
ôð* ˜�M‹Hñc ÷+ $5×	ðP Ð.Ð.Ð.÷Q $5×#4ú×	×	ús{   ŸN·CM5	Ã9AM5	ÅM5	Å1M5	Æ;M5	Ç%M5	Ç2AM5	È7M5	ÉM5	É.AM5	Ê1!M5	Ë#M5	Ë7M5	ÌAM5	ÍM5	Í!NÍ5NÎ NÎN	c                 óà  € \         P                  ! R R7      p V P                  RRR7       V P                  R\        RR7       V P                  RRR7       V P                  R	RR7       V P                  R
RR7       V P                  RRR7       V P                  R\        RR7       V P                  RRR7       V P                  RRR7       V P                  RRR7       V P	                  4       # )z0Sync PartKeepr data into parts_inventory schema.)r"   z--source-hostT)Úrequiredz--source-portiê  )ÚtypeÚdefaultz--source-dbz--source-userz--source-passwordz--target-hostz--target-portz--target-dbz--target-userz--target-password)ÚargparseÚArgumentParserÚadd_argumentr   Ú
parse_args)Úparsers    r   r^   r^   ú   sæ   € Ü×$Ò$Ð1cÔd€FØ
×Ñ˜°$ÐÔ7Ø
×Ñ˜¬c¸4ÐÔ@Ø
×Ñ˜°ÐÔ5Ø
×Ñ˜°$ÐÔ7Ø
×ÑÐ+°dÐÔ;Ø
×Ñ˜°$ÐÔ7Ø
×Ñ˜¬c¸4ÐÔ@Ø
×Ñ˜°ÐÔ5Ø
×Ñ˜°$ÐÔ7Ø
×ÑÐ+°dÐÔ;Ø×ÑÓÐr   c            	     óÎ  € \        4       p \        V P                  V P                  V P                  V P
                  V P                  4      p\        V P                  V P                  V P                  V P                  V P                  4      p \        V4       \        W4      p\        W4      p\        WW44      w  rVpVP!                  4        \#        R R\%        V4       2R\%        V4       2RV 2RV 2RV 24        TP+                  4        TP+                  4        R#   \&         d    TP)                  4        h i ; i  TP+                  4        TP+                  4        i ; i)zSync complete:zcategories=zstorage_locations=zparts_inserted=zparts_updated=zparts_matched_existing=N)r^   r   Úsource_hostÚsource_portÚsource_userÚsource_passwordÚ	source_dbÚtarget_hostÚtarget_portÚtarget_userÚtarget_passwordÚ	target_dbr   r7   r;   rV   ÚcommitÚprintÚlenÚ	ExceptionÚrollbackÚclose)Úargsr+   r,   r=   r>   rL   rM   rN   s           r   Úmainrr   	  s<  € Ü‹<€DÜ�t×'Ñ'¨×)9Ñ)9¸4×;KÑ;KÈT×MaÑMaÐcg×cqÑcqÓr€HÜ�t×'Ñ'¨×)9Ñ)9¸4×;KÑ;KÈT×MaÑMaÐcg×cqÑcqÓr€HðÜ�xÔ Ü# HÓ7ˆÜ*¨8Ó>ˆÜ.:¸8ÈwÓ.`Ñ+ˆÐ+Ø�‰ÔÜØØœ#˜g›,˜Ð(Ø ¤ W£ Ð/Ø˜h˜ZÐ(Ø˜W˜IÐ&Ø%Ð&6Ð%7Ð8õ	
ð 	�‰ÔØ�‰Öøô ô Ø×ÑÔØðûð 	�‰ÔØ�‰Õús   ÂA1D" Ä"D?Ä?E Å"E$Ú__main__)Ú__doc__Ú
__future__r   r[   Útypingr   r   r   Úpymysql.cursorsr   Úblueprints.partsinventoryr   r   r7   r;   rV   r^   rr   Ú__name__r   r   r   Ú<module>rz      sS   ðñ	õ #ã ß ã Ý &å 4õ	õ(õVõ<L/ò^òð6 ˆzÔÙ†Fñ r   