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 0000000..74b197e Binary files /dev/null and b/requirements.txt differ 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)