使用 Node.js、Sails 和 Flickr 的 Cron 作业
一个简单的 Flickr API 图片提取器,它将构建 Flickr API 图片的链接。
引言
我正在编写一个 Flickr API 图片提取器应用程序。
技术
- Nodejs 与 Sails 框架
- Flickr API(当然)
先决条件背景
- 您应该有使用 Sails 框架和 Node.js 的经验。
- 您应该有一个新的 Sails 项目,准备好放入代码。
新项目启动步骤
sails new flickrAccess
- 创建一个新的flickrAccess
Sails 项目npm install flickrAPI
- 连接 Flickr 的 Node.js 库:https://npmjs.net.cn/package/flickrapi
在 Sails 中像进程一样加载应用程序,无需 Web 服务器
Sails 主要是一个 Web 框架,所以通常的 'sails lift
' 命令也会创建并打开一个 Web 服务器。对于我们的目的,这不需要,实际上可能是一个安全隐患,使代码可以通过 HTTP 访问。
我们有两种选择,都涉及使用默认的 Node 命令通过 'node <文件名>
' 启动应用程序,而不是在命令/shell 提示符下执行 sails lift。(侧边栏:我在 Windows 上开发,在 Linux 上托管,所以仍然会将提示符称为命令提示符或 cmd)
将以下代码添加到应用程序的顶部。这是我们首先编写的代码之一,位于我们的 flickr-get-interesting.js 文件中(这就是我给根应用程序代码起的名字)
var Sails = require('sails');
Sails Lift / Load 之间的区别
您是否使用 Lift
/ Load
只有一个简单的区别:您是否需要 Web 服务器。Lift
会创建并启动一个 Web 服务器。
Sails.lift({
log: {
level: 'silent'
}
}, function() {
console.log('sails started..do commands');
process.stdin.destroy();
});
OR
Sails.load({
log: {level:'verbose'}
}, function(err, sails) {
console.log('sails started..do commands');
});
我们显然会使用 Load
,因为我们不需要服务器,也不需要修改默认的日志级别设置,所以我们只需要:
Sails.load (function(err, sails){
console.log('sails started..do commands');
});
此时,如果您执行 node flickr-get-interesting
,您应该会看到我们正在打印的日志。
sails started..do commands
Flickr API
此时,您需要拥有一个 Flickr 帐户、api_key
等。您可以在这里创建:https://www.flickr.com/services/apps/create/
必需
- 来自 Flickr App Garden 的 Flickr
api_key
- Flickr 密钥
用于我们实用方法的实用类
让我们创建一个 flickrUtils.js 文件,其中包含以下代码:
var util = require('util');
module.exports = {
api_key: "9d520e52f32630e1469231xxxxxxxxxx", //replace with your api_key
secret: "3e23bd445xxxxxxxx" // replace with your api secret
};
上面的代码将确保我们可以像 myUtils.api_key
一样访问我们的 api_key
/ 密钥,如果我们将其与 flickr-get-interesting.js 主代码文件中的 require 语句一起提及。
初始化 Flickr API
Flickr 是那些只需要 api_key
和密钥的 API 之一,一旦初始化,您就可以使用 API 方法查询它,几乎就像 Sails Blueprint API 一样。
让我们将所有 require 添加到主文件中并初始化 Flickr。
步骤
- 使用 Load 启动 Sails - 无需 Web 服务器
- 使用
api_key
和密钥初始化 Flickr API,并获得一个对象,以便以后使用 Flickr API 方法。
//flickr-get-interesting.js
var util = require('util');
var Sails = require('sails');
var flickrUtils = require('./flickrUtils.js');
var oFlickr; //using an external scoped variable for the api object,
//so we can use it in our other util methods without passing back-n-forth.
Sails.load(function(err, sails) {
console.log('sails started..do commands');
var Flickr = require("flickrapi"),
flickrOptions = {
api_key: flickrUtils.api_key,
secret: flickrUtils.secret
};
Flickr.tokenOnly(flickrOptions, function(error, flickr) {
oFlickr = flickr;
});
});
运行此代码之前,请确保所有 require 的文件都位于 Sails 项目的根目录中(- 请记住:我们不启动 Web 服务器或创建要从其他目录加载的资源...与常规的 Sails Web 项目不同)。
运行时,Flickr API 初始化需要相当长的时间.. 可能需要 2-3 分钟(不确定,但我认为它在第一次初始化时会下载一些 Flickr 库文件...之后,每次初始化都会快得多)。
啊!如果您没注意到:我们漏掉了一部分:“如何运行它?”
- ..不是用 sails lift
- 在 Sails 项目的根目录下,在您的命令/shell 提示符中使用以下命令:
node flickr-get-interesting.js
process.exit();
我们没有在代码中添加 process.exit();
行,所以 Flickr 会初始化,Sails 会加载应用程序并等待。
由于我们不期望它永远运行(我们期望它每隔几分钟运行一次,就像 cron 作业一样),我们将添加代码 process.exit();
获取有趣的内容
Flickr 在照片中有一个“有趣”的属性,还有一个 API 方法可以获取所有最近有趣的图片。
我们将调用此方法,并将 process.exit();
移至此方法的 Ajax success/error 块中,这样我们的进程就不会在收到 Flickr 的响应之前退出。
Flickr.tokenOnly(flickrOptions, function(error, flickr) {
oFlickr = flickr;
// we can now use "flickr" as our API object,
// but we can only call public methods and access public data
//flickr.photos.getRecent({
oFlickr.interestingness.getList({
page: 1,
per_page: 1 //change this appropriately later after debugging
//to get more of the interesting images
},
function(err, result) {
if (err) {
throw new Error(err);
finished();
}
//print the result object to console.log
console.log(util.inspect(result, {
showHidden: false,
depth: null
}));
// do something with result
finished();
});
});
});
function finished(){
process.exit();
}
同样,就像上面一样,您可以调用许多不同的 Flickr 方法。API 参考可以在 https://www.flickr.com/services/api/ 找到。
以下应用程序的修订版本和后续源代码版本与控制台应用程序的行为不同。
修订版 2
此修订版包含的内容
- 将我们的代码重构到不同的文件中,就像一个专业的项目应该做的那样。
- 将 Flickr 图片存储在数组中并进行处理。
重构
flickrUtils.js
我们将在那里编写我们的 Flickr 实用方法。
process.js
创建一个 process.js 并将所有 Flickr API 调用创建为包装方法。
为了方便从不同方法操作 Flickr 对象,我们将把 Flickr 对象放在我们的 process 对象的一个变量中,如下所示:
由于所有 Flickr 方法都是异步的,并且为了避免在 Flickr 调用中的响应事件中编写代码,我们将创建一个模型/对象结构来存储从 Flickr 方法接收到的值到模型中。您也可以简单地使用 JavaScript 数组对象...但我们将这样做,作为 Flickr 中的一个模型。
Promises
为了简化异步调用及其成功和失败,我们将使用 Promises,来自 Q 库。
我们在一个地方的循环中使用 Q Promise 库,这在 这里 有解释。
修订版 3
此修订版包含的内容
我们将继续使用 Sails,但为 flickrAccess
提供一个 Web API。
flickrAccess
的第三个修订版是创建一个带有后端模型的 Web API。- Web API 将从浏览器实例调用,并设置为 cron 作业,就像 PHP cron 作业一样。
- 我们将创建一个 Sails API,将数据记录到 mongo DB。
Sails 中的自定义模型
Sails 默认会附带 /api/models 文件夹...用于以结构化的方式加载模型。
我们将在该目录中创建一个自定义模型。
在 /api/models 中创建 fPhoto.js,并具有以下结构:
在此之后,当您启动 Sails 时,您会看到此消息...您可以选择 1 以安全起见,因为我们目前不将此模型与数据库连接使用。迁移选项仅在与数据库连接时才有意义...关于迁移设置的更多信息 在此。哦!是的,这意味着 Sails 模型(至少在 2015 年 5 月 16 日撰写本文时)并非设计为不使用数据库。迁移选项也显然没有离线选项。因此,使用自定义模型进行实体存储可能被认为是强行使用 Sails,而您也可以简单地使用普通的数组对象。
打扰一下,但看起来此应用程序尚未配置项目范围的“migrate”设置。
(也许这是您第一次加载它并带有模型?)
为了避免上述消息(因为它会阻止应用程序执行直到用户输入),请在 /config/models.js 中永久设置“migrate”选项。
后续步骤
我们可以通过添加代码将值存储到数据库来改进这一点。
作为 Cron 作业
要将其设置为 Cron 作业,您需要在 Cron 上设置以下命令,并指定文件名路径:
node /myproject folder path/flickr-get-interesting.js