
    7jR/                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
mZmZmZmZmZ ddlmZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZ ddlm Z m!Z! e G d d             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'de(de(de(dee#   fdZ)de(fdZ*d Z+ejX                  d        Z-dee"   fd Z.d! Z/d"e"de"fd#Z0d$eee(ee(ee(e(f   f   f      dee"   fd%Z1d1d"e"d&ee(   dee"   fd'Z2d$ee"   dee"   fd(Z3d)e"fd*Z4g fd+ee"   d,ee(   dee"   fd-Z5d.gg fd$eeee(e(f   ee(e(ee(e(f   f   f      d,ee(   dee!   fd/Z6g fd$eee(ee(ee(e(f   f   f      d,ee(   dee!   fd0Z7y)2z;Functions for searching through QMK keyboards and keymaps.
    )	dataclassN)CallableDictListOptionalTupleUnion)dottyDotty)cli)parallel_map)keymap_json)list_keyboardskeyboard_folder)list_keymapslocate_keymap)KeyboardKeymapBuildTargetBuildTargetc                   ~    e Zd ZU eed<   eed<   dZeed<   dZeed<   defdZ	de
fdZd	 Zedefd
       ZdefdZy)KeyboardKeymapDesckeyboardkeymapNdata
extra_argsreturnc                     | j                   j                         | j                  j                         z  t        j                  | j
                  d      j                         z  S NT)	sort_keys)r   __hash__r   jsondumpsr   selfs    C/home/hanthebot/chat/keyboard/qmk_firmware/lib/python/qmk/search.pyr   zKeyboardKeymapDesc.__hash__   sE    }}%%'$++*>*>*@@4::dooimCnCwCwCyyy    c                     | j                   | j                  t        j                  | j                  d      f|j                   |j                  t        j                  |j                  d      fk  S r   )r   r   r    r!   r   )r#   others     r$   __lt__zKeyboardKeymapDesc.__lt__   s}    t{{DJJtRV,WX\a\j\jlqlxlxz~  {E  {E  FK  FV  FV  bf  {g  \h  h  	hr%   c                     t        | j                  | j                        }t        |t              r|j                         | _        y || _        y N)r   r   r   
isinstancer   to_dictr   )r#   r   s     r$   	load_datazKeyboardKeymapDesc.load_data"   s2    4==$++6&0u&=DLLN	4	r%   c                 H    | j                   t        | j                         S d S r*   )r   r
   r"   s    r$   r
   zKeyboardKeymapDesc.dotty&   s    #'99#8uTYYBdBr%   c                     t        | j                  | j                  | j                        }| j                  |_        |S )N)r   r   r    )r   r   r   r   r   )r#   targets     r$   to_build_targetz"KeyboardKeymapDesc.to_build_target*   s0    *DMM$++\`\e\ef OOr%   )__name__
__module____qualname__str__annotations__r   dictr   intr   boolr(   r-   propertyr   r
   r   r1    r%   r$   r   r      sm    MKD$Jz# zht hH Cu C C!: r%   r   c                   R    e Zd ZU dZeed<   ee   ed<   eed<   eege	f   ed<   d Z
y)FilterFunctiona\  Base class for filters.
    It provides:
        - __init__: capture key and value

    Each subclass should provide:
        - func_name: how it will be specified on CLI
            >>> qmk find -f <func_name>...
        - apply: function that actually applies the filter
            ie: return whether the input kb/km satisfies the condition
    keyvalue	func_nameapplyc                      || _         || _        y r*   )r>   r?   )r#   r>   r?   s      r$   __init__zFilterFunction.__init__D   s    
r%   N)r2   r3   r4   __doc__r5   r6   r   r   r   r9   rC   r;   r%   r$   r=   r=   2   s6    	 
HC=N'($.//r%   r=   c                        e Zd ZdZdedefdZy)Existsexiststarget_infor   c                 2    | j                   |j                  v S r*   r>   r
   r#   rH   s     r$   rA   zExists.applyL   s    xx;,,,,r%   Nr2   r3   r4   r@   r   r9   rA   r;   r%   r$   rF   rF   I   s    I-!3 - -r%   rF   c                        e Zd ZdZdedefdZy)AbsentabsentrH   r   c                 2    | j                   |j                  vS r*   rJ   rK   s     r$   rA   zAbsent.applyS   s    xx{0000r%   NrL   r;   r%   r$   rN   rN   P   s    I1!3 1 1r%   rN   c                        e Zd ZdZdedefdZy)LengthlengthrH   r   c                     |j                   }| j                  |v xr. t        || j                           t        | j                        k(  S r*   )r
   r>   lenr8   r?   r#   rH   
info_dottys      r$   rA   zLength.applyZ   s<     &&
J&W3z$((/C+DDJJ+WXr%   NrL   r;   r%   r$   rR   rR   W   s    IY!3 Y Yr%   rR   c                        e Zd ZdZdedefdZy)ContainscontainsrH   r   c                 p    |j                   }| j                  |v xr | j                  || j                     v S r*   )r
   r>   r?   rV   s      r$   rA   zContains.applyb   s3     &&
J&M4::DHH9M+MNr%   NrL   r;   r%   r$   rY   rY   _   s    IO!3 O Or%   rY   r@   r>   r?   r   c                 j    t         j                         D ]  }| |j                  k(  s |||      c S  y)zInitialize a filter subclass based on regex findings and return it.
    None if no there's no filter with the name queried.
    N)r=   __subclasses__r@   )r@   r>   r?   subclasss       r$   _get_filter_classr_   g   s<    
 #113 (***C''( r%   c                      t         j                         D  cg c]  } d| j                   d }} dj                  |d d       d|d    z   S c c} w )N'z, z and )r=   r]   r@   join)fnamess     r$   filter_helprf   s   sV    )7)F)F)HIAqQIEI99U3BZ U59+#666 Js   Ac                 \   t        j                          	 t         j                  }| t         _        t         j                  j                  |        t        j                  j                  |        t        j                          |S # t        $ r t         j                  j
                  }Y yw xY wr*   )
r   acquire_lock	log_levelAttributeErrorloglevelsetLevelloggingrootrelease_lock)rl   olds     r$   _set_log_levelrr   x   sx    mm GGULL% J  ggmms   B #B+*B+c               #   \   K   t        t        j                        } d  t        |        y wr*   )rr   rn   CRITICAL)rq   s    r$   ignore_loggingru      s!     
))
*C	3s   *,c                     t               5  t        |       } t        |       D cg c]  }t        | |       c}cddd       S c c}w # 1 sw Y   yxY w)zQReturns a list of KeyboardKeymapDesc for all keymaps for the given keyboard.
    N)ru   r   r   r   r   r   s     r$   _all_keymapsrx      sR     
	 ["8,COPXCYZ"8V4Z[ [Z[ [s   AAAAAc                 b    t               5  t        | |      | ndcddd       S # 1 sw Y   yxY w)zYReturns the keyboard name if the keyboard+keymap combination exists, otherwise None.
    N)ru   r   rw   s     r$   _keymap_existsrz      s4     
	 Q(6:FxDQ Q Qs   %.r0   c                 f    t               5  | j                          | cddd       S # 1 sw Y   yxY w)z6Ensures a KeyboardKeymapDesc has its data loaded.
    N)ru   r-   )r0   s    r$   _load_keymap_infor|      s.     
	   s   '0targetsc                 R   g }| D ]  }d}t        |t              r|d   j                  d      }|d   }n|j                  d      }t        |      dk7  r&t        j
                  j                  d|        g c S |j                  t        |d   |d   |              t        |      S )zExpand a list of make targets into a list of KeyboardKeymapDesc.

    Caters for 'all' in either keyboard or keymap, or both.
    Nr   :      zInvalid build target: r   )
r+   tuplesplitrU   r   rk   errorappendr   expand_keymap_targets)r}   split_targetsr0   r   split_targets        r$   expand_make_targetsr      s    
 M 
j
fe$!!9??3/LJ!<<,L|!GGMM26(;<I/Qa]ghi
j !//r%   all_keyboardsc                 .   |
t               }| j                  dk(  r| j                  dk(  rat        j                  j                  d       g }t        t        |      D ]  }|j                  |        |D ]  }| j                  |_	         |S t        j                  j                  d| j                   d       t        j                  t        | j                        }t        d t        ||            D cg c]$  }t        || j                  | j                        & c}S | j                  dk(  r\t        j                  j                  d| j                   d       t        | j                        }|D ]  }| j                  |_	         |S | gS c c}w )	zExpand a keyboard input and keymap input into a list of KeyboardKeymapDesc.

    Caters for 'all' in either keyboard or keymap, or both.
    allz/Retrieving list of all keyboards and keymaps...z*Retrieving list of keyboards with keymap "z"...)r   c                 
    | d uS r*   r;   es    r$   <lambda>z'_expand_keymap_target.<locals>.<lambda>   s    st  }A  tA r%   r   z)Retrieving list of keymaps for keyboard ")r   r   r   r   rk   infor   rx   extendr   	functoolspartialrz   filterr   )r0   r   r}   kbtkeyboard_filters         r$   _expand_keymap_targetr      sy   
 &(%==E!GGLLJKG"<? #r"# 1%001NGGLLEfmm_TXYZ'//v}}UObh  jA  CO  P_  an  Co  cp  q\^&r6==VEVEVW  q  q==E!GGLLDV__DUUYZ["6??3G 1%001N8O qs   8)Fc                     g }t               }| D ]  }|j                  t        ||              t        t	        t        |                  S )zhExpand a list of KeyboardKeymapDesc inclusive of 'all', into a list of explicit KeyboardKeymapDesc.
    )r   r   r   listsortedset)r}   overall_targetsr   r0   s       r$   r   r      sM     O"$M M4V]KLMs?+,--r%   r   c                 "    | j                         S r*   )r1   r   s    r$   _construct_build_targetr      s    r%   target_listfiltersc           
         t        |      dk(  r#t        j                  j                  d       | }|S t        j                  j                  d       t	        t
        |       }t        j                  d      }t        j                  d      }|D ]  }|j                  |      }|j                  |      }||j                  d      j                         }	|j                  d      }
|j                  d      }t        |	|
|      }|2t        j                  j                  d	|j                  d              t        |j                  |      }|d
| dnd}t        j                  j                  d|	 d|
 d| d       |u|j                  d      }
|j                  d      }|j                  d      }t        j                  j                  d|
 d| d| d       d }t         ||
||      |      }kt        j                  j                  d	|         t        j                  j                  d       t        t!        t#        |                  }|S )zFilter a list of KeyboardKeymapDesc based on the supplied filters.

    Optionally includes the values of the queried info.json keys.
    r   zPreparing target list...z=Parsing data for all matching keyboard/keymap combinations...zL^(?P<function>[a-zA-Z]+)\((?P<key>[a-zA-Z0-9_\.]+)(,\s*(?P<value>[^#]+))?\)$zH^(?P<key>[a-zA-Z0-9_\.]+)\s*(?P<op>[\<\>\!=]=|\<|\>)\s*(?P<value>[^#]+)$functionr>   r?   z Unrecognized filter expression: z, {fg_cyan}z
{fg_reset} z"Filtering on condition: {fg_green}z{fg_reset}({fg_cyan}z)...opz!Filtering on condition: {fg_cyan}z{fg_reset} z
 {fg_cyan}z{fg_reset}...c                      t        j                        }t        j                  d| dt        j                        dt
        f fd}|S )N^$r   c                 L   | j                   j                        }}dv rCt        |dn|      }t        |      }dk(  r||k  S dk(  r||kD  S dk(  r||k  S dk(  r||k\  S y t        |dn|      }dk(  rj	                  |      d u S dk(  rj	                  |      d uS y )	N)<><=>=Fr   r   r   r   z!=z==)r
   getr8   r5   search)r   lhsrhskorulevs      r$   rd   z7_filter_keymap_targets.<locals>._make_filter.<locals>.f  s    ggkk!n 66"%s{e"DC"%c(C Cx'*Sy 0!"c'*Sy 0!"d'*cz 1!"d'*cz 1 "+ #&s{e"DC Dy'+{{3'74'? ?!"d'+{{3'7t'C C "+r%   )fnmatch	translaterecompile
IGNORECASEr   )r   r   r   exprrd   r   s   ```  @r$   _make_filterz,_filter_keymap_targets.<locals>._make_filter  sK    ",,Q/D::$qk2==ADD/ D D0 Hr%   )rU   r   rk   r   r   r|   r   r   matchgrouplowerr_   warningr   rA   r   r   r   )r   r   r}   valid_targetsfunction_recomparison_refilter_exprfunction_matchcomparison_matchr@   r>   r?   filter_class	value_strr   r   s                   r$   _filter_keymap_targetsr      sF   
 7|q/0L NI 	TU$%6Djj!pq

#no" 9	K(..{;N,22;?)*00<BBD	$**51&,,W50CG'GGOO&F~G[G[\]G^F_$`a &|'9'9= ICHCTmE7,?Z\	CI;Nfgjfkkw  yB  xC  CG  H  I!-&,,U3%++D1(..w7B3%}UWTXXdejdkkz{|< !'|CU'C] S"B;- PQs9	v 	/0vc-012Nr%   )r   defaultc           
          d }t        ||       } t        t        |       |      } t        t	        t        t        t        |                         } t        |       S )=Search for build targets matching the supplied criteria.
    c                 r    t        |       dk(  rt        | d   | d   | d         S t        | d   | d         S )N   r   r   r   )r   r   r   rw   )rU   r   r   s    r$   
_make_descz)search_keymap_targets.<locals>._make_desc8  s=    q6Q;%qtAaDQqTRR%qtAaDAAr%   )mapr   r   r   r   r   r   r   )r}   r   r   s      r$   search_keymap_targetsr   5  sM    B *g&G$%:7%CWMG3|$;T']KLMG'?r%   c           
          t        t        |       |      } t        t        t	        t
        t        |                         } t        |       S )r   )r   r   r   r   r   r   r   )r}   r   s     r$   search_make_targetsr   D  s;     %%8%A7KG3|$;T']KLMG'?r%   r*   )8rD   dataclassesr   
contextlibr   r   r    rn   r   typingr   r   r   r   r   r	   
dotty_dictr
   r   milcr   qmk.utilr   qmk.infor   qmk.keyboardr   r   
qmk.keymapr   r   qmk.build_targetsr   r   r   r=   rF   rN   rR   rY   r5   r_   rf   rr   contextmanagerru   rx   rz   r|   r   r   r   r   r   r   r   r;   r%   r$   <module>r      s   !      	 ? ? #  !   8 2 D   8 .-^ -1^ 1Y^ YO~ O	 	3 	s 	x?W 	7S 7

  [d#56 [Q0 5G 0eCsDcN7J1K,K&L!M 0RVWiRj 0("4 T#Y Z^_qZr @.4(:#; .EW@X .1  XZ M-?(@ M4PS9 M^bcu^v M` ewcw  OQ 4eCHouS#tTWY\T\~E]?^.^(_#`   CG  HK  CL   VZ  [f  Vg  eg eCsDcN7J1K,K&L!M X\]`Xa kop{k| r%   