
    ?g                     B   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	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 d dlZd dlZ	 d dlZe j4                  j7                  d      Ze dZe j4                  j=                   ej>                         dd      Z e d	Z!d
Z"e"dz   e"dz   e"dz   e"dz   e"dz   dZ#d Z$dZ%dZ&d Z'd Z( G d dej
                        Z) G d dejT                        Z+y# e$ r$Z ee        ej,                  d       Y dZ[dZ[ww xY w# e$ r d dlZY w xY w)    N)GioGtkGObjectGdk	GdkPixbufGLib)Image   ~z/.local/share/localecinnamonspicesz/.cinnamon/configs/z%https://cinnamon-spices.linuxmint.comz/json/applets.jsonz/json/themes.jsonz/json/desklets.jsonz/json/extensions.jsonz/json/actions.json)appletthemedesklet	extensionaction   c                 R    t        j                  | g|dt         j                  i y )Npriority)r   idle_addPRIORITY_DEFAULT)callbackargss     3/usr/share/cinnamon/cinnamon-settings/bin/Spices.pyui_thread_dor   -   s    MM(BTBD,A,AB    c                    t         j                  j                  |       sy t        j                  |       }t	        |      rR|D ]M  }t         j                  j                  | |      }t         j                  j                  |      sCt        |       O t        j                  |       }t	        |      dk(  r"t        d|        t        j                  |        y y )Nr   zRemoving empty folder:)	ospathisdirlistdirlenjoinremoveEmptyFoldersprintrmdir)r   filesffullpaths       r   r$   r$   1   s    77== JJtE
5z 	-Aww||D!,Hww}}X&"8,	- JJtE
5zQ&-
 r   c                   B     e Zd Z fdZd Zd Zd Zd Zd Zd Z	 xZ
S )ThreadedTaskManagerc                     t         |           || _        d| _        g | _        g | _        t        j                         | _        d| _	        y )NFr   )
super__init__max_threadsabort_statusjobsthreads	threadingLocklockstart_id)selfr/   	__class__s     r   r.   zThreadedTaskManager.__init__E   sA    &!	NN$	r   c                 X    t        | j                        t        | j                        z   S Nr"   r1   r2   r7   s    r   
get_n_jobszThreadedTaskManager.get_n_jobsN   s    499~DLL 111r   c                 f    t        | j                        dkD  xs t        | j                        dkD  S Nr   r;   r<   s    r   busyzThreadedTaskManager.busyQ   s(    499~!:S%6%::r   c                     | j                   5  | j                  j                  d|||f       d d d        | j                  dk(  r%t	        j
                  | j                        | _        y y # 1 sw Y   >xY wr?   )r5   r1   insertr6   r   r   check_start_job)r7   funcr   datas       r   pushzThreadedTaskManager.pushT   sb    YY 	8IIQx 67	8 ==A MM$*>*>?DM 	8 	8s    A**A3c                    d| _         t        | j                        dkD  rt        | j                        | j                  k(  ry | j
                  5  | j                  j                         }t        j                  | j                  |      }| j                  j                  |       d d d        j                          | j                          y y # 1 sw Y   +xY w)Nr   targetr   )r6   r"   r1   r2   r/   r5   popr3   Threadthread_function_wrapperappendstartrC   )r7   job	newthreads      r   rC   z#ThreadedTaskManager.check_start_job[   s    tyy>A4<< D$4$44 /iimmo%,,D4P4PWZ[	##I./
 OO  " / /s   ACCc                 >    || }| j                   5  	 | j                  j                  t        j                                | j
                  r| j                         sd| _        d d d        | j                          |t        ||       y y #  Y OxY w# 1 sw Y   0xY w)NF)	r5   r2   remover3   current_threadr0   r@   rC   r   )r7   rD   r   rE   results        r   rL   z+ThreadedTaskManager.thread_function_wrapperj   s    tYY 	*##I$<$<$>?   $)!	* 	6*  		* 	*s"   B-B#BBBBc                     | j                         r,| j                  5  d| _        | j                  d d = d d d        y y # 1 sw Y   y xY w)NT)r@   r5   r0   r1   r<   s    r   abortzThreadedTaskManager.abort{   sD    99; !$(!IIaL! ! ! !s	   >A)__name__
__module____qualname__r.   r=   r@   rF   rC   rL   rV   __classcell__r8   s   @r   r+   r+   D   s'    2;@#+"!r   r+   c                       e Zd Zej                  j
                  ddfej                  j
                  ddfej                  j
                  ddfdZd7 fd	Zd7dZd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd8dZd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d# Z&d8d$Z'd% Z(d& Z)e*d'        Z+e*d(        Z,d) Z-d* Z.d9d+Z/d, Z0d- Z1d. Z2d/ Z3e4fd0Z5d1 Z6d7d2Z7d7d3Z8d:d4Z9d5 Z:d6 Z; xZ<S );Spice_HarvesterN )installed-changedstatus-changedcache-loadedc                    t         
|           || _        || _        |dk(  | _        |dk(  | _        i | _        i | _        t        d      | _	        d | _
        g | _        g | _        g | _        g | _        g | _        g | _        d| _        d| _        d | _        d| _        d| _        d| _        t.        j0                  j3                  t5        j6                         dd| j                        | _        | j                  r,t:        j<                  j?                  d      | _         d	| _!        nq| j
                  r,t:        j<                  j?                  d
      | _         d| _!        n9t:        j<                  j?                  d      | _         d| j                   d| _!        | j                  s3| j@                  jE                  d| jB                   | jF                         | j                  rTtH         d| _%        t.        j0                  j3                  t5        jL                         d      }| jJ                  |f| _'        n| j
                  r\d}tH         d| | _%        t5        jP                         D cg c]
  }|d| z    }}|jS                  | jJ                         || _'        n<tH         d| j                   d| _%        d| j                   d| jJ                  f| _'        | jG                          | jU                          | jW                          tX        | _-        d | _.        d| _/        d | _0        	 t:        jb                  je                  | jJ                        jg                  dd       | _0        | j`                  jE                  d| jh                        | _/        	 | j
                  sd}d}	nd}d}	t:        jn                  jq                  t:        jr                  jt                  t:        jv                  jx                  d ||	|d | jz                  d 	       y c c}w # tj        $ r}tm        |       Y d }~d }~ww xY w# t4        j|                  $ r}tm        |       Y d }~y d }~ww xY w)Nr   r   
   Fr   r   r   zorg.cinnamon.themenamezorg.nemo.pluginszdisabled-actionszorg.cinnamonzenabled-sz	changed::z	/.themes/themesznemo/actions/z/.local/share//z/.local/share/cinnamon/zs/z/usr/share/cinnamon/changedzorg.Cinnamonz/org/Cinnamonzorg.Nemoz	/org/Nemo)?r-   r.   collection_typewindowrf   actionsindex_cachemeta_mapr+   download_manager_proxy_proxy_deferred_actions_proxy_signalsrunning_uuidsr1   progressbarsupdates_availableprocessing_jobsis_downloading_image_cachecurrent_job
total_jobsdownload_total_filesdownload_current_filer   r   r#   r   get_user_cache_dircache_folderr   Settingsnewsettingsenabled_keyconnect_update_statushomeinstall_folderget_user_data_dirspices_directoriesget_system_data_dirsrM   _load_metadata_load_cache
ABORT_NONEabort_download_sigLoadFinished	monitorIdmonitorFilenew_for_pathmonitor_directory_directory_changed	Exceptionr%   	DBusProxynew_for_busBusTypeSESSIONDBusProxyFlagsNONE_on_proxy_readyError)r7   ri   rj   old_install_folderrk   xsys_dirse	dbus_pathgsettingr8   s             r   r.   zSpice_Harvester.__init__   s   .%0&(2 3B 7')$ 	!#$*/'$%!%&"GGLL)@)@)BJPXZ^ZnZno;;LL,,-ABDM%D\\LL,,-?@DM1DLL,,^<DM!)$*>*>)?qAD{{MM!!Id.>.>-?"@$BUBUV;;%)F)"4D!#d.D.D.F!Q'+':':<N&OD#\\%G%)F.	"BD373L3L3NOaayM)OHOOOD//0'/D#%)F*A$BVBVAWWY"ZD)=d>R>R=SSU'VX\XkXk&lD#( $	88001D1DEWWXY[_`DL!\\11)T=T=TUDN

	<<*	*&	&MM%%ckk&9&93;M;M;R;RTX&/9dDL`L`bfhA P*  	!HH	 zz 	!HH	s8   *P+A)P A6P2 	P/P**P/2QQQc                    	 t         j                  j                  |      | _        | j                  j	                  d| j
                         | j                  j                         r| j                          nt        d       | j                  d| j                         | j                          y # t        j                  $ r}t        d|        Y d }~Sd }~ww xY w)Nzg-signalz?org.Cinnamon proxy created, but no owner - is Cinnamon running?z,Could not establish proxy for org.Cinnamon: XletAddedComplete)r   r   new_for_bus_finishro   r   
_on_signalget_name_ownersend_deferred_proxy_callsr%   r   r   connect_proxyr   )r7   objrT   rE   r   s        r   r   zSpice_Harvester._on_proxy_ready   s    		F--::6BDKKK
DOO<{{))+..0WX 	.0C0CD	 zz 	F@DEE	Fs   B B/ /CCCc                     |dk(  r.| j                   j                         dk(  r| j                          y |dk(  r| j                          | j                  D ]  \  }}||k(  s ||   y )NRunStateChangedr   XletsLoadedComplete)ro   GetRunStater   r   rq   )r7   proxysender_namesignal_nameparamsrd   r   s          r   r   zSpice_Harvester._on_signal   sm    ++{{&&(A-..0//!"11 	"ND(d"&!	"r   c                     | j                   j                         rB| j                  r5| j                  D ]  \  }} t        | j                   |      |    g | _        y y y r:   )ro   r   rp   getattrr7   commandr   s      r   r   z)Spice_Harvester.send_deferred_proxy_calls   s[    ;;%%'D,H,H!%!=!= 5-W-t45 ,.D(	 -I'r   c                 >    | j                   j                  ||f       y)z% connects a callback to a dbus signalN)rq   rM   )r7   rd   r   s      r   r   zSpice_Harvester.connect_proxy   s    ""D(#34r   c                 h    | j                   D ]#  }||v s| j                   j                  |        y y)z/ disconnects a previously connected dbus signalN)rq   rR   )r7   rd   signals      r   disconnect_proxyz Spice_Harvester.disconnect_proxy  s5    )) 	Fv~##**62	r   c                     | j                   | j                   j                         s| j                  j                  ||f       y t	        | j                   |      |  y)z sends a command over dbusN)ro   r   rp   rM   r   r   s      r   send_proxy_signalz!Spice_Harvester.send_proxy_signal	  sH    ;;dkk&@&@&B((//$@)GDKK)40r   c                    	 | j                   rR| j                   j                         r8| j                  s,| j                   j                  d| j                        | _        ng | _        | j                  d       y #  g | _        Y xY w)Nz(s)r`   )ro   r   rk   GetRunningXletUUIDsri   rr   emitr7   r   s     r   r   zSpice_Harvester._update_status  sh    	${{t{{99;DLL%)[[%D%DUDL`L`%a"%'" 			"#	$!#Ds   A%A9 9	Bc                     | j                   |   d   }t        j                  dt         d| j                   d| gd       y)z( opens to the web page of the given uuidz	spices-idz/usr/bin/xdg-openrg   zs/view/TcheckN)rl   
subprocessrunURL_SPICES_HOMEri   )r7   uuidids      r   open_spice_pagezSpice_Harvester.open_spice_page  sK    d#K0+)*!D,@,@+AMO!	#r   c                    t        j                         }|j                  d       |j                  d       |j	                  d       t        j
                         }|j                  |       |j                  t         j                  j                         |j                  d       ||_        | j                  j                  |       |S )z returns a Gtk.Widget that can be added to the application. This widget will show the
            progress of any asynchronous actions taking place (ie. refreshing the cache or
            downloading an applet)T r      )r   ProgressBarset_show_textset_textset_fractionRevealeraddset_transition_typeRevealerTransitionType
SLIDE_DOWNset_transition_durationrevealerrs   rM   )r7   progressbarr   s      r   get_progressbarzSpice_Harvester.get_progressbar!  s     oo'!!$'R   #<<>[!$$S%?%?%J%JK((-'  -r   c                 H    | j                   D ]  }|j                  |        y r:   )rs   r   )r7   textr   s      r   _set_progressbar_textz%Spice_Harvester._set_progressbar_text4  s%    ,, 	'K  &	'r   c                     | j                   D ]  }|j                  |        | j                  r(| j                  j                  t	        |dz               y y )Nd   )rs   r   rj   set_progressint)r7   fractionr   s      r   _set_progressbar_fractionz)Spice_Harvester._set_progressbar_fraction8  sL    ,, 	/K$$X.	/;;KK$$S#%67 r   c                 \    | j                   D ]  }|j                  j                  |        y r:   )rs   r   set_reveal_child)r7   visibler   s      r   _set_progressbar_visiblez(Spice_Harvester._set_progressbar_visible>  s+    ,, 	;K  11':	;r   c                    | j                   j                         ru| j                  dkD  rf| j                  }|| j                   j                         z
  }t	        |      t	        |      z  }t        d      d| d| z   }| j                  |       n||z  t	        ||z  dz   |z        z  }| j                  |       t        j                         r*t        j                          t        j                         r)y y )Nr
   zDownloading images: rg   )rn   r@   ry   r=   float_r   r   r   events_pendingmain_iteration)r7   count	blockSize	totalSizetotalcurrentr   r   s           r   _update_progressz Spice_Harvester._update_progressC  s      %%'D,E,E,I--Ed33>>@@GW~e4H*+'!E7.CCD&&t,y(5)i2G!2Ky1X+YYH&&x0  "    "r   c                     | xj                   dz  c_         | j                   |d<   | j                  j                  |       | j                  s| j	                          y y )Nr
   
job_number)rx   r1   rM   ru   _advance_queuer7   rO   s     r   	_push_jobzSpice_Harvester._push_jobT  sJ    1 OOL		##! $r   c                      |d   |      |d<   |j                  d      rt        j                  |d   |       t        j                  | j                         y )NrD   rT   r   )getr   r   r   r   s     r   _process_jobzSpice_Harvester._process_job[  sF    #FC(H77:MM#j/3/d))*r   c                 |   | j                   dkD  r,| j                  j                  | j                          d| _         d| _        | j                  ry | j                  d       t        | j                        dkD  r| j                  d       | j                  j                  d      }|| _
        |d   }| j                  dkD  r|d|d    d| j                   dz  }| j                  |       t        j                  | j                  |f	      }|j!                          y d
| _        d | _
        d| _        | j                  d
       | j                  d       | j                  ,	 | j                  j#                  d| j$                        | _         | j%                          y # t&        $ r}t)        |       Y d }~*d }~ww xY w)Nr   Tprogress_textr
   z (r   rg   )rH   Fr   rh   )r   r   
disconnectru   rv   r   r"   r1   r   rJ   rw   rx   r   r3   rK   r   rN   r   r   r   r%   )r7   rO   r   
job_threadr   s        r   r   zSpice_Harvester._advance_queuea  s|   >>ALL##DNN3DN#**&&q)tyy>A))$/))--"C"D'D""S./q0ACC&&t,"))1B1B#PJ#(D #DDO))%0&&r*||'%)\\%9%9)TE\E\%]DN ##% ! !HHs   !+F 	F;&F66F;c                    t        t        j                               }| d| }t        d|        	 |rdnd}t        ||      5 }| j	                  ||| j
                  |       d d d        |S # 1 sw Y   |S xY w# t        $ r}	 t        j                  |       n# t        $ r Y nw xY wt        |t              s1| j                  j                  s| j                  t        d      |       | j!                          Y d }~y d }~ww xY w)Nz?time=zDownloading from wbwzXAn error occurred while trying to access the server. Please try again in a little while.)roundtimer%   open_url_retriever   r   r   rR   OSError
isinstanceKeyboardInterruptrn   r0   errorMessager   rV   )r7   out_fileurlbinary	timestamp	open_argsoutfdr   s           r   	_downloadzSpice_Harvester._download  s    $))+&	VI;'!#'(	 &CIh	* Ne""3t/D/DfMN N   			(# a!23D<Q<Q<^<^!!!$~"  BC  DJJL	sT   A< A/%A< /A94A< 9A< <	DBD	B(%D'B((ADDc                    dd l }dd l}d}d}|j                         }		 |j                  ||	dd      }
|
j                  sJ t        |
j                  j                  d            }|
j                  |      D ]K  }|dz  }| j                         r y |s|j                  d	      }|j                  |       t        ||||       M y # t        $ r}|d }~ww xY w)
Nr   i    T   )proxiesstreamtimeoutzcontent-length)
chunk_sizer
   utf-8)proxygsettingsrequestsget_proxy_settingsr   okr   headersiter_content_is_aborteddecodewriter   r   )r7   r  r  
reporthookr  r  r  r   r   
proxy_inforesponser   rE   r   s                 r   r  zSpice_Harvester._url_retrieve  s     		#668
	||CDRT|UH;;;H,,001ABCI ---C F
##%;;w/DD!Z	9EF  	G	s   A2C 4C 	CCCc           	      P   i | _         | j                  D ]r  }t        j                  j	                  |      rAt        j
                  |      }|D ]$  }|dk(  r
t        j                  j                  ||      }|j                  d      d   }|j                  d      rt        j                  j	                  |      st               }t        j                  j                         }	 |j                  |t        j                  j                         	 |j'                  dd      s	 	 |j/                  dd      }	|	j1                  d	d
      |d<   	 |j/                  dd      |d<   	 |j3                  dd      |d<   d|d<   d|d<   | j4                  |d<   |j                  d      d   }
|
|d<   || j                   |
<   n!t        j                  j7                  |      r| j8                  r!t        j                  j;                  |      s	 t=        | dd      5 }t?        j@                  |      }||d<   t        jB                  |t        jD                        |d<   || j                   |<   d d d        ' et#        | d       u y # t        j                   $ r&}t#        d|d|j$                         Y d }~pd }~ww xY w# t        j                   $ r3}|j(                  t        j*                  j,                  k(  r	 Y d }~d }~ww xY w# t        j                   $ r&}t#        d|d|j$                         Y d }~d }~ww xY w# t        j                   $ r3}|j(                  t        j*                  j,                  k(  r	 Y d }~)d }~ww xY w# t        j                   $ r3}|j(                  t        j*                  j,                  k(  r	 Y d }~\d }~ww xY w# 1 sw Y   txY w# tF        $ r1}| jH                  st#        |       t#        d| d       Y d }~d }~ww xY w)Nzsample.nemo_action.nemo_actionr   zCould not read action file 'z': zNemo ActionActiveNamer   r   rd   z0Could not read Name field for action. Skipping 'Commentdescriptionz	Icon-NameiconFwritableTdisable_aboutr   r   z/metadata.jsonr  encodingz	Skipping z2: there was a problem trying to read metadata.jsonz does not exist! Skipping)%rm   r   r   r   existsr!   r#   splitendswithdictr   KeyFiler~   load_from_fileKeyFileFlagsKEEP_TRANSLATIONSr   r%   messageget_booleancodeKeyFileError	NOT_FOUNDget_locale_stringreplace
get_stringr   isfilerk   r    r  jsonloadaccessW_OKr   rf   )r7   	file_path
extensionsr   	full_path	uuid_pathmetadatakeyfiler   rd   _uuid	json_dataerrors                r   r   zSpice_Harvester._load_metadata  s   00 H	?Iww~~i(ZZ	2
& BlD33  "Y =I ) ? BI}}^4RWW^^I=V#'6"&,,"2"2"4%#229d>O>O>a>ab
% $+#6#6}h#O ( $P%#*#<#<]F#SD/3||C/DHV,
%6=6O6OP]_h6iH]3
%/6/A/A-Q\/]HV,
 05,481+/+>+>( $

> :1 =+0(/7e,	2 ||BGGMM),D 
l!%>&BW!U ?Yb+/99Y+?3< 079yyBGG7T 46>d 3	?uBlH #<=>QH	?   $zz %!9VWV_V_"`a$%  $zz % vv):):)D)DD $%  $zz %!_hjkjsjs"tu$%  $zz % vv):):)D)DD $%  $zz % vv):):)D)DD $%$? ?
  ) l#';; %e %	$7i&j kls   '*JK''LM%NO+AO,O+KJ??KL(LLM	#MM	N(NNO((OOO(#O++	P%4&P  P%c                 f    | j                          | j                          | j                  d       y )Nr_   )r   _generate_update_listr   r   s     r   r   z"Spice_Harvester._directory_changed  s'    ""$		%&r   c                     | j                   S )zE returns a dictionary of the metadata by uuid of all installed spicesrm   r<   s    r   get_installedzSpice_Harvester.get_installed  s    }}r   c                     || j                   v S )zI returns a boolean specifying whether the given spice is installed or notrP  r7   r   s     r   get_is_installedz Spice_Harvester.get_is_installed
  s    t}}$$r   c                     || j                   vry	 t        | j                  |   d         | j                   |   d   k  S # t        $ r Y yw xY w)zM returns a boolean indicating whether the given spice has an update availableFlast-editedlast_edited)rl   r   rm   r   rS  s     r   get_has_updatezSpice_Harvester.get_has_update  sY    t'''	t}}T*=9:T=M=Md=STa=bbb 		s   -? 	A
Ac                    d}| j                   se| j                  sY| j                  j                  | j                        }|D ]-  }|j                  dd      }||j                  d      v s)|dz  }/ |S | j                  r2| j                  j                  | j                        }| d}||vrd}|S | j                  j                  | j                        |k(  rd}|S )z2 returns the number of instances currently enabledr   !r   :r
   r%  )rf   rk   r   get_strvr   r=  r0  r>  )r7   r   enabled_countenabled_listitemdisabled_list	uuid_names          r   get_enabledzSpice_Harvester.get_enabled  s    {{4<<==11$2B2BCL$ '||C,4::c?*!Q&M'  \\ MM2243C3CDM&-I- !  ]]%%d&6&674?Mr   c                     || j                   v S )z checks whether the spice is currently running (it may be enabled but not running if
            there was an error in initialization))rr   rS  s     r   get_is_runningzSpice_Harvester.get_is_running+  s     t))))r   c                 2    t        | j                        dkD  S )z? returns True if there are updates available or False otherwiser   r"   rt   r<   s    r   are_updates_availablez%Spice_Harvester.are_updates_available0  s    4))*Q..r   c                 ,    t        | j                        S )z( returns the number of available updatesrf  r<   s    r   get_n_updateszSpice_Harvester.get_n_updates4  s    4))**r   c                     | j                   S )z% retrieves a copy of the index cache )rl   r<   s    r   	get_cachezSpice_Harvester.get_cache8  s    r   c                    t         j                  j                  | j                  d      }t         j                  j	                  | j                        s"t        j
                  | j                  dd       t         j                  j	                  |      sd| _        y d| _        t        |dd      5 }	 t        j                  |      | _
        d d d        | j!                          y # t        $ rL}	 t        j                  |       n#  Y nxY w| j                  t        d	      t        |             Y d }~id }~ww xY w# 1 sw Y   rxY w)
N
index.json  Tmodeexist_okFrr  r-  zTSomething went wrong with the spices download. Please try refreshing the list again.)r   r   r#   r|   r/  makedirs	has_cacher  r@  rA  rl   
ValueErrorrR   r	  r   strrN  )r7   filenamer(   details       r   r   zSpice_Harvester._load_cache<  s   77<< 1 1<@ww~~d//0KK))Eww~~h'"DN(C'2 	JaJ#'99Q< 	J 	""$  JIIh'!!!$z"{  ~A  BH  ~I  J  JJ	J 	JsB   2D?4C''	D<1DD7D	)D72D?7D<<D??Ec                     g | _         | j                  D ]A  }| j                  |      s| j                  |      s'| j                   j	                  |       C y r:   )rt   rl   rT  rX  rM   rS  s     r   rN  z%Spice_Harvester._generate_update_listR  sN    !#$$ 	4D$$T*t/B/B4/H&&--d3	4r   c                     | j                   | _        d| j                  i}t        d      |d<   | j	                  |       y)z5 downloads an updated version of the index and assetsrD   zRefreshing the cacher   N)rl   	old_cache_download_cacher   r   r   s     r   refresh_cachezSpice_Harvester.refresh_cacheX  s;    ))t++, !78Osr   c                     t         | j                     }t        j                  j	                  | j
                  d      }| j                  ||d      y | j                          | j                          y )Nrm  F)r  )	URL_MAPri   r   r   r#   r|   r  r   _download_image_cache)r7   load_assetsdownload_urlrw  s       r   r|  zSpice_Harvester._download_cache`  s\    t33477<< 1 1<@>>(L>?G""$r   c                    d| _         g | _        d| _        d| _        | j                  j                         D ]  \  }}| j                  rK| j                  t        j                  j                  | j                  |   d               }t        dz   |z   }nHt        j                  j                  | j                  |   d         }t        | j                  |   d   z   }| j                  j                  |       t        j                  j                  | j                  |      }t        j                  j                  |      r8| j!                  |      s'| j"                  |   d   | j                  |   d   k7  sB| j$                  j'                  | j(                  | j*                  ||f       | xj                  dz  c_         t-        | j*                         y )NTr   
screenshotz/uploads/themes/thumbs/r*  rW  r
   )rv   used_thumbsry   rz   rl   itemsrf   _sanitize_thumbr   r   basenamer   rM   r#   r|   r?  _is_bad_imager{  rn   rF   r  $_check_download_image_cache_completer   )r7   r   r   icon_basenamer  	icon_paths         r   r  z%Spice_Harvester._download_image_cachej  s   *.'$%!%&"''--/ 	/GD!{{ $ 4 4RWW5E5EdFVFVW[F\]iFj5k l.1JJ]Z " 0 01A1A$1G1O P.1A1A$1G1OO##M2T%6%6FI 77>>),0B0B90MQUQ_Q_`dQefsQtx|  yI  yI  JN  yO  P]  y^  R^%%**4>>4;d;dgpr~f  A))Q.)	/  	T>>?r   c                    | j                   j                         ry g }t        j                  | j                        }|D ](  }|| j
                  vs|dk7  s|j                  |       * |D ]@  }	 t        j                  t        j                  j                  | j                  |             B d| _
        d| _        d| _        | j                          | j                  d       y #  Y ~xY w)Nrm  r   Fra   )rn   r@   r   r!   r|   r  rM   rR   r   r#   ry   rz   rv   r   r   )r7   r   trashflistr(   ts         r   r  z4Spice_Harvester._check_download_image_cache_complete  s      %%' 

4,,- 	 A(((Q,->Q	   	A		"'',,t'8'8!<=	 %&!%&"*/'		.!s   0=C&&C*c                 N    	 t        j                  |        y# t        $ r Y yw xY w)NTF)r	   r  IOError)r   s    r   r  zSpice_Harvester._is_bad_image  s,    	JJt   		s    	$$c                 f    | j                  dd      j                  dd      j                  dd      S )NjpgpngJPGPNG)r=  )r  s    r   r  zSpice_Harvester._sanitize_thumb  s0    u-55eUCKKESXYYr   c                     | j                   rdn| j                  }|| j                  |d}t        d      |z  |d<   | j	                  |       y)z+ downloads and installs the given extensionN)r   rD   r   zInstalling %sr   )rk   _install_finished_installr   r   )r7   r   	_callbackrO   s       r   installzSpice_Harvester.install  sE     LLDd.D.D	T]]	J 1D8Osr   c                    |d   }t         | j                  |   d   z   }|| _        t        j                         \  }}| j                  ||      y 	 t        j                  |      5 }t        j                         }|j                         D ]a  }|j                  ||       |j                  dz	  }	t        j                  t        j                  j                  ||j                         |	       c | j"                  r|nt        j                  j                  ||      }
| j%                  |
|d       d d d        	 t/        j0                         t        j2                  |       y # 1 sw Y   5xY w# t&        $ r:}| j(                  s$| j+                   |d      |z  t-        |             Y d }~y d }~ww xY w# t&        $ r Y y w xY w)Nr   file   Tz^An error occurred during the installation of %s. Please report this incident to its developer.)r   rl   current_uuidtempfilemkstempr  zipfileZipFilemkdtempinfolistextractexternal_attrr   chmodr   r#   rw  rk   install_from_folderr   r   r	  rv  shutilrmtreerR   )r7   rO   r   r  r   ziptempfile_zip
tempfoldermemberpermissions
uuidfolderrx  s               r   r  zSpice_Harvester._install  s   6{&)9)9$)?)GG !))+;>>+|4<	- 
A%--/
"mmo UFLL4"("6"6""<KHHRWW\\*fooFT	U ,0<<ZRWW\\*VZ=[
((T4@
A 	MM*%IIk"%
A 
A  	&&!!!  %E  #F  IM  #M  OR  SY  OZ  [	  		sC   E0 &C
E$0E0 9*F6 $E-)E0 0	F390F..F36	GGc                 0   | j                   r| d| n|}t        j                  |      }| j                  sd|v rt        j                  j                  |d      }t        j                  |      D ]  }|j                  d      s|j                  d      d   }t        j                  j                  t        |d      }	t        j                  |	dd	       t        j                  d
dt        j                  j                  ||      dt        j                  j                  |	| d      gd        t        j                  j                  | j                        s$t        j                  dd| j                  gd       t        j                  j                  | j                  |      }
t        j                  j                  |
      rt        j                  |
       | j                   r:t        j                  j                  |
dz         rt        j                   |
dz          | j                   st        j"                  ||
       n"t        j"                  || j                  d       | j                   rs|| j$                  vre| j&                  j)                  | j*                        }| d}||vr7|j-                  |       | j&                  j/                  | j*                  |       t        j                  j                  |
d      }| j                  r"t        j                  j                  |      si }n,t1        |dd      5 }t3        j4                  |      }ddd       |r$|| j6                  v r| j6                  |   d   d<   n8t9        t:        j:                  j=                         j?                               d<   t3        j@                  |d      }t1        |dd      5 }|jC                  |       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)z) installs a spice from a specified folderrg   poz.po.r   LC_MESSAGESrn  Tro  z/usr/bin/msgfmtz-cz-oz.mor   z/usr/bin/mkdirz-pr%  )dirs_exist_okzmetadata.jsonrr  r  r-  NrW  rV     )indentzw+)"rk   r   r!   rf   r   r#   r1  r0  locale_instrs  r   r   r/  r   r  r  rR   copytreert   r   r\  r   rM   set_strvr  r@  rA  rl   r   datetimeutcnowr  dumpsr   )r7   folderr   from_spices_foldercontentspo_dirr  lang
locale_dirdestr`  ra  	meta_pathmdraw_metas                   r   r  z#Spice_Harvester.install_from_folder  s   (,VHAdV$&::g&{{xgt4JJv. 3D}}U+#zz#q1%'WW\\+t]%S
JUTJ"(94')ww||FD'A4')ww||J4&'M(O .233 ww~~d112NN,dD4G4GHPTUww||D//677>>$MM$<<BGGNN4.+@AIId^+,||OOFD)OOFD$7$7tL<<D(>(>> MM2243C3CDM&-I-$$Y/&&t'7'7GGGLL7	;;rww~~i8Biw7 %4YYt_% 44#3#33 $ 0 0 6} EB} #H$5$5$<$<$>$H$H$J KB}::b+)TG4 	!JJx 	! 	!% %	! 	!s   P %P P	Pc                    |d   }| j                  |      ro| j                  r6| j                  j                  d|| j                  j	                                y | j                  dd|| j                  j	                                y y )Nr   z(ss)
ReloadXlet)rb  ro   r  ri   upperr   )r7   rO   r   s      r   r  z!Spice_Harvester._install_finished
  sm    6{D!{{&&vtT5I5I5O5O5QR&&|VT4CWCWC]C]C_`	 "r   c                 f    || j                   d}t        d      |z  |d<   | j                  |       y)z+ uninstalls and removes the given extension)r   rD   zUninstalling %sr   N)
_uninstallr   r   )r7   r   rO   s      r   	uninstallzSpice_Harvester.uninstall  s1    T__5 !23d:Osr   c           
      j   	 |d   }| j                   st        j                  j                  t              rt        j
                  t              }|D ]  }t        j                  j                  t        j                  j                  t        |dd|z              r<t        j                  t        j                  j                  t        |dd|z               t        t        j                  j                  t        |              t        j                  j                  t        j                  j                  t        |            r7t        j                  t        j                  j                  t        |             t        j                  j                  t        j                  j                  t        |            r7t        j                  t        j                  j                  t        |             | j                  D ]7  }t        j                  t        j                  j                  ||      d       9 | j                  r| j                   j#                  | j$                        }| d}||v r7|j                  |       | j                   j'                  | j$                  |       	 t        j                  t        j                  j                  | d             y y # t(        $ r Y y w xY w# t*        $ r4}| j-                  t/        d      |d   z  t1        |             Y d }~y d }~ww xY w)Nr   r  z%s.moT)ignore_errorsr%  z%A problem occurred while removing %s.)rf   r   r   r/  r  r!   r?  r#   rR   r$   settings_dirr  r  old_settings_dirr   rk   r   r\  r   r  FileNotFoundErrorr   r	  r   rv  )	r7   rO   r   i19_folders
i19_folderr  r`  ra  rL  s	            r   r  zSpice_Harvester._uninstall  s2   	dv;D;;77>>+."$**["9K&1 R
77>>"'',,{JP]_fim_m*noIIbggll;
M[bei[i&jk*277<<Z+PQ	R 77>>"'',,|T"BCMM"'',,|T"BC77>>"'',,/?"FGMM"'',,/?"FG11 Nbggll648MN|| $ 6 6t7G7G H#fL1	-!((3MM**4+;+;]KIIbggll6dV<3HIJ  )  	da GH3v;VX[\aXbcc	ds6   J+K5 .6K& &	K2/K5 1K22K5 5	L2>*L--L2c                 H    | j                   D ]  }| j                  |        y)z applies all available updatesN)rt   r  rS  s     r   
update_allzSpice_Harvester.update_all9  s#    ** 	DLL	r   c                 F    || _         | j                  j                          y)z% trigger in-progress download to haltN)r   rn   rV   )r7   
abort_types     r   rV   zSpice_Harvester.abort>  s    (##%r   c                 .    | j                   j                  S r:   )rn   r0   r<   s    r   r  zSpice_Harvester._is_abortedC  s    $$111r   c                    t        j                  | j                  dt         j                  j                  t         j
                  j                        }|}||t        d      t        |      z  z  }t        j                  |      }|j                  |       |j                          |j                          |j                          y )NT)transient_formodalmessage_typebuttonsz

Details:  %s)r   MessageDialogrj   MessageTypeERRORButtonsTypeOKr   rv  htmlescape
set_markupshow_allr   destroy)r7   msgrx  dialogmarkupescs         r   _ui_error_messagez!Spice_Harvester._ui_error_messageF  s    "")-030E0E+.??+=+=? a*+s6{;;Fkk&!#

r   c                 2    t        | j                  ||       y r:   )r   r  )r7   r  rx  s      r   r	  zSpice_Harvester.errorMessageT  s    T++S&9r   c                 $   | j                   dk(  r'g }| j                  j                  d      }| j                  j                  d|dz          | j                  j	                  | j
                        D ]|  }|j                  d      }t        |d         }	|d   d| k(  r?|d   |k(  r7||	k  r2t        |	dz         |d<   |j                  dj                  |             l|j                  |       ~ |j                  d| d| d| d| d| 
       | j                  j                  | j
                  |       y | j                   dk(  r| j                  j                  d	      }
| j                  j                  d	|
dz          | j                  j	                  | j
                        }t        j                  j                         }|j                         }|j!                  |      }|j                  | d|
 d|j"                  d
z    d|j$                  d
z           | j                  j                  | j
                  |       y | j&                  rg| j                  j	                  | j
                        }| d}||v r8|j)                  |       | j                  j                  | j
                  |       y y | j                  j	                  | j
                        }|j                  |       | j                  j                  | j
                  |       y )Nr   znext-applet-idr
   r[  r   r   panelr   znext-desklet-idr   r%  )ri   r   get_intset_intr\  r   r0  r   rv  rM   r#   r  r   Screenget_defaultget_primary_monitorget_monitor_geometryr   yrk   rR   )r7   r   r  boxpositionentries	applet_identryinfopos
desklet_idenabledscreenprimaryprimary_rectdisabled_extensionsra  s                    r   enable_extensionz Spice_Harvester.enable_extensionW  s   8+G--.>?IMM!!"2Yq[B//0@0@A *{{3'$q'l7eWo-$q'S.XQT_!#a%jDGNN388D>2NN5)* NNU5'3%q
!D69+NOMM""4#3#3W=!!Y.../@AJMM!!"3jlDmm,,T-=-=>GZZ++-F002G!66w?LNNdV1ZL,..32F1GqZ]I]H^_`MM""4#3#3W=\\"&--"8"89I9I"J&-I//#**95&&t'7'79LM 0 mm,,T-=-=>GNN4 MM""4#3#3W=r   c                    | j                   ry | j                  rf| j                  j                  | j                        }| d}||vr7|j                  |       | j                  j                  | j                  |       y | j                  j                  | j                        }g }|D ]  }| j                  dk(  r$|j                  d      d   j                  d      }nD| j                  dk(  r$|j                  d      d   j                  d      }n|j                  d      }||k7  s|j                  |        | j                  j                  | j                  |       y )Nr%  r   r[     rZ  r   r   )
rf   rk   r   r\  r   rM   r  ri   r0  lstrip)r7   r   r  ra  enabled_extensionsnew_listenabled_extensionenabled_uuids           r   disable_extensionz!Spice_Harvester.disable_extension  s<   ;;<<"&--"8"89I9I"J&-I 33#**95&&t'7'79LM!]]33D4D4DE!3 		3##x/066s;A>EEcJ%%2066s;A>EEcJ077<t# 12		3 	t//:r   c                    	 | j                   rzt        j                  j                  | j                  t        j                  j                  | j                  |   d               }t        j                  j                  |ddd      }nyt        j                  j                  | j                  t        j                  j                  | j                  |   d               }t        j                  j                  |ddd      }t        j                  j                  |      S # t        $ r. t        d       t        j                  j                  dd	      cY S w xY w)
z  gets the icon  for a given uuidr  r   Tr*     zJThere was an error processing one of the images. Try refreshing the cache.zimage-missingr   )rf   r   r   r#   r|   r  rl   r   Pixbufnew_from_file_at_scaler   r	   new_from_pixbufr   r%   new_from_icon_name)r7   r   rD  pixbufs       r   get_iconzSpice_Harvester.get_icon  s   	D{{GGLL):):BGG<L<LTM]M]^bMcdpMq<rs	"))@@CQSUYZGGLL):):BGG<L<LTM]M]^bMcdjMk<lm	"))@@BPRTXY99,,V44 	D^_99//CC	Ds   DD   4EEr:   )T)F)r
   rightr   )=rW   rX   rY   r   SignalFlags	RUN_FIRST__gsignals__r.   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r   rQ  rT  rX  rb  rd  rg  ri  rk  r   rN  r}  r|  r  r  staticmethodr  r  r  r  r  r  r  r  r  
ABORT_USERrV   r  r  r	  r  r  r  rZ   r[   s   @r   r]   r]      s}   %11;;T2F"..88$C ,,66bALPd".51$#&'8;
!""+!&F(8K?Z'
%&*
/+ %,4%@4"0   Z Z D6!padB
  * &
2:&>P;4Dr   r]   ),r   sysgi.repositoryr   r   r   r   r   r   r  r  r  r  r   r3   PILr	   r  r  r   error_messager%   exitr@  ImportError
simplejsonr   
expanduserr   r  r#   get_user_config_dirr  r  r   r  r   ABORT_ERRORr  r   r$   r+   Objectr]   r^   r   r   <module>r+     sE   
 
EE
 
ww#*+ww||4D446
HMV./ 9 4422!66 #:: 44 

C&;!'// ;!|dDgnn dDc  	-CHHQKK  s)   6C& D &D+D

D	DD