我意识到它在帖子中说 ruby on rails,但这个答案与用 Ruby 编写解决方案一样合法(而且更容易/更快)
使用 Qt C++ 来做到这一点,那么你可以这样做:
(未经测试,您必须根据自己的具体情况进行调整)
代码概览:
- 创建一个程序,该程序每 20 分钟在 Timer 上循环一次,并遍历您使用
WATCH_DIR 指定的整个目录,如果它发现该目录中的任何文件在循环上次运行时间之间被修改(或在程序启动之后但在第一个循环运行之前),然后它将该确切文件上传到您使用 UPLOAD_URL 指定的任何 URL
然后创建一个名为AutoUploader.pro的文件和一个名为main.cpp的文件
AutoUploader.pro
QT += core network
QT -= gui
CONFIG += c++11
TARGET = AutoUploader
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
main.cpp
#include <QtCore/QCoreApplication>
#include <QtCore/qglobal.h>
#include <QDir>
#include <QDirIterator>
#include <QNetworkAccessManager>
#include <QTimer>
#include <QByteArray>
#include <QHash>
#define WATCH_DIR "/home/lenny/images"
#define UPLOAD_URL "http://127.0.0.1/upload.php"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MainLoop loop(WATCH_DIR);
return a.exec();
}
class MainLoop : public QObject {
Q_OBJECT
public:
MainLoop(QString _watch_directory = qApp->applicationDirPath()) {
watch_directory = _watch_directory;
// the ACTION="" part of the upload form
website_upload_url = UPLOAD_URL;
/* 20 minutes
20 * 60 * 1000 = num of milliseconds that makes up
20 mins = 1200000 ms */
QTimer::singleShot(1200000, this, SLOT(check_for_updates()));
/* this will stop any file modified before you ran this program from
being uploaded so it wont upload all of the files at runtime */
program_start_time = QDateTime::currentDateTime();
}
QDateTime program_start_time;
QString watch_directory;
QString website_upload_url;
// hash table to store all of the last modified times for each file
QHash<QString, QDateTime> last_modified_time;
~MainLoop() { qApp->exit(); }
public slots:
void check_for_updates() {
QDirIterator it(QDir(watch_directory));
/* loop through all file in directory */
while (it.hasNext()) {
QFileInfo info(it.next());
/* check to see if the files modified time is ahead of
program_start_time */
if (info.lastModified.msecsTo(program_start_time) < 1) {
upload_file(info.absoluteFilePath());
}
}
/* set program_start_time to the current time to catch stuff next
time around and then start a timer to repeat this command in
20 minutes */
program_start_time = QDateTime::currentDateTime();
QTimer::singleShot(1200000, this, SLOT(check_for_updates()));
}
/* upload file code came from
https://forum.qt.io/topic/11086/solved-qnetworkaccessmanager-uploading-files/2
*/
void upload_file(QString filename) {
QNetworkAccessManager *am = new QNetworkAccessManager(this);
QString path(filename);
// defined with UPLOAD_URL
QNetworkRequest request(QUrl(website_upload_url));
QString bound="margin"; //name of the boundary
//according to rfc 1867 we need to put this string here:
QByteArray data(QString("--" + bound + "\r\n").toAscii());
data.append("Content-Disposition: form-data; name=\"action\"\r\n\r\n");
data.append("upload.php\r\n");
data.append("--" + bound + "\r\n"); //according to rfc 1867
data.append(QString("Content-Disposition: form-data; name=\"uploaded\"; filename=\"%1\"\r\n").arg(QFileInfo(filename).fileName()));
data.append(QString("Content-Type: image/%1\r\n\r\n").arg(QFileInfo(filename).suffix())); //data type
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
return;
data.append(file.readAll()); //let's read the file
data.append("\r\n");
data.append("--" + bound + "--\r\n");
request.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
request.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());
this->reply = am->post(request,data);
connect(this->reply, SIGNAL(finished()), this, SLOT(replyFinished()));
}
void replyFinished() {
/* perform some code here whenever a download finishes */
}
};
在运行此程序之前,请务必通读它并通过阅读 cmets 和帖子进行必要的更改——您可能还需要根据您的平台安装 qt 框架
无论如何,最后一步是运行qmake 来创建项目makefile,最后运行make 来构建二进制文件。
显然,最后的步骤因您使用的系统而异。
...该程序将继续运行...基本上永远运行,直到您关闭它...每 20 分钟上传更改的文件
希望这会有所帮助...