はじめの前のおねがい
できれば「いいね♡」をお願いします。励みになります。
はじめに
今まで私のマイページ1では「Python3, Pythonista3: Wikipedia PageIDに変換したりAmazonのASINに変換したり2」などで、1つのコードであれもやりたい、これもやりたいと、色々な機能を含めてきたわけですが、実際に自分で運用していく中で、まあこのくらいのことができれば良いだろうという段階まで出来上がりました。つまり
をそれぞれ、http://
以降の文字列を参考にして判別し、〒
の場合は「乗換案内」の住所検索用に郵便番号の部分を取ったものを出力し、それ以外の場合はパーセントエンコードをするといったものです。
iPhoneでは別記事ではYouTube Liveのチャット取得機能も搭載していますが、Pythonista 3の場合はiPhone上にPythonista 3上で新しいファイルを作成保存する際に余計な工程が必要となり面倒なために省略していますが、それでも外出先にちまちまとLineやTwitter4、Facebook Messengerに、これらのリンクを貼り付ける場合に1つのコードで済ませられるようにするというのが、作成した最大の動機だったりします。
手順
- URLをクリップボードにコピー
- Pythonista 3あるいはPythonista 3コードが実行できるIDEを起動
- 本コードに必要なモジュール5をインストール6
- 本コードをコピペ
- 本コードを実行
- 変換後のものをクリップボードに再コピー
- コンソールに変換後のものや付属データを吐き出す
ソースコード
パソコン版などのPython 3でも使い回しできるように、pyperclip
とclipboard
とで動作を振り分けるようにしました。
ClipboardConverter.py
import re
import sys
import urllib.parse
import requests
# クリップボードモジュール振り分け
try:
import clipboard
def get_clipboard():
return clipboard.get()
def set_clipboard(text):
clipboard.set(text)
except ImportError:
try:
import pyperclip
def get_clipboard():
return pyperclip.paste()
def set_clipboard(text):
pyperclip.copy(text)
except ImportError:
sys.exit("クリップボードモジュールが利用できません。")
# クリップボード取得
class ClipboardURLFetcher:
def fetch_url(self):
url = get_clipboard()
if not url:
sys.exit("クリップボードに何も入っていません。")
return urllib.parse.unquote(url)
# 結果をクリップボードにペースト
class ClipboardManager:
@staticmethod
def copy_to_clipboard(text):
set_clipboard(text)
# 各プロセッサー基幹
class BaseURLProcessor:
def process_url(self, url):
raise NotImplementedError
# Amazonプロセッサー
class AmazonURLProcessor(BaseURLProcessor):
def process_url(self, url):
if 'https://www.amazon' not in url:
return None
domain = self.extract_domain(url)
asin = self.extract_asin(url)
if asin:
short_url = self.generate_short_url(asin, domain)
self.end_to_amznconv(short_url)
patterns = {
'/gp/product/': '/product/',
'/gp/aw/d/': '/aw/d/'
}
for suffix, pattern in patterns.items():
if suffix in url:
short_url = self.asin_url(url, pattern, domain)
self.end_to_amznconv(short_url)
return short_url
def extract_domain(self, url):
match = re.search(r'https://www\.amazon\.([a-z.]+)/', url)
if match:
return match.group(1)
return None
def extract_asin(self, url):
match = re.search(r'/dp/(\w{10})', url)
if match:
return match.group(1)
return None
def asin_url(self, url, pattern, domain):
pos = url.find(pattern) + len(pattern)
asin = url[pos:pos + 10]
return self.generate_short_url(asin, domain)
def generate_short_url(self, asin, domain):
return f'https://www.amazon.{domain}/dp/{asin}'
def end_to_amznconv(self, short_url):
print(f'クリップボードにコピー完了(Amazon):{short_url}')
return
# Wikipedia & Wiktionaryプロセッサー
class WikiURLProcessor(BaseURLProcessor):
def __init__(self, site):
self.site = site
def process_url(self, url):
if '?curid=' in url:
sys.exit(f'既に変換済みです:{url}')
if 'https://' not in url or (f'.{self.site}.org/wiki/' not in url and f'.m.{self.site}.org/wiki/' not in url):
return None
if f'.m.{self.site}.org/wiki/' in url:
url = url.replace(f'.m.{self.site}.org/wiki/', f'.{self.site}.org/wiki/')
match = re.search(r'https://([a-z\-]+)\.' + re.escape(self.site) + r'\.org/wiki/', url)
if not match:
sys.exit(f'無効なURLです:{url}')
lang = match.group(1)
text = url.replace(f'https://{lang}.{self.site}.org/wiki/', '')
page_id = self.get_page_id(lang, text)
if not page_id:
sys.exit(f'変換不可能なリンクです:{url}')
new_url = f'https://{lang}.{self.site}.org/?curid={page_id}' if self.site == 'wikipedia' else f'https://{lang}.{self.site}.org/w/index.php?curid={page_id}'
self.print_info(url, lang, text, page_id)
return new_url
def get_page_id(self, lang, title):
url = f'https://{lang}.{self.site}.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')
def print_info(self, url, lang, text, page_id):
encoded_url = urllib.parse.quote(url, safe='/:=@,.!?\"\'')
mobile_url = url.replace(f'.{self.site}.org/wiki/', f'.m.{self.site}.org/?curid=')
mobile_encoded_url = urllib.parse.quote(mobile_url, safe='/:=@,.!?\"\'')
print(f'{self.site.capitalize()}タイトル:{text}')
print(f'Page(s)ID:{page_id}')
print(f'タイトル込みURL:{url}')
print(f'PC用エンコード済みURL:{encoded_url}')
print(f'Mobile用エンコード済みURL:{mobile_encoded_url}')
print('')
print(f'{self.site.capitalize()}タイトル:{text}')
print(f'PC用ID込みURL:https://{lang}.{self.site}.org/?curid={page_id}')
print(f'Mobile用ID込みURL:https://{lang}.m.{self.site}.org/?curid={page_id}')
# URLエンコードプロセッサー
class TextURLEncoder(BaseURLProcessor):
def process_url(self, text):
encoded_text = urllib.parse.quote(text, safe='/:=@,.!?\"\'')
print(f'URLエンコードされたテキストをクリップボードにコピーしました:{encoded_text}')
return encoded_text
# GoogleMap→乗換案内プロセッサー
class AddressProcessor(BaseURLProcessor):
def process_url(self, in_text):
if '〒' in in_text[:2]:
url = in_text[:9]
text = in_text.replace(url, '')
address = text.translate(str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}))
address = address.replace('−','-')
address = address.lstrip()
zip = url.replace('〒', '')
address = address.replace(' ', '\n')
print(zip)
print(address)
return address
else:
return None
# メイン処理
def main():
fetcher = ClipboardURLFetcher()
url = fetcher.fetch_url()
processors = [
AddressProcessor(),
AmazonURLProcessor(),
WikiURLProcessor(site='wikipedia'), # Wikipedia用の処理
WikiURLProcessor(site='wiktionary'), # Wiktionary用の処理
TextURLEncoder()
]
for processor in processors:
new_url = processor.process_url(url)
if new_url is not None:
ClipboardManager.copy_to_clipboard(new_url)
break
# # スクリプトが直接実行された場合にmain関数を呼び出す
if __name__ == "__main__":
main()
終わりに
極力、class
とdef
を使用して、他のコードに転用できるように整理しましたが、まだ効率が十分ではありません。