From 52e023d5b1d9d59dd09925e84db7f843fadd1a73 Mon Sep 17 00:00:00 2001 From: yv1ing Date: Mon, 16 Dec 2024 12:24:28 +0800 Subject: [PATCH] new: Completed support for migrating images to Tencent Cloud COS --- .env | 7 ++++++ .gitignore | 4 +++- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++- main.py | 12 ++++++++++ markdown.py | 46 +++++++++++++++++++++++++++++++++++ picbed/__init__.py | 0 picbed/cos.py | 37 +++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 422 bytes uploader.py | 13 ++++++++++ utils.py | 5 ++++ 10 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 .env create mode 100644 main.py create mode 100644 markdown.py create mode 100644 picbed/__init__.py create mode 100644 picbed/cos.py create mode 100644 requirements.txt create mode 100644 uploader.py create mode 100644 utils.py diff --git a/.env b/.env new file mode 100644 index 0000000..c9f25f3 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +NEW_PIC_BED="COS" + +COS_SECRET_ID="" +COS_SECRET_KEY="" +COS_BUCKET="" +COS_REGION="" +COS_SAVE_PATH="" diff --git a/.gitignore b/.gitignore index 82f9275..71242bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ __pycache__/ *.py[cod] *$py.class +# Work dir and files +.idea + # C extensions *.so @@ -122,7 +125,6 @@ celerybeat.pid *.sage.py # Environments -.env .venv env/ venv/ diff --git a/README.md b/README.md index adfc942..d830805 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,58 @@ # ezMove -Script for batch migration of Markdown images to image hosting + +This is a script for batch migration of Markdown images to image hosting. + +## Quick Start + +### Step 0 + +Install required dependencies. + +```shell +pip install -r .\requirements.txt +``` + +### Step 1 + +Fill in the configuration information of the image hosting in the `.env` file. + +For example (use Tencent COS): + +```env +NEW_PIC_BED="COS" + +COS_SECRET_ID="" +COS_SECRET_KEY="" +COS_BUCKET="" +COS_REGION="" +COS_SAVE_PATH="" +``` + +### Step 2 + +Fill in the Markdown file directory of the image hosting service to be migrated in `main.py` + +For example: + +```python +# Fill in the directory of Markdown files waiting to be migrated here +markdown_files = find_files('./my_blogs') +``` + +### Step 3 + +Run `main.py` and have a cup of coffee while waiting for the program to finish running. + +```shell +python3 main.py +``` + + +## Todo + +- [x] Support Tencent Cloud COS +- [ ] Support Alibaba Cloud OSS +- [ ] Support Qiniu Cloud Image Hosting +- [ ] ... + + diff --git a/main.py b/main.py new file mode 100644 index 0000000..5d87b73 --- /dev/null +++ b/main.py @@ -0,0 +1,12 @@ +from dotenv import load_dotenv +from markdown import * + +load_dotenv() +new_pic_bed = os.getenv('NEW_PIC_BED') + +if __name__ == '__main__': + # Fill in the directory of Markdown files waiting to be migrated here + markdown_files = find_files('') + + for markdown_file in markdown_files: + replace_pic_bed(markdown_file, new_pic_bed) diff --git a/markdown.py b/markdown.py new file mode 100644 index 0000000..01fe01b --- /dev/null +++ b/markdown.py @@ -0,0 +1,46 @@ +from uploader import Uploader +import os +import re + +uploader = Uploader() + + +# find all markdown files in specified directory +def find_files(directory): + markdown_files = [] + for root, dirs, files in os.walk(directory): + for file in files: + if file.endswith(".md"): + markdown_files.append(os.path.join(root, file)) + + return markdown_files + + +# replace pic_bed for single markdown file +def replace_pic_bed(markdown_file, new_pic_bed): + img_pattern = re.compile(r'!\[.*\]\((.*)\)') + url_pattern = re.compile(r'\((.*)\)') + + old_file = open(markdown_file, 'r', encoding='utf-8') + old_lines = old_file.readlines() + old_file.close() + + new_file = open(markdown_file, 'w', encoding='utf-8') + for line in old_lines: + img_match = img_pattern.search(line) + if img_match: + url_match = url_pattern.search(line) + if url_match: + old_url = url_match.group(1) + new_url = uploader.upload_web_img(old_url, new_pic_bed) + + if new_url != '': + line = re.sub(img_pattern, lambda match: f'![]({new_url})', line) + print(f'-replaced {old_url} to {new_url}') + else: + print(f'-upload failed {old_url}') + + new_file.write(line) + + new_file.close() + print(f'!finished {markdown_file}\n') diff --git a/picbed/__init__.py b/picbed/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/picbed/cos.py b/picbed/cos.py new file mode 100644 index 0000000..c831fc0 --- /dev/null +++ b/picbed/cos.py @@ -0,0 +1,37 @@ +# Tencent COS + +from dotenv import load_dotenv +from qcloud_cos import CosConfig +from qcloud_cos import CosS3Client +from utils import get_current_timestamp +import requests +import os + + +load_dotenv() + +region = os.getenv('COS_REGION') +bucket = os.getenv('COS_BUCKET') +secret_id = os.getenv('COS_SECRET_ID') +secret_key = os.getenv('COS_SECRET_KEY') +save_path = os.getenv('COS_SAVE_PATH') + +config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=None, Scheme='https') +client = CosS3Client(config) + + +def cos_upload_img(img_old_url): + try: + stream = requests.get(img_old_url) + new_img_name = f'{get_current_timestamp()}.png' + resp = client.put_object( + Bucket=bucket, + Body=stream, + Key=new_img_name, + ) + if resp['ETag']: + return f'https://{bucket}.cos.{region}.myqcloud.com/{new_img_name}' + else: + return '' + except Exception as e: + print(e) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..74b197e301bb56584afb430054704cce63c2b207 GIT binary patch literal 422 zcmY+A+YW*-5JczM#7}{MXp9eji~>d?7p2vxAFrM*NHk5`w4Jjv-S;b3sa{@{4$LiM zp@g|qtd!l>rRJI`*HJsP4#F!^tBzB{T@CpRb&Stoj7~ zJX7==X2ux2di)yH#q_=oFBLZ}o?oYQ^s)Lmc^)|Vz;*EDq+9ThZ>Ik&1!|A7C5=@b zboOsc((`iBmDQngL1A6VLT`q&j{n~$Hr0A^y296?KYNIwyYUZsCu2S4t;p|#CV{uE Io6<6T0PH?KuK)l5 literal 0 HcmV?d00001 diff --git a/uploader.py b/uploader.py new file mode 100644 index 0000000..d48caac --- /dev/null +++ b/uploader.py @@ -0,0 +1,13 @@ +from picbed.cos import cos_upload_img + + +class Uploader: + def __init__(self): + pass + + def upload_web_img(self, img_url, pic_bed): + if pic_bed == 'COS': + return cos_upload_img(img_url) + else: + print('Unsupported image hosting type') + exit(1) diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..a566b30 --- /dev/null +++ b/utils.py @@ -0,0 +1,5 @@ +import time + + +def get_current_timestamp(): + return int(time.time() * 1000)