Elixir开发:从OS命令到Twitter数据获取
1. 使用Porcelain执行OS命令
1.1 配置Porcelain自动运行
在创建应用程序并将Porcelain作为依赖项添加后,我们需要对其进行配置以实现自动运行。具体步骤如下:
1. 在步骤3中,将Porcelain添加到 OsCommands 应用程序启动时会自动引导的应用程序列表中。
2. 在步骤5和6中,定义两个函数:
- list 函数:执行 ls 命令。若未传入路径选项,则默认使用应用程序目录。
- run 函数:功能更为通用,可执行操作系统中可用的任何命令。
1.2 Porcelain的更多特性
Porcelain允许将输入定义为文件或流,输出同样支持这样的定义方式。它是一个强大的工具,可用于构建文件系统监视器等,能在文件发生更改时执行相应操作。其最令人印象深刻的是,它能让我们借助底层操作系统的强大功能,扩展Elixir中的可用选项。
1.3 相关拓展
可以将Goon驱动与Porcelain结合使用。Goon用Go语言开发,能为Porcelain提供更多功能,特别是向外部程序发送EOF信号以及向程序发送操作系统信号的能力。更多关于Porcelain的信息,可参考文档: http://porcelain.readthedocs.org/ 。
2. 获取Twitter数据
2.1 准备工作
在开始构建应用程序之前,需要在Twitter上注册一个新应用,以获取用于身份验证和使用Twitter API的API密钥。具体操作如下:
1. 访问 https://apps.twitter.com ,点击“Create New App”按钮。
2. 按照步骤操作后,将获得四个必要的项: consumer_key 、 consumer_secret 、 access_token 和 access_token_secret 。
3. 这些值可以直接在应用程序中使用,也可以在bash或zsh(如果使用Unix系统)的初始化文件中设置为环境变量。
2.2 构建应用程序的步骤
2.2.1 创建新的Phoenix应用程序
> mix phoenix.new phoenix_twitter_stream code/phoenix_twitter_stream
注意:如需了解更多创建Phoenix应用程序的信息,请参考相关文档。
2.2.2 添加依赖项
在 mix.exs 文件中添加以下依赖项:
defp deps do
[
{:phoenix, "~> 0.8.0"},
{:cowboy, "~> 1.0"},
{:oauth, github: "tim/erlang-oauth"},
{:extwitter, "~> 0.1"}
]
end
2.2.3 获取并编译依赖项
> mix deps.get && mix deps.compile
2.2.4 配置应用程序使用Twitter API密钥
编辑 lib/phoenix_twitter_stream.ex 文件,添加以下配置块:
defmodule PhoenixTweeterStream do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
ExTwitter.configure(
consumer_key: System.get_env("SMM_TWITTER_CONSUMER_KEY"),
consumer_secret: System.get_env("SMM_TWITTER_CONSUMER_SECRET"),
access_token: System.get_env("SMM_TWITTER_ACCESS_TOKEN"),
access_token_secret: System.get_env("SMM_TWITTER_ACCESS_TOKEN_SECRET")
)
children = [
# Start the endpoint when the application starts
worker(PhoenixTweeterStream.Endpoint, []),
# Here you could define other workers and supervisors as children
# worker(PhoenixTweeterStream.Worker, [arg1, arg2, arg3]),
]
opts = [strategy: :one_for_one, name: PhoenixTweeterStream.Supervisor]
Supervisor.start_link(children, opts)
end
def config_change(changed, _new, removed) do
PhoenixTweeterStream.Endpoint.config_change(changed, removed)
:ok
end
end
注意:若不想将密钥设置为环境变量,可直接将密钥声明为字符串,例如: consumer_key: "this-is-an-example-key" 。
2.2.5 定义处理新推文查询的模块
在 lib/phoenix_twitter_stream/tweet_streamer.ex 文件中添加以下代码:
defmodule PhoenixTwitterStream.TweetStreamer do
def start(socket, query) do
stream = ExTwitter.stream_filter(track: query)
for tweet <- stream do
Phoenix.Channel.reply(socket, "tweet:stream", tweet)
end
end
end
2.2.6 创建处理推文的通道
在 web/channels/tweets.ex 文件中添加以下代码:
defmodule PhoenixTwitterStream.Channels.Tweets do
use Phoenix.Channel
alias PhoenixTwitterStream.TweetStreamer
def join("tweets", %{"track" => query}, socket) do
spawn(fn() -> TweetStreamer.start(socket, query) end)
{:ok, socket}
end
end
2.2.7 编辑应用程序路由器
编辑 /web/router.ex 文件,注册WebSocket处理程序和推文通道:
defmodule PhoenixTwitterStream.Router do
use Phoenix.Router
pipeline :browser do
plug :accepts, ~w(html)
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
end
pipeline :api do
plug :accepts, ~w(json)
end
socket "/ws" do
channel "tweets", PhoenixTwitterStream.Channels.Tweets
end
scope "/", PhoenixTwitterStream do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
end
2.2.8 替换索引模板内容
将 web/templates/page/index.html.eex 文件的内容替换为以下代码:
<div class="row">
<div class="col-lg-12">
<ul id="tweets"></ul>
</div>
<script src="/js/phoenix.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-2.1.1.js" type="text/javascript"></script>
<script type="text/javascript">
var my_track = "programming";
var socket = new Phoenix.Socket("ws://" + location.host + "/ws");
socket.join("tweets", {track: my_track}, function(chan){
chan.on("tweet:stream", function(message){
console.log(message);
$('#tweets').prepend($('<li>').text(message.text));
});
});
</script>
</div>
2.2.9 启动应用程序
> mix phoenix.server
2.2.10 访问应用程序
打开浏览器,访问 http://localhost:4000/ ,几秒后,推文将开始显示,新推文会显示在页面顶部。
2.3 应用程序的工作原理
- 创建Phoenix应用程序 :选择Phoenix是因为它适合实时显示带有推文更新的网页,通过WebSocket实现实时更新。
- 添加依赖项 :在步骤2中,添加了与Twitter API交互所需的依赖项,包括parroty的
extwitterElixir应用程序( https://hex.pm/packages/extwitter )和Tim的erlang-oauth应用程序( https://github.com/tim/erlang-oauth/ )。获取并编译依赖项后,在步骤4中添加Twitter API密钥,用于身份验证。 - 定义查询函数 :在步骤5中,定义的函数启动后会向Twitter查询包含特定查询词的推文。
stream = ExTwitter.stream_filter(track: query)定义了一个流,该流是ExTwitter应用程序过滤Twitter时间线后的结果,仅提取包含定义查询词的条目。for tweet <- stream do Phoenix.Channel.reply(socket, "tweet:stream", tweet)是一个流推导式,会将流中的每个新条目通过Phoenix通道发送出去。 - 定义通道 :在步骤6中定义的通道类似于WebSocket处理程序。
join函数在WebSocket连接建立时,通过spawn调用初始化步骤5中定义的模块,该函数接收前端代码中定义的查询字符串,并将其传递给ExTwitter作为过滤条件。 - 注册WebSocket处理程序 :在步骤7中,使用
use Phoenix.Router.Socket在路由器中注册并挂载WebSocket处理程序,使用channel "tweets", PhoenixTwitterStream.Channels.Tweets定义通道及其处理模块。注意,通道定义必须在任何作用域定义之外。 - 前端代码 :在步骤8中,将HTML和JavaScript混合在一个文件中,用于显示根页面并与服务器建立WebSocket连接。使用
phoenix.js库辅助处理Phoenix WebSocket和通道。前端代码的具体解释如下:-
var my_track = "programming":初始化查询词,这里过滤包含“programming”的所有推文。 -
var socket = new Phoenix.Socket("ws://" + location.host + "/ws"):初始化WebSocket连接,端点为/ws。 -
socket.join("tweets", {track: my_track}, function(chan){...}):加入tweets通道,当有新推文通过WebSocket连接到达时,将其添加到页面现有推文的顶部。
-
2.4 更多建议
若希望页面更新速度更快,可选择更热门的查询词。
3. 安装相关软件及参考资料
3.1 安装Elixir
访问 http://elixir-lang.org/install.html 获取安装Elixir和Erlang在主要操作系统上的所有文档。
3.2 安装PostgreSQL
- 安装过程信息: https://wiki.postgresql.org/wiki/Detailed_installation_guides
- 下载地址: http://www.postgresql.org/download/
3.3 安装Redis
- Redis主页: http://redis.io
- 下载页面和安装说明: http://redis.io/download
- 官方文档: http://redis.io/documentation
3.4 有用的链接
3.5 整体流程
graph LR
A[准备工作:获取Twitter API密钥] --> B[创建Phoenix应用程序]
B --> C[添加依赖项]
C --> D[获取并编译依赖项]
D --> E[配置应用程序使用API密钥]
E --> F[定义查询模块]
F --> G[创建通道模块]
G --> H[编辑路由器]
H --> I[替换索引模板内容]
I --> J[启动应用程序]
J --> K[访问应用程序]
以上就是从使用Porcelain执行OS命令到获取Twitter数据的详细过程,涵盖了应用程序的创建、配置、运行以及相关软件的安装和参考资料,希望能帮助你在Elixir开发中顺利实现这些功能。
4. Elixir开发中的其他关键技术点
4.1 数据结构与操作
4.1.1 列表操作
列表是Elixir中常用的数据结构,支持添加和减法操作:
- 添加列表 :使用 ++ 运算符,例如:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = list1 ++ list2
# result 为 [1, 2, 3, 4, 5, 6]
- 减去列表 :使用
--运算符,例如:
list1 = [1, 2, 3, 4]
list2 = [2, 4]
result = list1 -- list2
# result 为 [1, 3]
- 组合元组成列表 :可以将多个元组组合成一个列表,例如:
tuple1 = {1, "a"}
tuple2 = {2, "b"}
list = [tuple1, tuple2]
# list 为 [{1, "a"}, {2, "b"}]
4.1.2 映射操作
映射是一种键值对的数据结构,可用于创建键值存储:
map = %{:key1 => "value1", :key2 => "value2"}
# 获取值
value = map[:key1]
# value 为 "value1"
也可以使用 Map.new/0 函数创建空映射:
empty_map = Map.new()
4.1.3 关键字列表操作
关键字列表是一种特殊的列表,其中的元素是二元元组,第一个元素为原子:
keyword_list = [name: "John", age: 30]
# 获取值
name = keyword_list[:name]
# name 为 "John"
关键字列表的创建和操作示例如下:
# 创建
new_list = [color: "red", size: "large"]
# 操作
updated_list = Keyword.put(new_list, :shape, "circle")
4.2 函数定义与模式匹配
4.2.1 函数定义中的默认参数
在Elixir中可以定义带有默认参数的函数:
defmodule Example do
def greet(name \\ "Guest") do
"Hello, #{name}!"
end
end
# 调用
Example.greet() # 返回 "Hello, Guest!"
Example.greet("Alice") # 返回 "Hello, Alice!"
4.2.2 函数定义中的守卫子句和模式匹配
守卫子句和模式匹配可用于更精确地定义函数行为:
defmodule Math do
def add(a, b) when is_integer(a) and is_integer(b) do
a + b
end
def add(_, _) do
:error
end
end
# 调用
Math.add(1, 2) # 返回 3
Math.add(1, "a") # 返回 :error
4.3 并发与分布式编程
4.3.1 使用任务模块进行并发计算
Task 模块可用于执行多个并发计算:
defmodule ConcurrentExample do
def run do
task1 = Task.async(fn -> 1 + 1 end)
task2 = Task.async(fn -> 2 + 2 end)
result1 = Task.await(task1)
result2 = Task.await(task2)
{result1, result2}
end
end
# 调用
ConcurrentExample.run() # 返回 {2, 4}
4.3.2 创建和连接命名节点
可以创建命名节点并进行连接:
# 创建命名节点
Node.start(:node1@localhost)
Node.start(:node2@localhost)
# 连接节点
Node.connect(:node2@localhost)
在不同节点上执行代码可以使用 Node.spawn 函数:
pid = Node.spawn(:node2@localhost, fn -> 1 + 1 end)
4.4 错误处理与异常管理
在Elixir中,错误处理和异常管理是重要的部分:
try do
raise "An error occurred"
rescue
e in RuntimeError ->
IO.puts("Caught error: #{e.message}")
end
还可以使用 throw 和 catch 来处理特定情况:
try do
throw(:error)
catch
:error ->
IO.puts("Caught throw")
end
5. Phoenix框架深入
5.1 创建Phoenix应用程序的更多细节
5.1.1 创建视图和模板
视图和模板是Phoenix应用程序中用于呈现数据的重要部分。创建视图的示例如下:
defmodule PhoenixTwitterStream.Web.PageView do
use PhoenixTwitterStream.Web, :view
end
创建模板,例如在 web/templates/page/index.html.eex 中:
<h1>Welcome to the Phoenix Twitter Stream</h1>
5.1.2 实现主题
在Phoenix应用程序中可以实现主题,例如在通道中处理不同的主题:
defmodule PhoenixTwitterStream.Channels.Tweets do
use Phoenix.Channel
def join("tweets:programming", payload, socket) do
# 处理编程主题的逻辑
{:ok, socket}
end
def join("tweets:sports", payload, socket) do
# 处理体育主题的逻辑
{:ok, socket}
end
end
5.2 保护Phoenix应用程序
可以使用SSL保护Phoenix应用程序,在配置文件中添加SSL相关配置:
config :phoenix_twitter_stream, PhoenixTwitterStream.Endpoint,
https: [
port: 443,
cipher_suite: :strong,
keyfile: "priv/ssl/selfsigned_key.pem",
certfile: "priv/ssl/selfsigned_cert.pem"
]
5.3 Phoenix应用程序的整体架构
graph LR
A[客户端] --> B[WebSocket连接]
B --> C[Phoenix路由器]
C --> D[通道处理]
D --> E[查询模块]
E --> F[Twitter API]
F --> E
E --> D
D --> C
C --> B
B --> A
6. 总结
通过以上内容,我们全面了解了Elixir开发的多个方面,从使用Porcelain执行OS命令,到获取Twitter数据,再到Elixir中的数据结构操作、并发编程、错误处理以及Phoenix框架的深入应用。掌握这些技术点可以帮助我们开发出高效、稳定且功能丰富的Elixir应用程序。在实际开发中,我们可以根据具体需求灵活运用这些知识,不断优化和完善我们的项目。同时,合理利用参考资料和相关工具,能够进一步提升开发效率和质量。希望这些内容能为你的Elixir开发之旅提供有力的支持。
超级会员免费看
7

被折叠的 条评论
为什么被折叠?



