Rails 项目整合 mega.nz 云盘
导言
最近做一个 Rails (RoR) 项目,需要将文件上传保存到 MEGA 云盘。MEGA 云盘是一个类似于 Dropbox、Google Drive 的云存储服务,提供了大容量的免费存储空间和端到端加密保护用户隐私。MEGA 没有提供官方的 Ruby SDK,但它提供了一个命令行工具 MEGA CMD 来简化文件操作。通过这个工具,我们可以在 Rails 应用中使用 system
或 `cmd` 轻松集成 MEGA 的文件上传和下载功能。
使用方式
安装 MEGA CMD
提示:不要安装 Ubuntu 仓库中的版本,因为它太旧了。可以直接从 MEGA 官网下载最新版 MEGA CMD。
我的系统是 Ubuntu 24.04,所以下载对应的 deb 包:
wget https://mega.nz/linux/repo/xUbuntu_24.04/amd64/megacmd-xUbuntu_24.04_amd64.deb && sudo apt install "$PWD/megacmd-xUbuntu_24.04_amd64.deb"
安装成功后,可以通过 mega-cmd
命令来使用 MEGA CMD 工具。
登录 MEGA 账号
登录 MEGA 账号
MEGA CMD> login [email protected] your_password
登录成功后,可以使用 ls
命令列出 MEGA 云盘的文件列表。
[email protected]:/$ ls
欢迎使用 MEGA.pdf
MEGA CMD 提供了丰富的命令行操作,可以通过 help
命令查看所有可用命令。还可以查看用户手册:https://github.com/meganz/MEGAcmd/blob/master/UserGuide.md
RoR 中集成 MEGA CMD,实现文件上传和分享
class UploadToMegaJob < ApplicationJob
queue_as :default
def perform(batch_upload_id)
batch_upload = BatchUpload.find(batch_upload_id)
batch_upload.uploading!
Rails.logger.info("Starting upload for BatchUpload ID: #{batch_upload_id}")
batch_upload.files.each do |file|
temp_path = ActiveStorage::Blob.service.path_for(file.key)
remote_path = "#{ENV['MEGA_CLOUD_DIR']}#{batch_upload.id}/#{file.filename}"
if system("mega-put '-c' '#{temp_path}' '#{remote_path}'")
stock = Stock.create!(
service: batch_upload.service,
batch_upload: batch_upload,
order: nil,
filename: file.filename,
mega_path: remote_path,
mega_link: mega_link(remote_path),
state: :available
)
Rails.logger.info("Uploaded #{file.filename} to MEGA and created stock record with ID #{stock.id}")
else
Rails.logger.error("Failed to upload #{file.filename} to MEGA")
end
end
batch_upload.completed!
Rails.logger.info("Completed upload for BatchUpload ID: #{batch_upload_id}")
rescue StandardError => e
batch_upload.failed!
Rails.logger.error("Failed to upload BatchUpload ID: #{batch_upload_id} with error: #{e.message}")
end
private
def mega_link(path)
megacmd_output = `mega-export -a "#{path}"`
Rails.logger.info("MEGA command output: #{megacmd_output}")
# export -a /STOCK/1/t2.png的输出格式为:
# Exported /STOCK/1/t2.png: https://mega.nz/file/bxxynKxZ#BGIDsuMDlNZywyO_uF2INgxyjiGCAttozehrc1DmfBE
if $?.success?
# 解析 megacmd 输出以获取链接
mega_link = megacmd_output.match(/https:\/\/mega\.nz\/file\/[a-zA-Z0-9]+#[a-zA-Z0-9_-]+/)[0]
Rails.logger.info("Fetched MEGA link for #{path}: #{mega_link}")
mega_link
else
Rails.logger.error("Failed to fetch MEGA link for #{path}")
end
end
end
结语
通过 Ruby 的 system
方法,我们可以轻松地在 Rails 应用中集成 MEGA CMD,实现文件的上传和分享功能。MEGA CMD 提供了丰富的命令行操作,可以满足大部分文件管理需求。还可以通过自定义 ActiveStorage
的服务来封装 MEGA CMD 的操作,使其更符合 Rails 的惯例。