File indexing completed on 2024-05-19 05:49:20
0001 /*************************************************************************** 0002 * Copyright © 2009 Jonathan Thomas <echidnaman@kubuntu.org> * 0003 * Copyright © 2009-2021 Harald Sitter <apachelogger@ubuntu.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU General Public License as * 0007 * published by the Free Software Foundation; either version 2 of * 0008 * the License or (at your option) version 3 or any later version * 0009 * accepted by the membership of KDE e.V. (or its successor approved * 0010 * by the membership of KDE e.V.), which shall act as a proxy * 0011 * defined in Section 14 of version 3 of the license. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, * 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0016 * GNU General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU General Public License * 0019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0020 ***************************************************************************/ 0021 0022 #include "apportevent.h" 0023 0024 #include <QDebug> 0025 #include <QStandardPaths> 0026 #include <QDir> 0027 0028 #include <KProcess> 0029 #include <KToolInvocation> 0030 #include <KDirWatch> 0031 0032 ApportEvent::ApportEvent(QObject* parent) 0033 : Event(parent, "Apport") 0034 { 0035 const bool apportKde = QFile::exists("/usr/share/apport/apport-kde"); 0036 const bool apportGtk = QFile::exists("/usr/share/apport/apport-gtk"); 0037 qDebug() << "ApportEvent ::" 0038 << "apport-kde=" << apportKde 0039 << "apport-gtk=" << apportGtk; 0040 if (!apportKde && !apportGtk) { 0041 return; 0042 } 0043 qDebug() << "Using ApportEvent"; 0044 0045 auto apportDirWatch = new KDirWatch(this); 0046 apportDirWatch->addDir("/var/crash/"); 0047 connect(apportDirWatch, &KDirWatch::dirty, this, &ApportEvent::onDirty); 0048 0049 // Force check, we just started up and there might have been crashes on reboot 0050 show(); 0051 } 0052 0053 ApportEvent::~ApportEvent() 0054 { 0055 } 0056 0057 bool ApportEvent::reportsAvailable() 0058 { 0059 // TODO: there is also a --system arg for checkreports, update-notifier does seem to use 0060 // that in an either-or combo... so question is why does that --system arg exist at 0061 // all if we are supposed to either-or the results of two runs anyway? 0062 KProcess *apportProcess = new KProcess(); 0063 apportProcess->setProgram(QStringList() << "/usr/share/apport/apport-checkreports"); 0064 0065 if (apportProcess->execute() == 0) { 0066 return true; 0067 } 0068 return false; 0069 } 0070 0071 void ApportEvent::show() 0072 { 0073 if (isHidden()) { 0074 return; 0075 } 0076 0077 if (!reportsAvailable()) { 0078 qDebug() << "no reports available, aborting"; 0079 return; 0080 } 0081 0082 QString icon = QString("apport"); 0083 QString text(i18nc("Notification when apport detects a crash", 0084 "An application has crashed on your system (now or in the past)")); 0085 QStringList actions; 0086 actions << i18nc("Opens a dialog with more details", "Details"); 0087 actions << i18nc("Button to dismiss this notification once", "Ignore for now"); 0088 actions << i18nc("Button to make this notification never show up again", 0089 "Never show again"); 0090 0091 Event::show(icon, text, actions); 0092 } 0093 0094 void ApportEvent::batchUploadAllowed() 0095 { 0096 const QString script = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0097 "kubuntu-notification-helper/whoopsie-upload-all"); 0098 if (script.isEmpty()) { 0099 qWarning() << "ApportEvent: whoopsie-upload-all not found"; 0100 return; 0101 } 0102 qDebug() << "running" << script; 0103 KToolInvocation::kdeinitExec(script); 0104 } 0105 0106 void ApportEvent::run() 0107 { 0108 KToolInvocation::kdeinitExec("/usr/share/apport/apport-kde"); 0109 Event::run(); 0110 } 0111 0112 void ApportEvent::apportDirEvent() 0113 { 0114 qDebug(); 0115 0116 QDir dir(QLatin1String("/var/crash")); 0117 dir.setNameFilters(QStringList() << QLatin1String("*.crash")); 0118 0119 bool foundCrashFile = false; 0120 bool foundAutoUpload = false; 0121 foreach (const QFileInfo &fileInfo, dir.entryInfoList()) { 0122 CrashFile f(fileInfo); 0123 if (f.isAutoUploadAllowed()) 0124 foundAutoUpload = true; 0125 continue; 0126 if (f.isValid()) { 0127 foundCrashFile = true; 0128 continue; 0129 } 0130 } 0131 0132 qDebug() << "foundCrashFile" << foundCrashFile 0133 << "foundAutoUpload" << foundAutoUpload; 0134 0135 if (foundAutoUpload) { 0136 batchUploadAllowed(); 0137 } 0138 0139 if (foundCrashFile) { 0140 show(); 0141 } 0142 } 0143 0144 void ApportEvent::onDirty(const QString &path) 0145 { 0146 if (isHidden()) { 0147 return; 0148 } 0149 0150 qDebug() << path; 0151 if (path.isEmpty()) { // Check whole directory for possible crash files. 0152 apportDirEvent(); 0153 return; 0154 } 0155 0156 // Check param path for validity. 0157 CrashFile f(path); 0158 if (f.isAutoUploadAllowed()) { 0159 batchUploadAllowed(); 0160 } else if (f.isValid()) { 0161 show(); 0162 } 0163 }