Skip to content

Commit 44359d6

Browse files
committed
site: rebuild manual de la web [2026-04-24 16:53]
1 parent 32a139f commit 44359d6

41 files changed

Lines changed: 5094 additions & 23 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/web_sensor/.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

apps/web_sensor/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Temporary files, for example, from tests.
14+
/tmp/
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
web_sensor-*.tar
24+

apps/web_sensor/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# WebSensor
2+
3+
**TODO: Add description**
4+
5+
## Installation
6+
7+
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
8+
by adding `web_sensor` to your list of dependencies in `mix.exs`:
9+
10+
```elixir
11+
def deps do
12+
[
13+
{:web_sensor, "~> 0.1.0"}
14+
]
15+
end
16+
```
17+
18+
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
19+
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
20+
be found at <https://hexdocs.pm/web_sensor>.
21+

apps/web_sensor/lib/sensor_web.ex

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
defmodule SensorWeb do
2+
@moduledoc """
3+
Componente de percepción digital. Transforma datos del entorno
4+
web (APIs, HTML) en perceptos estructurados para un agente.
5+
"""
6+
7+
@doc """
8+
Obtiene el precio actual de Bitcoin desde la API pública de CoinGecko.
9+
Retorna un mapa con el percepto estructurado.
10+
"""
11+
def precio_bitcoin do
12+
url = "https://api.coingecko.com/api/v3/simple/price" <>
13+
"?ids=bitcoin&vs_currencies=usd&include_24hr_change=true"
14+
15+
case Req.get(url) do
16+
{:ok, %{status: 200, body: body}} ->
17+
btc = body["bitcoin"]
18+
{:ok, %{
19+
asset: "bitcoin",
20+
precio_usd: btc["usd"],
21+
cambio_24h: Float.round((btc["usd_24h_change"] || 0.0) * 1.0, 2),
22+
timestamp: DateTime.utc_now()
23+
}}
24+
25+
{:ok, %{status: status}} ->
26+
{:error, "HTTP #{status}"}
27+
28+
{:error, exception} ->
29+
{:error, Exception.message(exception)}
30+
end
31+
end
32+
33+
@doc """
34+
Sensor genérico: extrae texto de una página web usando un selector CSS.
35+
"""
36+
def scrape_texto(url, selector) do
37+
case Req.get(url) do
38+
{:ok, %{status: 200, body: html}} when is_binary(html) ->
39+
texto =
40+
html
41+
|> Floki.parse_document!()
42+
|> Floki.find(selector)
43+
|> Floki.text()
44+
|> String.trim()
45+
46+
{:ok, texto}
47+
48+
{:ok, %{status: _status, body: body}} when is_map(body) ->
49+
{:ok, inspect(body)}
50+
51+
{:ok, %{status: status}} ->
52+
{:error, "HTTP #{status}"}
53+
54+
{:error, exception} ->
55+
{:error, Exception.message(exception)}
56+
end
57+
end
58+
end

apps/web_sensor/lib/web_sensor.ex

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule WebSensor do
2+
@moduledoc """
3+
Documentation for `WebSensor`.
4+
"""
5+
6+
@doc """
7+
Hello world.
8+
9+
## Examples
10+
11+
iex> WebSensor.hello()
12+
:world
13+
14+
"""
15+
def hello do
16+
:world
17+
end
18+
end

apps/web_sensor/mix.exs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule WebSensor.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :web_sensor,
7+
version: "0.1.0",
8+
elixir: "~> 1.18",
9+
start_permanent: Mix.env() == :prod,
10+
deps: deps()
11+
]
12+
end
13+
14+
def application do
15+
[extra_applications: [:logger]]
16+
end
17+
18+
defp deps do
19+
[
20+
{:req, "~> 0.5.0"},
21+
{:floki, "~> 0.37.0"}
22+
]
23+
end
24+
end

apps/web_sensor/mix.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
%{
2+
"finch": {:hex, :finch, "0.21.0", "b1c3b2d48af02d0c66d2a9ebfb5622be5c5ecd62937cf79a88a7f98d48a8290c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87dc6e169794cb2570f75841a19da99cfde834249568f2a5b121b809588a4377"},
3+
"floki": {:hex, :floki, "0.37.1", "d7aaee758c8a5b4a7495799a4260754fec5530d95b9c383c03b27359dea117cf", [:mix], [], "hexpm", "673d040cb594d31318d514590246b6dd587ed341d3b67e17c1c0eb8ce7ca6f04"},
4+
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
5+
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
6+
"mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"},
7+
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
8+
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
9+
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
10+
"req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"},
11+
"telemetry": {:hex, :telemetry, "1.4.1", "ab6de178e2b29b58e8256b92b382ea3f590a47152ca3651ea857a6cae05ac423", [:rebar3], [], "hexpm", "2172e05a27531d3d31dd9782841065c50dd5c3c7699d95266b2edd54c2dafa1c"},
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ExUnit.start()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
defmodule WebSensorTest do
2+
use ExUnit.Case
3+
doctest WebSensor
4+
5+
test "greets the world" do
6+
assert WebSensor.hello() == :world
7+
end
8+
end

apps/web_sensor/test_sensor.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
IO.puts "--- Probando Sensor Web (Bitcoin) ---"
2+
case SensorWeb.precio_bitcoin() do
3+
{:ok, percepto} ->
4+
IO.puts "✅ ÉXITO"
5+
IO.inspect(percepto)
6+
{:error, razon} ->
7+
IO.puts "❌ ERROR"
8+
IO.puts "Razón: #{inspect(razon)}"
9+
end

0 commit comments

Comments
 (0)