
    XRgd                     .   d dl Z d dlZd dlZd dlZ ej                  dd       d dlmZmZmZm	Z	 ddl
mZmZmZmZ ddlmZmZmZmZ dZdZd	Ze	j.                  j1                         j3                  d
        G d d      Z G d dej6                        Zy)    NGtkz3.0)GLibGObjectGior      )cache_flatpak_aptdialogs)print_timingcheck_mldebugwarnafz/usr/share/linuxmint/iconsc                   t    e 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	 ddZd Zd Zd ZddZd Zd Zy)InstallerTaskinstallremoveupdatenoneokbroken	forbiddenunknowninit
installingupdatingremovingfinishedfailedNc                 t   t         j                  | _        |
| _        || _        || _        |	| _        d | _        d | _        g | _	        i | _
        g | _        || _        || _        | j                  | _        d | _        d | _        d | _        t'        j(                         | _        || _        || _        || _        || _        d| _        | j6                  | _        d | _        d | _        d | _        d| _         d | _!        g | _"        g | _#        g | _$        g | _%        g | _&        g | _'        g | _(        d| _)        d| _*        d| _+        |rv|j                  | _        |jX                  j[                  d      rd| _.        d| _/        d| _0        y |j\                  | _.        |j`                  | _0        |j^                  | _/        y y )Nc                       yNT r%       @/usr/lib/python3/dist-packages/mintcommon/installer/installer.py<lambda>z(InstallerTask.__init__.<locals>.<lambda>N       r&   c                       yr$   r%   r%   r&   r'   r(   z(InstallerTask.__init__.<locals>.<lambda>O   r)   r&   Fr   r    )1r   INSTALL_TASKtypeuse_mainloopparent_windowpkginfois_addon_taskas_pkgnameinitial_refs_to_updateref_prior_versions_dicttransaction_loginfo_ready_callbackinfo_error_callbackSTATUS_NONEinfo_ready_statusconfirmcancelexecuter   Cancellablecancellableclient_progress_cbclient_finished_cberror_cleanup_cbfinished_cleanup_cb
has_windowPROGRESS_STATE_INITprogress_statecurrent_package_nameerror_messagetransactionpkit_request_idexec_string
to_installto_reinstall	to_removeto_purge	to_updateto_downgradeto_skip_upgradedownload_sizeinstall_size
freed_sizepkg_hash
startswitharchbranchremote)selfr0   	installerclient_info_ready_callbackclient_info_error_callbackclient_installer_finished_cbclient_installer_progress_cbinstaller_cleanup_cbinstaller_error_cleanup_cbr1   r.   r/   s               r'   __init__zInstallerTask.__init__(   s    "..	(* * 	 ')# (*$!
 $> #=  "&!1!1 $" ??, #?">
 !;#7  #66$(!!   
 !  DI**3/	  #LL	%nn%nn r&   c                     | j                   t        j                  k(  r!|j                  | j                        | _        y |j                  | j                        | _        y N)r-   r   r,   get_versionr0   versionget_installed_version)r[   r\   s     r'   set_versionzInstallerTask.set_version   sB    99222$00>DL %::4<<HDLr&   c                     | j                   S re   )r6   r[   s    r'   get_transaction_logz!InstallerTask.get_transaction_log   s    ###r&   c                     | j                   y | j                  r1t        j                  | j                   | t        j                         y | j                  |        y N)priority)r7   r.   r   idle_addPRIORITY_DEFAULTrk   s    r'   call_info_ready_callbackz&InstallerTask.call_info_ready_callback   sD    ##+MM$22D4CXCXY$$T*r&   c                    	 |j                   | _        |r| j                  +t	        j
                  | j                  | j                         y | j                  r1t        j                  | j                  | t        j                         y | j                  |        y t	        j
                  | j                  | j                         y #  t        |      | _        Y xY wrn   )messagerH   strr8   r   
show_errorr/   r.   r   rp   rq   )r[   error
info_stages      r'   handle_errorzInstallerTask.handle_error   s    	,!&D ''/""4#5#5t7I7IJ  d66tG\G\]((.t1143E3EF	,!$UDs   C Cc                     | j                   sy | j                  r1t        j                  | j                   | t        j                         y | j                  |        y rn   )rC   r.   r   rp   rq   rk   s    r'   call_finished_cleanup_callbackz,InstallerTask.call_finished_cleanup_callback   sA    ''MM$22D4CXCXY$$T*r&   c                     | j                   sy | j                  r1t        j                  | j                   | t        j                         y | j                  |        y rn   )rB   r.   r   rp   rq   rk   s    r'   call_error_cleanup_callbackz)InstallerTask.call_error_cleanup_callback   sA    $$MM$//@U@UV!!$'r&   )FFNF)__name__
__module____qualname__r,   UNINSTALL_TASKUPDATE_TASKr9   	STATUS_OKSTATUS_BROKENSTATUS_FORBIDDENSTATUS_UNKNOWNrE   PROGRESS_STATE_INSTALLINGPROGRESS_STATE_UPDATINGPROGRESS_STATE_REMOVINGPROGRESS_STATE_FINISHEDPROGRESS_STATE_FAILEDrc   ri   rl   rr   ry   r{   r}   r%   r&   r'   r   r      s    LNK KIM"N ! ,((($
 z~e-NI$+G$+(r&   r   c                      e Zd Zdej                  j
                  ddfiZedfdZd Z	d Z
d1dZd1d	Zd
 Zd Zed        Zed        Z	 d2dZ	 d3dZd ZedfdZd Zd Zd Zd Zd Zed        Zed        Zd Zd Zd Zd Z d Z!d3d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, Z0d- Z1d. Z2d/ Z3d0 Z4y)4	Installerappstream-changedNr%   Fc                 b   t         j                  j                  |        i | _        || _        |r(t        j                  d      }|j                  | _        nd | _        d| _	        d| _
        d| _        | j                         | _        i | _        d | _        t        j                         | _        y )Nzmint-common-installer-tmp)prefixF)r   Objectrc   taskspkg_typetempfileNamedTemporaryFiler3   
cache_pathremotes_changedinitedhave_flatpak_get_flatpak_statusr   _init_cbtimestartup_timer)r[   r   tempr   s       r'   rc   zInstaller.__init__   s    %
 ++3NOAffDO"DO$! 446
!YY[r&   c                 b    	 t        j                  dd       ddlm} y#  t	        d       Y yxY w)NFlatpakz1.0r   )r   Tz`No flatpak support, install flatpak and gir1.2-flatpak-1.0 and restart mintinstall to enable it.F)girequire_versiongi.repositoryr   r   )r[   r   s     r'   r   zInstaller._get_flatpak_status   s2    	uy%0-	usts    .c                    | j                   t        k(  r| j                  st        d       yt	        j
                  d      | _        | j                         rd| _        i | _	        t        j                  | j                   | j                  | j                        | _
        | j                  j                  | j                  j                  k(  r$| j                  sd| _        | j!                          yy)z
        Loads the cache synchronously.  Returns True if all went ok, and returns False if there
        is no cache (or it's too old.)  You should then call init() with a callback so the cache
        can be regenerated.
        z?Not syncing for flatpaks only, as there is currently no supportTzcom.linuxmint.install)	schema_idF)r   PKG_TYPE_FLATPAKr   r   r   Settingssettings_fp_remotes_have_changedr   backend_tabler   PkgCacher   statusr   r   initialize_appstreamrk   s    r'   	init_synczInstaller.init_sync   s     ==,,T5F5FST/FG((*#'D ^^DMM4??DDUDUV
::

 4 44T=Q=QDK%%'r&   c                    i | _         t        j                  | j                  | j                  | j
                        | _        || _        | j                  j                  | j                  j                  k(  r4| j                  s(d| _
        t        j                  | j                         | S | j                  rt        d       | j                  j                  | j                         | S )z
        Loads the cache asynchronously.  If there is no cache (or it's too old,) it causes
        one to be generated and saved.  The ready_callback is called on idle once this is finished.
        Tz=Installer: Flatpak remotes have changed, forcing a new cache.)r   r   r   r   r   r   r   r   r   r   r   r   rp   _idle_cache_load_doner   force_new_cache_asyncr[   ready_callbacks     r'   r   zInstaller.init
  s    
  ^^DMM4??DDUDUV
&::

 4 44T=Q=QDKT778  ##UVJJ,,T-G-GHr&   c                 :    | j                   j                  |       y)zU
        Forces the cache to regenerate, calling read_callback when complete
        N)r   r   r   s     r'   force_new_cachezInstaller.force_new_cache!  s     	

((8r&   c                 8    | j                   j                          y)z>
        Forces the cache to regenerate synchronously
        N)r   r   rk   s    r'   force_new_cache_synczInstaller.force_new_cache_sync'  s     	

""$r&   c                    d| _         | j                  r| j                          d| _        | j                          t	        dt        j
                         | j                  z
  dz  z         | j                  r| j                          y y )NTFz$Full installer startup took %0.3f msg     @@)r   r   _store_remotesr   r   r   r   r   rk   s    r'   r   zInstaller._idle_cache_load_done-  sl    !#(D !!#4tGYGY9Y]c8cde==MMO r&   c                 *   d}d}| j                   j                  d      }| j                         }|D ]@  }|dz  }|j                  d|j                  dt        |j                        }||vs>d} n |st        |      |k7  rd}t        d|       |S )a  
        We check here for changed remotes.  We care if names, urls, and disabled status changed.
        The 'noenumerate' property won't change, and is usually marked on standalone (-source) ref
        installs.  We don't want to generate a new cache for those - their app can be accessed via
        installed apps, plus if you uninstall the app, the remote gets auto-removed.
        Fr   flatpak-remotesr   ::TzRemotes have changed:)	r   get_strvlist_flatpak_remotesr3   urlru   disabledlenr   )r[   changedreal_remote_countsaved_remotes
fp_remotesremote_infoitems          r'   r   z"Installer._fp_remotes_have_changed;  s     ../@A..0
% 	K"#.#3#3[__c+J^J^F_`D=(	 =!%66%w/r&   c                     g }| j                         }|D ]D  }|j                  d|j                  dt        |j                        }|j                  |       F | j                  j                  d|       y )Nr   r   )r   r3   r   ru   r   appendr   set_strv)r[   new_remotesr   r   r   s        r'   r   zInstaller._store_remotesZ  sj    ..0
% 	%K#.#3#3[__c+J^J^F_`Dt$	%
 	0+>r&   c                    |j                   | j                  j                         v rE| j                  |j                      }t        j                  |j
                  |       |j                  S t        || ||||| j                  | j                  ||
      }| j                  |      rt        j                  |_        nt        j                  |_        |j                  |        | j                  |      |_        |j                   j#                  d      r!t%        j&                  |       |j                  S t)        j&                  |       |j                  S )a  
        Initiates calculations for installing or removing a particular package
        (depending upon whether or not the selected package is installed.  Creates
        an InstallerTask instance and populates it with info relevant for display
        and for execution later.  When this is completed, ready_callback is called,
        with the newly-created task as its argument.  Note:  At that point, this is
        the *only* reference to the task object.  It can be safely discarded.  If
        the task is to be run, Installer.execute_task() is called, passing this task
        object, along with callback functions.  The task object is then added to a
        queue (and is tracked in self.tasks from there on out.)
        )r.   r/   r   )rV   r   keysr   rp   r7   r?   r   _task_finished_task_errorpkginfo_is_installedr   r-   r,   ri   get_appstream_pkg_for_pkginfor2   rW   r
   select_packagesr	   )	r[   r0   r]   r^   r_   r`   r.   r/   tasks	            r'   select_pkginfozInstaller.select_pkginfog  s    tzz00::g../DT55t<###Wd79S9;W!00$2B2B*6m	U $$W-%44DI%22DI88A&&s+  &  $$T*r&   c                     t        d| ||||| j                  | j                  |	      }t         j                  |_        |r|ng |_        t        j                  |       y)z
        Creates an InstallerTask populated with all flatpak packages that can be
        updated. If refs is empty, selects all possible updates, otherwise, only attempts
        to update refs.
        N)r.   )r   r   r   r   r-   r4   r	   select_updates)r[   refsr]   r^   r_   r`   r.   r   s           r'   select_flatpak_updatesz Installer.select_flatpak_updates  s[     T479S9;W!00$2B2B*6	8 "--	.2d#%r&   c                 @    t        j                  | j                        S )z
        Returns a list of flatpak pkginfos that can be updated.  Unlike
        prepare_flatpak_update, this is for the convenience of displaying information
        to the user.
        )r	   list_updated_pkginfosr   rk   s    r'   list_updated_flatpak_pkginfosz'Installer.list_updated_flatpak_pkginfos  s     --djj99r&   c                 <    | j                   j                  |||      S )z
        Attempts to find and return a PkgInfo object, given a package name.  If
        pkg_type is None, looks in first apt, then flatpaks.
        )r   find_pkginfo)r[   r3   r   rZ   s       r'   r   zInstaller.find_pkginfo  s    
 zz&&tXv>>r&   c                 `    | j                   r"t        j                  | j                  ||       yy)a;  
        Accepts a GFile to a .flatpakref on a local path.  If the flatpak's remote
        has not been previously added to the system installation, this also adds
        it and downloads Appstream info as well, before calling ready_callback with
        the created (or existing) PkgInfo as an argument.
        N)r   r	   get_pkginfo_from_filer   r[   filer   s      r'   get_pkginfo_from_ref_filez#Installer.get_pkginfo_from_ref_file  s(     **4::t^L r&   c                 r    | j                   r"t        j                  | j                  ||       y |dd       y)z
        Accepts a GFile to a .flatpakrepo on a local path.  Adds the remote if it
        doesn't exist already, fetches any appstream data, and then calls
        ready_callback
        Nzno-flatpak-support)r   r	   add_remote_from_repo_filer   r   s      r'   r   z#Installer.add_remote_from_repo_file  s.     ..tzz4P4!56r&   c                 F    | j                   rt        j                         S g S )z
        Returns a list of FlatpakRemoteInfos.  The remote_name can be used to match
        with PkgInfo.remote and the title is for display.
        )r   r	   list_remotesrk   s    r'   r   zInstaller.list_flatpak_remotes  s!    
 ((**Ir&   c                 v    | j                   r,t        j                         D ]  }|j                  |k(  s|c S  g S re   )r   r	   r   r3   )r[   remote_namerZ   s      r'   get_remote_info_for_namez"Installer.get_remote_info_for_name  s;    "//1 ";;+-!M" 	r&   c                     | j                   rl|j                  j                  d      rt        j                  |      S | j
                  r0|j                  j                  d      rt        j                  |      S y)z
        Returns whether or not a given package is currently installed.  This uses
        the AptCache or the FlatpakInstallation to check.
        r   r   F)r   rV   rW   r
   r   r   r	   r[   r0   s     r'   r   zInstaller.pkginfo_is_installed  s`    
 ;;**3/0099""w'7'7'B'B3'G44W==r&   c                 \    | j                   r t        j                  | j                         yy)z
        Flatpaks installed from .flatpakref files may not actually be in the saved
        pkginfo cache, specifically, if they're added from no-enumerate-marked remotes.
        This gets run at startup to collect and generate their info.
        N)r   r	   generate_uncached_pkginfosr   rk   s    r'   r   z$Installer.generate_uncached_pkginfos  s$     //

; r&   c                     | j                   r t        j                  | j                         t	        j
                          y)zs
        Loads and caches the xmlb pools so they can be used to provide
        display info for packages.
        )cbN)r   r	   r   on_appstream_loadedr
   get_apt_cacherk   s    r'   r   zInstaller.initialize_appstream  s/     ))T-E-EF 	r&   c                 F    | j                          | j                  d       y )Nr   )r   emitrk   s    r'   r   zInstaller.on_appstream_loaded   s    '')		%&r&   c                     d }|j                   j                  d      r(t        j                  |      }||| j                  |<   |S t        j                  |      }|S )Nr   )rV   rW   r
   search_for_pkginfo_apt_pkgr   r	   $search_for_pkginfo_appstream_package)r[   r0   backend_components      r'   r   z'Installer.get_appstream_pkg_for_pkginfo  sd     &&s+ $ ? ? H ,.?""7+ !  !) M Mg V  r&   c                     |j                   j                  d      rt        d       | j                  |      }|y|j	                         S )zT
        Return the launchables associated with the AsApp for this pkginfo.
        r   z(launch_flatpak: pkginfo is not a flatpakN)rV   rW   r   r   get_launchablesr[   r0   r2   s      r'   get_flatpak_launchablesz!Installer.get_flatpak_launchables  sH    
 &&s+<=33G<>%%''r&   c                 b    t        j                         j                         j                         S )z
        Return the root path for the flatpak installation (generally /var/lib/flatpak for system
        and ~/.local/share/flatpak for user.
        )r	   
get_fp_sysget_pathrk   s    r'   get_flatpak_root_pathzInstaller.get_flatpak_root_path  s%     ""$--/88::r&   c                     |j                   j                  d      ryt        j                  |      }t	        |      dk(  ry|S )zJ
        Returns an array of app ids of names of available addons
        r   Nr   )rV   rW   r	   _get_addons_for_pkginfor   )r[   r0   addonss      r'   
get_addonszInstaller.get_addons'  s?     &&s+11':v;!r&   c                    |rM|j                   j                  d      r2	 t        j                  |j                     j
                  j                  S | j                  |      }|j                  |      S # t        $ r Y -w xY w)z
        Returns the description of the package.  If for_search is True,
        this is the raw, unformatted string in the case of apt.
        r   )
rV   rW   r
   
_apt_cacher3   	candidatedescription	Exceptionr   get_description)r[   r0   
for_searchr2   s       r'   r
  zInstaller.get_description5  su    
 '**55c:w||4>>JJJ 33G<&&v..	  s   0A2 2	A>=A>c                 F    | j                  |      }|j                  |      S )z3
        Returns a list of screenshot urls
        )r   get_screenshotsr   s      r'   r  zInstaller.get_screenshotsC  s%     33G<&&v..r&   c                 F    | j                  |      }|j                  |      S zB
        Returns the current version string, if available
        )r   rf   r   s      r'   rf   zInstaller.get_versionK  s%     33G<""6**r&   c                 F    | j                  |      }|j                  |      S r  )r   get_developerr   s      r'   r  zInstaller.get_developerS  s%     33G<$$V,,r&   c                     |j                   j                  d      r| j                  |      S t        j                  |      S )zF
        Returns the currently deployed version of a flatpak.
        r   )rV   rW   rf   r	   _get_deployed_versionr   s     r'   rh   zInstaller.get_installed_version[  s<     &&s+##G,, 11'::r&   c                 F    | j                  |      }|j                  |      S )z
        Returns the home page url for a package.  If there is
        no url for the package, in the case of flatpak, the remote's url
        is displayed instead
        )r   get_homepage_urlr   s      r'   r  zInstaller.get_homepage_urlg  s%     33G<''//r&   c                 F    | j                  |      }|j                  |      S )z
        Returns the help url for a package.  If there is
        no url for the package, returns an empty string. Apt always returns
        an empty string.
        )r   get_help_urlr   s      r'   r  zInstaller.get_help_urlq  s%     33G<##F++r&   c                 N    t        | j                  j                               dkD  S )Nr   r   r   r   rk   s    r'   is_busyzInstaller.is_busy{  s    4::??$%))r&   c                 H    t        | j                  j                               S re   r  rk   s    r'   get_task_countzInstaller.get_task_count~  s    4::??$%%r&   c                     g }| j                   j                         D ]*  }|j                  | j                   |   j                         , |S re   )r   r   r   r0   )r[   pkginfosrV   s      r'   get_active_pkginfoszInstaller.get_active_pkginfos  sC    

) 	:HOODJJx0889	: r&   c                 b    |j                   j                  | j                  j                         v S )zF
        Returns whether a given task is currently executing.
        )r0   rV   r   r   r[   r   s     r'   task_runningzInstaller.task_running  s$     ||$$

(999r&   c                 "    |j                         S re   )r;   r!  s     r'   confirm_taskzInstaller.confirm_task  s    ||~r&   c                 $    |j                          y re   )r<   r!  s     r'   cancel_taskzInstaller.cancel_task  s    r&   c                     |j                   |j                   j                  }nd}|| j                  |<   t        d|d|j                  d       |j                          y)aE  
        Executes a given task.  The client_finished_cb is required always, to notify
        when the task completes. The progress and error callbacks are optional.  If
        they're left out, a standalone progress window is created to allow the user to
        see the task's progress (and cancel it if desired.)
        NupdateszStarting task for package z, type '')r0   rV   r   r   r-   r=   r[   r   keys      r'   execute_taskzInstaller.execute_task  sI     <<#,,''CC

33		JKr&   c                     |j                   s	 | j                  d= t        d       n2|j                   j                  }|r	 | j                  |= t        d|       | j	                  |       y #  Y xY w#  Y xY w)Nr(  zDone with update task (success)zDone with task (success)r0   r   r   rV   _post_task_updater*  s      r'   r   zInstaller._task_finished  u    ||JJy)78 ,,''C

34c: 	t$   A+  A2 +A/2A6c                     |j                   s	 | j                  d= t        d       n2|j                   j                  }|r	 | j                  |= t        d|       | j	                  |       y #  Y xY w#  Y xY w)Nr(  zDone with update task (failure)zDone with task (failure)r.  r*  s      r'   r   zInstaller._task_error  r0  r1  c                     |j                   rX|j                   j                  j                  d      r3t        j                  | j
                  |f      }|j                          y | j                  |       y )Nr   )targetargs)r0   rV   rW   	threadingThread_apt_post_task_update_threadstart_run_client_callback)r[   r   threads      r'   r/  zInstaller._post_task_update  sS    <<DLL11<<SA%%T-N-NVZU\]FLLN%%d+r&   c                 N    t        j                          | j                  |       y re   )r
   sync_cache_installed_statesr:  r!  s     r'   r8  z&Installer._apt_post_task_update_thread  s    ((* 	!!$'r&   c                 ~    |j                   r1t        j                  |j                   |t        j                         y y rn   )rA   r   rp   r   rq   r!  s     r'   r:  zInstaller._run_client_callback  s.    ""T44dTEZEZ[ #r&   re   )FNr~   )5r   r   r   r   SignalFlagsRUN_LAST__gsignals__PKG_TYPE_ALLrc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r
  r  rf   r  rh   r  r  r  r  r  r"  r$  r&  r,  r   r   r/  r8  r:  r%   r&   r'   r   r      sT   g11::D"EL !-5 ).	:.9%  < 
? 
? :>) \ -2&(: +7t ?M
7 < < 	 	'
!(;//+-
;0,*&:&%&%&,(\r&   r   )r6  r   r   r   r   r   r   r   r   r   r+   r   r	   r
   r   miscr   r   r   r   rB  PKG_TYPE_APTr   	IconThemeget_defaultappend_search_pathr   r   r   r%   r&   r'   <module>rH     s       	   5%   1 1 , , 5 5      . ./K Lr( r(hW\ W\r&   