Skip to content

Instantly share code, notes, and snippets.

@frodo821
Last active December 22, 2018 07:48
Show Gist options
  • Save frodo821/92267d3a12098663966b6048e18723f1 to your computer and use it in GitHub Desktop.
Save frodo821/92267d3a12098663966b6048e18723f1 to your computer and use it in GitHub Desktop.
from os.path import dirname, join, exists
from os import makedirs
from docx import Document
from .storage import load, storage, add_storage
try:
load()
except:
pass
KT = {
'ADDR': lambda x: x.address.translate(TT),
'TOP': lambda x: x.zipcode[:3],
'BOTTOM': lambda x: x.zipcode[3:],
'NAME': lambda x: x.name}
TT = {49: '一', 50: '二', 51: '三', 52: '四', 53: '五', 54: '六', 55: '七', 56: '八', 57: '九', 48: '〇'}
def generate(path=None):
path = path or dirname(__file__)
if not exists(path):
makedirs(path)
for s in storage:
template = Document(join(dirname(__file__), "template.docx"))
elem = template.element.findall(
'.//w:t',
{'w':'http://schemas.openxmlformats.org/wordprocessingml/2006/main'})
for e in filter(lambda x: x.text.startswith('$'), elem):
e.text = KT[e.text[1:]](s)
template.save(join(path, f"{s.name}_atenamen.docx"))
def main(path=None):
if not exists(join(dirname(__file__), 'addresses.json')):
add_storage()
save()
generate(path)
python-docx==0.8.7
requests==2.18.4
#-*- coding: utf-8;-*-
from os.path import join, dirname
from json import dumps, loads
from requests import get
# このライブラリは https://gist.github.com/frodo821/bf4d69d42f06b9735813176d1ab87873 で公開中
from utils.data import data
APIENTRY = "http://zipcoda.net/api?address="
storage = []
@data
class Address:
name: str
address: str
zipcode: str
def to_dict(self):
return {k: getattr(k, self) for k in self.__annotations__}
def add_storage():
state = 0
tmp = {}
skip = False
try:
while True:
if state == 0:
line = input("宛名を入力してください> ").strip()
if not line:
print("宛名は必須項目です。")
continue
if not skip:
ans = input(f'{line}様宛でよろしいですね? (y/N/A) ').lower()
while ans not in ('y','n','a'):
ans = input(f'{line}様宛でよろしいですね? (y/N/A) ').lower()
if ans == 'y':
state = 1
elif ans == 'a':
skip = True
state = 1
else:
pass
else:
state = 1
if state == 1:
tmp['name'] = line
continue
if state == 1:
line = input("宛先を入力してください> ").strip()
if not line:
print("宛先は必須項目です。")
continue
if not skip:
ans = input(f'{line}宛でよろしいですね? (y/N/A) ').lower()
while ans not in ('y','n','a'):
ans = input(f'{line}宛でよろしいですね? (y/N/A) ').lower()
if ans == 'y':
state = 2
elif ans == 'a':
skip = True
state = 2
else:
pass
else:
state = 2
if state == 2:
tmp['address'] = line
continue
if state == 2:
line = input("郵便番号を入力してください> ").strip()
if not line:
print("郵便番号を検索します...")
res = get(APIENTRY+tmp['address'])
if res.status_code != 200:
print("検索に失敗しました。手動で入力してください。")
continue
guess = [(i['zipcode'], i['diff']) for i in loads(res.text)['items']]
guess.sort(key=lambda x: x[1])
use = guess[0]
line = use[0]
tmp['zipcode'] = line
print(f'郵便番号を〒{line}で登録しました。')
state = 0
storage.append(Address(**tmp))
tmp = {}
continue
except:
pass
def serialize():
return dumps([s.to_dict() for s in storage])
def deserialize(src):
global storage
storage.clear()
storage.extend(Address(**i) for i in loads(src))
return storage
def save():
with open(join(dirname(__file__), 'addresses.json'), 'w') as f:
f.write(serialize())
def load():
with open(join(dirname(__file__), 'addresses.json')) as f:
deserialize(f.read())

年賀状宛名面自動生成スクリプト

これを使えば宛名面が簡単に作成できます! 適当なディレクトリに

  • *addresses.json
  • __init__.py
  • storage.py
  • template.docx

を配置すればOK! 斜線は自動生成されるのであなたが気にする必要はなし!

使い方は簡単! 例えば、適当なsys.pathが通っているディレクトリの中のnewyearに配置したということで話を進めよう。

>>> from newyear import main
>>> main()

これで完了! 宛名面のファイルを出力したいディレクトリを指定することもできて、

>>> from newyear import main
>>> main("/path/to/output/to/which/you/want")

main関数に引数に渡すだけ。簡単ですね!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment