J0mh7 xdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZddlm Z ddl!Z"ddl#Z"ddl$Z"ddl%Z"ddl&m'Z(ddl)m*Z*dZ+e jXj[d d Z.d Z/d Z0d&d e1de2dzde2dzfdZ3de1de2de2dzfdZ4de2de5e1e1ffdZ6de7fdZ8ddde9e1de7de ddfdZ:dZ; d'dZGd d!Z?Gd"d#Z@Gd$d%e@ZAy)(zAbstract Apport user interface. This encapsulates the workflow and common code for any user interface implementation (like GTK, Qt, or CLI). N)Sequence)gettext)Any)impl)get_process_user_and_groupz2.28.1APPORT_SYMPTOMS_DIRz/usr/share/apport/symptomsi c tjd|jddjd}t |S#t t f$rYywxYw)zExtract process ID from report.z Pid: (.*) ProcStatusN)researchgetgroupint IndexErrorAttributeError)reportpids +/usr/lib/python3/dist-packages/apport/ui.pyget_pidr?sMii <(DEKKAN3x  's?AAAkeydefaultreturncj ttj|S#ttf$r|cYSwxYw)zGet an environment variable as integer. Return None if it doesn't exist or failed to convert to integer. The optional second argument can specify an alternate default. )rosenvironKeyError ValueError)rrs r _get_env_intr Hs3 2::c?## j !s 22nameuidc tjddddt||gddd}|jdk7s |jsyt |jj S) Npgrepz-nz-x-uTF)capture_outputchecktextr) subprocessrunstr returncodestdoutrstrip)r!r"processs r_get_newest_process_for_userr0Ts^nn $dCHd3  G Qgnn w~~##% &&ctd|}|iStjd|tjtjztj z} t jj|} tj|dDcic] }||vr|||c}S#t$ricYtj|SwxYw#tj|wxYwcc}w)zFind D-BUS address and XDG_DATA_DIRS for the given user. The D-BUS address and XDG_DATA_DIRS is needed for xdg-open. It is incredibly hard, or alternatively, unsafe to funnel it through pkexec/env/sudo, so grab it from gvfsd. gvfsd/proc/)DBUS_SESSION_BUS_ADDRESS XDG_DATA_DIRS) r0ropenO_RDONLYO_PATH O_DIRECTORYapport fileutilsget_process_environOSErrorclose)r" gvfsd_pid gvfsd_pid_fd gvfsd_envrs r_get_users_environrC`s-Wc:I 77  bkkBII5FL$$88F  A   )  Ys^      s*B(C(( C 3C C  CC%cttjjdxstjjdS)z:Check if a display server is specified in the environment.DISPLAYWAYLAND_DISPLAY)boolrrrr1r has_displayrI|s-  y)NRZZ^^C {46>>@t353F3 LL E z "C {llJJ$$&  Aq||G$l): 1 C   !#&&,,CKNN   __U]]C8   s#Dc tjt|dy#t$r,}|jtj k(rYd}~yYd}~yd}~wwxYw)z8Check if the process with the given ID is still running.rNFT)rkillrr>errnoESRCHrerrors r still_runningrksK C!   ;;%++ % & s" AAAct|tsJ |j|j |ri} t |d5}t t|j|d|ddd|d||}|s!tjjd|ytjjtjj|d|d<|s2d |vr#tj,j/|d }n t1d tj,j3|}|r|j5| |j7|d |vr|j?|rt#j$d d|vrdtj@vrd|vrd |vrtCd|d <nwtEjF|djIdsNtEjJ|djIds%tCd|djIdz|d <d|vr|jM} | r| |d<|jOddk(rDdtj@vr2|jQ} | r tCddjS| z|d <|ru t |d5}tjT|d|jW|ddddtj,jY|tjT|dyy#t$rYwxYw#1swYxYw#t $rt#j$dYpt&$rMtjjd |t)j*t#j$dYwxYw#t8$r |sd |vrYct:$r} t=| |d <Yd} ~ d} ~ wwxYw#t8$r |sd |vrYwxYw#1swY%xYw#t$r,} tjjd|| Yd} ~ Xd} ~ wwxYw)ayCollect information about report. Encapsulate calls to add_*_info() and update given report, so that this function is suitable for threading. ui must be a HookUI instance, it gets passed to add_hooks_info(). If reportfile is not None, the file is written back with the new data. If symptom_script is given, it will be run first (for run_symptom()). utf-8encodingexecNr*z8symptom script %s did not determine the affected packagerSymptomzsymptom script %s crashed:ExecutablePathzAcalled without a package, and report does not have ExecutablePathSnapUnreportableReasonCrashDBAPPORT_DISABLE_DISTRO_CHECKPackagez4This package does not seem to be installed correctlyzThis does not seem to be an official %s package. Please retry after updating the indexes of available packages, if that does not work then remove related third party packages and try again. DistroReleaseTitle ProblemTypeCrashAPPORT_IGNORE_OBSOLETE_PACKAGESzYou have some obsolete package versions installed. Please upgrade the following packages and check if the problem still occurs: %sz, abT)only_newzCannot update %s: %si)- isinstanceHookUI add_gdb_infor> add_os_infor7rpcompilereadr;loggingrjrpathsplitextbasename StopIterationsysexit Exception traceback print_excr<find_file_packager find_snap add_snap_infoadd_package_infor SystemErrorr+add_hooks_infor_ packagingis_distro_packagesplitis_native_origin_packagestandard_titlerobsolete_packagesjoinchmodwritemark_report_seen) r reportfilepackageuisymptom_scriptignore_uninstalledsymbfsnaprjtitleold_pkgss rthread_collect_infors b& !! !    nw7 F1WQVVX~v>E F"d5k&"-G$$N" " 0 01A1A.1Q RST UF9   v %&&88@P9QRGS     % %g .D T" 2(6)   $ HHQK '1CF*vV/C34N4F/0#449%++-a0#<<9%++-a0 .!1779!<=/0&f%%' #F7O  =!W, -RZZ ?++- +,@, (# ,$F' (  Lj$' /1Q' Q . / ))*5 U#]     F F  HHQK  NN !=~ N    ! HHQK (  "fF&:  2'*5z#$2D  &&*>  : / / L NN !7U K K  LsL L4&L',6L4#AL4 N-B$O$" P.*O;P L$#L$'L1,L44N*AN*)N*-O!O!OO!$O87O8;PP P=!P88P=cXeZdZUdZdZeed<dZeed<dZeed<dZ eed<dZ eed<y) ActionzAction to take on a problem report. Possible actions: examine the crash ('examine'), report the crash ('report'), restart the crashed application ('restart'), or ignore further crashes ('ignore'). FexamineignorerememberrrestartN) __name__ __module__ __qualname____doc__rrG__annotations__rrrrrHr1rrrEs;GTFDHdFDGTr1rceZdZdZdeefdZdZdZe dZ dZ e dZ e d Z d8d ed zd efd Zd efdZdZdZdZe deed ej,fdZdeed ej,fdZe dZdZdZdZdZdZded d fdZdZ d9dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z) d:d&ed'e*d zd e+fd(Z,d)Z-d*Z.d+Z/d,Z0d-Z1d.Z2d/e3d zd d fd0Z4d1Z5d2Z6d3Z7d4Z8d5Z9d6Z:d7Z;y ); UserInterfaceaApport user interface API. This provides an abstract base class for encapsulating the workflow and common code for any user interface implementation (like GTK, Qt, or CLI). A concrete subclass must implement all the abstract ui_* methods. argvcd|_d|_d|_d|_d|_d|_d|_ tjjd|_tj |j|j#||_y#t$r3}tjjdt|Yd}~md}~wt$r"tjjdYwxYw)z8Initialize program state and parse command line options.r;NFzDCould not import module, is a package upgrade in progress? Error: %sz8/etc/apport/crashdb.conf is damaged: No default database)gettext_domainr report_file cur_package offer_restartspecified_a_pkgupload_progressr;crashdb get_crashdb ImportErrorrfatalr+rr textdomain parse_argvrL)selfrrjs r__init__zUserInterface.__init__`s&37 '+"$# !>>55d;DL 4../OOD)   NN E      NN J  s$B C2)C+C21C2c|d}d|_tjdk(rtjj }ntjj }|D]Y}|j|s|jsJ|jddk(r|j|n|j|d}[|S)aPresent all currently pending crash reports. Ask the user what to do about them, and offer to file bugs for them. Crashes that occurred in a different desktop (logind) session than the one that is currently running are not processed. This skips crashes that happened during logout, which are uninteresting and confusing to see at the next login. Return True if at least one crash report was processed, False otherwise. FTrrzHang) rrgeteuidr;r<get_new_system_reportsget_new_reports load_reportr finish_hang run_crash)rresultreportsrs r run_crasheszUserInterface.run_crashess" ::<1 &&==?G&&668G A##A&;; ;{{=)V3  #q!F  r1cP||_ tjj||j s|j |sy|j sJd|j vry|j jddk(rd|j vrd|j vrd|j vrtjj|j jdtd }td |z}td }|jtd |z|d |ytjj}|j|}|j s |jrd|j vr|j!|j y|jr|jy|j"r|j#|j$r|j j' |j(r|j+|j |j syd|j vr1|j ddk7rtjj/||j0j3|j r3|j5ry|j7ry|j9yy#t$rYwxYw#t,$rYwxYw#t:$r<|jtdtdt=j>dYyt$r}|j@t@jBk(r tjDjGd|j@t@jHk(r:|jtdtdt=j>d|j@t@jJk(r:|jtd|jLt=j>dd}~wwxYw)zPresent and report a particular crash. If confirm is True, ask the user what to do about it, and offer to file a bug for it. If confirm is False, the user will not be asked, and the crash is reported right away. NIgnorerzr{SignalCoreDump Stacktracerrzunknown programz+Sorry, the program "%s" closed unexpectedlyzxYour computer does not have enough free memory to automatically analyze the problem and send a report to the developers. Problem in %s _MarkForUploadFalseInvalid problem reportz2You are not allowed to access this problem report.r zOut of memory, abortingErrorz@There is not enough disk space available to process this report.)'rr;r<rr>rrrrrrrui_error_messageallowed_to_reportui_present_report_detailsr collect_inforr mark_ignorerremember_send_reportrmark_report_uploadracceptshandle_duplicatecheck_unreportable file_reportPermissionErrorrrrgENOMEMrrENOSPCEIOstrerror)rrsubjectheadingfooterrresponserjs rrzUserInterface.run_crashsq'j    11+> ;;t'7'7 'D;; ;4;;&  .'9 +dkk1  3''**KKOO$4a8I6JKIJWT; %%o&0WIT&2J & 0 0 B B D 556GHH("2"2#4;;6%%'{{"   '') $$--hoo> ?? !DKK/KK 01W<  33K@||##DKK0 ((***,  "1O  n  6   ! !*+FG  HHQK {{ell*$$%>?  ,%%gJ=   )%%a(@&A5>>R  sK K(K($CK(+A1K(K(:AK(='K$ K(1A4K(&K(7K( KK(KK( K%"K($K%%K((AP%,P%4C,P  P%ctjj|tjj|y)zFinish processing a hanging application after the core pipe handler has handed the report back. This will signal to whoopsie that the report needs to be uploaded. N)r;r<rr)rs rrzUserInterface.finish_hangs, ++A.))!,r1c tjd|_|jjs%|j t dt dy |jj||jj|jjd d}tjj||_|jj#tjj%}|j'|t)|}|jrXtjj+|j|t-j.t)|t0j2n-t-j.t)|t0j4|j6r!|j9||j7y#t$r}t|dk(r:|j t dt dtjdnGt|d k(r9|j t d t d tjdYd }~ d }~wwxYw)aReport an application hanging. This will first present a dialog containing the information it can collect from the running application (everything but the trace) with the option of terminating or restarting the application, optionally reporting that this error occurred. A SIGABRT will then be sent to the process and a series of noninteractive processes will collect the remaining information and mark the report for uploading. rzNo PID specifiedz;You need to specify a PID. See --help for more information.Fzinvalid process Invalid PIDz(The specified process ID does not exist.r znot accessiblez Not your PIDz0The specified process ID does not belong to you.Nrrr ) modal_forT)r;ReportrrLrrr add_proc_inforr+rrrrr<rrrrrrmark_hanging_processrrfsignalSIGABRTSIGKILLr wait_for_pid)rrrjrrrs rrun_hangzUserInterface.run_hang'smmF+ yy}}  ! !$%OP   KK % %c * $$&{{/4!++==dC !",,>>@112CsSVx1X ??    1 1$++s C GGCHfnn - GGCHfnn -      c " LLN7 5z..%%m$a(R&S U//%%n%HI  sG J(BI==Jc tjt|dt jd6#t$r(}|jtj k(rYd}~yd}~wwxYw)zwaitpid() does not work for non-child processes. Query the process state in a loop, waiting for "no such process." rNr )rrfrr>rgrhtimesleepris rrzUserInterface.wait_for_pid[sX  C!$ JJqM ;;%++- s8 A)A$#A$$A)c^tjt|tjy)z!Kill process with signal SIGSEGV.N)rrfrrSIGSEGV)rs r kill_segvzUserInterface.kill_segvis C&..)r1Nrrc |jjsN|jjs8|s6|jry|j t dt dyt jd|_|jjr tjd|jjtjtjztjz}tjdtj|}tj|d 5}|jj!}d d d t#d }|t$zrd |j_n1|jj'|jj|n|jj5|jjr3|jjj7|j_|jjd k(rt9j:|_n|jj|_ |j?||jCry|jE|jGry |jd=|jjJr tjLjO|jjJ}|jQdr;tSj|d5}|jjU|d d d nattjLjO|jjJd5}|jjU|d d d yd} |jW| } | jr|jYy#1swYxYw#t($r'|j t dt dYyt*t,f$rQ}t/|dd t0j2k(rYd }~y|j t dt dYd }~yd }~wwxYw#t*$r}dtA|vrwdtA|vrj|j<s(|j t dt d|zn1|j t dt d|j<zYd }~yd }~wwxYw#tH$rYhwxYw#1swYxYw#1swYxYw#t,$r.}|j t dtA|Yd }~yd }~wwxYw)a@Report a bug. If a pid is given on the command line, the report will contain runtime debug information. Either a package or a pid must be specified; if none is given, show a list of symptoms. If a symptom script is given, this will be run first (used by run_symptom()). TzNo package specifiedzHYou need to specify a package or a PID. See --help for more information.FBugr4stat)dir_fdrmrnNlinux)r proc_pid_fdzPermission deniedzfThe specified process does not belong to you. Please run this program as the process owner or as root.rgrz6The specified process ID does not belong to a program.rzdoes not existrz7Symptom script %s did not determine an affected packagezPackage %s does not exist ProcCmdlinez.gzwbCannot create report)-rLrr run_symptomsrrr;rrrr7r8r9r:iorrr PF_KTHREADrrrr>getattrrgENOENTadd_proc_environr.rget_kernel_packagerrr+radd_extra_tagsrrsaver expanduserendswithgziprrr) rrr  stat_filerrflagsrjsavefilerrs rrun_report_bugzUserInterface.run_report_bugns\yy  ~  "  ! !()8 mmE*  99==!  ggTYY]]O,bkkBII.E.V GGFBKK L WWY9,Q668>>+D,DG :%(/DII%KK-- IIMM{.. KK ( ( * 99   $ 1 1 7 7 9DII  99   '(;;=D #yy00D     n -"  " " $   "  M* 99>> M77--diinn=$$U+8T2-a ))!,--bgg00@$G-1 ))!,- !% 556GHH  "u,,# %%)*M( 5'40ELL@!%%m$NO . CJ&+;s5z+I''))23ST() ))23569I9II  6   ---- M%%a(>&?ULL MsBO+1OA"O+%Q<) T AT<'T"AT< T/%T<O(#O++-Q9Q9(Q4 $Q44Q9< TA?T  T  T TT"T,'T</T94T<< U3$U..U3c Z|jj|jjs%|j t dt dy|jj |jj}|s|jt d}|sytjd|_ |jjr&|jjjg}n/|jj|jj}d}|D]Q}||_||jd<||jd< tj ||j1d d }S|s%|j3t dt dy|jj5|jj7|j9|jd= |jd=t=|jdk(r%|j3t dt dyd }|j?|}|jr?|jjA|jj|jd|dy y#t"$rot$j&j)t$j&j+tjj,d|d st/d |d YYwxYw#t:$rY#wxYw)z:Update an existing bug with locally collected information.zUpdating problem reportzYou are not the reporter or subscriber of this problem report, or the report is a duplicate or already closed. Please create a new report using "apport-bug".FaHYou are not the reporter of this problem report. It is much easier to mark a bug as a duplicate of another than to move your comments and attachments to a new bug. Subsequently, we recommend that you file a new bug report using "apport-bug" and make a comment in this bug about the one you file. Do you really want to proceed?r SourcePackagerwsource_.pyzPackage z. not installed and no hook available, ignoringT)rz$No additional information collected.Daterzapport information)change_descriptionattachment_comment)!r can_updaterL update_reportrr is_reporterui_question_yesnor;rrrr.get_affected_packagesrr get_versionrrrexistsrPACKAGE_HOOK_DIRprintrui_info_message add_user_inforrrlenrupdate)rr'rpkgsinfo_collectedprrs rrun_update_reportzUserInterface.run_update_reports||&&tyy'>'>?  ! !+,P ll..tyy/F/FG &&P AmmE* 99  II%%++-.D<<55dii6M6MND "A D +,DKK (%&DKK " %%a(     6!N# "&  +,a0V.W  !!# $$&  KK   O, t{{ q  +,a0V.W !112CD ?? LL   '' $#.#7  [ ww~~GGLL!?!?71#SAQRHQC'UVW  .   s%J"9 L"A1LL L*)L*c Ntjtjjtd}g}|D]}tjj |j dr2i} t|d5}tt|j|d|dddd|vr!tjjd |tjj#tjj |d }|j%|j'd ||f|sy |j)|j%d |j+t-d|Dcgc]\}}| c}}d } | E|| d d} | r7|j/tjjt| dzyy y#1swY.xYw#t$r8tjjd|tj YwxYwcc}}w)zlReport a bug from a list of available symptoms. Return False if no symptoms are available. z*.pyrrmrnrpNzsymptom script %s is invalidr*z0symptom script %s does not define run() functionr descriptionF)z Other problemNz+What kind of problem do you want to report?r r!T)globrrrsymptom_script_dirrr\r7rprrrr;rrjrrrappendrsortui_question_choicerr) rscriptssymptomsscriptrr symptom_namer8r!chsymptoms rrzUserInterface.run_symptomsLs ))BGGLL);VDE SFww'2237D &73Bq66:DABD $$F77++BGG,<,r!uoa(G##BGGLL1CWu_$UVEBB $$%CVL##% ( &G$G3 H! G G=HHcRtjjt|jj dz}tjj |s<|jtdtd|jj zy|j|y)z#Report a bug with a symptom script.r!zUnknown symptomzThe symptom "%s" is not known.N) rrrr:rLrCr+rrr)rr@s r run_symptomzUserInterface.run_symptomsx0$))2C2Ce2KLww~~f%  ! !#$23dii6G6GG   F#r1c|jjr|jy|jjr&|j |jj y|jj r|jS|jj|jS|jjrtty|jjr' |j|jjy|jj&r't)j*ddk(r%|j!t#dt#dy|j-dt#d t/j0d d gd t.j2t.j2 }|j4dk(rF t7|j8j;d|j_|jS|j!t#dt#ddz|j>jAzy|jCS#t$r.}|j!t#dt%|Yd}~yd}~wwxYw#t<$r'|j!t#dt#dYywxYw)zCall appropriate run_* method according to command line arguments. Return True if at least one report has been processed, and False otherwise. TNrXDG_SESSION_TYPEwaylandr a<The window option cannot be used on Wayland. Please find the window's process ID and then run 'ubuntu-bug '. The process ID can be found by running the System Monitor application. In the Processes tab, scroll until you find the correct application. The process ID is the number listed in the ID column.r z^After closing this message please click on an application window to report a problem about it.xprop _NET_WM_PIDF)r'r-stderrrz2xprop failed to determine process ID of the windowr)"rLrCrEhangingrrfilebugrr&r6versionr- __version__ crash_filerr>rrr+windowrgetenvr.r)r*PIPEr,rr-rrrKdecoder)rrjrIs rrun_argvzUserInterface.run_argvsZ 99       99   MM$))-- ( 99  &&( ( 99 " " .))+ + 99   +  99   Otyy334 99  yy+, 9%%,-D    H NN-(!! E 1$ $' (:(:(usage-p --packagezSpecify package name.help--tagr;tags@Add an extra tag to the report. Can be specified multiple times.actionrdestr]r& report_number)metavartyper NF) argparseArgumentParserr add_argumentr parse_argsrCrNrQrOrM)rparserrLs rparse_argv_updatezUserInterface.parse_argv_updates((q1K/LMD+A6M4NO UV   O_3O  ab*     r1c  t|dkDrdtjvrqtjj tjj |dtjj tjd|d<|d}|jds|jdr|j|St|dkDr"jdrtj}nd}tjtd}|jd d d d |xs td |jddd td|jddtd|xs td|jddd|xs td|jdd|xs td |jd!d"t|xs td#$|jd%d td&|jd'd(d)|xs&td*tj j"z|jd+d)td,|jd-d.gd/td01|jd2d3d td4|jd5d6tj7|j%|d8d}|j&}|`|j(r`|j*|j,|j.|j0|j2|j4g}t7|r|j9d9t|d8k(rjdr d:|_|S||Stjj;tjj t<|d;zrd:|_||_|S|jd<s|jd=r ||_|S|j?rd:|_||_|Sd>|vr |jAd?rtj jC|jEd>d@}|s|j9|dAnM|jGdBdCr!|j9|dD|dEdF|dBdGn|j9|dD|dEdHtIjJd8n@tMjN|} | s)|j9|dItIjJd8d:|_ |_(|Sd:|_d:|_)||_(|S)JzParse command line options. If a single argument is given without any options, this tries to "do what I mean". rAPPORT_INVOKED_ASz -update-bugz-collectz-bugNzI%(prog)s [options] [symptom|pid|package|program path|.apport/.crash file]rXz-fz --file-bug store_truerNzStart in bug filing mode. Requires --package and an optional --pid, or just a --pid. If neither is given, display a list of known symptoms. (Implied if a single argument is given.))rbrcr]z-wz--windowz7Click a window as a target for filing a problem report.)rbr]r%z --update-bugr&z;Start in bug updating mode. Can take an optional --package.)rfrcr]z-sz --symptomSYMPTOMzWFile a bug report about a symptom. (Implied if symptom name is given as only argument.))rer]rZr[zSpecify package name in --file-bug mode. This is optional if a --pid is specified. (Implied if package name is given as only argument.)r\z-Pz--pidzSpecify a running program in --file-bug mode. If this is specified, the bug report will contain more information. (Implied if pid is given as only argument.))rfr]z --hangingz*The provided pid is a hanging application.-cz --crash-filePATHzReport the crash from given .apport or .crash file instead of the pending ones in %s. (Implied if file is given as only argument.)z--savezIn bug filing mode, save the collected information into a file instead of reporting it. This file can then be reported later on from a different machine.r^r;r_r`raz-vz --versionz Print the Apport version number.issue?)nargsr]r zL-u/--update-bug option cannot be used together with options for a new reportTr!z.crashz.apport/z /snap/binrLzv is provided by a snap. No contact address has been provided; visit the forum at https://forum.snapcraft.io/ for help.contactr z$ is provided by a snap published by developerz. Contact them via z for help.z`. No contact address has been provided; visit the forum at https://forum.snapcraft.io/ for help.z does not belong to a package.)*r0rrrrdirnamerrrlrgSUPPRESSrhrrirr;r< report_dirrjrsr&rNrRrCrrQranyrjr+r:isdigitr\rrrrrrget_file_packagerr) rrcmdsuppressrkrLrsargs_only_for_new_reportsrpkgs rrzUserInterface.parse_argvs{ t9q="bjj0'',,GGOODG,GG$$RZZ0C%DEQq'C||M*cll:.F--d33 t9q=S\\&1((HH((J    O     LM     PNO     /     /     @    ?@    *@ )) *    ?    UV     56  G3X5F5FG  ab*  J       ) %,- 5 t9>cll62DLK =K 77>>"'',,'955=I JDL DLd _^^H % )B#DO\ W]]_DLDHR ME\ ,''11%++c2B22FGLL '"AB XXi,LL '" -./ $Y0 < LL '" -./DE  007LLE7*H!IJHHQKDLDL  DL#'D  DL r1c|dkrtjd|dz S|dkrtjd|dz Stjd|tdz S)zKFormat the given integer as humanly readable and i18n'ed file size.i@Bz%.1f KBg@@iʚ;z%.1f MBg.Az%.1f GB)locale format_stringfloat)sizes rformat_filesizezUserInterface.format_filesizes_ '>'' 4&=A A * '' 4)3CD D##IteJ6G/GHHr1c|jsJd}|jD]3}|j|s ||j|jz }5|S#t$r|t|j|z }Y^wxYw)z'Return the size of the complete report.rrget_on_disk_sizerr0rrrbs rget_complete_sizezUserInterface.get_complete_sizes{{{ 0A{{1~0DKKN;;==D 0  &0C A//D0s A$A<;A<c |jsJd}|jD]9}|dk7s |j|s ||j|jz };|S#t$r|t|j|z }YdwxYw)z&Return the size of the reduced report.rrrrs rget_reduced_sizezUserInterface.get_reduced_sizes{{{ 4AJ;;q>4 A ? ? AA  4 *4DKKN 334s A$BBc|jrd|jvrytjdy|jS)zCheck whether to offer the "Examine locally" button. This will be true if the report has a core dump, apport-retrace is installed and a terminal is available (see ui_has_terminal()). rFzapport-retrace)rshutilwhichui_has_terminalrs rcan_examine_locallyz!UserInterface.can_examine_locallys; {{j ; <<( ) 1##%%r1c <|jrd|jvsJtjdk(ritjtjddd|jj d|jdt jdyy)zReopen the crashed application.r rshrqRespawnCommandr N)rrforksetsidexeclprrrrs rrzUserInterface.restartss{{} ;;; 779> IIK II  0$++m2LM   HHQK r1c|jsJ|jtdtdtdtd|jzgd}|ytjj d}d|d }d }d |jj d d zd z}|d z|z|d z|z|dz|zdz|zd}|j||dy)zLocally examine crash report.zJThis will launch apport-retrace in a terminal window to examine the crash.zRun gdb sessionz1Run gdb session without downloading debug symbolsz)Update %s with fully symbolic stack traceFNz~/.cache/apport/retracezapport-retrace -S system -C z -v zapport-retrace 'z'\''z--gdb z --output  )rr r)rr=rrrrreplaceui_run_terminal)rr cache_dirretrace_with_downloadretrace_no_downloadfileargcmdss rrzUserInterface.examine s ** )  #$EF=>AQAQQ        GG&&'@A ">yk N/((00g>>D%x/'9"X-7${2W}t d }|jt d |d t|Yd}~yd}~wwxYw)z#Put whoopsie in auto or never mode./usr/bin/gdbuscall-y-dcom.ubuntu.WhoopsiePreferences-o/com/ubuntu/WhoopsiePreferences-mz/com.ubuntu.WhoopsiePreferences.SetReportCrashes) rrrrrrrrzCalledProcessErrorrr)rrrjmsgs rrz"UserInterface.remember_send_report-s%   # #$45E $**,    # #  667 ;C  ! !>?%tCJ<(    sA AB')4B""B'c|jd|jvry|jdjjdrc tj|jd}t |t sJd|vsJ tjjd||_ y tjjd|jd|_ y#tttf$r,}d|jdd||jd<Yd}~y d}~wwxYw#ttf$r#d |jdd |jd<YywxYw#ttf$r#d |jdd |jd<Yy wxYw) z+Process reports' CrashDB field, if present.NruT{rz=A package hook defines an invalid crash database definition:  rtFz@A package hook wants to send this report to the crash database "z" which does not exist.)rlstripr\ast literal_evalrdictAssertionError SyntaxErrorrr;r load_crashdbrrr)rspecrjs rcheck_report_crashdbz"UserInterface.check_report_crashdbVs ;; )4;;"> ;;y ! ( ( * 5 5c : '' I(>?!$---~%~ %~~::4F ( %~~99$ I@VW 7#K< %%)[[%;$EOFErrorzlibrjreprrrrr+r= ui_stop_info_collection_progressadd_tagspoprrr<rrsearch_bug_patternsget_bugpattern_baseurl return_valueknown anonymizer\_is_snapr ui_shutdown)rrr on_finishedexe_pathr orig_timecur_timehookuiorig_envicthreadrjresrbpthread known_threadvalanonymize_threads rrzUserInterface.collect_info~sa {{{(. $% KKOOM *g 5,$++:U KKOOM *g 5.DKK:W  ;;??= )W 4{{'7>(+8 EDKK0@$A#B!DC47 01M DKK/ww~~dkk2C&DE<C %r$++.?"@!ACKK 45##  t{{ */D /SDKK(=>?I 122774;;/?#@AJJKHH$07 ,-Ckk"23 4 01    3" KK # # %  2 2 4||##DKK0-/4;;.::??,!??33.. ((((&* 4  '')::<$,,.'')    " !!(+<&&(2$dkk)A$ I(>>#C11. iL4;;v+>>./$++i2HH C1#: I., ; KK(=>&$++5 KK8QCZ F+#t{{2 KK 5!T[[0 KK 399;HHQK$t{{)B $$T[[__Z%@%F%Fs%KL$++%  3 T[[8X( ;((''11$2B2BC88Ir*8999ftK'8$y/J9KDKK 45 9:D9ftK'89 9:DKK 45 18 ,-#t{{2$:S:S:U557M  .-?;;??=1\A +!??33;;::,,==?A4 '')::<$ c*'') R&&( ((*2:2G2G2IDKK/{{}-6%77<<--T[[N 8  ""$"++-::<$$))#.#++- &&("//1?d{69 N369 N3 &77t{{?T?T7U   " " $"++-668 $))#.#++-  & & (  1 1 3$4;;6(t{{:*$++=!KKOOM2>II(S%T[[8--/))23ST $$&HHQK  M s-$ $ 4::6<UVC;>%tDK=8QDKK 454;DKK 01!@+4;;><=S= $899@ $45 <NN((tE{;;! ! e* %KK 455%tDK=8QDKK 45R"-$ $$) HHQK s#him:m9o o2h=<h=m7jAmm'Am  mm65m69o (oo  o/.o/2ppcZ|jsJd|jvxsd|jvS)Nrrs)rrs rrzUserInterface._is_snaps+{{{t{{*Cf .CCr1c td|gdy#t$rtj|ddrYyd}YnwxYwn#t$r}d|}Yd}~nd}~wwxYwt d }t d |z}|j |||zy) zjOpen the given URL in a new browser window. Display an error dialog if everything fails. zxdg-openTrJNr )new autoraiser rzUnable to start web browserz'Unable to start web browser to open %s.)rdr> webbrowserr7rrr)rurl error_detailsrjrmessages ropen_urlzUserInterface.open_urls ) # *c!2F #??3A> "  # ) LM )/0=>D eW}%<=s-!;?;?;? AAAc  jsJjjjsyjjdjjdk(r jd= jd=d_fd}t j fd}tjD]!}|jdsj|=#jtjjjjj||f}|j |jrvj!j  jd d \}}}j#|||j%|j'|jrv|j'|jA} jCjjEj| } | rjG| yy#t$rYwxYw#t$rYwxYw#t j($rYwxYw#t*$rt-j.d Yt0j2t4j6j8f$r>}t;d } j=t;d| dt?|Yd}~yd}~wwxYw)zOUpload the current report and guide the user to the reporting web page.Nr ArchitectureStacktraceAddressSignaturec,t||z _yN)rr)senttotalrs rprogress_callbackz4UserInterface.file_report..progress_callbacks#(;#6D r1cvtj}j|||f|jyr) threadingEventputwait)rr(message_displayed message_queues rmessage_callbackz3UserInterface.file_report..message_callbacks2 ) 1    ud,=> ?  " " $r1rrTr)blocktimeoutr zHCannot connect to crash database, please check your Internet connection.zNetwork problemr)$rrrrrrqueue SimpleQueuelistr\ui_start_upload_progressr;ruploadrrui_set_upload_progressr.setrEmptyrrrsmtplibSMTPConnectErrorurllibrjURLErrorrrr+rui_stop_upload_progressget_comment_urlr) rr rrbupthreadrr( msg_displayedrjrticketrrs ` @rrzUserInterface.file_reports{{{ ||##DKK0  ;;??0 1T[[__^5T T KK 56   89 $ 7))+  % dkk" #A||C KKN # %%'??++<<&&++02BC,   ##%++D,@,@A1>1B1B"C2C2.E4((5!%%'&&(##%    &&( $$&ll**4;;?  MM#  {     H{{!  HHQK((&,,*?*?@ :C  ! !!$5"63%tCJ<8P Q   sm/ H<= I +I57A II5I5< I I  III2/I51I22I55K?,K?4K::K?c  tj|_t|d5}|jj |ddddd|jvr t d d |jvr&|jd j!d|_ytj$j'|jj)dd|_y#1swYxYw#t $r.d|_|jtdtdYy t$r6}d|_|jtd |jYd}~y d}~wtt ttjf$rE}d|_td }|jtd |d t|Yd}~y d}~wwxYw)zLoad report from given path and do some consistency checks. This might issue an error message and return False if the report cannot be processed, otherwise self.report is initialized and True is returned. rb compressed)binaryNrzz+Report does not contain "ProblemType" fieldzMemory exhaustionzEYour system does not have enough memory to process this crash report.Frrrrwrrrr T)r;rrr7loadr MemoryErrorrrr>r TypeErrorrrrjrrrr<rr)rrrrjrs rrzUserInterface.load_reports  --/DKdD! 9Q   < 8 9DKK/ !NOO00  ##{{95;;=a@D   &//AA  0"5 D C 9 9 DK  ! !%&5  DK  ! !!$<"=u~~ N:~tzzB DKMNC  ! !*+uDe -F   s@%C&C!C&C#C&&4GG$,E&G;;F;;Gc|jsJ|jj|jsyd|jvrt|jdtr+|jdj d|jd<d|jvr-t d|jdjdz}nd}|j|t d|jdzy y) znCheck if the current report is unreportable. If so, display an info message and return True. FrtUTF-8rwrrr z#The problem cannot be reported: %sT) rrrrbytesrUrrr.)rrs rrz UserInterface.check_unreportable?s {{{||##DKK0 4;; .$++&:;UC48KK(5&/ 01DKK'/*T[[-C-I-I-KA-NN  9:++234  r1c |jsJd|jvr> KK  0 r1rrctd)a Show details of the bug report. Return the action and options as an Action object: - Valid attributes are: report the crash ('report'), restart the crashed application ('restart'), or ignore further crashes ('ignore'). .this function must be overridden by subclassesNotImplementedError)rrrs rrz'UserInterface.ui_present_report_detailss""RSSr1ctd)z:Show an information message box with given title and text.r?r@rrr(s rr.zUserInterface.ui_info_message!"RSSr1ctd)z4Show an error message box with given title and text.r?r@rCs rrzUserInterface.ui_error_messagerDr1ctd)zOpen a indefinite progress bar for data collection. This tells the user to wait while debug information is being collected. r?r@rs rrz/UserInterface.ui_start_info_collection_progress ""RSSr1ctd)zaAdvance the data collection progress bar. This function is called every 100 ms. r?r@rs rrz/UserInterface.ui_pulse_info_collection_progress ""RSSr1ctd)z,Close debug data collection progress window.r?r@rs rrz.UserInterface.ui_stop_info_collection_progressrDr1ctd)z{Open progress bar for data upload. This tells the user to wait while debug information is being uploaded. r?r@rs rrz&UserInterface.ui_start_upload_progressrIr1progressctd)zUpdate data upload progress bar. Set the progress bar in the debug data upload progress window to the given ratio (between 0 and 1, or None for indefinite progress). This function is called every 100 ms. r?r@)rrLs rrz$UserInterface.ui_set_upload_progresss""RSSr1ctd)z(Close debug data upload progress window.r?r@rs rr!z%UserInterface.ui_stop_upload_progressrDr1cy)zdCalled right before terminating the program. This can be used for for cleaning up. NrHrs rrzUserInterface.ui_shutdownsr1ctd)zpCheck for a terminal window. Check if a terminal application is available and can be launched. r?r@rs rrzUserInterface.ui_has_terminalrIr1ctd)zRun command in a terminal window. Run given command in a terminal window; raise an exception if terminal cannot be opened. r?r@)rcommands rrzUserInterface.ui_run_terminalrGr1ctd)Show a yes/no question. Return True if the user selected "Yes", False if selected "No" or "None" on cancel/dialog closing. r?r@rr(s rr(zUserInterface.ui_question_yesnorGr1ctd)mShow an question with predefined choices. options is a list of strings to present. If multiple is True, they should be check boxes, if multiple is False they should be radio buttons. Return list of selected option indexes, or None if the user cancelled. If multiple == False, the list will always have one element. r?r@rr(optionsmultiples rr=z UserInterface.ui_question_choices""RSSr1ctd)mShow a file selector dialog. Return path if the user selected a file, or None if cancelled. r?r@rUs rui_question_filezUserInterface.ui_question_filerIr1r)NFN)TN)"Hxt--2h  **}S4Z}4}~]4]~1f $M"f (2D2D*UtCyUX-?-?UnII   & 0B'''R&RJNkZ D>*M^*X2@ D1GK T!% T9rs&       $ 38 ZZ^^$9;WX   c C$J #*  's ' 't 'CDcN8PTP .3& s)&&*&>A& &RNSN$b    TTD6^#^#B6r1