Skip to content

Commit

Permalink
feat: filename 倒序,方便在 folder 中查看
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaddeusJiang committed Jul 22, 2024
1 parent c5b08c2 commit a862a13
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 38 deletions.
Binary file added docs/bug_log_发送20分钟长视频.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/dev-log.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## FIXME: bug: 无法发送 20 分钟的长视频

![bug log: 无法发送 20 分钟的长视频](./bug_log_发送20分钟长视频.png)

> Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
> Check the documentation of this method in https://core.telegram.org/bots/api#sendvideo
## 2024-07-22 x.com 无法下载图片 tweet

like: https://x.com/magnum_d1ngus/status/1815029025984643510?s=46

## ex_gram message struct

![ex_gram message struct](ex_gram_input.png)

# ins response

```elixir
Expand Down
Binary file added docs/ex_gram_input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/todos.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Todos

- [ ] list all ins response
- [ ] image
- [ ] images
- [ ] video
- [ ] videos
- [ ] images and videos
- [ ] with url I should download?

big task

- [x] download ins videos and images
- [ ] download multiple files in one task
- [ ] make it fast and with UI progress bar
Expand Down
31 changes: 28 additions & 3 deletions lib/aier_bot/bot.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,36 @@ defmodule AierBot.Bot do
answer(context, "Here is your help:")
end

# def handle({:text, text, message}, context) do
def handle({:text, text, %{chat: chat}}, _context) do
url = CobaltClient.get_download_url(text)
{file_name, file_content} = FileDownloader.download(url)
urls = extract_urls_from_string(text)

{:ok, _} = bot_send_file(chat.id, file_name, file_content)
if Enum.empty?(urls) do
# TODO: 思考:使用 DSL answer 还是 function send_message?
# answer(context, "No URL found.")
ExGram.send_message(chat.id, "No URL found.")
else
# MEMO: for payment, free only one url, for multiple urls, need to pay
url = List.first(urls)

case CobaltClient.get_download_url(url) do
{:ok, download_url} ->
{:ok, file_name, file_content} = FileDownloader.download(download_url)

{:ok, _} = bot_send_file(chat.id, file_name, file_content)

{:error, error} ->
ExGram.send_message(chat.id, "Failed to download file. Reason: #{inspect(error)}")
end
end
end

defp extract_urls_from_string(str) do
regex = ~r/http[s]?:\/\/[^\s]+/
matches = Regex.scan(regex, str)

# 扁平化匹配结果,因为Regex.scan返回的是一个列表的列表
Enum.map(matches, fn [url] -> url end)
end

defp bot_send_file(chat_id, file_name, file_content) do
Expand Down
45 changes: 26 additions & 19 deletions lib/aier_bot/cobalt_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ defmodule AierBot.CobaltClient do
get_download_url("https://www.instagram.com/p/C9pr7NDPAyd/?igsh=azBiNHJ0ZXd3bTFh") #=>
"""
def get_download_url("https://www.instagram.com/" <> _ = text) do
# def get_download_url("https://www.instagram.com/" <> _ = text) do
def get_download_url(text) do
# https://www.instagram.com/p/C9pr7NDPAyd/?igsh=azBiNHJ0ZXd3bTFh => https://www.instagram.com/p/C9pr7NDPAyd/
url = String.split(text, "?") |> hd()
# IO.inspect(pure_url)
Expand All @@ -25,40 +26,46 @@ defmodule AierBot.CobaltClient do
#
case response.body do
%{"url" => url} ->
url
{:ok, url}

%{"status" => "picker", "picker" => picker_items} ->
# [%{"url" => url}] = picker_items
# error: you attempted to apply a function named :first on [], If you are using Kernel.apply/3, make sure the module is an atom. If you are using the dot syntax, such as module.function(), make sure the left-hand side of the dot is an atom representing a module
# picker_items.first()["url"]
Enum.at(picker_items, 0)["url"]
# TODO: handle multiple urls
{:ok, Enum.at(picker_items, 0)["url"]}

# url
%{"status" => "error", "text" => error_msg} ->
IO.puts("Error: #{error_msg}")

{:error, error_msg}

_ ->
IO.inspect(response.body)
nil
{:error, "Unknown error"}
end

{:error, error} ->
error
{:error, error}
end
end

# TODO: get_download_urls for multiple urls
def get_download_url(url) do
case post("api/json", %{url: url}) do
{:ok, response} ->
# %{
# "status" => "redirect",
# "url" => "https://video.twimg.com/amplify_video/1814202798097268736/vid/avc1/720x1192/HAD9zyJn1xoP4oRN.mp4?tag=16"
# }
%{"url" => url} = response.body
url
# def get_download_url(url) do
# case post("api/json", %{url: url}) do
# {:ok, response} ->
# # %{
# # "status" => "redirect",
# # "url" => "https://video.twimg.com/amplify_video/1814202798097268736/vid/avc1/720x1192/HAD9zyJn1xoP4oRN.mp4?tag=16"
# # }
# %{"url" => url} = response.body
# url

# TODO send photo to telegram
# # TODO send photo to telegram

{:error, error} ->
error
end
end
# {:error, error} ->
# error
# end
# end
end
40 changes: 24 additions & 16 deletions lib/aier_bot/file_downloader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,40 @@ defmodule AierBot.FileDownloader do
use Tesla

def download(url) do
# https://video.twimg.com/amplify_video/1814202798097268736/vid/avc1/720x1192/HAD9zyJn1xoP4oRN.mp4?tag=16

IO.puts(url)
IO.inspect(url, label: "Download URL")

# TODO: support youtube video download,
case get(url) do
{:ok, %Tesla.Env{status: 200, body: body, headers: headers}} ->
# TODO: 可以使用异步,并且实时更新 bot 状态
IO.puts("Downloading file...")

# [..., {"content-type", "video/mp4"}, ...] = headers
utc_now_str =
DateTime.utc_now() |> DateTime.shift_zone!("Etc/UTC") |> DateTime.to_iso8601()

content_type = headers |> Enum.find(fn {k, _} -> k == "content-type" end) |> elem(1)
# IO.puts("Content-Type: #{content_type}")
file_path = (utc_now_str <> "_" <> content_type) |> String.replace("/", ".")
ext =
headers
|> Enum.find(fn {k, _} -> k == "content-type" end)
|> elem(1)
|> String.split("/")
|> List.last()

File.write("./.local/storage/#{file_path}", body)
IO.puts("File downloaded successfully.")
{file_path, body}
file_name = gen_desc_filename() <> "." <> ext
File.write("./.local/storage/#{file_name}", body)
{:ok, file_name, body}

{:ok, %Tesla.Env{status: status}} ->
IO.puts("Failed to download file. Status: #{status}")
{:error, "Failed to download file"}

{:error, reason} ->
IO.puts("Failed to download file. Reason: #{inspect(reason)}")
{:error, "Failed to download file"}
end
end

@spec gen_desc_filename() :: String.t()
defp gen_desc_filename() do
# 10^16 - current_time = 9999999999999999 - current_time = 9999999999999999 - 1630848000000 = 9999999998361159
max = :math.pow(10, 16) |> round()
utc_now = DateTime.utc_now() |> DateTime.to_unix()

(max - utc_now)
|> Integer.to_string()
|> String.pad_leading(16, "0")
end
end

0 comments on commit a862a13

Please sign in to comment.