【问题标题】:Automatic File Uploader to Website自动文件上传到网站
【发布时间】:2017-03-19 21:15:02
【问题描述】:

我有一个带有上传文件表单的网站。一旦我的计算机上的本地文件夹发生更改,我想自动登录并上传图像文件。能否就此事提供任何指导。

【问题讨论】:

  • 您可能必须编写本机应用程序才能执行此操作,因为这样的功能会带来安全风险,并且很可能不被普通浏览器支持。
  • 您能详细说明一下吗?我对事情有点陌生。什么方法会奏效?
  • 您计算机上的本地文件的站点与您的网站的来源不同,为了防止 XSS(跨站点脚本),可以将文件发送到网站的唯一方法是由用户本机选择文件。无法从网站或 javascript 轮询计算机的本地磁盘以确定文件是否已更改(至少我不知道)
  • 我希望计算机上的程序检查文件夹/文件的更改并上传它们。与网站无关
  • 哦,我明白了……这让事情变得更清楚了……

标签: ruby-on-rails ubuntu web web-crawler image-uploading


【解决方案1】:

根据我的理解,您可以为此编写一个任务,它可以每小时运行一次,并检查目录中是否进行了任何更改,然后将这些文件上传到您的应用程序上。

【讨论】:

  • 任何关于如何写的详细信息?
  • 是的,请查看Sidekiq gem
【解决方案2】:

我不知道你正在开发什么样的系统,但你可以做这样的事情。如果您使用的是 linux 系统,则可以使用watch 命令来跟踪所选目录的活动。您可以做的是在由 watch 命令触发的 ruby​​ 脚本中使用 Mechanize 之类的东西,然后通过选择具有最新创建日期的文件来提交表单并为您上传文件。

【讨论】:

    【解决方案3】:

    我意识到它在帖子中说 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 分钟上传更改的文件

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多