1st proto for GUI webcache editor
This commit is contained in:
parent
5d6b1ea2a1
commit
241586a3a7
@ -62,7 +62,7 @@ bool BeagleQueueCache::getFromCache(const string& udi, Rcl::Doc &dotdoc,
|
|||||||
LOGERR(("BeagleQueueCache::getFromCache: cache is null\n"));
|
LOGERR(("BeagleQueueCache::getFromCache: cache is null\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!m_cache->get(udi, dict, data)) {
|
if (!m_cache->get(udi, dict, &data)) {
|
||||||
LOGDEB(("BeagleQueueCache::getFromCache: get failed\n"));
|
LOGDEB(("BeagleQueueCache::getFromCache: get failed\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "fragbuts.h"
|
#include "fragbuts.h"
|
||||||
#include "specialindex.h"
|
#include "specialindex.h"
|
||||||
#include "rclmain_w.h"
|
#include "rclmain_w.h"
|
||||||
|
#include "webcache.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -74,6 +75,19 @@ void RclMain::showSpellDialog()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RclMain::showWebcacheDialog()
|
||||||
|
{
|
||||||
|
if (webcache == 0) {
|
||||||
|
webcache = new WebcacheEdit(0);
|
||||||
|
connect(new QShortcut(quitKeySeq, webcache), SIGNAL (activated()),
|
||||||
|
this, SLOT (fileExit()));
|
||||||
|
webcache->show();
|
||||||
|
} else {
|
||||||
|
webcache->close();
|
||||||
|
webcache->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RclMain::showIndexStatistics()
|
void RclMain::showIndexStatistics()
|
||||||
{
|
{
|
||||||
showSpellDialog();
|
showSpellDialog();
|
||||||
|
|||||||
@ -103,6 +103,7 @@
|
|||||||
<addaction name="toolsSpellAction"/>
|
<addaction name="toolsSpellAction"/>
|
||||||
<addaction name="actionShowQueryDetails"/>
|
<addaction name="actionShowQueryDetails"/>
|
||||||
<addaction name="actionQuery_Fragments"/>
|
<addaction name="actionQuery_Fragments"/>
|
||||||
|
<addaction name="actionWebcache_Editor"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="preferencesMenu">
|
<widget class="QMenu" name="preferencesMenu">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -532,6 +533,11 @@
|
|||||||
<string>Index &statistics</string>
|
<string>Index &statistics</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionWebcache_Editor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Webcache Editor</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="2" margin="2"/>
|
<layoutdefault spacing="2" margin="2"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|||||||
@ -350,6 +350,8 @@ void RclMain::init()
|
|||||||
this, SLOT(showAdvSearchDialog()));
|
this, SLOT(showAdvSearchDialog()));
|
||||||
connect(toolsSpellAction, SIGNAL(triggered()),
|
connect(toolsSpellAction, SIGNAL(triggered()),
|
||||||
this, SLOT(showSpellDialog()));
|
this, SLOT(showSpellDialog()));
|
||||||
|
connect(actionWebcache_Editor, SIGNAL(triggered()),
|
||||||
|
this, SLOT(showWebcacheDialog()));
|
||||||
connect(actionQuery_Fragments, SIGNAL(triggered()),
|
connect(actionQuery_Fragments, SIGNAL(triggered()),
|
||||||
this, SLOT(showFragButs()));
|
this, SLOT(showFragButs()));
|
||||||
connect(actionSpecial_Indexing, SIGNAL(triggered()),
|
connect(actionSpecial_Indexing, SIGNAL(triggered()),
|
||||||
|
|||||||
@ -42,6 +42,7 @@ class CronToolW;
|
|||||||
class RTIToolW;
|
class RTIToolW;
|
||||||
class FragButs;
|
class FragButs;
|
||||||
class SpecIdxW;
|
class SpecIdxW;
|
||||||
|
class WebcacheEdit;
|
||||||
|
|
||||||
#include "ui_rclmain.h"
|
#include "ui_rclmain.h"
|
||||||
|
|
||||||
@ -73,6 +74,7 @@ public:
|
|||||||
fragbuts(0),
|
fragbuts(0),
|
||||||
specidx(0),
|
specidx(0),
|
||||||
periodictimer(0),
|
periodictimer(0),
|
||||||
|
webcache(0),
|
||||||
restable(0),
|
restable(0),
|
||||||
displayingTable(0),
|
displayingTable(0),
|
||||||
m_idNoStem(0),
|
m_idNoStem(0),
|
||||||
@ -122,6 +124,7 @@ public slots:
|
|||||||
virtual void previewClosed(Preview *w);
|
virtual void previewClosed(Preview *w);
|
||||||
virtual void showAdvSearchDialog();
|
virtual void showAdvSearchDialog();
|
||||||
virtual void showSpellDialog();
|
virtual void showSpellDialog();
|
||||||
|
virtual void showWebcacheDialog();
|
||||||
virtual void showIndexStatistics();
|
virtual void showIndexStatistics();
|
||||||
virtual void showFragButs();
|
virtual void showFragButs();
|
||||||
virtual void showSpecIdx();
|
virtual void showSpecIdx();
|
||||||
@ -200,6 +203,7 @@ private:
|
|||||||
FragButs *fragbuts;
|
FragButs *fragbuts;
|
||||||
SpecIdxW *specidx;
|
SpecIdxW *specidx;
|
||||||
QTimer *periodictimer;
|
QTimer *periodictimer;
|
||||||
|
WebcacheEdit *webcache;
|
||||||
ResTable *restable;
|
ResTable *restable;
|
||||||
bool displayingTable;
|
bool displayingTable;
|
||||||
QAction *m_idNoStem;
|
QAction *m_idNoStem;
|
||||||
|
|||||||
@ -41,6 +41,7 @@ HEADERS += \
|
|||||||
systray.h \
|
systray.h \
|
||||||
uiprefs_w.h \
|
uiprefs_w.h \
|
||||||
viewaction_w.h \
|
viewaction_w.h \
|
||||||
|
webcache.h \
|
||||||
widgets/editdialog.h \
|
widgets/editdialog.h \
|
||||||
widgets/listdialog.h \
|
widgets/listdialog.h \
|
||||||
widgets/qxtconfirmationmessage.h
|
widgets/qxtconfirmationmessage.h
|
||||||
@ -78,6 +79,7 @@ SOURCES += \
|
|||||||
systray.cpp \
|
systray.cpp \
|
||||||
uiprefs_w.cpp \
|
uiprefs_w.cpp \
|
||||||
viewaction_w.cpp \
|
viewaction_w.cpp \
|
||||||
|
webcache.cpp \
|
||||||
widgets/qxtconfirmationmessage.cpp \
|
widgets/qxtconfirmationmessage.cpp \
|
||||||
xmltosd.cpp
|
xmltosd.cpp
|
||||||
|
|
||||||
@ -98,7 +100,8 @@ FORMS = \
|
|||||||
ssearchb.ui \
|
ssearchb.ui \
|
||||||
uiprefs.ui \
|
uiprefs.ui \
|
||||||
viewaction.ui \
|
viewaction.ui \
|
||||||
|
webcache.ui
|
||||||
|
|
||||||
RESOURCES = recoll.qrc
|
RESOURCES = recoll.qrc
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
|
|||||||
195
src/qtgui/webcache.cpp
Normal file
195
src/qtgui/webcache.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* Copyright (C) 2016 J.F.Dockes
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#include "autoconfig.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include MEMORY_INCLUDE
|
||||||
|
#include UNORDERED_MAP_INCLUDE
|
||||||
|
|
||||||
|
#ifndef USING_STD_REGEX
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#else
|
||||||
|
#include <regex>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "recoll.h"
|
||||||
|
#include "webcache.h"
|
||||||
|
#include "beaglequeuecache.h"
|
||||||
|
#include "circache.h"
|
||||||
|
#include "conftree.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class CEnt {
|
||||||
|
public:
|
||||||
|
CEnt(const string& ud, const string& ur, const string& mt)
|
||||||
|
: udi(ud), url(ur), mimetype(mt) {
|
||||||
|
}
|
||||||
|
string udi;
|
||||||
|
string url;
|
||||||
|
string mimetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebcacheModelInternal {
|
||||||
|
public:
|
||||||
|
STD_SHARED_PTR<BeagleQueueCache> cache;
|
||||||
|
vector<CEnt> all;
|
||||||
|
vector<CEnt> disp;
|
||||||
|
};
|
||||||
|
|
||||||
|
WebcacheModel::WebcacheModel(QObject *parent)
|
||||||
|
: QAbstractTableModel(parent), m(new WebcacheModelInternal())
|
||||||
|
{
|
||||||
|
qDebug() << "WebcacheModel::WebcacheModel()";
|
||||||
|
m->cache =
|
||||||
|
STD_SHARED_PTR<BeagleQueueCache>(new BeagleQueueCache(theconfig));
|
||||||
|
|
||||||
|
if (m->cache) {
|
||||||
|
bool eof;
|
||||||
|
m->cache->cc()->rewind(eof);
|
||||||
|
while (!eof) {
|
||||||
|
string udi, sdic;
|
||||||
|
m->cache->cc()->getCurrent(udi, sdic);
|
||||||
|
ConfSimple dic(sdic);
|
||||||
|
string mime, url;
|
||||||
|
dic.get("mimetype", mime);
|
||||||
|
dic.get("url", url);
|
||||||
|
if (!udi.empty()) {
|
||||||
|
m->all.push_back(CEnt(udi, url, mime));
|
||||||
|
m->disp.push_back(CEnt(udi, url, mime));
|
||||||
|
}
|
||||||
|
if (!m->cache->cc()->next(eof))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebcacheModel::rowCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
//qDebug() << "WebcacheModel::rowCount(): " << m->disp.size();
|
||||||
|
return int(m->disp.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebcacheModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
//qDebug() << "WebcacheModel::columnCount()";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant WebcacheModel::headerData (int col, Qt::Orientation orientation,
|
||||||
|
int role) const
|
||||||
|
{
|
||||||
|
// qDebug() << "WebcacheModel::headerData()";
|
||||||
|
if (orientation != Qt::Horizontal || role != Qt::DisplayRole) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
switch (col) {
|
||||||
|
case 0: return QVariant(tr("MIME"));
|
||||||
|
case 1: return QVariant(tr("Url"));
|
||||||
|
default: return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant WebcacheModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
//qDebug() << "WebcacheModel::data()";
|
||||||
|
Q_UNUSED(index);
|
||||||
|
if (role != Qt::DisplayRole) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
int row = index.row();
|
||||||
|
if (row < 0 || row >= int(m->disp.size())) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We now read the data on init */
|
||||||
|
#if 0
|
||||||
|
string sdic;
|
||||||
|
if (!m->cache->cc()->get(m->disp[row].udi, sdic)) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
ConfSimple dic(sdic);
|
||||||
|
//ostringstream os; dic.write(os); cerr << "DIC: " << os.str() << endl;
|
||||||
|
string mime, url;
|
||||||
|
dic.get("mimetype", mime);
|
||||||
|
dic.get("url", url);
|
||||||
|
#else
|
||||||
|
const string& mime = m->disp[row].mimetype;
|
||||||
|
const string& url = m->disp[row].url;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0: return QVariant(QString::fromUtf8(mime.c_str()));
|
||||||
|
case 1: return QVariant(QString::fromUtf8(url.c_str()));
|
||||||
|
default: return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef USING_STD_REGEX
|
||||||
|
#define M_regexec(A,B,C,D,E) regexec(&(A),B,C,D,E)
|
||||||
|
#else
|
||||||
|
#define M_regexec(A,B,C,D,E) (!regex_match(B,A))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void WebcacheModel::setSearchFilter(const QString& _txt)
|
||||||
|
{
|
||||||
|
string txt = qs2utf8s(_txt);
|
||||||
|
|
||||||
|
#ifndef USING_STD_REGEX
|
||||||
|
regex_t exp;
|
||||||
|
if (regcomp(&exp, txt.c_str(), REG_NOSUB|REG_EXTENDED)) {
|
||||||
|
//qDebug() << "regcomp failed for " << _txt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
basic_regex exp;
|
||||||
|
try {
|
||||||
|
exp = basic_regexp(txt, std::regex_constants::nosubs |
|
||||||
|
std::regex_constants::extended);
|
||||||
|
} catch(...) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m->disp.clear();
|
||||||
|
for (unsigned int i = 0; i < m->all.size(); i++) {
|
||||||
|
if (!M_regexec(exp, m->all[i].url.c_str(), 0, 0, 0)) {
|
||||||
|
m->disp.push_back(m->all[i]);
|
||||||
|
} else {
|
||||||
|
//qDebug() << "match failed. exp" << _txt << "data" <<
|
||||||
|
// m->all[i].url.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit dataChanged(createIndex(0,0,0), createIndex(1, m->all.size(),0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebcacheEdit::WebcacheEdit(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
qDebug() << "WebcacheEdit::WebcacheEdit()";
|
||||||
|
setupUi(this);
|
||||||
|
m_model = new WebcacheModel(this);
|
||||||
|
webcacheTV->setModel(m_model);
|
||||||
|
connect(searchLE, SIGNAL(textEdited(const QString&)),
|
||||||
|
m_model, SLOT(setSearchFilter(const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
61
src/qtgui/webcache.h
Normal file
61
src/qtgui/webcache.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* Copyright (C) 2016 J.F.Dockes
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef _WEBCACHE_H_INCLUDED_
|
||||||
|
#define _WEBCACHE_H_INCLUDED_
|
||||||
|
#include "autoconfig.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include MEMORY_INCLUDE
|
||||||
|
|
||||||
|
#include "ui_webcache.h"
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
class WebcacheModelInternal;
|
||||||
|
|
||||||
|
class WebcacheModel : public QAbstractTableModel {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WebcacheModel(QObject *parent = 0);
|
||||||
|
|
||||||
|
// Reimplemented methods
|
||||||
|
virtual int rowCount (const QModelIndex& = QModelIndex()) const;
|
||||||
|
virtual int columnCount(const QModelIndex& = QModelIndex()) const;
|
||||||
|
virtual QVariant headerData (int col, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole) const;
|
||||||
|
virtual QVariant data(const QModelIndex& index,
|
||||||
|
int role = Qt::DisplayRole ) const;
|
||||||
|
public slots:
|
||||||
|
void setSearchFilter(const QString&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WebcacheModelInternal *m;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebcacheEdit : public QDialog, public Ui::Webcache {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WebcacheEdit(QWidget *parent);
|
||||||
|
private:
|
||||||
|
WebcacheModel *m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _WEBCACHE_H_INCLUDED_ */
|
||||||
51
src/qtgui/webcache.ui
Normal file
51
src/qtgui/webcache.ui
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Webcache</class>
|
||||||
|
<widget class="QDialog" name="Webcache">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Webcache editor</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="searchLBL">
|
||||||
|
<property name="text">
|
||||||
|
<string>Search regexp</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>searchLE</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="searchLE"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="webcacheTV">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -30,6 +30,8 @@
|
|||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "chrono.h"
|
#include "chrono.h"
|
||||||
|
#include MEMORY_INCLUDE
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
@ -857,7 +859,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// instance == -1 means get latest. Otherwise specify from 1+
|
// instance == -1 means get latest. Otherwise specify from 1+
|
||||||
bool CirCache::get(const string& udi, string& dic, string& data, int instance)
|
bool CirCache::get(const string& udi, string& dic, string *data, int instance)
|
||||||
{
|
{
|
||||||
Chrono chron;
|
Chrono chron;
|
||||||
if (m_d->m_fd < 0) {
|
if (m_d->m_fd < 0) {
|
||||||
@ -900,7 +902,7 @@ bool CirCache::get(const string& udi, string& dic, string& data, int instance)
|
|||||||
}
|
}
|
||||||
// Did we read an appropriate entry ?
|
// Did we read an appropriate entry ?
|
||||||
if (o_good != 0 && (instance == -1 || instance == finst)) {
|
if (o_good != 0 && (instance == -1 || instance == finst)) {
|
||||||
bool ret = m_d->readDicData(o_good, d_good, dic, &data);
|
bool ret = m_d->readDicData(o_good, d_good, dic, data);
|
||||||
LOGDEB0(("Circache::get: hfound, %d mS\n",
|
LOGDEB0(("Circache::get: hfound, %d mS\n",
|
||||||
chron.millis()));
|
chron.millis()));
|
||||||
return ret;
|
return ret;
|
||||||
@ -920,8 +922,7 @@ bool CirCache::get(const string& udi, string& dic, string& data, int instance)
|
|||||||
} else if (ret != CCScanHook::Stop) {
|
} else if (ret != CCScanHook::Stop) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool bret =
|
bool bret = m_d->readDicData(getter.m_offs, getter.m_hd, dic, data);
|
||||||
m_d->readDicData(getter.m_offs, getter.m_hd, dic, &data);
|
|
||||||
LOGDEB0(("Circache::get: scanfound, %d mS\n", chron.millis()));
|
LOGDEB0(("Circache::get: scanfound, %d mS\n", chron.millis()));
|
||||||
|
|
||||||
return bret;
|
return bret;
|
||||||
@ -943,8 +944,8 @@ bool CirCache::erase(const string& udi)
|
|||||||
// If the mem cache is not up to date, update it, we're too lazy
|
// If the mem cache is not up to date, update it, we're too lazy
|
||||||
// to do a scan
|
// to do a scan
|
||||||
if (!m_d->m_ofskhcplt) {
|
if (!m_d->m_ofskhcplt) {
|
||||||
string dic, data;
|
string dic;
|
||||||
get("nosuchudi probably exists", dic, data);
|
get("nosuchudi probably exists", dic);
|
||||||
if (!m_d->m_ofskhcplt) {
|
if (!m_d->m_ofskhcplt) {
|
||||||
LOGERR(("CirCache::erase : cache not updated after get\n"));
|
LOGERR(("CirCache::erase : cache not updated after get\n"));
|
||||||
return false;
|
return false;
|
||||||
@ -1265,13 +1266,13 @@ bool CirCache::getCurrentUdi(string& udi)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CirCache::getCurrent(string& udi, string& dic, string& data)
|
bool CirCache::getCurrent(string& udi, string& dic, string *data)
|
||||||
{
|
{
|
||||||
if (m_d == 0) {
|
if (m_d == 0) {
|
||||||
LOGERR(("CirCache::getCurrent: null data\n"));
|
LOGERR(("CirCache::getCurrent: null data\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!m_d->readDicData(m_d->m_itoffs, m_d->m_ithd, dic, &data)) {
|
if (!m_d->readDicData(m_d->m_itoffs, m_d->m_ithd, dic, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1368,85 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy all entries from occ to ncc. Both are already open.
|
||||||
|
static bool copyall(STD_SHARED_PTR<CirCache> occ,
|
||||||
|
STD_SHARED_PTR<CirCache> ncc, int& nentries,
|
||||||
|
ostringstream& msg)
|
||||||
|
{
|
||||||
|
bool eof = false;
|
||||||
|
if (!occ->rewind(eof)) {
|
||||||
|
if (!eof) {
|
||||||
|
msg << "Initial rewind failed" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nentries = 0;
|
||||||
|
while (!eof) {
|
||||||
|
string udi, sdic, data;
|
||||||
|
if (!occ->getCurrent(udi, sdic, &data)) {
|
||||||
|
msg << "getCurrent failed: " << occ->getReason() << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Shouldn't getcurrent deal with this ?
|
||||||
|
if (sdic.size() == 0) {
|
||||||
|
//cerr << "Skip empty entry" << endl;
|
||||||
|
occ->next(eof);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConfSimple dic(sdic);
|
||||||
|
if (!dic.ok()) {
|
||||||
|
msg << "Could not parse entry attributes dic" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//cerr << "UDI: " << udi << endl;
|
||||||
|
if (!ncc->put(udi, &dic, data)) {
|
||||||
|
msg << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
|
||||||
|
"]" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nentries++;
|
||||||
|
occ->next(eof);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append all entries from sdir to ddir
|
||||||
|
int CirCache::append(const string ddir, const string& sdir, string *reason)
|
||||||
|
{
|
||||||
|
ostringstream msg;
|
||||||
|
// Open source file
|
||||||
|
STD_SHARED_PTR<CirCache> occ(new CirCache(sdir));
|
||||||
|
if (!occ->open(CirCache::CC_OPREAD)) {
|
||||||
|
if (reason) {
|
||||||
|
msg << "Open failed in " << sdir << " : " <<
|
||||||
|
occ->getReason() << endl;
|
||||||
|
*reason = msg.str();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Open dest file
|
||||||
|
STD_SHARED_PTR<CirCache> ncc(new CirCache(ddir));
|
||||||
|
if (!ncc->open(CirCache::CC_OPWRITE)) {
|
||||||
|
if (reason) {
|
||||||
|
msg << "Open failed in " << ddir << " : " <<
|
||||||
|
ncc->getReason() << endl;
|
||||||
|
*reason = msg.str();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nentries;
|
||||||
|
if (!copyall(occ, ncc, nentries, msg)) {
|
||||||
|
if (reason) {
|
||||||
|
*reason = msg.str();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nentries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else // TEST ->
|
#else // TEST ->
|
||||||
#include "autoconfig.h"
|
#include "autoconfig.h"
|
||||||
|
|
||||||
@ -1380,163 +1460,17 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp)
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include MEMORY_INCLUDE
|
||||||
|
|
||||||
#include "circache.h"
|
#include "circache.h"
|
||||||
#include "fileudi.h"
|
#include "fileudi.h"
|
||||||
#include "conftree.h"
|
#include "conftree.h"
|
||||||
#include "readfile.h"
|
#include "readfile.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
#include "smallut.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Copy all entries from occ to ncc. Both are already open.
|
|
||||||
bool copyall(STD_SHARED_PTR<CirCache> occ,
|
|
||||||
STD_SHARED_PTR<CirCache> ncc, int& nentries)
|
|
||||||
{
|
|
||||||
bool eof = false;
|
|
||||||
if (!occ->rewind(eof)) {
|
|
||||||
if (!eof) {
|
|
||||||
cerr << "Initial rewind failed" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nentries = 0;
|
|
||||||
while (!eof) {
|
|
||||||
string udi, sdic, data;
|
|
||||||
if (!occ->getCurrent(udi, sdic, data)) {
|
|
||||||
cerr << "getCurrent failed: " << occ->getReason() << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Shouldn't getcurrent deal with this ?
|
|
||||||
if (sdic.size() == 0) {
|
|
||||||
//cerr << "Skip empty entry" << endl;
|
|
||||||
occ->next(eof);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ConfSimple dic(sdic);
|
|
||||||
if (!dic.ok()) {
|
|
||||||
cerr << "Could not parse entry attributes dic" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//cerr << "UDI: " << udi << endl;
|
|
||||||
if (!ncc->put(udi, &dic, data)) {
|
|
||||||
cerr << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
|
|
||||||
"]" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
nentries++;
|
|
||||||
occ->next(eof);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#warning resizecc is not useful, create(newsize) works !
|
|
||||||
|
|
||||||
// Wrote the following at a point where I thought that simple resizing
|
|
||||||
// did not work. Upon further study (or updates?), it appears it does
|
|
||||||
// ! So the following code is not useful actually
|
|
||||||
|
|
||||||
// Resize circache. This can't be done easily if the write point is
|
|
||||||
// inside the file (we already reached the old max size). We create a
|
|
||||||
// new file with the new size and copy the old entries into it. The
|
|
||||||
// old file is then renamed into a backup and the new file renamed in
|
|
||||||
// place.
|
|
||||||
bool resizecc(const string& dir, int newmbs)
|
|
||||||
{
|
|
||||||
// Create object for existing file and get the file name
|
|
||||||
STD_SHARED_PTR<CirCache> occ(new CirCache(dir));
|
|
||||||
string ofn = occ->getpath();
|
|
||||||
|
|
||||||
// Check for previous backup
|
|
||||||
string backupfn = ofn + ".orig";
|
|
||||||
if (access(backupfn.c_str(), 0) >= 0) {
|
|
||||||
cerr << "Backup file " << backupfn <<
|
|
||||||
" exists, please move it out of the way" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!occ->open(CirCache::CC_OPREAD)) {
|
|
||||||
cerr << "Open failed in " << dir << " : " << occ->getReason() << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the new empty file in a temporary directory
|
|
||||||
string tmpdir = path_cat(dir, "tmp");
|
|
||||||
if (access(tmpdir.c_str(), 0) < 0) {
|
|
||||||
if (mkdir(tmpdir.c_str(), 0700) < 0) {
|
|
||||||
cerr << "Cant create temporary directory " << tmpdir << " ";
|
|
||||||
perror("mkdir");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STD_SHARED_PTR<CirCache> ncc(new CirCache(tmpdir));
|
|
||||||
string nfn = ncc->getpath();
|
|
||||||
if (!ncc->create(off_t(newmbs) * 1000 * 1024,
|
|
||||||
CirCache::CC_CRUNIQUE | CirCache::CC_CRTRUNCATE)) {
|
|
||||||
cerr << "Cant create new file in " << tmpdir << " : " <<
|
|
||||||
ncc->getReason() << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nentries;
|
|
||||||
if (!copyall(occ, ncc, nentries)) {
|
|
||||||
cerr << "Copy failed\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done with our objects here, there is no close() method, so
|
|
||||||
// delete them
|
|
||||||
occ.reset();
|
|
||||||
ncc.reset();
|
|
||||||
|
|
||||||
// Create backup by renaming the old file
|
|
||||||
if (rename(ofn.c_str(), backupfn.c_str()) < 0) {
|
|
||||||
cerr << "Could not create backup " << backupfn << " : ";
|
|
||||||
perror("rename");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cout << "Created backup file " << backupfn << endl;
|
|
||||||
|
|
||||||
// Move the new file in place.
|
|
||||||
if (rename(nfn.c_str(), ofn.c_str()) < 0) {
|
|
||||||
cerr << "Could not rename new file from " << nfn << " to " <<
|
|
||||||
ofn << " : ";
|
|
||||||
perror("rename");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cout << "Resize done, copied " << nentries << " entries " << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append all entries from sdir to ddir
|
|
||||||
bool appendcc(const string ddir, const string& sdir)
|
|
||||||
{
|
|
||||||
// Open source file
|
|
||||||
STD_SHARED_PTR<CirCache> occ(new CirCache(sdir));
|
|
||||||
if (!occ->open(CirCache::CC_OPREAD)) {
|
|
||||||
cerr << "Open failed in " << sdir << " : " << occ->getReason() << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Open dest file
|
|
||||||
STD_SHARED_PTR<CirCache> ncc(new CirCache(ddir));
|
|
||||||
if (!ncc->open(CirCache::CC_OPWRITE)) {
|
|
||||||
cerr << "Open failed in " << ddir << " : " << ncc->getReason() << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nentries;
|
|
||||||
if (!copyall(occ, ncc, nentries)) {
|
|
||||||
cerr << "Copy failed\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
occ.reset();
|
|
||||||
ncc.reset();
|
|
||||||
|
|
||||||
cout << "Copy done, copied " << nentries << " entries " << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *thisprog;
|
static char *thisprog;
|
||||||
|
|
||||||
static char usage [] =
|
static char usage [] =
|
||||||
@ -1546,7 +1480,6 @@ static char usage [] =
|
|||||||
" -g [-i instance] [-D] <dirname> <udi>: get\n"
|
" -g [-i instance] [-D] <dirname> <udi>: get\n"
|
||||||
" -D: also dump data\n"
|
" -D: also dump data\n"
|
||||||
" -e <dirname> <udi> : erase\n"
|
" -e <dirname> <udi> : erase\n"
|
||||||
" -s <dirname> <newmbs> : resize\n"
|
|
||||||
" -a <targetdir> <dir> [<dir> ...]: append old content to target\n"
|
" -a <targetdir> <dir> [<dir> ...]: append old content to target\n"
|
||||||
" The target should be first resized to hold all the data, else only\n"
|
" The target should be first resized to hold all the data, else only\n"
|
||||||
" as many entries as capacity permit will be retained\n"
|
" as many entries as capacity permit will be retained\n"
|
||||||
@ -1569,7 +1502,6 @@ static int op_flags;
|
|||||||
#define OPT_D 0x80
|
#define OPT_D 0x80
|
||||||
#define OPT_u 0x100
|
#define OPT_u 0x100
|
||||||
#define OPT_e 0x200
|
#define OPT_e 0x200
|
||||||
#define OPT_s 0x400
|
|
||||||
#define OPT_a 0x800
|
#define OPT_a 0x800
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -1620,9 +1552,6 @@ int main(int argc, char **argv)
|
|||||||
case 'p':
|
case 'p':
|
||||||
op_flags |= OPT_p;
|
op_flags |= OPT_p;
|
||||||
break;
|
break;
|
||||||
case 's':
|
|
||||||
op_flags |= OPT_s;
|
|
||||||
break;
|
|
||||||
case 'u':
|
case 'u':
|
||||||
op_flags |= OPT_u;
|
op_flags |= OPT_u;
|
||||||
break;
|
break;
|
||||||
@ -1660,21 +1589,14 @@ b1:
|
|||||||
cerr << "Create failed:" << cc.getReason() << endl;
|
cerr << "Create failed:" << cc.getReason() << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (op_flags & OPT_s) {
|
|
||||||
if (argc != 1) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
int newmbs = atoi(*argv++);
|
|
||||||
argc--;
|
|
||||||
if (!resizecc(dir, newmbs)) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else if (op_flags & OPT_a) {
|
} else if (op_flags & OPT_a) {
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
Usage();
|
Usage();
|
||||||
}
|
}
|
||||||
while (argc) {
|
while (argc) {
|
||||||
if (!appendcc(dir, *argv++)) {
|
string reason;
|
||||||
|
if (CirCache::append(dir, *argv++, &reason) < 0) {
|
||||||
|
cerr << reason << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
@ -1698,11 +1620,24 @@ b1:
|
|||||||
}
|
}
|
||||||
string udi;
|
string udi;
|
||||||
make_udi(fn, "", udi);
|
make_udi(fn, "", udi);
|
||||||
sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n",
|
string cmd("xdg-mime query filetype ");
|
||||||
udi.c_str());
|
// Should do more quoting here...
|
||||||
string sdic;
|
cmd += "'" + fn + "'";
|
||||||
sdic.assign(dic, strlen(dic));
|
FILE *fp = popen(cmd.c_str(), "r");
|
||||||
ConfSimple conf(sdic);
|
char* buf=0;
|
||||||
|
size_t sz = 0;
|
||||||
|
::getline(&buf, &sz, fp);
|
||||||
|
pclose(fp);
|
||||||
|
string mimetype(buf);
|
||||||
|
free(buf);
|
||||||
|
trimstring(mimetype, "\n\r");
|
||||||
|
cout << "Got [" << mimetype << "]\n";
|
||||||
|
|
||||||
|
string s;
|
||||||
|
ConfSimple conf(s);
|
||||||
|
conf.set("udi", udi);
|
||||||
|
conf.set("mimetype", mimetype);
|
||||||
|
//ostringstream str; conf.write(str); cout << str.str() << endl;
|
||||||
|
|
||||||
if (!cc.put(udi, &conf, data, 0)) {
|
if (!cc.put(udi, &conf, data, 0)) {
|
||||||
cerr << "Put failed: " << cc.getReason() << endl;
|
cerr << "Put failed: " << cc.getReason() << endl;
|
||||||
@ -1722,7 +1657,7 @@ b1:
|
|||||||
string udi = *argv++;
|
string udi = *argv++;
|
||||||
argc--;
|
argc--;
|
||||||
string dic, data;
|
string dic, data;
|
||||||
if (!cc.get(udi, dic, data, instance)) {
|
if (!cc.get(udi, dic, &data, instance)) {
|
||||||
cerr << "Get failed: " << cc.getReason() << endl;
|
cerr << "Get failed: " << cc.getReason() << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,8 +64,9 @@ public:
|
|||||||
|
|
||||||
virtual std::string getpath();
|
virtual std::string getpath();
|
||||||
|
|
||||||
|
// Set data to 0 if you just want the header
|
||||||
virtual bool get(const std::string& udi, std::string& dic,
|
virtual bool get(const std::string& udi, std::string& dic,
|
||||||
std::string& data, int instance = -1);
|
std::string *data = 0, int instance = -1);
|
||||||
|
|
||||||
// Note: the dicp MUST have an udi entry
|
// Note: the dicp MUST have an udi entry
|
||||||
enum PutFlags {NoCompHint = 1};
|
enum PutFlags {NoCompHint = 1};
|
||||||
@ -84,7 +85,7 @@ public:
|
|||||||
virtual bool rewind(bool& eof);
|
virtual bool rewind(bool& eof);
|
||||||
/** Get entry under cursor */
|
/** Get entry under cursor */
|
||||||
virtual bool getCurrent(std::string& udi, std::string& dic,
|
virtual bool getCurrent(std::string& udi, std::string& dic,
|
||||||
std::string& data);
|
std::string *data = 0);
|
||||||
/** Get current entry udi only. Udi can be empty (erased empty), caller
|
/** Get current entry udi only. Udi can be empty (erased empty), caller
|
||||||
* should call again */
|
* should call again */
|
||||||
virtual bool getCurrentUdi(std::string& udi);
|
virtual bool getCurrentUdi(std::string& udi);
|
||||||
@ -94,6 +95,18 @@ public:
|
|||||||
/* Debug. This writes the entry headers to stdout */
|
/* Debug. This writes the entry headers to stdout */
|
||||||
virtual bool dump();
|
virtual bool dump();
|
||||||
|
|
||||||
|
/* Utility: append all entries from sdir to ddir.
|
||||||
|
*
|
||||||
|
* This does not need to be a member at all, just using the namespace here.
|
||||||
|
*
|
||||||
|
* @param ddir destination circache (must be previously created
|
||||||
|
* with appropriate size)
|
||||||
|
* @param sdir source circache
|
||||||
|
* @ret number of entries copied or -a
|
||||||
|
*/
|
||||||
|
static int append(const std::string ddir, const std::string& sdir,
|
||||||
|
std::string *reason = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CirCacheInternal *m_d;
|
CirCacheInternal *m_d;
|
||||||
std::string m_dir;
|
std::string m_dir;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user