├── README.md └── jpholidayp /README.md: -------------------------------------------------------------------------------- 1 | # jpholidayp 2 | 3 | Is it holiday today in Japan? 4 | 5 | ## SYNOPSIS 6 | 7 | jpholidayp 8 | 9 | ## DESCRIPTION 10 | 11 | Check "Is it holiday today?" in Japan. 12 | 13 | No arguments, and no output. 14 | Reports as exit status: 15 | 16 | * 0 (success): holiday 17 | * 1: not holiday 18 | 19 | "Holiday" means: 20 | 21 | * Sunday and Saturday 22 | * In [holiday_jp](https://github.com/holiday-jp/holiday_jp) 23 | 24 | It creates cache file at ~/.jpholidayp directory. 25 | 26 | ## EXAMPLES 27 | 28 | usages in crontab. 29 | 30 | jpholidayp && some-command 31 | 32 | Run some-command in holiday. 33 | 34 | jpholidayp || some-command 35 | 36 | Run some-command in weekday. 37 | 38 | ## REQUIRES 39 | 40 | * Python 41 | * PyYAML 42 | 43 | ## PROXY 44 | 45 | This program accesses internet server once in 5 days. 46 | 47 | If you have to use proxy to access internet, set `https_proxy` 48 | environment variable. 49 | 50 | ## AUTHOR 51 | 52 | emasaka 53 | -------------------------------------------------------------------------------- /jpholidayp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import os 4 | import errno 5 | from datetime import datetime, date, timedelta 6 | from contextlib import closing 7 | import yaml 8 | try: 9 | from urllib2 import urlopen # Python 2.x 10 | except ImportError: 11 | from urllib.request import urlopen # Python 3.x 12 | try: 13 | import cPickle as pickle # Python 2.x 14 | except ImportError: 15 | import pickle # Python 3.x 16 | 17 | datadir = "~/.jpholidayp" 18 | cachefile = "cache" 19 | cachedays = 5 20 | 21 | class Cache: 22 | def __init__(self): 23 | try: 24 | os.mkdir(os.path.expanduser(datadir)) 25 | except OSError: 26 | # get exception instance on Python <= 2.5, 2.6/2.7 and 3.x 27 | if sys.exc_info()[1].errno != errno.EEXIST: 28 | raise 29 | 30 | def get(self): 31 | file = os.path.join(os.path.expanduser(datadir), cachefile) 32 | if not os.path.exists(file): 33 | return None 34 | today = datetime.utcnow().date() 35 | try: 36 | with open(file, 'rb') as f: 37 | dat = pickle.load(f) 38 | except: # cache file may be broken 39 | return None 40 | if dat["expires"] <= today: 41 | return None 42 | else: 43 | return dat["val"] 44 | 45 | def set(self, val): 46 | expires = datetime.utcnow().date() + timedelta(cachedays) 47 | dat = {"expires": expires, "val": val} 48 | file = os.path.join(os.path.expanduser(datadir), cachefile) 49 | with open(file, 'wb') as f: 50 | pickle.dump(dat, f, protocol=2) # for Python 2.x and 3.x 51 | 52 | class HolidayJp: 53 | URL = 'https://raw.githubusercontent.com/holiday-jp/holiday_jp/master/holidays.yml' 54 | 55 | def __init__(self): 56 | cache = Cache() 57 | c = cache.get() 58 | if c: 59 | dat = c["holiday_jp"] 60 | else: 61 | with closing(urlopen(self.URL)) as res: 62 | dat = yaml.load(res, Loader=yaml.SafeLoader) 63 | cache.set({"holiday_jp": dat}) 64 | self.holiday_jp = dat 65 | 66 | def is_holiday(self, dt): 67 | return dt in self.holiday_jp.keys() 68 | 69 | class JpHoliday: 70 | @classmethod 71 | def is_national_holiday(self, dt): 72 | holiday_jp = HolidayJp() 73 | return holiday_jp.is_holiday(dt) 74 | 75 | # value of datetime.weekday() 76 | SATURDAY = 5 77 | SUNDAY = 6 78 | 79 | @classmethod 80 | def is_holiday(self, dt): 81 | w = dt.weekday() 82 | if w == self.SATURDAY or w == self.SUNDAY: 83 | return True 84 | elif self.is_national_holiday(dt): 85 | return True 86 | else: 87 | return False 88 | 89 | # exit statuses 90 | EXIT_HOLIDAY = 0 91 | EXIT_WEEKDAY = 1 92 | EXIT_ERROR = 2 93 | 94 | def jpholidayp(): 95 | today = date.today() 96 | if JpHoliday.is_holiday(today): 97 | sys.exit(EXIT_HOLIDAY) 98 | else: 99 | sys.exit(EXIT_WEEKDAY) 100 | 101 | if __name__ == "__main__": 102 | jpholidayp() 103 | --------------------------------------------------------------------------------