uncompress file before starting external viewer except if in the nouncompforviewmts list
This commit is contained in:
parent
8b1797b4a5
commit
ad4f24923f
@ -721,6 +721,8 @@ string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag)
|
||||
LOGDEB(("RclConfig::getMimeViewerDef: mtype %s apptag %s\n",
|
||||
mtype.c_str(), apptag.c_str()));
|
||||
string hs;
|
||||
if (mimeview == 0)
|
||||
return hs;
|
||||
if (apptag.empty() || !mimeview->get(mtype + string("|") + apptag,
|
||||
hs, "view"))
|
||||
mimeview->get(mtype, hs, "view");
|
||||
@ -740,6 +742,8 @@ bool RclConfig::getMimeViewerDefs(vector<pair<string, string> >& defs)
|
||||
|
||||
bool RclConfig::setMimeViewerDef(const string& mt, const string& def)
|
||||
{
|
||||
if (mimeview == 0)
|
||||
return false;
|
||||
string pconfname = path_cat(m_confdir, "mimeview");
|
||||
// Make sure this exists
|
||||
close(open(pconfname.c_str(), O_CREAT|O_WRONLY, 0600));
|
||||
@ -763,6 +767,17 @@ bool RclConfig::setMimeViewerDef(const string& mt, const string& def)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RclConfig::mimeViewerNeedsUncomp(const string &mimetype)
|
||||
{
|
||||
string s;
|
||||
vector<string> v;
|
||||
if (mimeview != 0 && mimeview->get("nouncompforviewmts", s, "") &&
|
||||
stringToStrings(s, v) &&
|
||||
find_if(v.begin(), v.end(), StringIcmpPred(mimetype)) != v.end())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return icon name and path
|
||||
*/
|
||||
|
||||
@ -209,6 +209,10 @@ class RclConfig {
|
||||
string getMimeViewerDef(const string &mimetype, const string& apptag);
|
||||
bool getMimeViewerDefs(vector<pair<string, string> >&);
|
||||
bool setMimeViewerDef(const string& mimetype, const string& cmd);
|
||||
/** Check if mime type is designated as needing no uncompress before view
|
||||
* (if a file of this type is found compressed). Default is true,
|
||||
* exceptions are found in the nouncompforviewmts mimeview list */
|
||||
bool mimeViewerNeedsUncomp(const string &mimetype);
|
||||
|
||||
/** Store/retrieve missing helpers description string */
|
||||
string getMissingHelperDesc();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
while true;do
|
||||
make FORMATS=html
|
||||
make FORMATS="html html-split"
|
||||
cp *.html /usr/local/www/lesbonscomptes/recoll/usermanual/
|
||||
sleep 1
|
||||
done
|
||||
|
||||
@ -3605,7 +3605,7 @@ x-my-tag = mailmytag
|
||||
which will override those from the central configuration
|
||||
file.</para>
|
||||
<para>Please note that these entries must be placed under a
|
||||
<literal>[view]</literal> section.</para>
|
||||
<literal>[view]</literal> section.</para>
|
||||
|
||||
<para>The keys in the file are normally mime types. You can add an
|
||||
application tag to specialize the choice for an area of the
|
||||
@ -3618,6 +3618,14 @@ x-my-tag = mailmytag
|
||||
all <filename>mimeview</filename> entries will be ignored
|
||||
except the one labelled <literal>application/x-all</literal>
|
||||
(which is set to use <command>xdg-open</command> by default).</para>
|
||||
|
||||
|
||||
<para>The <literal>nouncompforviewmts</literal> entry, (placed at
|
||||
the top level, outside of the <literal>[view]</literal> section),
|
||||
holds a list of mime types that should not be uncompressed before
|
||||
starting the viewer (if they are found compressed, ie:
|
||||
<replaceable>mydoc.doc.gz</replaceable>).</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="rcl.install.config.examples">
|
||||
|
||||
@ -46,6 +46,7 @@ using namespace std;
|
||||
#include "fileudi.h"
|
||||
#include "beaglequeuecache.h"
|
||||
#include "cancelcheck.h"
|
||||
#include "copyfile.h"
|
||||
|
||||
#ifdef RCL_USE_XATTR
|
||||
#include "pxattr.h"
|
||||
@ -946,6 +947,110 @@ bool FileInterner::idocToFile(TempFile& otemp, const string& tofile,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileInterner::isCompressed(const string& fn, RclConfig *cnf)
|
||||
{
|
||||
LOGDEB(("FileInterner::isCompressed: [%s]\n", fn.c_str()));
|
||||
struct stat st;
|
||||
if (stat(fn.c_str(), &st) < 0) {
|
||||
LOGERR(("FileInterner::isCompressed: can't stat [%s]\n", fn.c_str()));
|
||||
return false;
|
||||
}
|
||||
string l_mime = mimetype(fn, &st, cnf, true);
|
||||
if (l_mime.empty()) {
|
||||
LOGERR(("FileInterner::isUncompressed: can't get mime for [%s]\n",
|
||||
fn.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
list<string>ucmd;
|
||||
if (cnf->getUncompressor(l_mime, ucmd)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn,
|
||||
RclConfig *cnf, const Rcl::Doc& doc)
|
||||
{
|
||||
LOGDEB(("FileInterner::maybeUncompressToTemp: [%s]\n", fn.c_str()));
|
||||
struct stat st;
|
||||
if (stat(fn.c_str(), &st) < 0) {
|
||||
LOGERR(("FileInterner::maybeUncompressToTemp: can't stat [%s]\n",
|
||||
fn.c_str()));
|
||||
return false;
|
||||
}
|
||||
string l_mime = mimetype(fn, &st, cnf, true);
|
||||
if (l_mime.empty()) {
|
||||
LOGERR(("FileInterner::maybeUncompress.: can't id. mime for [%s]\n",
|
||||
fn.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
list<string>ucmd;
|
||||
if (!cnf->getUncompressor(l_mime, ucmd)) {
|
||||
return true;
|
||||
}
|
||||
// Check for compressed size limit
|
||||
int maxkbs = -1;
|
||||
if (cnf->getConfParam("compressedfilemaxkbs", &maxkbs) &&
|
||||
maxkbs >= 0 && int(st.st_size / 1024) > maxkbs) {
|
||||
LOGINFO(("FileInterner:: %s over size limit %d kbs\n",
|
||||
fn.c_str(), maxkbs));
|
||||
return false;
|
||||
}
|
||||
TempDir tmpdir;
|
||||
temp =
|
||||
TempFile(new TempFileInternal(cnf->getSuffixFromMimeType(doc.mimetype)));
|
||||
if (!tmpdir.ok() || !temp->ok()) {
|
||||
LOGERR(("FileInterner: cant create temporary file/dir"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// uncompressfile choses the output file name, there is good
|
||||
// reason for this, but it's not nice here. Have to copy or rename
|
||||
// the uncompressed file
|
||||
string uncomped;
|
||||
if (!uncompressfile(cnf, fn, ucmd, tmpdir, uncomped)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// uncompressfile choses the output file name, there is good
|
||||
// reason for this, but it's not nice here. Have to copy or rename
|
||||
// the uncompressed file.
|
||||
// Hopefully the cross-dev case won't happen as we're
|
||||
// probably choosing the temp names in the same dir. However...
|
||||
// Unix really should have a rename-else-copy call...
|
||||
if (stat(temp->filename(), &st) < 0) {
|
||||
LOGERR(("FileInterner::maybeUncompressToTemp: can't stat [%s]\n",
|
||||
temp->filename()));
|
||||
return false;
|
||||
}
|
||||
struct stat st1;
|
||||
if (stat(uncomped.c_str(), &st1) < 0) {
|
||||
LOGERR(("FileInterner::maybeUncompressToTemp: can't stat [%s]\n",
|
||||
uncomped.c_str()));
|
||||
return false;
|
||||
}
|
||||
if (st.st_dev == st1.st_dev) {
|
||||
if (rename(uncomped.c_str(), temp->filename()) < 0) {
|
||||
LOGERR(("FileInterner::maybeUncompress: rename [%s] -> [%s]"
|
||||
"failed, errno %d\n",
|
||||
uncomped.c_str(), temp->filename(), errno));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
string reason;
|
||||
bool ret = copyfile(uncomped.c_str(), temp->filename(), reason);
|
||||
if (ret == false) {
|
||||
LOGERR(("FileInterner::maybeUncompress: copy [%s] -> [%s]"
|
||||
"failed: %s\n",
|
||||
uncomped.c_str(), temp->filename(), reason.c_str()));
|
||||
return false;
|
||||
}
|
||||
// We let the tempdir cleanup get rid of uncomped
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@ -156,11 +156,25 @@ class FileInterner {
|
||||
static bool idocToFile(TempFile& temp, const string& tofile,
|
||||
RclConfig *cnf, const Rcl::Doc& doc);
|
||||
|
||||
/**
|
||||
* Does file appear to be the compressed version of a document?
|
||||
*/
|
||||
static bool isCompressed(const string& fn, RclConfig *cnf);
|
||||
|
||||
/**
|
||||
* Check input compressed, allocate temp file and uncompress if it is.
|
||||
* @return true if ok, false for error. Actual decompression is indicated
|
||||
* by the TempFile status (!isNull())
|
||||
*/
|
||||
static bool maybeUncompressToTemp(TempFile& temp, const string& fn,
|
||||
RclConfig *cnf, const Rcl::Doc& doc);
|
||||
|
||||
const string& getReason() const {return m_reason;}
|
||||
static void getMissingExternal(string& missing);
|
||||
static void getMissingDescription(string& desc);
|
||||
bool ok() {return m_ok;}
|
||||
|
||||
|
||||
private:
|
||||
static const unsigned int MAXHANDLERS = 20;
|
||||
RclConfig *m_cfg;
|
||||
|
||||
@ -1096,6 +1096,32 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
|
||||
url = string("file://") + fn;
|
||||
}
|
||||
|
||||
// If using an actual file, check that it exists, and if it is
|
||||
// compressed, we may need an uncompressed version
|
||||
if (!fn.empty() && rclconfig->mimeViewerNeedsUncomp(doc.mimetype)) {
|
||||
if (access(fn.c_str(), R_OK) != 0) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("Can't access file: ") +
|
||||
QString::fromLocal8Bit(fn.c_str()));
|
||||
return;
|
||||
}
|
||||
TempFile temp;
|
||||
if (FileInterner::isCompressed(fn, rclconfig)) {
|
||||
if (!FileInterner::maybeUncompressToTemp(temp, fn, rclconfig,
|
||||
doc)) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("Can't uncompress file: ") +
|
||||
QString::fromLocal8Bit(fn.c_str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!temp.isNull()) {
|
||||
m_tempfiles.push_back(temp);
|
||||
fn = temp->filename();
|
||||
url = string("file://") + fn;
|
||||
}
|
||||
}
|
||||
|
||||
// Substitute %xx inside prototype command
|
||||
string efftime;
|
||||
if (!doc.dmtime.empty() || !doc.fmtime.empty()) {
|
||||
@ -1134,6 +1160,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
|
||||
|
||||
if (!istempfile)
|
||||
historyEnterDoc(g_dynconf, doc.meta[Rcl::Doc::keyudi]);
|
||||
|
||||
// We should actually monitor these processes so that we can
|
||||
// delete the temp files when they exit
|
||||
LOGDEB(("Executing: [%s]\n", ncmd.c_str()));
|
||||
|
||||
@ -4,6 +4,11 @@
|
||||
# External viewers, launched by the recoll GUI when you click on a result
|
||||
# 'edit' link
|
||||
|
||||
# Mime types which we should not uncompress if they are found gzipped or
|
||||
# bzipped because the native viewer knows how to handle. These would be
|
||||
# exceptions and the list is normally empty
|
||||
#nouncompforviewmts =
|
||||
|
||||
[view]
|
||||
# Pseudo entry used if the 'use desktop' preference is set in the GUI
|
||||
application/x-all = xdg-open %f
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user