Порівняти коміти
	
		
			15 Коміти
		
	
	
		
			v0.2
			...
			11decb757f
		
	
	| Автор | SHA1 | Дата | |
|---|---|---|---|
| 11decb757f | |||
| b71c234fb4 | |||
| bc908a1038 | |||
| 8ba4ee5847 | |||
| 451c79088a | |||
| 1a39118470 | |||
| 0d2e518000 | |||
| b108cb7151 | |||
| c82cf03814 | |||
| 8a82da95bd | |||
| a408173064 | |||
| dd479fa668 | |||
| e76988ee77 | |||
| f29f997289 | |||
| afa9d33f3d | 
							
								
								
									
										33
									
								
								gui/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								gui/main.cpp
									
									
									
									
									
								
							| @@ -26,8 +26,7 @@ void enableIpcSandbox() | ||||
| 	policy->namespace_options = EXILE_UNSHARE_USER | EXILE_UNSHARE_MOUNT | EXILE_UNSHARE_NETWORK; | ||||
| 	policy->no_new_privs = 1; | ||||
| 	policy->drop_caps = 1; | ||||
| 	policy->vow_promises = | ||||
| 		exile_vows_from_str("thread cpath wpath rpath unix stdio prot_exec proc shm fsnotify ioctl error"); | ||||
| 	policy->vow_promises = exile_vows_from_str("thread cpath rpath unix stdio proc error"); | ||||
| 	policy->mount_path_policies_to_chroot = 1; | ||||
|  | ||||
| 	QString ipcSocketPath = Common::ipcSocketPath(); | ||||
| @@ -35,6 +34,12 @@ void enableIpcSandbox() | ||||
| 	QString ipcSocketPathDir = info.absolutePath(); | ||||
| 	std::string stdIpcSocketPath = ipcSocketPathDir.toStdString(); | ||||
|  | ||||
| 	/* we only need the 'server' side of the 'unix' vow (for unix sockets)'. The process | ||||
| 	 * has no business to connect anywhere. | ||||
| 	 * | ||||
| 	 * Maybe this case should be handled by exile at some point, but for now deal with it here */ | ||||
| 	exile_append_syscall_policy(policy, EXILE_SYS(connect), EXILE_SYSCALL_DENY_RET_ERROR, NULL, 0); | ||||
|  | ||||
| 	/* ALLOW_EXEC is needed for fallback, not in landlock mode. It does not allow executing anything though here | ||||
| 	 * due to the vows */ | ||||
| 	exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_EXEC, "/"); | ||||
| @@ -43,9 +48,26 @@ void enableIpcSandbox() | ||||
| 	int ret = exile_enable_policy(policy); | ||||
| 	if(ret != 0) | ||||
| 	{ | ||||
| 		qDebug() << "Failed to establish sandbox"; | ||||
| 		qDebug() << "Failed to establish sandbox" << Qt::endl; | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	/* Arguments are irrelevant for sandbox test, just want to silence analyzer/compiler warnings */ | ||||
| 	ret = socket(AF_INET, SOCK_STREAM, 0); | ||||
| 	if(ret != -1 || errno != EACCES) | ||||
| 	{ | ||||
| 		qCritical() << "Sandbox sanity check failed" << Qt::endl; | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	const struct sockaddr *addr = {}; | ||||
| 	ret = connect(3, addr, sizeof(*addr)); | ||||
| 	if(ret != -1 || errno != EACCES) | ||||
| 	{ | ||||
| 		qCritical() << "Sandbox sanity check failed" << Qt::endl; | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	exile_free_policy(policy); | ||||
| } | ||||
|  | ||||
| @@ -66,7 +88,7 @@ int main(int argc, char *argv[]) | ||||
| 			{ | ||||
| 				enableIpcSandbox(); | ||||
| 			} | ||||
| 			QApplication a(argc, argv); | ||||
| 			QCoreApplication a(argc, argv); | ||||
|  | ||||
| 			IpcServer *ipcserver = new IpcServer(); | ||||
| 			qDebug() << "Launching IPC Server"; | ||||
| @@ -120,7 +142,6 @@ int main(int argc, char *argv[]) | ||||
| 	} | ||||
| 	Common::setupAppInfo(); | ||||
| 	QCommandLineParser parser; | ||||
| 	parser.addOption({{"s", "no-sandbox"}, "Disable sandboxing"}); | ||||
| 	QStringList appArgs; | ||||
| 	for(int i = 0; i < argc; i++) | ||||
| 	{ | ||||
| @@ -128,6 +149,7 @@ int main(int argc, char *argv[]) | ||||
| 	} | ||||
| 	parser.parse(appArgs); | ||||
|  | ||||
| 	QApplication a(argc, argv); | ||||
| 	try | ||||
| 	{ | ||||
| 		Common::ensureConfigured(); | ||||
| @@ -138,7 +160,6 @@ int main(int argc, char *argv[]) | ||||
| 		QMessageBox::critical(nullptr, "Error", e.message); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	QApplication a(argc, argv); | ||||
| 	a.setWindowIcon(QIcon(":/looqs.svg")); | ||||
| 	QObject::connect(&a, &QApplication::aboutToQuit, &process, &QProcess::kill); | ||||
|  | ||||
|   | ||||
| @@ -192,12 +192,6 @@ void MainWindow::connectSignals() | ||||
|  | ||||
| 			QMessageBox::about(this, "About looqs", html); | ||||
| 		}); | ||||
| 	connect(ui->menuOpenConfigInTextEditorAction, &QAction::triggered, this, | ||||
| 			[this](bool checked) | ||||
| 			{ | ||||
| 				QSettings setting; | ||||
| 				QDesktopServices::openUrl(setting.fileName()); | ||||
| 			}); | ||||
| 	connect(ui->menuAboutQtAction, &QAction::triggered, this, | ||||
| 			[this](bool checked) { QMessageBox::aboutQt(this, "About Qt"); }); | ||||
| 	connect(ui->menuSyncIndexAction, &QAction::triggered, this, &MainWindow::startIndexSync); | ||||
| @@ -215,6 +209,7 @@ void MainWindow::connectSignals() | ||||
| 			}); | ||||
| 	connect(this, &MainWindow::beginIndexSync, indexSyncer, &IndexSyncer::sync); | ||||
| 	connect(&this->progressDialog, &QProgressDialog::canceled, indexSyncer, &IndexSyncer::cancel); | ||||
| 	connect(ui->btnSaveSettings, &QPushButton::clicked, this, &MainWindow::saveSettings); | ||||
| } | ||||
|  | ||||
| void MainWindow::startIndexSync() | ||||
| @@ -236,6 +231,7 @@ void MainWindow::startIndexSync() | ||||
|  | ||||
| 	emit beginIndexSync(); | ||||
| } | ||||
|  | ||||
| void MainWindow::spinPreviewPageValueChanged(int val) | ||||
| { | ||||
| 	makePreviews(val); | ||||
| @@ -253,6 +249,7 @@ void MainWindow::startIndexing() | ||||
|  | ||||
| 	ui->previewsTab->setEnabled(false); | ||||
| 	ui->resultsTab->setEnabled(false); | ||||
| 	ui->settingsTab->setEnabled(false); | ||||
| 	ui->txtPathScanAdd->setEnabled(false); | ||||
| 	ui->txtSearch->setEnabled(false); | ||||
| 	ui->previewProcessBar->setValue(0); | ||||
| @@ -289,6 +286,7 @@ void MainWindow::finishIndexing() | ||||
| 	ui->btnStartIndexing->setText("Start indexing"); | ||||
| 	ui->previewsTab->setEnabled(true); | ||||
| 	ui->resultsTab->setEnabled(true); | ||||
| 	ui->settingsTab->setEnabled(true); | ||||
| 	ui->txtPathScanAdd->setEnabled(true); | ||||
| 	ui->txtSearch->setEnabled(true); | ||||
| } | ||||
| @@ -351,6 +349,49 @@ void MainWindow::tabChanged() | ||||
| 			makePreviews(ui->spinPreviewPage->value()); | ||||
| 		} | ||||
| 	} | ||||
| 	/* Settings tab active */ | ||||
| 	if(ui->tabWidget->currentIndex() == 3) | ||||
| 	{ | ||||
| 		initSettingsTabs(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::initSettingsTabs() | ||||
| { | ||||
| 	QSettings settings; | ||||
|  | ||||
| 	QString pdfViewerCmd = settings.value(SETTINGS_KEY_PDFVIEWER).toString(); | ||||
| 	QString excludedPaths = Common::excludedPaths().join(';'); | ||||
| 	QString mountPaths = Common::mountPaths().join(';'); | ||||
| 	QString databasePath = Common::databasePath(); | ||||
| 	int numPagesPerPreview = settings.value(SETTINGS_KEY_PREVIEWSPERPAGE, 20).toInt(); | ||||
|  | ||||
| 	ui->txtSettingPdfPreviewerCmd->setText(pdfViewerCmd); | ||||
| 	ui->txtSettingIgnoredPaths->setText(excludedPaths); | ||||
| 	ui->txtSettingMountPaths->setText(mountPaths); | ||||
| 	ui->spinSettingNumerPerPages->setValue(numPagesPerPreview); | ||||
| 	ui->txtSettingDatabasePath->setText(databasePath); | ||||
| } | ||||
|  | ||||
| void MainWindow::saveSettings() | ||||
| { | ||||
| 	QSettings settings; | ||||
|  | ||||
| 	QString pdfViewerCmd = ui->txtSettingPdfPreviewerCmd->text(); | ||||
| 	QStringList excludedPaths = ui->txtSettingIgnoredPaths->text().split(';'); | ||||
| 	QStringList mountPaths = ui->txtSettingMountPaths->text().split(';'); | ||||
| 	QString databasePath = ui->txtSettingDatabasePath->text(); | ||||
|  | ||||
| 	settings.setValue(SETTINGS_KEY_PDFVIEWER, pdfViewerCmd); | ||||
| 	settings.setValue(SETTINGS_KEY_EXCLUDEDPATHS, excludedPaths); | ||||
| 	settings.setValue(SETTINGS_KEY_MOUNTPATHS, mountPaths); | ||||
| 	settings.setValue(SETTINGS_KEY_PREVIEWSPERPAGE, ui->spinSettingNumerPerPages->value()); | ||||
| 	settings.setValue(SETTINGS_KEY_DBPATH, databasePath); | ||||
|  | ||||
| 	settings.sync(); | ||||
|  | ||||
| 	QProcess::startDetached(qApp->arguments()[0], qApp->arguments().mid(1)); | ||||
| 	qApp->quit(); | ||||
| } | ||||
|  | ||||
| void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration) | ||||
| @@ -389,7 +430,7 @@ void MainWindow::lineEditReturnPressed() | ||||
| 		ui->lblSearchResults->setText("Invalid paranthesis"); | ||||
| 		return; | ||||
| 	} | ||||
| 	if(indexerTabActive()) | ||||
| 	if(ui->tabWidget->currentIndex() > 1) | ||||
| 	{ | ||||
| 		ui->tabWidget->setCurrentIndex(0); | ||||
| 	} | ||||
| @@ -454,6 +495,11 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| 		bool exists = pathInfo.exists(); | ||||
| 		if(exists) | ||||
| 		{ | ||||
| 			if(!result.wasContentSearch) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly... | ||||
| 			{ | ||||
| 				if(PreviewGenerator::get(pathInfo) != nullptr) | ||||
| @@ -502,7 +548,7 @@ void MainWindow::makePreviews(int page) | ||||
| 	scaleText.chop(1); | ||||
|  | ||||
| 	QVector<QString> wordsToHighlight; | ||||
| 	QRegularExpression extractor(R"#("([^"]*)"|(\p{L}+))#"); | ||||
| 	QRegularExpression extractor(R"#("([^"]*)"|((\p{L}|\p{N})+))#"); | ||||
| 	for(const Token &token : this->contentSearchQuery.getTokens()) | ||||
| 	{ | ||||
| 		if(token.type == FILTER_CONTENT_CONTAINS) | ||||
|   | ||||
| @@ -61,6 +61,7 @@ class MainWindow : public QMainWindow | ||||
| 	void openDocument(QString path, int num); | ||||
| 	void openFile(QString path); | ||||
| 	unsigned int currentPreviewGeneration = 1; | ||||
| 	void initSettingsTabs(); | ||||
|   private slots: | ||||
| 	void lineEditReturnPressed(); | ||||
| 	void treeSearchItemActivated(QTreeWidgetItem *item, int i); | ||||
| @@ -73,6 +74,7 @@ class MainWindow : public QMainWindow | ||||
| 	void finishIndexing(); | ||||
| 	void addPathToIndex(); | ||||
| 	void startIndexSync(); | ||||
| 	void saveSettings(); | ||||
|  | ||||
|   signals: | ||||
| 	void startIpcPreviews(RenderConfig config, const QVector<RenderTarget> &targets); | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>1221</width> | ||||
|     <height>709</height> | ||||
|     <width>1280</width> | ||||
|     <height>736</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
| @@ -27,7 +27,7 @@ | ||||
|        <enum>QTabWidget::South</enum> | ||||
|       </property> | ||||
|       <property name="currentIndex"> | ||||
|        <number>0</number> | ||||
|        <number>3</number> | ||||
|       </property> | ||||
|       <widget class="QWidget" name="resultsTab"> | ||||
|        <attribute name="title"> | ||||
| @@ -81,8 +81,8 @@ | ||||
|             <rect> | ||||
|              <x>0</x> | ||||
|              <y>0</y> | ||||
|              <width>1185</width> | ||||
|              <height>419</height> | ||||
|              <width>1244</width> | ||||
|              <height>446</height> | ||||
|             </rect> | ||||
|            </property> | ||||
|            <layout class="QHBoxLayout" name="horizontalLayout"/> | ||||
| @@ -344,6 +344,145 @@ | ||||
|         </item> | ||||
|        </layout> | ||||
|       </widget> | ||||
|       <widget class="QWidget" name="settingsTab"> | ||||
|        <attribute name="title"> | ||||
|         <string>Settings</string> | ||||
|        </attribute> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||
|         <item> | ||||
|          <widget class="QGroupBox" name="groupPdfSettings"> | ||||
|           <property name="title"> | ||||
|            <string>PDF Viewer</string> | ||||
|           </property> | ||||
|           <layout class="QVBoxLayout" name="verticalLayout_5"> | ||||
|            <item> | ||||
|             <widget class="QLabel" name="label_2"> | ||||
|              <property name="text"> | ||||
|               <string>Command to open PDF pages in (%f = file path; %p = page number)</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QLineEdit" name="txtSettingPdfPreviewerCmd"/> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QGroupBox" name="groupMountPaths"> | ||||
|           <property name="title"> | ||||
|            <string>Mount paths</string> | ||||
|           </property> | ||||
|           <layout class="QVBoxLayout" name="verticalLayout_7"> | ||||
|            <item> | ||||
|             <widget class="QLabel" name="lblMountPaths"> | ||||
|              <property name="text"> | ||||
|               <string>Path prefixes of files that should not be removed during sync, even if they cannot be accessed (e . g. files indexed on external disks) . Separated by ;</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QLineEdit" name="txtSettingMountPaths"/> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QGroupBox" name="groupBox"> | ||||
|           <property name="title"> | ||||
|            <string>Ignored paths</string> | ||||
|           </property> | ||||
|           <layout class="QVBoxLayout" name="verticalLayout_8"> | ||||
|            <item> | ||||
|             <widget class="QLabel" name="label_3"> | ||||
|              <property name="text"> | ||||
|               <string>Path prefixes that should always be ignored during indexing (will be applied before the ignore patterns). Separated by ;</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QLineEdit" name="txtSettingIgnoredPaths"/> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QGroupBox" name="groupSettingDatabasePath"> | ||||
|           <property name="title"> | ||||
|            <string>Database path</string> | ||||
|           </property> | ||||
|           <layout class="QVBoxLayout" name="verticalLayout_10"> | ||||
|            <item> | ||||
|             <widget class="QLabel" name="lblSettingDatabasePath"> | ||||
|              <property name="text"> | ||||
|               <string>Path of the database. Note: Changing it here will create an empty, new database. The old will not be moved.  </string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QLineEdit" name="txtSettingDatabasePath"/> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QGroupBox" name="Misc"> | ||||
|           <property name="title"> | ||||
|            <string>Misc</string> | ||||
|           </property> | ||||
|           <layout class="QVBoxLayout" name="verticalLayout_9"> | ||||
|            <item> | ||||
|             <layout class="QHBoxLayout" name="horizontalLayout_9"> | ||||
|              <item> | ||||
|               <widget class="QLabel" name="label_4"> | ||||
|                <property name="text"> | ||||
|                 <string>Max number of previews per 'page' in 'Previews' tab: </string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item> | ||||
|               <widget class="QSpinBox" name="spinSettingNumerPerPages"/> | ||||
|              </item> | ||||
|              <item> | ||||
|               <spacer name="horizontalSpacer_2"> | ||||
|                <property name="orientation"> | ||||
|                 <enum>Qt::Horizontal</enum> | ||||
|                </property> | ||||
|                <property name="sizeHint" stdset="0"> | ||||
|                 <size> | ||||
|                  <width>40</width> | ||||
|                  <height>20</height> | ||||
|                 </size> | ||||
|                </property> | ||||
|               </spacer> | ||||
|              </item> | ||||
|             </layout> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <spacer name="verticalSpacer"> | ||||
|           <property name="orientation"> | ||||
|            <enum>Qt::Vertical</enum> | ||||
|           </property> | ||||
|           <property name="sizeHint" stdset="0"> | ||||
|            <size> | ||||
|             <width>20</width> | ||||
|             <height>40</height> | ||||
|            </size> | ||||
|           </property> | ||||
|          </spacer> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="btnSaveSettings"> | ||||
|           <property name="text"> | ||||
|            <string>Save settings and restart</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </widget> | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item> | ||||
| @@ -368,7 +507,7 @@ | ||||
|     <rect> | ||||
|      <x>0</x> | ||||
|      <y>0</y> | ||||
|      <width>1221</width> | ||||
|      <width>1280</width> | ||||
|      <height>35</height> | ||||
|     </rect> | ||||
|    </property> | ||||
| @@ -376,7 +515,6 @@ | ||||
|     <property name="title"> | ||||
|      <string>looqs</string> | ||||
|     </property> | ||||
|     <addaction name="menuOpenConfigInTextEditorAction"/> | ||||
|     <addaction name="menuSyncIndexAction"/> | ||||
|     <addaction name="menuAboutAction"/> | ||||
|     <addaction name="menuAboutQtAction"/> | ||||
| @@ -389,11 +527,6 @@ | ||||
|     <string>About</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="menuOpenConfigInTextEditorAction"> | ||||
|    <property name="text"> | ||||
|     <string>Open config in text editor</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="menuAboutQtAction"> | ||||
|    <property name="text"> | ||||
|     <string>About Qt</string> | ||||
|   | ||||
| @@ -14,13 +14,6 @@ | ||||
| #include "databasefactory.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| #define SETTINGS_KEY_DBPATH "dbpath" | ||||
| #define SETTINGS_KEY_FIRSTRUN "firstrun" | ||||
| #define SETTINGS_KEY_IPCSOCKETPATH "ipcsocketpath" | ||||
| #define SETTINGS_KEY_PDFVIEWER "pdfviewer" | ||||
| #define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths" | ||||
| #define SETTINGS_KEY_MOUNTPATHS "mountpaths" | ||||
|  | ||||
| inline void initResources() | ||||
| { | ||||
| 	Q_INIT_RESOURCE(migrations); | ||||
| @@ -91,10 +84,10 @@ void Common::setPdfViewer() | ||||
| void Common::ensureConfigured() | ||||
| { | ||||
| 	QSettings settings; | ||||
| 	QVariant firstRun = settings.value(SETTINGS_KEY_FIRSTRUN); | ||||
| 	if(!firstRun.isValid()) | ||||
| 	QString dbpath = databasePath(); | ||||
| 	if(dbpath == "") | ||||
| 	{ | ||||
| 		QString dbpath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); | ||||
| 		dbpath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); | ||||
| 		QDir dir; | ||||
| 		if(!dir.exists(dbpath)) | ||||
| 		{ | ||||
| @@ -104,38 +97,34 @@ void Common::ensureConfigured() | ||||
| 			} | ||||
| 		} | ||||
| 		dbpath += "/looqs.sqlite"; | ||||
| 	} | ||||
| 	if(!QFile::exists(dbpath)) | ||||
| 	{ | ||||
| 		if(!initSqliteDatabase(dbpath)) | ||||
| 		{ | ||||
| 			throw LooqsGeneralException("Failed to initialize sqlite database"); | ||||
| 		} | ||||
|  | ||||
| 		settings.setValue(SETTINGS_KEY_FIRSTRUN, false); | ||||
| 		settings.setValue(SETTINGS_KEY_DBPATH, dbpath); | ||||
| 		setPdfViewer(); | ||||
| 	} | ||||
| 	else | ||||
| 	DatabaseFactory factory{dbpath}; | ||||
| 	auto db = factory.forCurrentThread(); | ||||
| 	DBMigrator migrator{db}; | ||||
| 	if(migrator.migrationNeeded()) | ||||
| 	{ | ||||
|  | ||||
| 		QString dbpath = databasePath(); | ||||
| 		if(!QFile::exists(dbpath)) | ||||
| 		{ | ||||
| 			throw LooqsGeneralException("Database " + dbpath + " was not found"); | ||||
| 		} | ||||
| 		DatabaseFactory factory{dbpath}; | ||||
| 		auto db = factory.forCurrentThread(); | ||||
| 		DBMigrator migrator{db}; | ||||
| 		if(migrator.migrationNeeded()) | ||||
| 		{ | ||||
| 			QFile out; | ||||
| 			out.open(stderr, QIODevice::WriteOnly); | ||||
| 			Logger migrationLogger{&out}; | ||||
| 			migrationLogger << "Database is being upgraded, please be patient..." << Qt::endl; | ||||
| 			QObject::connect(&migrator, &DBMigrator::migrationDone, | ||||
| 							 [&migrationLogger](uint32_t migration) | ||||
| 							 { migrationLogger << "Progress: Successfully migrated to: " << migration << Qt::endl; }); | ||||
| 			migrator.performMigrations(); | ||||
| 			migrationLogger << "Database upgraded successfully" << Qt::endl; | ||||
| 		} | ||||
| 		QFile out; | ||||
| 		out.open(stderr, QIODevice::WriteOnly); | ||||
| 		Logger migrationLogger{&out}; | ||||
| 		migrationLogger << "Database is being upgraded, please be patient..." << Qt::endl; | ||||
| 		QObject::connect(&migrator, &DBMigrator::migrationDone, | ||||
| 						 [&migrationLogger](uint32_t migration) | ||||
| 						 { migrationLogger << "Progress: Successfully migrated to: " << migration << Qt::endl; }); | ||||
| 		migrator.performMigrations(); | ||||
| 		migrationLogger << "Database upgraded successfully" << Qt::endl; | ||||
| 	} | ||||
| 	QVariant pdfViewer = settings.value(SETTINGS_KEY_PDFVIEWER); | ||||
| 	if(!pdfViewer.isValid()) | ||||
| 	{ | ||||
| 		setPdfViewer(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -176,19 +165,18 @@ QString Common::ipcSocketPath() | ||||
| 	// return settings.value(SETTINGS_KEY_IPCSOCKETPATH, "/tmp/.looqs/looqs-ipc-socket").toString(); | ||||
| } | ||||
|  | ||||
| static QStringList excludedPaths = {"/proc", "/sys", "/dev", "/tmp", "/var/run", "/run"}; | ||||
|  | ||||
| QStringList Common::excludedPaths() | ||||
| { | ||||
| 	static int ran = false; | ||||
| 	static QStringList excludedPaths; | ||||
| 	if(!ran) | ||||
| 	{ | ||||
| 		QSettings settings; | ||||
| 		QStringList userExcludedPaths = settings.value(SETTINGS_KEY_EXCLUDEDPATHS).toStringList(); | ||||
| 		QStringList defaults{"/proc", "/sys", "/dev", "/tmp", "/var/run", "/run"}; | ||||
| 		excludedPaths = settings.value(SETTINGS_KEY_EXCLUDEDPATHS, defaults).toStringList(); | ||||
| 		ran = true; | ||||
| 		::excludedPaths.append(userExcludedPaths); | ||||
| 	} | ||||
| 	return ::excludedPaths; | ||||
| 	return excludedPaths; | ||||
| } | ||||
|  | ||||
| QStringList Common::mountPaths() | ||||
|   | ||||
| @@ -2,6 +2,14 @@ | ||||
| #define COMMON_H | ||||
| #include <QCoreApplication> | ||||
| #include <QFileInfo> | ||||
|  | ||||
| #define SETTINGS_KEY_DBPATH "dbpath" | ||||
| #define SETTINGS_KEY_IPCSOCKETPATH "ipcsocketpath" | ||||
| #define SETTINGS_KEY_PDFVIEWER "pdfviewer" | ||||
| #define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths" | ||||
| #define SETTINGS_KEY_MOUNTPATHS "mountpaths" | ||||
| #define SETTINGS_KEY_PREVIEWSPERPAGE "previewsPerPage" | ||||
|  | ||||
| namespace Common | ||||
| { | ||||
| void setupAppInfo(); | ||||
|   | ||||
| @@ -19,7 +19,21 @@ void Indexer::beginIndexing() | ||||
| 	QVector<QString> dirs; | ||||
|  | ||||
| 	WildcardMatcher wildcardMatcher; | ||||
| 	wildcardMatcher.setPatterns(this->ignorePattern); | ||||
|  | ||||
| 	QStringList ignoreList = this->ignorePattern; | ||||
|  | ||||
| 	for(QString &excludedPath : Common::excludedPaths()) | ||||
| 	{ | ||||
| 		QString pattern = excludedPath; | ||||
| 		if(!pattern.endsWith("/")) | ||||
| 		{ | ||||
| 			pattern += "/"; | ||||
| 		} | ||||
| 		pattern += "*"; | ||||
| 		ignoreList.append(excludedPath); | ||||
| 	} | ||||
| 	ignoreList.append(this->ignorePattern); | ||||
| 	wildcardMatcher.setPatterns(ignoreList); | ||||
| 	for(QString &path : this->pathsToScan) | ||||
| 	{ | ||||
| 		if(wildcardMatcher.match(path)) | ||||
| @@ -40,7 +54,7 @@ void Indexer::beginIndexing() | ||||
| 	if(!dirs.empty()) | ||||
| 	{ | ||||
| 		this->dirScanner->setPaths(dirs); | ||||
| 		this->dirScanner->setIgnorePatterns(this->ignorePattern); | ||||
| 		this->dirScanner->setIgnorePatterns(ignoreList); | ||||
|  | ||||
| 		this->dirScanner->scan(); | ||||
| 	} | ||||
|   | ||||
| @@ -23,12 +23,12 @@ QueryType LooqsQuery::getQueryType() | ||||
| 	return static_cast<QueryType>(tokensMask & COMBINED); | ||||
| } | ||||
|  | ||||
| bool LooqsQuery::hasContentSearch() | ||||
| bool LooqsQuery::hasContentSearch() const | ||||
| { | ||||
| 	return (this->getTokensMask() & FILTER_CONTENT) == FILTER_CONTENT; | ||||
| } | ||||
|  | ||||
| bool LooqsQuery::hasPathSearch() | ||||
| bool LooqsQuery::hasPathSearch() const | ||||
| { | ||||
| 	return (this->getTokensMask() & FILTER_PATH) == FILTER_PATH; | ||||
| } | ||||
| @@ -181,8 +181,8 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b | ||||
| 	QStringList loneWords; | ||||
| 	LooqsQuery result; | ||||
| 	QRegularExpression rx( | ||||
| 		"((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\p{L},])+)|(?<boolean>AND|OR)" | ||||
| 		"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\p{L}]+))"); | ||||
| 		"((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\p{L}\\p{N},])+)|(?<boolean>AND|OR)" | ||||
| 		"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\p{L}\\p{N}]+))"); | ||||
| 	QRegularExpressionMatchIterator i = rx.globalMatch(expression); | ||||
| 	auto previousWasBool = [&result] { return !result.tokens.empty() && ((result.tokens.last().type & BOOL) == BOOL); }; | ||||
| 	auto previousWas = [&result](TokenType t) { return !result.tokens.empty() && (result.tokens.last().type == t); }; | ||||
|   | ||||
| @@ -61,8 +61,8 @@ class LooqsQuery | ||||
| 	{ | ||||
| 		this->limit = limit; | ||||
| 	} | ||||
| 	bool hasContentSearch(); | ||||
| 	bool hasPathSearch(); | ||||
| 	bool hasContentSearch() const; | ||||
| 	bool hasPathSearch() const; | ||||
|  | ||||
| 	void addSortCondition(SortCondition sc); | ||||
| 	static bool checkParanthesis(QString query); | ||||
|   | ||||
| @@ -35,7 +35,7 @@ void SandboxedProcessor::enableSandbox(QString readablePath) | ||||
| 	struct exile_policy *policy = exile_init_policy(); | ||||
| 	if(policy == NULL) | ||||
| 	{ | ||||
| 		qCritical() << "Could not init exile"; | ||||
| 		qCritical() << "Could not init exile" << Qt::endl; | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 	policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER; | ||||
| @@ -43,6 +43,8 @@ void SandboxedProcessor::enableSandbox(QString readablePath) | ||||
| 	std::string readablePathLocation; | ||||
| 	if(!readablePath.isEmpty()) | ||||
| 	{ | ||||
| 		policy->namespace_options |= EXILE_UNSHARE_MOUNT; | ||||
| 		policy->mount_path_policies_to_chroot = 1; | ||||
| 		readablePathLocation = readablePath.toStdString(); | ||||
| 		if(exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, readablePathLocation.c_str()) != 0) | ||||
| 		{ | ||||
|   | ||||
| @@ -7,6 +7,7 @@ class SearchResult | ||||
|   public: | ||||
| 	FileData fileData; | ||||
| 	QVector<unsigned int> pages; | ||||
| 	bool wasContentSearch = false; | ||||
| }; | ||||
|  | ||||
| #endif // SEARCHRESULT_H | ||||
|   | ||||
| @@ -213,6 +213,7 @@ QVector<SearchResult> SqliteSearch::search(const LooqsQuery &query) | ||||
| 		throw LooqsGeneralException("SQL Error: " + dbQuery.lastError().text()); | ||||
| 	} | ||||
|  | ||||
| 	bool contentSearch = query.hasContentSearch(); | ||||
| 	while(dbQuery.next()) | ||||
| 	{ | ||||
| 		SearchResult result; | ||||
| @@ -229,6 +230,7 @@ QVector<SearchResult> SqliteSearch::search(const LooqsQuery &query) | ||||
| 				result.pages.append(page.toUInt()); | ||||
| 			} | ||||
| 		} | ||||
| 		result.wasContentSearch = contentSearch; | ||||
| 		results.append(result); | ||||
| 	} | ||||
| 	return results; | ||||
|   | ||||
 Submodule submodules/exile.h updated: 42d44b0cc1...8f38dc4480
									
								
							
		Посилання в новій задачі
	
	Block a user