You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
12 KiB
422 lines
12 KiB
/*
|
|
* This file is part of the KFTPGrabber project
|
|
*
|
|
* Copyright (C) 2003-2006 by the KFTPGrabber developers
|
|
* Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
|
|
*
|
|
* 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
|
|
* is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
|
|
* NON-INFRINGEMENT. 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., 51 Franklin Steet, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*
|
|
* In addition, as a special exception, the copyright holders give
|
|
* permission to link the code of portions of this program with the
|
|
* OpenSSL library under certain conditions as described in each
|
|
* individual source file, and distribute linked combinations
|
|
* including the two.
|
|
*
|
|
* You must obey the GNU General Public License in all respects
|
|
* for all of the code used other than OpenSSL. If you modify
|
|
* file(s) with this exception, you may extend this exception to your
|
|
* version of the file(s), but you are not obligated to do so. If you
|
|
* do not wish to do so, delete this exception statement from your
|
|
* version. If you delete this exception statement from all source
|
|
* files in the program, then also delete it here.
|
|
*/
|
|
#include "filter.h"
|
|
|
|
#include <ntqregexp.h>
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdelocale.h>
|
|
#include <kstaticdeleter.h>
|
|
#include <tdeconfig.h>
|
|
|
|
namespace KFTPCore {
|
|
|
|
namespace Filter {
|
|
|
|
Condition::Condition(Field field, Type type, const TQVariant &value)
|
|
: m_field(field),
|
|
m_type(type),
|
|
m_value(value)
|
|
{
|
|
}
|
|
|
|
bool Condition::matches(const KFTPEngine::DirectoryEntry &entry) const
|
|
{
|
|
bool result = false;
|
|
TQString check;
|
|
|
|
switch (m_field) {
|
|
default:
|
|
case Filename: check = entry.filename(); break;
|
|
case EntryType: check = entry.type(); break;
|
|
case Size: check = TQString::number(entry.size()); break;
|
|
}
|
|
|
|
switch (m_type) {
|
|
case None: result = false; break;
|
|
|
|
case Contains: result = (check.contains(m_value.toString()) > 0); break;
|
|
case ContainsNot: result = (check.contains(m_value.toString()) == 0); break;
|
|
|
|
case Is: result = (check == m_value.toString()); break;
|
|
case IsNot: result = (check != m_value.toString()); break;
|
|
|
|
case Matches: {
|
|
TQRegExp r(m_value.toString());
|
|
result = (r.search(check) > -1);
|
|
break;
|
|
}
|
|
case MatchesNot: {
|
|
TQRegExp r(m_value.toString());
|
|
result = (r.search(check) == -1);
|
|
break;
|
|
}
|
|
|
|
case Greater: result = (check.toULongLong() > m_value.toULongLong()); break;
|
|
case Smaller: result = (check.toULongLong() < m_value.toULongLong()); break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ConditionChain::ConditionChain()
|
|
: TQPtrList<Condition>(),
|
|
m_type(All)
|
|
{
|
|
setAutoDelete(true);
|
|
}
|
|
|
|
ConditionChain::ConditionChain(Type type)
|
|
: TQPtrList<Condition>(),
|
|
m_type(type)
|
|
{
|
|
setAutoDelete(true);
|
|
}
|
|
|
|
bool ConditionChain::matches(const KFTPEngine::DirectoryEntry &entry) const
|
|
{
|
|
if (isEmpty())
|
|
return false;
|
|
|
|
TQPtrList<Condition>::ConstIterator le = end();
|
|
for (TQPtrList<Condition>::ConstIterator i = begin(); i != le; ++i) {
|
|
bool match = (*i)->matches(entry);
|
|
|
|
if (match && m_type == Any)
|
|
return true;
|
|
else if (!match && m_type == All)
|
|
return false;
|
|
}
|
|
|
|
if (m_type == Any)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
Action::Action()
|
|
: m_valid(false)
|
|
{
|
|
}
|
|
|
|
Action::Action(Type type, const TQVariant &value)
|
|
: m_valid(true),
|
|
m_type(type),
|
|
m_value(value)
|
|
{
|
|
}
|
|
|
|
ActionChain::ActionChain()
|
|
: TQPtrList<Action>()
|
|
{
|
|
setAutoDelete(true);
|
|
}
|
|
|
|
const Action *ActionChain::getAction(Action::Type type) const
|
|
{
|
|
ActionChain::ConstIterator le = end();
|
|
for (ActionChain::ConstIterator i = begin(); i != le; ++i)
|
|
if ((*i)->type() == type)
|
|
return (*i);
|
|
|
|
return 0;
|
|
}
|
|
|
|
Rule::Rule()
|
|
: m_name(TQString::null),
|
|
m_enabled(false)
|
|
{
|
|
}
|
|
|
|
Rule::Rule(const Rule *rule)
|
|
: m_name(rule->name()),
|
|
m_enabled(rule->isEnabled())
|
|
{
|
|
// Copy conditions
|
|
const ConditionChain *conditionList = rule->conditions();
|
|
m_conditionChain.setType(conditionList->type());
|
|
|
|
ConditionChain::ConstIterator cle = conditionList->end();
|
|
for (ConditionChain::ConstIterator i = conditionList->begin(); i != cle; ++i) {
|
|
const Condition *c = (*i);
|
|
|
|
m_conditionChain.append(new Condition(c->field(), c->type(), c->value()));
|
|
}
|
|
|
|
// Copy actions
|
|
const ActionChain *actionList = rule->actions();
|
|
|
|
ActionChain::ConstIterator ale = actionList->end();
|
|
for (ActionChain::ConstIterator i = actionList->begin(); i != ale; ++i) {
|
|
const Action *a = (*i);
|
|
|
|
m_actionChain.append(new Action(a->type(), a->value()));
|
|
}
|
|
}
|
|
|
|
Rule::Rule(const TQString &name)
|
|
: m_name(name),
|
|
m_enabled(true)
|
|
{
|
|
// Add a simple condition and a simple action
|
|
m_conditionChain.append(new Condition(Filename, Condition::Contains, TQVariant("")));
|
|
m_actionChain.append(new Action(Action::None, TQVariant()));
|
|
}
|
|
|
|
Filters *Filters::m_self = 0;
|
|
static KStaticDeleter<Filters> staticFiltersDeleter;
|
|
|
|
Filters *Filters::self()
|
|
{
|
|
if (!m_self) {
|
|
staticFiltersDeleter.setObject(m_self, new Filters());
|
|
}
|
|
|
|
return m_self;
|
|
}
|
|
|
|
Filters::Filters()
|
|
: TQPtrList<Rule>(),
|
|
m_enabled(true)
|
|
{
|
|
setAutoDelete(true);
|
|
|
|
// Generate human readable strings
|
|
m_fieldNames << i18n("Filename");
|
|
m_fieldNames << i18n("Entry Type");
|
|
m_fieldNames << i18n("Size");
|
|
|
|
m_actionNames << " ";
|
|
m_actionNames << i18n("Change priority");
|
|
m_actionNames << i18n("Skip when queuing");
|
|
m_actionNames << i18n("Colorize in list view");
|
|
m_actionNames << i18n("Hide from list view");
|
|
m_actionNames << i18n("Lowercase destination");
|
|
|
|
// Load the filters
|
|
load();
|
|
}
|
|
|
|
Filters::~Filters()
|
|
{
|
|
if (m_self == this)
|
|
staticFiltersDeleter.setObject(m_self, 0, false);
|
|
}
|
|
|
|
void Filters::save()
|
|
{
|
|
int num = 0;
|
|
TDEConfig *config = kapp->config();
|
|
|
|
config->setGroup("Filters");
|
|
config->writeEntry("count", count());
|
|
|
|
// Remove any existing sections
|
|
for (int i = 0; ; i++) {
|
|
TQString groupName = TQString("Filter #%1").arg(i);
|
|
|
|
if (config->hasGroup(groupName))
|
|
config->deleteGroup(groupName);
|
|
else
|
|
break;
|
|
}
|
|
|
|
Filters::ConstIterator le = end();
|
|
for (Filters::ConstIterator i = begin(); i != le; ++i, num++) {
|
|
const Rule *rule = (*i);
|
|
|
|
config->setGroup(TQString("Filter #%1").arg(num));
|
|
config->writeEntry("name", rule->name());
|
|
config->writeEntry("enabled", rule->isEnabled());
|
|
|
|
// Write conditions
|
|
int cnum = 0;
|
|
const ConditionChain *conditions = rule->conditions();
|
|
config->writeEntry("conditions", conditions->count());
|
|
config->writeEntry("conditions-type", (int) conditions->type());
|
|
|
|
ConditionChain::ConstIterator cle = conditions->end();
|
|
for (ConditionChain::ConstIterator j = conditions->begin(); j != cle; ++j, cnum++) {
|
|
const Condition *c = (*j);
|
|
TQString prefix = TQString("condition%1-").arg(cnum);
|
|
|
|
config->writeEntry(prefix + "field", (int) c->field());
|
|
config->writeEntry(prefix + "type", (int) c->type());
|
|
config->writeEntry(prefix + "value", c->value());
|
|
config->writeEntry(prefix + "valueType", (int) c->value().type());
|
|
}
|
|
|
|
// Write actions
|
|
int anum = 0;
|
|
const ActionChain *actions = rule->actions();
|
|
config->writeEntry("actions", actions->count());
|
|
|
|
ActionChain::ConstIterator ale = actions->end();
|
|
for (ActionChain::ConstIterator j = actions->begin(); j != ale; ++j, anum++) {
|
|
const Action *a = (*j);
|
|
TQString prefix = TQString("action%1-").arg(anum);
|
|
|
|
config->writeEntry(prefix + "type", (int) a->type());
|
|
config->writeEntry(prefix + "value", a->value());
|
|
config->writeEntry(prefix + "valueType", (int) a->value().type());
|
|
}
|
|
}
|
|
}
|
|
|
|
void Filters::load()
|
|
{
|
|
int num = 0;
|
|
TDEConfig *config = kapp->config();
|
|
|
|
config->setGroup("Filters");
|
|
num = config->readNumEntry("count");
|
|
|
|
for (int i = 0; i < num; i++) {
|
|
Rule *rule = new Rule();
|
|
|
|
config->setGroup(TQString("Filter #%1").arg(i));
|
|
rule->setName(config->readEntry("name", i18n("Unnamed Rule")));
|
|
rule->setEnabled(config->readBoolEntry("enabled", true));
|
|
|
|
// Read conditions
|
|
ConditionChain *conditions = const_cast<ConditionChain*>(rule->conditions());
|
|
int cnum = config->readNumEntry("conditions");
|
|
conditions->setType((ConditionChain::Type) config->readNumEntry("conditions-type"));
|
|
|
|
for (int j = 0; j < cnum; j++) {
|
|
TQString prefix = TQString("condition%1-").arg(j);
|
|
|
|
conditions->append(new Condition((Field) config->readNumEntry(prefix + "field"),
|
|
(Condition::Type) config->readNumEntry(prefix + "type"),
|
|
config->readPropertyEntry(prefix + "value",
|
|
(TQVariant::Type) config->readNumEntry(prefix + "valueType"))));
|
|
}
|
|
|
|
// Read actions
|
|
ActionChain *actions = const_cast<ActionChain*>(rule->actions());
|
|
int anum = config->readNumEntry("actions");
|
|
|
|
for (int j = 0; j < anum; j++) {
|
|
TQString prefix = TQString("action%1-").arg(j);
|
|
|
|
actions->append(new Action((Action::Type) config->readNumEntry(prefix + "type"),
|
|
config->readPropertyEntry(prefix + "value",
|
|
(TQVariant::Type) config->readNumEntry(prefix + "valueType"))));
|
|
}
|
|
|
|
append(rule);
|
|
}
|
|
}
|
|
|
|
const ActionChain *Filters::process(const KFTPEngine::DirectoryEntry &entry) const
|
|
{
|
|
if (m_enabled) {
|
|
TQPtrList<Rule>::ConstIterator le = end();
|
|
for (TQPtrList<Rule>::ConstIterator i = begin(); i != le; ++i) {
|
|
const Rule *rule = (*i);
|
|
|
|
if (rule->isEnabled() && rule->conditions()->matches(entry))
|
|
return rule->actions();
|
|
}
|
|
}
|
|
|
|
// Nothing has matched
|
|
return 0;
|
|
}
|
|
|
|
const Action *Filters::process(const KFTPEngine::DirectoryEntry &entry, TQValueList<Action::Type> types) const
|
|
{
|
|
const ActionChain *chain = process(entry);
|
|
|
|
if (!chain || chain->isEmpty())
|
|
return 0;
|
|
|
|
// Find an action that matches the filter
|
|
ActionChain::ConstIterator le = chain->end();
|
|
for (ActionChain::ConstIterator i = chain->begin(); i != le; ++i) {
|
|
if (types.contains((*i)->type()))
|
|
return (*i);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const Action *Filters::process(const KFTPEngine::DirectoryEntry &entry, Action::Type filter) const
|
|
{
|
|
const ActionChain *chain = process(entry);
|
|
|
|
if (!chain || chain->isEmpty())
|
|
return 0;
|
|
|
|
// Find an action that matches the filter
|
|
ActionChain::ConstIterator le = chain->end();
|
|
for (ActionChain::ConstIterator i = chain->begin(); i != le; ++i) {
|
|
if ((*i)->type() == filter)
|
|
return (*i);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const Action *Filters::process(const KURL &url, filesize_t size, bool directory, Action::Type filter) const
|
|
{
|
|
KFTPEngine::DirectoryEntry entry;
|
|
entry.setFilename(url.filename());
|
|
entry.setSize(size);
|
|
entry.setType(directory ? 'd' : 'f');
|
|
|
|
return process(entry, filter);
|
|
}
|
|
|
|
const ActionChain *Filters::process(const KURL &url, filesize_t size, bool directory) const
|
|
{
|
|
KFTPEngine::DirectoryEntry entry;
|
|
entry.setFilename(url.filename());
|
|
entry.setSize(size);
|
|
entry.setType(directory ? 'd' : 'f');
|
|
|
|
return process(entry);
|
|
}
|
|
|
|
const Action *Filters::process(const KURL &url, Action::Type filter) const
|
|
{
|
|
return process(url, 0, false, filter);
|
|
}
|
|
|
|
}
|
|
|
|
}
|