13 using namespace Huggle;
17 PythonEngine *Core::Python = NULL;
33 QDateTime Core::StartupTime = QDateTime::currentDateTime();
39 QList<HuggleQueueFilter *> Core::FilterDB;
45 Core::Log(
"DEBUG: Huggle is running in a safe mode");
49 #if QT_VERSION >= 0x050000
50 QTextCodec::setCodecForLocale(QTextCodec::codecForName(
"UTF-8"));
52 QTextCodec::setCodecForCStrings(QTextCodec::codecForName(
"UTF-8"));
54 vf =
new QFile(
":/huggle/resources/Resources/Header.txt");
55 vf->open(QIODevice::ReadOnly);
66 Configuration::LocalConfig_IgnorePatterns.append(
"/sandbox");
67 Configuration::LocalConfig_IgnorePatterns.append(
"/Sandbox");
68 Configuration::LocalConfig_RevertSummaries.append(
"Test edits;Reverted edits by [[Special:Contributions/$1|$1]] identified as test edits");
71 Core::Python =
new PythonEngine();
75 Core::LoadLocalizations();
77 HuggleQueueFilter::Filters.append(HuggleQueueFilter::DefaultFilter);
84 Core::Log(
"Not loading plugins in a safe mode");
86 Core::Log(
"Loaded in " + QString::number(Core::StartupTime.msecsTo(QDateTime::currentDateTime())));
97 if (!db.open(QIODevice::ReadOnly | QIODevice::Text))
102 text = QString(db.readAll());
108 QFile vf(
":/huggle/resources/Resources/Definitions.txt");
109 vf.open(QIODevice::ReadOnly);
110 text = QString(vf.readAll());
116 QDomNodeList list = d.elementsByTagName(
"wiki");
118 while (xx < list.count())
120 QDomElement e = list.at(xx).toElement();
121 if (!e.attributes().contains(
"name"))
125 if (!e.attributes().contains(
"url"))
131 site->SupportOAuth =
false;
135 if (e.attributes().contains(
"path"))
137 site->
LongPath = e.attribute(
"path");
139 if (e.attributes().contains(
"wl"))
143 if (e.attributes().contains(
"script"))
147 if (e.attributes().contains(
"https"))
149 site->
SupportHttps = Configuration::SafeBool(e.attribute(
"https"));
151 if (e.attributes().contains(
"oauth"))
153 site->SupportOAuth = Configuration::SafeBool(e.attribute(
"oauth"));
155 if (e.attributes().contains(
"channel"))
166 while (text.startsWith(
" "))
185 if (edit->Previous != NULL && edit->Next != NULL)
187 edit->Previous->Next = edit->Next;
188 edit->Next->Previous = edit->Previous;
193 if (edit->Previous != NULL)
195 edit->Previous->Next = NULL;
198 if (edit->Next != NULL)
200 edit->Next->Previous = NULL;
206 QString Core::GetSummaryOfWarningTypeFromWarningKey(QString key)
209 while (
id<Configuration::LocalConfig_RevertSummaries.count())
211 QString line = Configuration::LocalConfig_RevertSummaries.at(
id);
212 if (line.startsWith(key +
";"))
214 return Core::GetValueFromKey(line);
218 return Configuration::DefaultRevertSummary;
221 QString Core::GetNameOfWarningTypeFromWarningKey(QString key)
224 while (
id<Configuration::LocalConfig_WarningTypes.count())
226 QString line = Configuration::LocalConfig_WarningTypes.at(
id);
227 if (line.startsWith(key) +
";")
229 return Core::GetValueFromKey(line);
236 QString Core::GetKeyOfWarningTypeFromWarningName(QString
id)
239 while (i<Configuration::LocalConfig_WarningTypes.count())
241 QString line = Configuration::LocalConfig_WarningTypes.at(i);
242 if (line.endsWith(
id) || line.endsWith(
id +
","))
244 return Core::GetKeyFromValue(line);
253 Configuration::LocalConfig_ScoreParts.clear();
254 while (text.contains(
"score-parts("))
256 text = text.mid(text.indexOf(
"score-parts(") + 12);
257 if (!text.contains(
")"))
261 int score = text.mid(0, text.indexOf(
")")).toInt();
270 if (!text.contains(
":"))
275 text = text.mid(text.indexOf(
":") + 1);
277 QStringList lines = text.split(
"\n");
280 while (line < lines.count())
282 QString l = lines.at(line);
283 QStringList items = l.split(
",");
285 while ( CurrentItem < items.count() )
287 QString w =
Core::Trim(items.at(CurrentItem));
304 while (line < word.count())
306 Configuration::LocalConfig_ScoreParts.append(
ScoreWord(word.at(line), score));
320 if (!file.open(QIODevice::Truncate | QIODevice::WriteOnly))
325 QString xx =
"<definitions>\n";
328 WikiUser::ProblematicUserListLock.lock();
335 WikiUser::ProblematicUserListLock.unlock();
336 xx +=
"</definitions>";
337 file.write(xx.toUtf8());
342 QString Core::GetValueFromKey(QString item)
344 if (item.contains(
";"))
346 QString type = item.mid(item.indexOf(
";") + 1);
347 if (type.endsWith(
","))
349 type = type.mid(0, type.length() - 1);
356 QString Core::GetKeyFromValue(QString item)
358 if (item.contains(
";"))
360 QString type = item.mid(0, item.indexOf(
";"));
366 void Core::ParseWords(QString text)
368 Configuration::LocalConfig_ScoreWords.clear();
369 while (text.contains(
"score-words("))
371 text = text.mid(text.indexOf(
"score-words(") + 12);
372 if (!text.contains(
")"))
376 int score = text.mid(0, text.indexOf(
")")).toInt();
385 if (!text.contains(
":"))
390 text = text.mid(text.indexOf(
":") + 1);
392 QStringList lines = text.split(
"\n");
395 while (line < lines.count())
397 QString l = lines.at(line);
398 QStringList items = l.split(
",");
400 while ( CurrentItem < items.count() )
402 QString w =
Core::Trim(items.at(CurrentItem));
419 while (line < word.count())
421 Configuration::LocalConfig_ScoreWords.append(
ScoreWord(word.at(line), score));
431 Core::Log(
"Cowardly refusing to message NULL user");
451 Core::Log(
"WARNING: recovering definitions from last session");
460 Core::Log(
"WARNING: Unable to recover the definitions");
467 defs.open(QIODevice::ReadOnly);
468 QString Contents(defs.readAll());
470 list.setContent(Contents);
471 QDomNodeList l = list.elementsByTagName(
"user");
478 QDomElement e = l.at(i).toElement();
479 if (!e.attributes().contains(
"name"))
485 user->
Username = e.attribute(
"name");
486 if (e.attributes().contains(
"badness"))
488 user->setBadnessScore(e.attribute(
"badness").toInt());
497 void Core::FinalizeMessages()
504 QList<Message*> list;
514 while (x<list.count())
521 QString Core::RetrieveTemplateToWarn(QString type)
524 while (x < Configuration::LocalConfig_WarningTemplates.count())
526 if (Core::GetKeyFromValue(Configuration::LocalConfig_WarningTemplates.at(x)) == type)
528 return Core::GetValueFromKey(Configuration::LocalConfig_WarningTemplates.at(x));
535 EditQuery *Core::EditPage(
WikiPage *page, QString text, QString summary,
bool minor)
565 Message =
"<" + QDateTime::currentDateTime().toString() +
"> " + Message;
566 std::cout << Message.toStdString() << std::endl;
567 Core::InsertToRingLog(Message);
578 if (QDir().exists(EXTENSION_PATH))
580 QDir d(EXTENSION_PATH);
581 QStringList extensions = d.entryList();
583 while (xx < extensions.count())
585 QString name = extensions.at(xx).toLower();
586 if (name.endsWith(
".so") || name.endsWith(
".dll"))
588 name = QString(EXTENSION_PATH) + QDir::separator() + extensions.at(xx);
589 QPluginLoader *extension =
new QPluginLoader(name);
590 if (extension->load())
592 QObject* root = extension->instance();
595 iExtension *
interface = qobject_cast<iExtension*>(root);
598 Core::Log(
"Unable to cast the library to extension");
601 if (interface->Register())
604 Core::Log(
"Successfully loaded: " + extensions.at(xx));
608 Core::Log(
"Unable to register: " + extensions.at(xx));
614 Core::Log(
"Failed to load (reason: " + extension->errorString() +
"): " + extensions.at(xx));
622 Core::Log(
"There is no extensions folder, skipping load");
629 QFile *vf =
new QFile(
":/huggle/git/version.txt");
630 vf->open(QIODevice::ReadOnly);
631 QString version(vf->readAll());
632 version = version.replace(
"\n",
"");
634 #ifdef PRODUCTION_BUILD
645 Core::Log(
"DEBUG[" + QString::number(Verbosity) +
"]: " + Message);
692 #if QT_VERSION >= 0x050000
693 QThread::usleep(200000);
709 QApplication::quit();
729 void Core::InsertToRingLog(QString text)
740 QMessageBox *mb =
new QMessageBox();
741 mb->setWindowTitle(
"Function is restricted now");
742 mb->setText(
"You can't perform this action in developer mode, because you aren't logged into the wiki");
754 if (_e->Status == StatusProcessed)
759 if (_e->
User == NULL)
761 throw new Exception(
"Edit user was NULL in Core::PreProcessEdit");
766 _e->
User->SetBot(
true);
771 _e->Status = StatusProcessed;
778 throw new Exception(
"NULL edit in PostProcessEdit(WikiEdit *_e) is not a valid edit");
809 QList<Query*> Finished;
824 while (curr < Finished.count())
826 Query *item = Finished.at(curr);
839 throw new Exception(
"NULL edit in PreflightCheck(WikiEdit *_e) is not a valid edit");
843 QMessageBox::StandardButton q = QMessageBox::question(NULL,
"Revert edit"
844 ,
"This page is in userspace, so even if it looks like it is a vandalism,"\
845 " it may not be, are you sure you want to revert it?"
846 , QMessageBox::Yes|QMessageBox::No);
847 if (q == QMessageBox::No)
859 throw new Exception(
"NULL edit in RevertEdit(WikiEdit *_e, QString summary, bool minor, bool rollback, bool keep) is not a valid edit");
861 if (_e->
User == NULL)
863 throw new Exception(
"Object user was NULL in Core::Revert");
866 if (_e->
Page == NULL)
868 throw new Exception(
"Object page was NULL");
874 query->Summary = summary;
876 query->MinorEdit = minor;
895 void Core::ExceptionHandler(
Exception *exception)
902 Language *Core::MakeLanguage(QString text, QString name)
906 QStringList keys = text.split(
"\n");
908 while (p < keys.count())
910 if (keys.at(p).contains(
":"))
912 QString line = keys.at(p);
913 while (line.startsWith(
" "))
917 QString key = line.mid(0, line.indexOf(
":"));
918 QString lang = line.mid(line.indexOf(
":") + 1);
919 while (lang.startsWith(
" "))
923 if (!l->Messages.contains(key))
925 l->Messages.insert(key, lang);
930 if (l->Messages.contains(
"name"))
939 QFile *f =
new QFile(
":/huggle/text/Localization/" + name +
".txt");
940 f->open(QIODevice::ReadOnly);
946 QString Core::Localize(QString key)
949 if (
id.endsWith(
"]]"))
951 id = key.mid(0, key.length() - 2);
953 if (
id.startsWith(
"[["))
965 if (l->Messages.contains(
id))
967 return l->Messages[id];
982 void Core::LoadLocalizations()
987 Core::Log(
"Skipping load of other languages, because of safe mode");
1017 bool Core::ReportPreFlightCheck()
1023 QMessageBox::StandardButton q = QMessageBox::question(NULL,
"Report user"
1024 ,
"This user has already reached warning level 4, so no further templates will be "\
1025 "delivered to them. You can report them now, but please, make sure that they already reached the proper "\
1026 "number of recent warnings! You can do so by clicking the \"talk page\" button in following form. "\
1027 "Keep in mind that this form and this warning is displayed no matter if your revert was successful "\
1028 "or not, so you might conflict with other users here (double check if user isn't already reported) "\
1029 "Do you want to report this user?"
1030 , QMessageBox::Yes|QMessageBox::No);
1031 if (q == QMessageBox::No)
1038 int Core::RunningQueriesGetCount()
1050 bool HgApplication::notify(QObject *receiver, QEvent *event)
1055 done = QApplication::notify(receiver, event);
1058 Core::ExceptionHandler(ex);
1061 Core::ExceptionHandler(&ex);
static QString HuggleVersion
Version.
static QString GetProjectScriptURL()
Return a script url like http://en.wikipedia.org/w/.
virtual bool SafeDelete()
Use this if you are not sure if you can delete this object in this moment.
static QString WikiDB
Path to a file where information about wikis are stored.
static QString GetProjectWikiURL()
Return a full url like http://en.wikipedia.org/wiki/.
static WikiPage * AIVP
Pointer to AIV page.
static void Log(QString Message)
Write text to terminal as well as ring log.
static WikiPage * UAAP
Pointer to UAA page.
static QString GetConfigurationPath()
Return a configuration path.
static void SaveDefs()
Store a definitions of problematic users, see WikiUser::ProblematicUsers for details.
static QString HtmlHeader
This string contains a html header.
void Process()
Execute query.
QString LongPath
long article path (wiki/ for example on english wp)
static QString GetProjectURL()
Return a base url of current project.
static void PostProcessEdit(WikiEdit *_e)
bool UsingSR
Whether software rollback should be used instead of regular rollback.
static QString RingLogToText()
Return a ring log represented as 1 huge string.
static QString HtmlFooter
This string contains a html footer.
QString summary
Edit summary.
virtual bool Processed()
Returns true in case that query is processed.
void UnregisterConsumer(const int consumer)
This function will remove a string which prevent the object from being removed.
bool Minor
Whether the edit is minor or not.
static QString GetURLProtocolPrefix()
Return a prefix for url.
void RegisterConsumer(const int consumer)
Registers a consumer.
QString page
Page that is going to be edited.
Feed provider stub class every provider must be derived from this one.
void ProcessEdit(WikiEdit *e, bool IgnoreHistory=false)
Recreate interface, should be called everytime you do anything with main form.
static void AppendQuery(Query *item)
Insert a query to internal list of running queries, so that they can be watched This will insert it t...
The RevertQuery class can be used to rollback any edit.
static void VersionRead()
VersionRead - read the version from embedded git file.
QString Username
Username.
static Message * MessageUser(WikiUser *user, QString message, QString title, QString summary, bool section=true, Query *dependency=NULL)
MessageUser Message user.
QString LanguageName
This is a short language name which is used by system.
static QList< EditQuery * > PendingMods
Pending changes.
static ProcessorThread * Processor
This is a post-processor for edits.
QString IRCChannel
IRC channel of this site, if it doesn't have a channel leave it empty.
bool SupportHttps
Whether the site supports the ssl.
static void DeleteEdit(WikiEdit *edit)
Remove edit in proper manner.
static void CheckQueries()
Check if all running queries are finished and if so it removes them from list.
static void LoadConfig()
Load the local configuration from disk.
Window that is displayed as first when huggle is started.
This is similar to query, just it's more simple, you can use it to deliver messages to users...
static HuggleFeed * SecondaryFeedProvider
Pointer to secondary feed provider.
static bool WarnUserSpaceRoll
Warn you in case you want to revert a user page.
static void Shutdown()
Terminate the process, call this after you release all resources and finish all queries.
Edits are post processed in this thread.
static RevertQuery * RevertEdit(WikiEdit *_e, QString summary="", bool minor=false, bool rollback=true, bool keep=false)
RevertEdit Reverts the edit.
QString Summary
Summary of edit.
void RemoveQuery(Query *q)
Remove a query from list no matter if it finished or not.
static void PreProcessEdit(WikiEdit *_e)
static HuggleFeed * PrimaryFeedProvider
Pointer to primary feed provider.
static void LocalInit(QString name)
Initializes a localization with given name.
QString ScriptPath
short path
static QString Language
Language selected by user this is only a language of interface.
void PostProcess()
This function is called by internals of huggle.
bool EditMadeByHuggle
If this is true the edit was made by huggle.
QStringList UnwrittenLogs
ProcessList * Queries
Pointer to processes.
static QList< WikiUser * > ProblematicUsers
List of users that are scored in this instance of huggle.
Every exception raised by huggle is defined by this class.
Query * Dependency
If this dependency is not a NULL then a message is sent after it is Processed (see Query::Processed()...
QString text
Text a page will be replaced with.
static void Init()
Function which is called as one of first when huggle is loaded.
static unsigned int Verbosity
Verbosity for debugging to terminal etc, can be switched with parameter –verbosity.
static void DeveloperError()
Display a message box telling user that function is not allowed during developer mode.
QMutex lUnwrittenLogs
Mutex we lock unwritten logs with so that only 1 thread can write to it.
Modifications of mediawiki pages can be done using this query.
static WikiSite Project
currently selected project
static QList< WikiEdit * > ProcessingEdits
static QList< Query * > RunningQueries
List of all running queries.
static QString EditSuffixOfHuggle
Suffix used by huggle.
void Process()
Execute query.
static int RingLogMaxSize
Maximum size of ringlog.
WikiUser * User
User who changed the page.
static bool Running
Change this to false when you want to terminate all threads properly (you will need to wait few ms) ...
static void DebugLog(QString Message, unsigned int Verbosity=1)
This log is only shown if verbosity is same or larger than requested verbosity.
static void ParsePats(QString text)
Parse a part patterns for score words.
static QList< Message * > Messages
List of all messages that are being sent.
QString URL
URL of wiki, no http prefix must be present.
static QList< iExtension * > Extensions
List of extensions loaded in huggle.
static QStringList RingLog
Ring log is a buffer that contains system messages.
static QList< Language * > LocalizationData
Languages D:
static void ExtensionLoad()
Load extensions (libraries as well as python)
static Login * f_Login
Login form.
static QStringList RingLogToQStringList()
Return a ring log as qstring list.
void Send()
Send a message to user.
QString LanguageID
Long identifier of language that is seen by user.
static QList< WikiSite * > ProjectList
List of projects.
void Lock()
Lock this object so that other threads can't change consumers or modify its properties.
static void TrimProblematicUsersList()
Delete all users that have badness score 0 these users aren't necessary to be stored in a list...
static bool _SafeMode
If this is true some functionalities will be disabled.
static bool PreflightCheck(WikiEdit *_e)
Check if we can revert this edit.
static MainWindow * Main
Pointer to main.
QString PageName
Name of page.
static QString Trim(QString text)
Remove leading and finishing space of string.
bool Bot
Edit is a bot edit.
static void SaveConfig()
Save the local configuration to file.
static void LoadDefs()
Load a definitions of problematic users, see WikiUser::ProblematicUsers for details.
WikiPage * Page
Page that was changed by edit.
bool Section
If edit will be created in new section.
void UpdateQuery(Query *q)
Update information about query in list.
QString Data
Data retrieved by query.
static bool AskUserBeforeReport
Ask user if they really want to report someone.
Query base class for all http queries executed by huggle.
QueryResult * Result
Result of query, see documentation of QueryResult for more.
static bool EnforceManualSoftwareRollback
If this is true huggle will always use software rollback even if user has the rollback privileges...