Python3, Pythonista3: Wikipedia PageIDに変換したりAmazonのASINに変換したり

# はじめに
本コードはiOS版アプリPythonista3を用いて、クリップボードにコピーされたWikipediaのURL（テキスト形式）をWikipedia PageIDのURLに変換したり、AmazonのASINに変換してクリップボードにコピーし直すというものです。

1. URLをクリップボードにコピー
1. Pythonista3を起動
1. 本コードを実行
1. Pythonista3のコンソールに変換後URLを吐き出す

という趣旨です。
# きっかけ
LINEやMessengerなどでWikipediaとAmazonのコピーを貼り付けることがよくあるので、手間を省くために作成しました。
# 前準備
Pythonista3は有料です。別途お買い求めください。
# ソースコード
下記に2種類のソースコードを掲載しておきます。
##python3
```python:En_Wikipedia_and_Amazon.py　(1)
import re
import sys
import urllib.parse
import requests
import pyperclip

class ClipboardURLFetcher:
    # クリップボードからURLを取得するクラス
    def fetch_url(self):
        url = pyperclip.paste()
        if len(url) == 0:
            sys.exit("URLをクリップボードに入れてください")
        return urllib.parse.unquote(url)

class AmazonURLProcessor:
    # Amazon URLを処理するクラス
    def process_url(self, url):
        if 'https://www.amazon' not in url:
            return url
        
        # Amazon URL 処理
        domain = 'com' if 'https://www.amazon.com/' in url else 'co.jp'
        asin = self.extract_asin(url, domain)
        if asin:
            short_url = f'https://www.amazon.{domain}/dp/{asin}'
            pyperclip.copy(short_url)
            print(f'クリップボードにコピー完了（Amazon）：{short_url}')
            sys.exit(0)
        return url
    
    def extract_asin(self, url, domain):
        if '/dp/' in url:
            pos = url.find('/dp/')
            return url[pos+4:pos+14]
        if '/gp/product/' in url:
            pos = url.find('/product/')
            return url[pos+9:pos+19]
        if '/gp/aw/d/' in url:
            pos = url.find('/aw/d/')
            return url[pos+6:pos+16]
        return None

class WikipediaURLProcessor:
    # Wikipedia URLを処理するクラス
    def process_url(self, url):
        if '?curid=' in url:
            sys.exit(f'既に変換済みです：{url}')
            
        # モバイル版URLも含めた条件に変更
        if 'https://' not in url or ('.wikipedia.org/wiki/' not in url and '.m.wikipedia.org/wiki/' not in url):
            sys.exit(f'Wikipediaのアドレスではありません：{url}')
            
        # モバイル版URLから通常のURLへの変換
        if '.m.wikipedia.org/wiki/' in url:
            url = url.replace('.m.wikipedia.org/wiki/', '.wikipedia.org/wiki/')
            
        lang = url[8:10]
        text = url.replace(f'https://{lang}.wikipedia.org/wiki/', '')
        page_id = self.get_wikipedia_page_id(lang, text)
        
        if not page_id:
            sys.exit(f'変換不可能なリンクです：{url}')
            
        new_url = f'https://{lang}.wikipedia.org/?curid={page_id}'
        pyperclip.copy(new_url)
        
        print(f'タイトル：{text}')
        print(f'Page(s)ID：{page_id}')
        print(f'元URL：{url}')
        encoded_url = urllib.parse.quote(url, safe='/:=@,.!?"\'')
        print(f'PC用エンコード済みURL：{encoded_url}')
        
        if '.m.wikipedia.org/' in url:
            pc_url = url.replace('.m', '')
            print(f'PC用エンコード済みURL：{pc_url}')
            
        mobile_url = url.replace('.wikipedia', '.m.wikipedia')
        print(f'Mobile用エンコード済みURL：{mobile_url}')
        mobile_id_url = new_url.replace('.wikipedia', '.m.wikipedia')
        print(f'Mobile用ID込みURL：{mobile_id_url}')
        
        return new_url
    
    def get_wikipedia_page_id(self, lang, title):
        url = f'https://{lang}.wikipedia.org/w/api.php'
        params = {
            'action': 'query',
            'titles': title,
            'format': 'json'
        }
        response = requests.get(url, params=params)
        data = response.json()
        page = next(iter(data['query']['pages'].values()))
        return page.get('pageid')

class TextURLEncoder:
    # テキストをURLエンコードしてクリップボードに出力するクラス
    def process_text(self, text):
        encoded_text = urllib.parse.quote(text, safe='/:=@,.!?"\'')
        pyperclip.copy(encoded_text)
        print(f'URLエンコードされたテキストをクリップボードにコピーしました：{encoded_text}')

def main():
    fetcher = ClipboardURLFetcher()
    url = fetcher.fetch_url()
    # Amazon URLの処理    
    if 'amazon' in url:
        amazon_processor = AmazonURLProcessor()
        amazon_processor.process_url(url)
    # Wikipedia URLの処理
    elif 'wikipedia.org/wiki/' in url:
        wiki_processor = WikipediaURLProcessor()
        wiki_processor.process_url(url)
    # それ以外のテキストの処理（URLエンコード）
    else:
        text_encoder = TextURLEncoder()
        text_encoder.process_text(url)
        
if __name__ == "__main__":
    main()
```
##pythonista3
```python:En_Wikipedia_and_Amazon.py　(2)
import re
import sys
import urllib.parse
import requests
import clipboard

class ClipboardURLFetcher:
    # クリップボードからURLを取得するクラス
    def fetch_url(self):
        url = clipboard.get()
        if len(url) == 0:
            sys.exit("URLをクリップボードに入れてください")
        return urllib.parse.unquote(url)

class AmazonURLProcessor:
    # Amazon URLを処理するクラス
    def process_url(self, url):
        if 'https://www.amazon' not in url:
            return url

        domain = 'com' if 'https://www.amazon.com/' in url else 'co.jp'
        asin = self.extract_asin(url, domain)
        if asin:
            short_url = f'https://www.amazon.{domain}/dp/{asin}'
            clipboard.set(short_url)
            print(f'クリップボードにコピー完了（Amazon）：{short_url}')
            sys.exit(0)
        return url

    def extract_asin(self, url, domain):
        if '/dp/' in url:
            pos = url.find('/dp/')
            return url[pos+4:pos+14]
        if '/gp/product/' in url:
            pos = url.find('/product/')
            return url[pos+9:pos+19]
        if '/gp/aw/d/' in url:
            pos = url.find('/aw/d/')
            return url[pos+6:pos+16]
        return None

class WikipediaURLProcessor:
    # Wikipedia URLを処理するクラス
    def process_url(self, url):
        if '?curid=' in url:
            sys.exit(f'既に変換済みです：{url}')
        
        # モバイル版URLも含めた条件に変更
        if 'https://' not in url or ('.wikipedia.org/wiki/' not in url and '.m.wikipedia.org/wiki/' not in url):
            sys.exit(f'Wikipediaのアドレスではありません：{url}')

        # モバイル版URLから通常のURLへの変換
        if '.m.wikipedia.org/wiki/' in url:
            url = url.replace('.m.wikipedia.org/wiki/', '.wikipedia.org/wiki/')

        lang = url[8:10]
        text = url.replace(f'https://{lang}.wikipedia.org/wiki/', '')
        page_id = self.get_wikipedia_page_id(lang, text)

        if not page_id:
            sys.exit(f'変換不可能なリンクです：{url}')

        new_url = f'https://{lang}.wikipedia.org/?curid={page_id}'
        clipboard.set(new_url)

        print(f'タイトル：{text}')
        print(f'Page(s)ID：{page_id}')
        print(f'元URL：{url}')
        encoded_url = urllib.parse.quote(url, safe='/:=@,.!?"\'')
        print(f'PC用エンコード済みURL：{encoded_url}')

        if '.m.wikipedia.org/' in url:
            pc_url = url.replace('.m', '')
            print(f'PC用エンコード済みURL：{pc_url}')

        mobile_url = url.replace('.wikipedia', '.m.wikipedia')
        print(f'Mobile用エンコード済みURL：{mobile_url}')
        mobile_id_url = new_url.replace('.wikipedia', '.m.wikipedia')
        print(f'Mobile用ID込みURL：{mobile_id_url}')

        return new_url

    def get_wikipedia_page_id(self, lang, title):
        url = f'https://{lang}.wikipedia.org/w/api.php'
        params = {
            'action': 'query',
            'titles': title,
            'format': 'json'
        }
        response = requests.get(url, params=params)
        data = response.json()
        page = next(iter(data['query']['pages'].values()))
        return page.get('pageid')

class TextURLEncoder:
    # テキストをURLエンコードしてクリップボードに出力するクラス
    def process_text(self, text):
        encoded_text = urllib.parse.quote(text, safe='/:=@,.!?"\'')
        clipboard.set(encoded_text)
        print(f'URLエンコードされたテキストをクリップボードにコピーしました：{encoded_text}')

def main():
    fetcher = ClipboardURLFetcher()
    url = fetcher.fetch_url()

    if 'amazon' in url:
        amazon_processor = AmazonURLProcessor()
        amazon_processor.process_url(url)
    elif 'wikipedia.org/wiki/' in url:
        wiki_processor = WikipediaURLProcessor()
        wiki_processor.process_url(url)
        # それ以外のテキストの処理（URLエンコード）
    else:
            text_encoder = TextURLEncoder()
            text_encoder.process_text(url)

if __name__ == "__main__":
    main()
```

# 終わりに
とりあえず、便利そうなものを混ぜてみただけです。