Lưu media
Kho chữ giữ tri thức và link, Cloudinary giữ file nặng. Mỗi lần lưu cho ra một link mở được và một dòng trong kho-media.md.
Thứ tự ưu tiên: lời người dùng trong phiên, rồi file luật của kho, rồi skill này.
Cài đặt lần đầu (chỉ chạy khi kho chưa có kho-media.md)
-
Hỏi người dùng đã có tài khoản Cloudinary chưa. Chưa có thì chỉ: vào cloudinary.com, đăng ký gói miễn phí, mở mục API Keys để thấy Cloud name, API Key, API Secret.
-
Mã nằm ở file
.envtại gốc kho. Kho chưa có.envthì tạo với 3 dòng dưới đây; đã có thì thêm dòng còn thiếu, không đụng dòng khác. Máy đã có file khác chứa 3 mã này và người dùng muốn dùng file đó thì ghi đường dẫn file đó thay cho.env.CLOUDINARY_CLOUD_NAME= CLOUDINARY_API_KEY= CLOUDINARY_API_SECRET= -
Kho có Git thì chạy
git check-ignore -q .env. Không bị chặn thì thêm.envvào.gitignoretrước khi làm tiếp. Nếu.envđã từng được lưu vào Git thì dừng và báo người dùng. -
Mở
.envcho người dùng: Windowsnotepad .env, Macopen -e .env. Nhờ họ tự dán mã vào sau dấu=, không thêm dấu cách hay ngoặc kép, rồi lưu, không dán vào khung chat. API Secret giống chìa khoá két. Ai có nó đều xoá hoặc đổi được mọi ảnh. -
Người dùng báo xong thì kiểm 3 dòng đã có giá trị, nhưng chỉ kiểm có hay trống, không in giá trị ra.
-
Tạo
kho-media.mdtheo mẫu cuối file này, ghi tên file mã, không ghi giá trị mã. Thêm một dòng vàoindex.md. -
Nhờ người dùng đưa một ảnh thử, chạy quy trình bên dưới, gửi link. Mở được là xong.
Quy trình lưu
1. Có cần lên mây không
Hỏi ảnh dùng ở đâu, nếu chưa rõ.
- Cần link công khai (bài đăng, email, bot, tài liệu, trang dựng ở nền tảng khác): đi tiếp.
- Web có thư mục ảnh riêng và đang tải ảnh từ đó: không đẩy lên mây, vì sẽ có hai bản lệch nhau. Đề xuất chép vào thư mục ảnh của web và đặt tên sạch; người dùng đồng ý mới chép. Dừng ở đây.
- Bản nháp, bản thử, ảnh chụp màn hình tạm: để ở máy, nói lý do. Nghi ngờ thì hỏi: "Bạn sẽ dùng cái này vào việc gì?"
2. Có bị trùng không
Tìm tên và mục đích trong kho-media.md. Đã có thì đưa lại link cũ, hỏi người dùng có muốn đẩy bản mới không. Người dùng chỉ hỏi tìm link thì trả lời từ đây rồi dừng.
3. Có lộ thông tin riêng không
Link công khai thì ai có link đều xem được, và khó thu hồi hết khi đã phát tán. Nhìn nội dung ảnh. Có khuôn mặt hoặc tên khách, trẻ em, số điện thoại, số tài khoản, giấy tờ, tin nhắn riêng thì nói rõ thấy gì và hỏi người dùng có chắc muốn đưa lên không.
4. Xếp ngăn, đặt tên
| Ngăn | Chứa gì | Ghi link vào |
|---|---|---|
kho-media/thuong-hieu | Logo, chân dung, ảnh bìa, nhận diện | Trang thương hiệu hoặc hồ sơ |
kho-media/san-pham/<ten-san-pham> | Ảnh sản phẩm, mockup, video giới thiệu | Trang sản phẩm đó |
kho-media/noi-dung/<yyyy-MM> | Ảnh bài đăng, banner, thumbnail, video ngắn | Trang kế hoạch nội dung |
kho-media/bang-chung | Feedback, trước-sau, chứng nhận, báo chí | Trang sản phẩm liên quan |
kho-media/su-kien/<ten-su-kien> | Ảnh, video sự kiện, lớp học | Trang sự kiện đó |
Tên file và tên ngăn: không dấu, chữ thường, nối bằng -, đọc là hiểu, ví dụ feedback-khach-lan-a. Chưa chắc ngăn nào thì hỏi một câu kèm 2 lựa chọn đánh số. Nhiều file thì trình bảng tên và ngăn một lần, duyệt rồi đẩy lần lượt; file lỗi thì ghi lại và làm tiếp file khác.
5. Đẩy lên
Lấy tên file mã từ kho-media.md, dùng đường dẫn đầy đủ. File mã nằm trong kho có Git thì chạy git check-ignore -q <file mã> trước: không bị chặn thì dừng và báo người dùng. Chép đúng lệnh theo hệ điều hành, chỉ thay 4 giá trị ở đầu. Không in mã ra màn hình, không chép mã vào câu trả lời, trang hay file khác. Lệnh tự chép file sang tên tạm không dấu vì đường dẫn có dấu hoặc khoảng trắng dễ làm lệnh đẩy lỗi.
Windows (PowerShell):
$tep='<duong-dan-file>'; $ngan='<ngan>'; $ten='<ten-khong-duoi>'; $fileMa='<duong-dan-file-ma>'
$m=@{}; Get-Content -LiteralPath $fileMa | ForEach-Object { if($_ -match '^\s*(?:CLOUDINARY_)?(CLOUD_NAME|API_KEY|API_SECRET)\s*=\s*(.+?)\s*$'){ $m[$Matches[1]]=$Matches[2] } }
$ts=[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
$bam=[Security.Cryptography.SHA1]::Create().ComputeHash([Text.Encoding]::UTF8.GetBytes("folder=$ngan&overwrite=false&public_id=$ten×tamp=$ts$($m.API_SECRET)"))
$ky=-join($bam | ForEach-Object { $_.ToString('x2') })
$tenTam="luu-media-$ts"+[IO.Path]::GetExtension($tep); Copy-Item -LiteralPath $tep -Destination (Join-Path $env:TEMP $tenTam)
Push-Location $env:TEMP
try { curl.exe -sS -X POST "https://api.cloudinary.com/v1_1/$($m.CLOUD_NAME)/auto/upload" -F "file=@$tenTam" -F "api_key=$($m.API_KEY)" -F "timestamp=$ts" -F "folder=$ngan" -F "overwrite=false" -F "public_id=$ten" -F "signature=$ky" }
finally { Remove-Item -LiteralPath $tenTam -ErrorAction SilentlyContinue; Pop-Location }
Mac, Linux (bash):
TEP='<duong-dan-file>'; NGAN='<ngan>'; TEN='<ten-khong-duoi>'; FILE_MA='<duong-dan-file-ma>'
lay() { sed -n -E "s/^[[:space:]]*(CLOUDINARY_)?$1[[:space:]]*=[[:space:]]*//p" "$FILE_MA" | tr -d '\r' | sed -E 's/[[:space:]]+$//' | head -n 1; }
TS=$(date +%s)
KY=$(printf '%s' "folder=$NGAN&overwrite=false&public_id=$TEN×tamp=$TS$(lay API_SECRET)" | { if command -v shasum >/dev/null; then shasum -a 1; else sha1sum; fi; } | cut -d' ' -f1)
curl -sS -X POST "https://api.cloudinary.com/v1_1/$(lay CLOUD_NAME)/auto/upload" -F "file=@$TEP" -F "api_key=$(lay API_KEY)" -F "timestamp=$TS" -F "folder=$NGAN" -F "overwrite=false" -F "public_id=$TEN" -F "signature=$KY"
Kết quả trả về dạng JSON: lấy secure_url. Có error thì báo đúng nội dung lỗi và dừng, không tự viết lại công thức. File quá lớn so với gói đang dùng thì báo người dùng nén bớt. Lệnh dùng overwrite=false để không đè file cùng tên: đuôi file hoặc nội dung trả về khác file vừa đưa thì đổi tên rồi đẩy lại.
6. Kiểm và ghi vào bộ não
- Mở thử link, kiểm trả về thành công.
- Thêm dòng vào
kho-media.md, ngày giờ lấy từ máy. - Thêm link vào mục
Mediacủa trang liên quan theo cột cuối của bảng ngăn. Chưa có trang đó thì chỉ ghikho-media.mdvà báo.
7. Báo
Đưa link, ngăn, 2 trang đã ghi. Với ảnh dùng cho web hoặc bài viết, đưa thêm bản tải nhanh bằng cách chèn đoạn sau vào ngay sau /upload/: f_auto,q_auto,w_1200/. Cloudinary sẽ tự chọn định dạng, chất lượng và thu chiều rộng về 1200 px.
Không làm
- Không xoá hay đổi file trên Cloudinary. Người dùng tự làm trong Media Library, hoặc yêu cầu riêng và xác nhận.
- Không đưa file ảnh, video vào kho Git.
- Mã chỉ nằm ở file mã đã khai. Không ghi vào trang, nhật ký, skill hay khung chat. Trước khi chia sẻ thư mục kho cho người khác, nhắc người dùng bỏ
.envra.
Mẫu kho-media.md
# Kho media - mục lục
Kho mây: Cloudinary. File mã: `.env` ở gốc kho, không lên GitHub.
| Ngày giờ | Tên file | Ngăn | Link | Dùng cho |
|---|---|---|---|