PK!.Y\ jma_feed/__init__.pyfrom itertools import chain from pkg_resources import DistributionNotFound, get_distribution from jma_feed.feed import AtomFeed, AtomFeedEntry from jma_feed.report import ( Report, ReportBodyMeteorology, ReportBodySeismology, ReportBodyVolcanology, ) try: __version__ = get_distribution('jma-feed').version except DistributionNotFound: __version__ = '(local)' # Minutely Update FEED_URL_REGULAR_SHORT_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/regular.xml' FEED_URL_EXTRA_SHORT_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/extra.xml' FEED_URL_EQVOL_SHORT_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/eqvol.xml' FEED_URL_OTHER_SHORT_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/other.xml' # Hourly Update FEED_URL_REGULAR_LONG_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/regular_l.xml' FEED_URL_EXTRA_LONG_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/extra_l.xml' FEED_URL_EQVOL_LONG_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/eqvol_l.xml' FEED_URL_OTHER_LONG_TERM = 'http://www.data.jma.go.jp/developer/xml/feed/other_l.xml' def fetch_reports(feed_url): """Fetch JMA reports which are listed in feed. Args: feed_url (str): URL of JMA feed """ feed = AtomFeed(feed_url) return [Report(entry.link) for entry in feed.entries] def fetch_all_reports(long_term=False): """Fetch all JMA reports. Args: long_term (bool): true if use long-term feeds """ if long_term: feed_urls = [ FEED_URL_REGULAR_LONG_TERM, FEED_URL_EXTRA_LONG_TERM, FEED_URL_EQVOL_LONG_TERM, FEED_URL_OTHER_LONG_TERM, ] else: feed_urls = [ FEED_URL_REGULAR_SHORT_TERM, FEED_URL_EXTRA_SHORT_TERM, FEED_URL_EQVOL_SHORT_TERM, FEED_URL_OTHER_SHORT_TERM, ] nested_list = [fetch_reports(feed_url) for feed_url in feed_urls] return list(chain.from_iterable(nested_list)) def fetch_all_certain_type_reports(long_term=False, report_type=ReportBodyMeteorology): return [ report for report in fetch_all_reports(long_term) if isinstance(report.body, report_type) ] def fetch_all_meteorology_reports(long_term=False): """Fetch all JMA meteorology reports. Args: long_term (bool): true if use long-term feeds """ return fetch_all_certain_type_reports(long_term, ReportBodyMeteorology) def fetch_all_seismology_reports(long_term=False): """Fetch all JMA seismology reports. Args: long_term (bool): true if use long-term feeds """ return fetch_all_certain_type_reports(long_term, ReportBodySeismology) def fetch_all_volcanology_reports(long_term=False): """Fetch all JMA volcanology reports. Args: long_term (bool): true if use long-term feeds """ return fetch_all_certain_type_reports(long_term, ReportBodyVolcanology) PK!%}jma_feed/feed.pyfrom jma_feed.xml import XmlDocument class AtomFeed(XmlDocument): """Model class which represents Atom feed.""" def __init__(self, target): super(AtomFeed, self).__init__(target, {'atom': 'http://www.w3.org/2005/Atom'}) @property def title(self): return self._element_text('atom:title') @property def subtitle(self): return self._element_text('atom:subtitle') @property def updated(self): return self._element_text('atom:updated') @property def id(self): return self._element_text('atom:id') @property def rights(self): return self._element_text('atom:rights') @property def entries(self): elements = self._elements('atom:entry') return [AtomFeedEntry(element) for element in elements] class AtomFeedEntry(XmlDocument): """Model class which represents Atom feed each entry.""" def __init__(self, target): super(AtomFeedEntry, self).__init__(target, {'atom': 'http://www.w3.org/2005/Atom'}) @property def title(self): return self._element_text('atom:title') @property def updated(self): return self._element_text('atom:updated') @property def id(self): return self._element_text('atom:id') @property def author(self): return self._element_text('atom:author/atom:name') @property def content(self): return self._element_text('atom:content') @property def link(self): return self._element_attr('atom:link', 'href') PK!Dg3G3Gjma_feed/report.pyfrom jma_feed.xml import XmlDocument JMX_NS_MAP = { 'jmx': 'http://xml.kishou.go.jp/jmaxml1/', 'jmx_ib': 'http://xml.kishou.go.jp/jmaxml1/informationBasis1/', 'jmx_eb': 'http://xml.kishou.go.jp/jmaxml1/elementBasis1/', 'jmx_add': 'http://xml.kishou.go.jp/jmaxml1/addition1/', 'jmx_mete': 'http://xml.kishou.go.jp/jmaxml1/body/meteorology1/', 'jmx_seis': 'http://xml.kishou.go.jp/jmaxml1/body/seismology1/', 'jmx_volc': 'http://xml.kishou.go.jp/jmaxml1/body/volcanology1/', } class Report(XmlDocument): """Model class which represents JMA report.""" def __init__(self, target): super(Report, self).__init__(target, JMX_NS_MAP) @property def control(self): element = self._element('jmx:Control') return ReportControl(element) @property def head(self): element = self._element('jmx_ib:Head') return ReportHead(element) @property def body(self): xpath, element = self._find_element('jmx_mete:Body', 'jmx_seis:Body', 'jmx_volc:Body') if xpath == 'jmx_mete:Body': return ReportBodyMeteorology(element) if xpath == 'jmx_seis:Body': return ReportBodySeismology(element) if xpath == 'jmx_volc:Body': return ReportBodyVolcanology(element) return None class ReportControl(XmlDocument): """Model class which represents JMA control part.""" def __init__(self, target): super(ReportControl, self).__init__(target, JMX_NS_MAP) @property def title(self): return self._element_text('jmx:Title') @property def date_time(self): return self._element_text('jmx:DateTime') @property def status(self): return self._element_text('jmx:Status') @property def editorial_office(self): return self._element_text('jmx:EditorialOffice') @property def publishing_office(self): return self._element_text('jmx:PublishingOffice') class ReportHead(XmlDocument): """Model class which represents JMA head part.""" def __init__(self, target): super(ReportHead, self).__init__(target, JMX_NS_MAP) @property def title(self): return self._element_text('jmx_ib:Title') @property def report_date_time(self): return self._element_text('jmx_ib:ReportDateTime') @property def target_date_time(self): return self._element_text('jmx_ib:TargetDateTime') @property def event_id(self): return self._element_text('jmx_ib:EventID') @property def info_type(self): return self._element_text('jmx_ib:InfoType') @property def serial(self): return self._element_text('jmx_ib:Serial') @property def info_kind(self): return self._element_text('jmx_ib:InfoKind') @property def info_kind_version(self): return self._element_text('jmx_ib:InfoKindVersion') @property def headline_text(self): return self._element_text('jmx_ib:Headline/jmx_ib:Text') @property def headline_information_list(self): elements = self._elements('jmx_ib:Headline/jmx_ib:Information') return [HeadlineInformation(element) for element in elements] class ReportBodyMeteorology(XmlDocument): """Model class which represents JMA meteorology body part.""" def __init__(self, target): super(ReportBodyMeteorology, self).__init__(target, JMX_NS_MAP) @property def target_area(self): element = self._element('jmx_mete:TargetArea') if element == None: return None return MeteorologyArea(element) @property def comment(self): element = self._element('jmx_mete:Comment') if element == None: return None return MeteorologyComment(element) @property def notices(self): elements = self._elements('jmx_mete:Notice') return [element.text for element in elements] @property def warnings(self): elements = self._elements('jmx_mete:Warning') return [MeteorologyWarning(element) for element in elements] @property def meteorological_infos(self): elements = self._elements('jmx_mete:MeteorologicalInfos/jmx_mete:MeteorologicalInfo') return [MeteorologicalInfo(element) for element in elements] @property def time_series_infos(self): elements = self._elements('jmx_mete:MeteorologicalInfos/jmx_mete:TimeSeriesInfo') return [TimeSeriesInfo(element) for element in elements] class ReportBodySeismology(XmlDocument): """Model class which represents JMA seismology body part.""" def __init__(self, target): super(ReportBodySeismology, self).__init__(target, JMX_NS_MAP) @property def naming(self): return self._element_text('jmx_seis:Naming') @property def text(self): return self._element_text('jmx_seis:Text') @property def next_advisory(self): return self._element_text('jmx_seis:NextAdvisory') @property def comments(self): element = self._element('jmx_seis:Comments') if element == None: return None return SeismologyComment(element) @property def earthquakes(self): elements = self._elements('jmx_seis:Earthquake') return [Earthquake(element) for element in elements] @property def tsunami(self): element = self._element('jmx_seis:Tsunami') if element == None: return None return Tsunami(element) class ReportBodyVolcanology(XmlDocument): """Model class which represents JMA volcanology body part.""" def __init__(self, target): super(ReportBodyVolcanology, self).__init__(target, JMX_NS_MAP) @property def notice(self): return self._element_text('jmx_volc:Notice') @property def text(self): return self._element_text('jmx_volc:Text') @property def volcano_infos(self): elements = self._elements('jmx_volc:VolcanoInfo') return [VolcanoInfo(element) for element in elements] @property def ash_infos(self): elements = self._elements('jmx_volc:AshInfos/jmx_volc:AshInfo') return [AshInfo(element) for element in elements] class HeadlineInformation(XmlDocument): def __init__(self, target): super(HeadlineInformation, self).__init__(target, JMX_NS_MAP) @property def type(self): return self._element_attr('.', 'type') @property def items(self): elements = self._elements('jmx_ib:Item') return [HeadlineInformationItem(element) for element in elements] class HeadlineInformationItem(XmlDocument): def __init__(self, target): super(HeadlineInformationItem, self).__init__(target, JMX_NS_MAP) @property def kinds(self): elements = self._elements('jmx_ib:Kind') return [HeadlineInformationItemKind(element) for element in elements] @property def areas_code_type(self): return self._element_attr('jmx_ib:Areas', 'codeType') @property def areas(self): elements = self._elements('jmx_ib:Areas/jmx_ib:Area') return [HeadlineInformationItemArea(element) for element in elements] class HeadlineInformationItemKind(XmlDocument): def __init__(self, target): super(HeadlineInformationItemKind, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_ib:Name') @property def code(self): return self._element_text('jmx_ib:Code') @property def condition(self): return self._element_text('jmx_ib:Condition') class HeadlineInformationItemArea(XmlDocument): def __init__(self, target): super(HeadlineInformationItemArea, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_ib:Name') @property def code(self): return self._element_text('jmx_ib:Code') class MeteorologyWarning(XmlDocument): def __init__(self, target): super(MeteorologyWarning, self).__init__(target, JMX_NS_MAP) @property def items(self): elements = self._elements('jmx_mete:Item') return [MeteorologyItem(element) for element in elements] class MeteorologicalInfo(XmlDocument): def __init__(self, target): super(MeteorologicalInfo, self).__init__(target, JMX_NS_MAP) @property def items(self): elements = self._elements('jmx_mete:Item') return [MeteorologyItem(element) for element in elements] @property def date_time(self): return self._element_text('jmx_mete:DateTime') @property def duration(self): return self._element_text('jmx_mete:Duration') @property def name(self): return self._element_text('jmx_mete:Name') class TimeSeriesInfo(XmlDocument): def __init__(self, target): super(TimeSeriesInfo, self).__init__(target, JMX_NS_MAP) @property def items(self): elements = self._elements('jmx_mete:Item') return [MeteorologyItem(element) for element in elements] @property def time_defines(self): elements = self._elements('jmx_mete:TimeDefines/jmx_mete:TimeDefine') return [TimeDefine(element) for element in elements] class TimeDefine(XmlDocument): def __init__(self, target): super(TimeDefine, self).__init__(target, JMX_NS_MAP) @property def date_time(self): return self._element_text('jmx_mete:DateTime') @property def duration(self): return self._element_text('jmx_mete:Duration') @property def name(self): return self._element_text('jmx_mete:Name') class MeteorologyComment(XmlDocument): def __init__(self, target): super(MeteorologyComment, self).__init__(target, JMX_NS_MAP) @property def texts(self): elements = self._elements('jmx_mete:Text') return [MeteorologyText(element) for element in elements] class MeteorologyText(XmlDocument): def __init__(self, target): super(MeteorologyText, self).__init__(target, JMX_NS_MAP) @property def text(self): return self._element_text('.') @property def type(self): return self._element_attr('.', 'type') class MeteorologyItem(XmlDocument): def __init__(self, target): super(MeteorologyItem, self).__init__(target, JMX_NS_MAP) @property def kinds(self): elements = self._elements('jmx_mete:Kind') return [MeteorologyKind(element) for element in elements] @property def area(self): element = self._element('jmx_mete:Area') if element == None: return None return MeteorologyArea(element) @property def change_status(self): return self._element_text('jmx_mete:ChangeStatus') @property def full_status(self): return self._element_text('jmx_mete:FullStatus') @property def editing_mark(self): return self._element_text('jmx_mete:EditingMark') class MeteorologyKind(XmlDocument): def __init__(self, target): super(MeteorologyKind, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_mete:Name') @property def code(self): return self._element_text('jmx_mete:Code') @property def status(self): return self._element_text('jmx_mete:Status') @property def condition(self): return self._element_text('jmx_mete:Condition') class MeteorologyArea(XmlDocument): def __init__(self, target): super(MeteorologyArea, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_mete:Name') @property def code(self): return self._element_text('jmx_mete:Code') class Earthquake(XmlDocument): def __init__(self, target): super(Earthquake, self).__init__(target, JMX_NS_MAP) @property def origin_time(self): return self._element_text('jmx_seis:OriginTime') @property def arrival_time(self): return self._element_text('jmx_seis:ArrivalTime') @property def condition(self): return self._element_text('jmx_seis:Condition') @property def hypocenter(self): element = self._element('jmx_seis:Hypocenter') if element == None: return None return Hypocenter(element) @property def magnitudes(self): elements = self._elements('jmx_eb:Magnitude') return [element.text for element in elements] class Hypocenter(XmlDocument): def __init__(self, target): super(Hypocenter, self).__init__(target, JMX_NS_MAP) @property def source(self): return self._element_text('jmx_seis:Source') @property def area(self): element = self._element('jmx_seis:Area') if element == None: return None return HypoArea(element) class HypoArea(XmlDocument): def __init__(self, target): super(HypoArea, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_seis:Name') @property def code(self): return self._element_text('jmx_seis:Code') @property def coordinate(self): return self._element_text('jmx_eb:Coordinate') class Tsunami(XmlDocument): def __init__(self, target): super(Tsunami, self).__init__(target, JMX_NS_MAP) @property def release(self): return self._element_text('jmx_eb:Release') @property def observation(self): element = self._element('jmx_seis:Observation') if element == None: return None return TsunamiDetail(element) @property def estimation(self): element = self._element('jmx_seis:Estimation') if element == None: return None return TsunamiDetail(element) @property def forecast(self): element = self._element('jmx_seis:Forecast') if element == None: return None return TsunamiDetail(element) class TsunamiDetail(XmlDocument): def __init__(self, target): super(TsunamiDetail, self).__init__(target, JMX_NS_MAP) @property def items(self): elements = self._elements('jmx_seis:Item') return [TsunamiItem(element) for element in elements] class TsunamiItem(XmlDocument): def __init__(self, target): super(TsunamiItem, self).__init__(target, JMX_NS_MAP) class SeismologyComment(XmlDocument): def __init__(self, target): super(SeismologyComment, self).__init__(target, JMX_NS_MAP) @property def warning_comment(self): element = self._element('jmx_seis:WarningComment') if element == None: return None return SeismologyCommentForm(element) @property def forecast_comment(self): element = self._element('jmx_seis:ForecastComment') if element == None: return None return SeismologyCommentForm(element) @property def observation_comment(self): element = self._element('jmx_seis:ObservationComment') if element == None: return None return SeismologyCommentForm(element) @property def var_comment(self): element = self._element('jmx_seis:VarComment') if element == None: return None return SeismologyCommentForm(element) @property def free_form_comment(self): return self._element_text('jmx_seis:FreeFormComment') class SeismologyCommentForm(XmlDocument): def __init__(self, target): super(SeismologyCommentForm, self).__init__(target, JMX_NS_MAP) @property def text(self): return self._element_text('jmx_seis:Text') @property def code(self): return self._element_text('jmx_seis:Code') @property def code_type(self): return self._element_attr('.', 'codeType') class VolcanoInfo(XmlDocument): def __init__(self, target): super(VolcanoInfo, self).__init__(target, JMX_NS_MAP) @property def items(self): elements = self._elements('jmx_volc:Item') return [VolcanologyItem(element) for element in elements] class AshInfo(XmlDocument): def __init__(self, target): super(AshInfo, self).__init__(target, JMX_NS_MAP) @property def start_time(self): return self._element_text('jmx_volc:StartTime') @property def end_time(self): return self._element_text('jmx_volc:EndTime') @property def items(self): elements = self._elements('jmx_volc:Item') return [VolcanologyItem(element) for element in elements] class VolcanologyItem(XmlDocument): def __init__(self, target): super(VolcanologyItem, self).__init__(target, JMX_NS_MAP) @property def kind(self): element = self._element('jmx_volc:Kind') if element == None: return None return VolcanologyKind(element) @property def areas(self): elements = self._elements('jmx_volc:Areas/jmx_volc:Area') return [VolcanologyArea(element) for element in elements] class VolcanologyKind(XmlDocument): def __init__(self, target): super(VolcanologyKind, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_volc:Name') @property def formal_name(self): return self._element_text('jmx_volc:FormalName') @property def code(self): return self._element_text('jmx_volc:Code') @property def condition(self): return self._element_text('jmx_volc:Condition') class VolcanologyArea(XmlDocument): def __init__(self, target): super(VolcanologyArea, self).__init__(target, JMX_NS_MAP) @property def name(self): return self._element_text('jmx_volc:Name') @property def code(self): return self._element_text('jmx_volc:Code') @property def coordinate(self): return self._element_text('jmx_eb:Coordinate') PK!ޙPb""jma_feed/tests/__init__.py"""Unit tests for the package.""" PK!4dUJJjma_feed/tests/conftest.py"""Unit tests configuration file.""" import log import pytest from pkg_resources import resource_string def pytest_configure(config): """Disable verbose output when running tests.""" log.init(debug=True) terminal = config.pluginmanager.getplugin('terminal') class QuietReporter(terminal.TerminalReporter): # type: ignore """Reporter that only shows dots when running tests.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.verbosity = 0 self.showlongtestinfo = False self.showfspath = False terminal.TerminalReporter = QuietReporter @pytest.fixture() def feed_samples(): sample_regular_feed = resource_string('jma_feed.tests.resources', 'sample_regular.xml').decode( 'utf-8' ) yield (sample_regular_feed,) @pytest.fixture() def report_samples(): sample_mete1 = resource_string('jma_feed.tests.resources', 'sample_mete1.xml').decode('utf-8') sample_mete2 = resource_string('jma_feed.tests.resources', 'sample_mete2.xml').decode('utf-8') sample_seis1 = resource_string('jma_feed.tests.resources', 'sample_seis1.xml').decode('utf-8') sample_volc1 = resource_string('jma_feed.tests.resources', 'sample_volc1.xml').decode('utf-8') yield (sample_mete1, sample_mete2, sample_seis1, sample_volc1) PK!$jma_feed/tests/resources/__init__.pyPK! ET~~)jma_feed/tests/resources/sample_mete1.xml 府県天気概況 2019-02-10T20:22:17Z 通常 銚子地方気象台 銚子地方気象台 天気概況 2019-02-11T05:22:00+09:00 2019-02-11T05:22:00+09:00 発表 平文情報 1.0_0 千葉県では、11日朝から11日昼過ぎまで大雪や電線等への着雪に注意してください。 千葉県 120000  日本海西部には低気圧があって東へ進んでいます。また、伊豆諸島付近に は気圧の谷が停滞しています。  千葉県は、曇りで、雪や雨が降っている所があります。  11日は、気圧の谷の影響により、はじめ雪や雨で、北西部と北東部では 昼過ぎから、南部では昼前から曇りとなるでしょう。  12日は、冬型の気圧配置となるためおおむね晴れますが、伊豆諸島付近 が気圧の谷となるため、夕方からは曇りとなる見込みです。  太平洋沿岸では、11日はうねりを伴い波がやや高く、12日は波がやや 高いでしょう。 PK!=eyLL)jma_feed/tests/resources/sample_mete2.xml 気象警報・注意報 2019-02-10T02:18:29Z 通常 和歌山地方気象台 和歌山地方気象台 和歌山県気象警報・注意報 2019-02-10T11:18:00+09:00 2019-02-10T11:18:00+09:00 発表 気象警報・注意報 1.0_1 注意報を解除します。 解除 00 和歌山県 300000 解除 00 北部 300010 解除 00 南部 300020 解除 00 紀北 300011 解除 00 紀中 300012 解除 00 田辺・西牟婁 300021 解除 00 新宮・東牟婁 300022 解除 00 和歌山市 3020100 解除 00 海南市 3020200 解除 00 橋本市 3020300 解除 00 有田市 3020400 解除 00 御坊市 3020500 解除 00 田辺市田辺 3020601 解除 00 田辺市龍神 3020602 解除 00 田辺市中辺路 3020603 解除 00 田辺市大塔 3020604 解除 00 田辺市本宮 3020605 解除 00 新宮市 3020700 解除 00 紀の川市 3020800 解除 00 岩出市 3020900 解除 00 紀美野町 3030400 解除 00 かつらぎ町 3034100 解除 00 九度山町 3034300 解除 00 高野町 3034400 解除 00 湯浅町 3036100 解除 00 広川町 3036200 解除 00 有田川町 3036600 解除 00 美浜町 3038100 解除 00 日高町 3038200 解除 00 由良町 3038300 解除 00 印南町 3039000 解除 00 みなべ町 3039100 解除 00 日高川町 3039200 解除 00 白浜町 3040100 解除 00 上富田町 3040400 解除 00 すさみ町 3040600 解除 00 那智勝浦町 3042100 解除 00 太地町 3042200 解除 00 古座川町 3042400 解除 00 北山村 3042700 解除 00 串本町 3042800 強風注意報 15 解除 和歌山県 300000 警報・注意報種別に変化有 全域 1 強風注意報 15 解除 北部 300010 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 南部 300020 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 紀北 300011 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 紀中 300012 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 田辺・西牟婁 300021 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 新宮・東牟婁 300022 警報・注意報種別に変化有 全域 0 強風注意報 15 解除 和歌山市 3020100 警報・注意報種別に変化有 強風注意報 15 解除 海南市 3020200 警報・注意報種別に変化有 強風注意報 15 解除 橋本市 3020300 警報・注意報種別に変化有 強風注意報 15 解除 有田市 3020400 警報・注意報種別に変化有 強風注意報 15 解除 御坊市 3020500 警報・注意報種別に変化有 強風注意報 15 解除 田辺市田辺 3020601 警報・注意報種別に変化有 強風注意報 15 解除 田辺市龍神 3020602 警報・注意報種別に変化有 強風注意報 15 解除 田辺市中辺路 3020603 警報・注意報種別に変化有 強風注意報 15 解除 田辺市大塔 3020604 警報・注意報種別に変化有 強風注意報 15 解除 田辺市本宮 3020605 警報・注意報種別に変化有 強風注意報 15 解除 新宮市 3020700 警報・注意報種別に変化有 強風注意報 15 解除 紀の川市 3020800 警報・注意報種別に変化有 強風注意報 15 解除 岩出市 3020900 警報・注意報種別に変化有 強風注意報 15 解除 紀美野町 3030400 警報・注意報種別に変化有 強風注意報 15 解除 かつらぎ町 3034100 警報・注意報種別に変化有 強風注意報 15 解除 九度山町 3034300 警報・注意報種別に変化有 強風注意報 15 解除 高野町 3034400 警報・注意報種別に変化有 強風注意報 15 解除 湯浅町 3036100 警報・注意報種別に変化有 強風注意報 15 解除 広川町 3036200 警報・注意報種別に変化有 強風注意報 15 解除 有田川町 3036600 警報・注意報種別に変化有 強風注意報 15 解除 美浜町 3038100 警報・注意報種別に変化有 強風注意報 15 解除 日高町 3038200 警報・注意報種別に変化有 強風注意報 15 解除 由良町 3038300 警報・注意報種別に変化有 強風注意報 15 解除 印南町 3039000 警報・注意報種別に変化有 強風注意報 15 解除 みなべ町 3039100 警報・注意報種別に変化有 強風注意報 15 解除 日高川町 3039200 警報・注意報種別に変化有 強風注意報 15 解除 白浜町 3040100 警報・注意報種別に変化有 強風注意報 15 解除 上富田町 3040400 警報・注意報種別に変化有 強風注意報 15 解除 すさみ町 3040600 警報・注意報種別に変化有 強風注意報 15 解除 那智勝浦町 3042100 警報・注意報種別に変化有 強風注意報 15 解除 太地町 3042200 警報・注意報種別に変化有 強風注意報 15 解除 古座川町 3042400 警報・注意報種別に変化有 強風注意報 15 解除 北山村 3042700 警報・注意報種別に変化有 強風注意報 15 解除 串本町 3042800 警報・注意報種別に変化有 PK!=O{{+jma_feed/tests/resources/sample_regular.xml 高頻度(定時) JMAXML publishing feed 2019-02-11T11:33:01+09:00 urn:uuid:4e2e12c8-4601-3c0f-8c8a-75cc83dcf6ac 利用規約, Terms of Use ]]> アジア太平洋地上実況図 urn:uuid:d25c00b2-c23d-313c-830b-201eb7ada516 2019-02-11T02:31:44Z 気象庁予報部 【アジア太平洋地上実況図】 府県天気予報 urn:uuid:01a1dc5a-a2ec-34fc-bd8b-265d3e24b614 2019-02-11T02:31:34Z 熊本地方気象台 【熊本県府県天気予報】 警報級の可能性(明日まで) urn:uuid:d5f08845-c2f7-37c5-b586-cc9b98e99c9e 2019-02-11T02:20:00Z 熊本地方気象台 【熊本県警報級の可能性(明日まで)】 府県天気概況 urn:uuid:d2d30d51-572c-390e-9fe1-964c9a6c2244 2019-02-11T02:17:45Z 熊本地方気象台 【天気概況】熊本、芦北地方では11日夕方まで、天草地方では11日夜のはじめ頃まで、強風に注意してください。 府県天気概況 urn:uuid:f233532d-1d2f-3a52-8bbb-e5779b709d2e 2019-02-11T02:16:14Z 徳島地方気象台 【天気概況】 地上実況図 urn:uuid:1794d098-bfa7-3def-b478-4b9d9ebb6b7d 2019-02-11T02:09:11Z 気象庁予報部 【地上実況図】 府県天気概況 urn:uuid:7c09b20b-e6f7-3a15-87bf-2f6d366b2851 2019-02-11T01:58:31Z 石垣島地方気象台 【天気概況】八重山地方の沿岸の海域では波が高くなっており、波の高い状態は12日昼前まで続く見込みです。海上や海岸付近では、高波に注意してください。 府県天気概況 urn:uuid:af036d3d-339c-3011-acec-76cae68860f0 2019-02-11T01:55:00Z 前橋地方気象台 【天気概況】 府県天気概況 urn:uuid:73bdc4e2-8b80-3605-8ae9-4ad93ab15e59 2019-02-11T01:53:32Z 水戸地方気象台 【天気概況】南部では、11日夕方まで大雪に警戒してください。 府県天気概況 urn:uuid:2289383e-b15c-380b-b70d-824a804ac2ba 2019-02-11T01:53:04Z 横浜地方気象台 【天気概況】 府県天気概況 urn:uuid:35298f77-cd9f-3238-ae9e-fcf98ecebcb8 2019-02-11T01:51:09Z 長野地方気象台 【天気概況】北部、中部では、11日までなだれに注意してください。 全般週間天気予報 urn:uuid:352ef0d9-4f5d-36c7-bf0d-f2ffcc31c4e0 2019-02-11T01:51:06Z 気象庁予報部 【全般週間天気予報】 PK!P P )jma_feed/tests/resources/sample_seis1.xml 震源・震度に関する情報 2019-02-10T00:57:21Z 通常 気象庁本庁 気象庁 震源・震度情報 2019-02-10T09:57:00+09:00 2019-02-10T09:57:00+09:00 20190210095432 発表 1 地震情報 1.0_1 10日09時54分ころ、地震がありました。 2019-02-10T09:54:00+09:00 2019-02-10T09:54:00+09:00 岩手県沖 286 +40.4+142.1-50000/ 3.6 地震情報/都道府県等 地震情報/細分区域 気象・地震・火山情報/市町村等 震度観測点 1 青森県021 青森県三八上北2021 階上町02446001 階上町道仏*02446311 岩手県031 岩手県沿岸北部2101 久慈市03207001 久慈市川崎町03207001 久慈市枝成沢03207011 岩手洋野町03507001 岩手洋野町種市03507001 岩手県内陸北部2121 九戸村03506001 九戸村伊保内*03506311 この地震による津波の心配はありません。 0215 *印は気象庁以外の震度観測点についての情報です。 0262 PK!|cdd)jma_feed/tests/resources/sample_volc1.xml 降灰予報(定時) 2019-02-10T20:00:00Z 通常 気象庁本庁 気象庁地震火山部 火山名 霧島山(えびの高原(硫黄山)周辺) 降灰予報(定時) 2019-02-11T05:00:00+09:00 2019-02-11T06:00:00+09:00 2019-02-12T00:00:00+09:00 552 発表 1 降灰予報 1.1_0  現在、霧島山(えびの高原(硫黄山)周辺)は噴火警戒レベル2(火口周辺規制)です。霧島山(えびの高原(硫黄山)周辺)で噴火が発生した場合には、11日09時から12時までは火口から南東方向、11日21時から24時までは火口から南方向に降灰が予想されます。 降灰予報(定時) 06 霧島山(えびの高原(硫黄山)周辺) 552 降灰 70 宮崎県宮崎市 4520100 宮崎県都城市 4520200 宮崎県日南市 4520400 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県三股町 4534100 宮崎県高原町 4536100 鹿児島県曽於市 4621700 鹿児島県霧島市 4621800 鹿児島県志布志市 4622100 鹿児島県大崎町 4646800 小さな噴石の落下 75 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 降灰予報(定時) 06 霧島山(えびの高原(硫黄山)周辺) 552 +3156.82+13051.23+1317/ 降灰 70 宮崎県宮崎市 4520100 宮崎県都城市 4520200 宮崎県日南市 4520400 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県三股町 4534100 宮崎県高原町 4536100 鹿児島県曽於市 4621700 鹿児島県霧島市 4621800 鹿児島県志布志市 4622100 鹿児島県大崎町 4646800 小さな噴石の落下 75 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T06:00:00+09:00 2019-02-11T09:00:00+09:00 降灰 70 +31.9795+130.8400/+31.9799+130.8600/+31.9796+130.8800/+31.9764+130.9000/+31.9600+130.9172/+31.9598+130.9200/+31.9588+130.9400/+31.9533+130.9600/+31.9400+130.9768/+31.9395+130.9800/+31.9368+131.0000/+31.9259+131.0200/+31.9200+131.0270/+31.9172+131.0400/+31.9115+131.0600/+31.9000+131.0791/+31.8997+131.0800/+31.8937+131.1000/+31.8887+131.1200/+31.8822+131.1400/+31.8800+131.1457/+31.8759+131.1600/+31.8737+131.1800/+31.8689+131.2000/+31.8627+131.2200/+31.8600+131.2275/+31.8540+131.2400/+31.8479+131.2600/+31.8419+131.2800/+31.8400+131.2868/+31.8219+131.3000/+31.8200+131.3016/+31.8027+131.3200/+31.8000+131.3253/+31.7886+131.3200/+31.7800+131.3179/+31.7600+131.3144/+31.7400+131.3052/+31.7300+131.3000/+31.7200+131.2945/+31.7124+131.2800/+31.7068+131.2600/+31.7032+131.2400/+31.7072+131.2200/+31.7113+131.2000/+31.7185+131.1800/+31.7200+131.1764/+31.7254+131.1600/+31.7363+131.1400/+31.7400+131.1336/+31.7442+131.1200/+31.7501+131.1000/+31.7600+131.0801/+31.7600+131.0800/+31.7718+131.0600/+31.7800+131.0506/+31.7846+131.0400/+31.8000+131.0248/+31.8035+131.0200/+31.8200+131.0038/+31.8236+131.0000/+31.8400+130.9827/+31.8413+130.9800/+31.8479+130.9600/+31.8600+130.9464/+31.8612+130.9400/+31.8664+130.9200/+31.8800+130.9063/+31.8811+130.9000/+31.9000+130.8803/+31.9000+130.8800/+31.9019+130.8600/+31.9200+130.8419/+31.9202+130.8400/+31.9400+130.8202/+31.9600+130.8205/+31.9795+130.8400/ 南東 50 宮崎県宮崎市 4520100 宮崎県都城市 4520200 宮崎県日南市 4520400 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県三股町 4534100 宮崎県高原町 4536100 鹿児島県霧島市 4621800 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9544+130.8800/+31.9400+130.8986/+31.9248+130.8800/+31.9212+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 3 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T09:00:00+09:00 2019-02-11T12:00:00+09:00 降灰 70 +31.9796+130.8400/+31.9799+130.8600/+31.9793+130.8800/+31.9671+130.9000/+31.9600+130.9071/+31.9593+130.9200/+31.9511+130.9400/+31.9400+130.9514/+31.9385+130.9600/+31.9233+130.9800/+31.9200+130.9834/+31.9169+131.0000/+31.9000+131.0188/+31.8994+131.0200/+31.8917+131.0400/+31.8800+131.0532/+31.8772+131.0600/+31.8680+131.0800/+31.8600+131.0898/+31.8563+131.1000/+31.8499+131.1200/+31.8400+131.1337/+31.8359+131.1400/+31.8365+131.1600/+31.8271+131.1800/+31.8209+131.2000/+31.8200+131.2029/+31.8157+131.2200/+31.8105+131.2400/+31.8031+131.2600/+31.8000+131.2668/+31.7820+131.2800/+31.7800+131.2826/+31.7669+131.3000/+31.7600+131.3096/+31.7414+131.3000/+31.7400+131.2994/+31.7200+131.2924/+31.7112+131.2800/+31.7090+131.2600/+31.7075+131.2400/+31.7078+131.2200/+31.7080+131.2000/+31.7125+131.1800/+31.7200+131.1653/+31.7216+131.1600/+31.7292+131.1400/+31.7400+131.1275/+31.7430+131.1200/+31.7502+131.1000/+31.7600+131.0905/+31.7686+131.0800/+31.7800+131.0672/+31.7835+131.0600/+31.8000+131.0407/+31.8003+131.0400/+31.8103+131.0200/+31.8200+131.0099/+31.8249+131.0000/+31.8400+130.9838/+31.8413+130.9800/+31.8466+130.9600/+31.8600+130.9456/+31.8608+130.9400/+31.8675+130.9200/+31.8800+130.9075/+31.8807+130.9000/+31.9000+130.8803/+31.9000+130.8800/+31.9008+130.8600/+31.9200+130.8408/+31.9202+130.8400/+31.9400+130.8202/+31.9600+130.8204/+31.9796+130.8400/ 南東 50 宮崎県宮崎市 4520100 宮崎県都城市 4520200 宮崎県日南市 4520400 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県三股町 4534100 宮崎県高原町 4536100 鹿児島県霧島市 4621800 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9536+130.8800/+31.9400+130.8989/+31.9256+130.8800/+31.9212+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 3 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T12:00:00+09:00 2019-02-11T15:00:00+09:00 降灰 70 +31.9796+130.8400/+31.9799+130.8600/+31.9704+130.8800/+31.9600+130.8904/+31.9593+130.9000/+31.9400+130.9196/+31.9398+130.9200/+31.9343+130.9400/+31.9200+130.9547/+31.9173+130.9600/+31.9000+130.9788/+31.8990+130.9800/+31.8873+131.0000/+31.8800+131.0078/+31.8718+131.0200/+31.8600+131.0325/+31.8541+131.0400/+31.8400+131.0552/+31.8358+131.0600/+31.8213+131.0800/+31.8200+131.0817/+31.8076+131.1000/+31.8000+131.1113/+31.7933+131.1200/+31.7825+131.1400/+31.7800+131.1443/+31.7668+131.1600/+31.7600+131.1692/+31.7477+131.1800/+31.7411+131.2000/+31.7400+131.2023/+31.7314+131.2200/+31.7200+131.2333/+31.7073+131.2400/+31.7000+131.2467/+31.6850+131.2600/+31.6800+131.2623/+31.6766+131.2600/+31.6655+131.2400/+31.6645+131.2200/+31.6640+131.2000/+31.6716+131.1800/+31.6800+131.1602/+31.6801+131.1600/+31.6905+131.1400/+31.7000+131.1246/+31.7025+131.1200/+31.7145+131.1000/+31.7200+131.0911/+31.7250+131.0800/+31.7400+131.0656/+31.7427+131.0600/+31.7600+131.0440/+31.7622+131.0400/+31.7797+131.0200/+31.7800+131.0197/+31.7898+131.0000/+31.8000+130.9896/+31.8052+130.9800/+31.8200+130.9643/+31.8217+130.9600/+31.8400+130.9401/+31.8400+130.9400/+31.8483+130.9200/+31.8600+130.9082/+31.8628+130.9000/+31.8800+130.8828/+31.8808+130.8800/+31.9000+130.8608/+31.9002+130.8600/+31.9200+130.8402/+31.9202+130.8400/+31.9400+130.8202/+31.9600+130.8204/+31.9796+130.8400/ 南東 50 宮崎県都城市 4520200 宮崎県日南市 4520400 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県三股町 4534100 宮崎県高原町 4536100 鹿児島県霧島市 4621800 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9511+130.8800/+31.9400+130.8936/+31.9228+130.8800/+31.9208+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 3 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T15:00:00+09:00 2019-02-11T18:00:00+09:00 降灰 70 +31.9796+130.8400/+31.9799+130.8600/+31.9600+130.8799/+31.9599+130.8800/+31.9400+130.8999/+31.9394+130.9000/+31.9200+130.9194/+31.9182+130.9200/+31.9000+130.9382/+31.8948+130.9400/+31.8800+130.9547/+31.8691+130.9600/+31.8600+130.9691/+31.8400+130.9799/+31.8398+130.9800/+31.8200+130.9985/+31.8171+131.0000/+31.8000+131.0158/+31.7933+131.0200/+31.7800+131.0328/+31.7680+131.0400/+31.7600+131.0478/+31.7456+131.0600/+31.7400+131.0683/+31.7258+131.0800/+31.7200+131.0846/+31.7000+131.0959/+31.6939+131.1000/+31.6800+131.1079/+31.6600+131.1171/+31.6553+131.1200/+31.6400+131.1328/+31.6200+131.1339/+31.6027+131.1400/+31.6000+131.1449/+31.5989+131.1400/+31.5967+131.1200/+31.6000+131.1169/+31.6200+131.1043/+31.6235+131.1000/+31.6327+131.0800/+31.6400+131.0748/+31.6522+131.0600/+31.6600+131.0509/+31.6724+131.0400/+31.6800+131.0343/+31.6904+131.0200/+31.7000+131.0113/+31.7200+131.0047/+31.7254+131.0000/+31.7400+130.9859/+31.7450+130.9800/+31.7600+130.9647/+31.7634+130.9600/+31.7800+130.9435/+31.7831+130.9400/+31.8000+130.9235/+31.8036+130.9200/+31.8200+130.9038/+31.8265+130.9000/+31.8400+130.8866/+31.8600+130.8802/+31.8603+130.8800/+31.8800+130.8608/+31.8817+130.8600/+31.9000+130.8417/+31.9200+130.8400/+31.9201+130.8400/+31.9400+130.8202/+31.9600+130.8204/+31.9796+130.8400/ 南東 50 宮崎県都城市 4520200 宮崎県小林市 4520500 宮崎県えびの市 4520900 宮崎県高原町 4536100 鹿児島県曽於市 4621700 鹿児島県霧島市 4621800 鹿児島県志布志市 4622100 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9450+130.8800/+31.9400+130.8850/+31.9254+130.8800/+31.9200+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 3 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T18:00:00+09:00 2019-02-11T21:00:00+09:00 降灰 70 +31.9796+130.8400/+31.9799+130.8600/+31.9600+130.8799/+31.9596+130.8800/+31.9400+130.8996/+31.9200+130.8999/+31.9177+130.9000/+31.9000+130.9174/+31.8800+130.9195/+31.8706+130.9200/+31.8600+130.9303/+31.8400+130.9385/+31.8223+130.9400/+31.8200+130.9423/+31.8000+130.9569/+31.7896+130.9600/+31.7800+130.9692/+31.7600+130.9776/+31.7499+130.9800/+31.7400+130.9890/+31.7200+130.9974/+31.7130+131.0000/+31.7000+131.0164/+31.6898+131.0200/+31.6800+131.0243/+31.6600+131.0304/+31.6400+131.0340/+31.6200+131.0375/+31.6127+131.0400/+31.6000+131.0480/+31.5800+131.0541/+31.5600+131.0586/+31.5400+131.0592/+31.5308+131.0600/+31.5200+131.0614/+31.5000+131.0612/+31.4800+131.0608/+31.4600+131.0601/+31.4595+131.0600/+31.4600+131.0594/+31.4800+131.0443/+31.4812+131.0400/+31.5000+131.0366/+31.5163+131.0200/+31.5200+131.0177/+31.5400+131.0066/+31.5475+131.0000/+31.5600+130.9927/+31.5800+130.9822/+31.5861+130.9800/+31.6000+130.9758/+31.6200+130.9691/+31.6327+130.9600/+31.6400+130.9553/+31.6600+130.9471/+31.6800+130.9428/+31.7000+130.9402/+31.7006+130.9400/+31.7200+130.9254/+31.7400+130.9207/+31.7413+130.9200/+31.7600+130.9029/+31.7675+130.9000/+31.7800+130.8880/+31.8000+130.8809/+31.8031+130.8800/+31.8200+130.8650/+31.8400+130.8609/+31.8487+130.8600/+31.8600+130.8494/+31.8800+130.8411/+31.9000+130.8402/+31.9044+130.8400/+31.9200+130.8244/+31.9400+130.8201/+31.9600+130.8204/+31.9796+130.8400/ 60 宮崎県都城市 4520200 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県曽於市 4621700 鹿児島県霧島市 4621800 鹿児島県志布志市 4622100 鹿児島県大崎町 4646800 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9400+130.8798/+31.9202+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 1 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800 2019-02-11T21:00:00+09:00 2019-02-12T00:00:00+09:00 降灰 70 +31.9797+130.8400/+31.9799+130.8600/+31.9600+130.8799/+31.9586+130.8800/+31.9400+130.8986/+31.9200+130.8996/+31.9000+130.8996/+31.8800+130.8997/+31.8682+130.9000/+31.8600+130.9058/+31.8400+130.9119/+31.8200+130.9141/+31.8000+130.9152/+31.7800+130.9164/+31.7600+130.9171/+31.7400+130.9174/+31.7200+130.9155/+31.7000+130.9140/+31.6800+130.9093/+31.6618+130.9000/+31.6600+130.8989/+31.6400+130.8905/+31.6200+130.8825/+31.6145+130.8800/+31.6200+130.8677/+31.6227+130.8600/+31.6400+130.8499/+31.6600+130.8424/+31.6800+130.8428/+31.6849+130.8400/+31.7000+130.8327/+31.7200+130.8322/+31.7400+130.8306/+31.7600+130.8306/+31.7800+130.8304/+31.8000+130.8304/+31.8200+130.8265/+31.8400+130.8259/+31.8600+130.8237/+31.8800+130.8223/+31.9000+130.8215/+31.9200+130.8204/+31.9400+130.8201/+31.9600+130.8203/+31.9797+130.8400/ 40 宮崎県都城市 4520200 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県曽於市 4621700 鹿児島県霧島市 4621800 小さな噴石の落下 75 1 +31.9588+130.8600/+31.9400+130.8789/+31.9206+130.8600/+31.9400+130.8412/+31.9588+130.8600/ 南東 1 宮崎県小林市 4520500 宮崎県えびの市 4520900 鹿児島県霧島市 4621800  現在、霧島山(えびの高原(硫黄山)周辺)は噴火警戒レベル2(火口周辺規制)です。霧島山(えびの高原(硫黄山)周辺)で噴火が発生した場合には、11日09時から12時までは火口から南東方向、11日21時から24時までは火口から南方向に降灰が予想されます。  11日6時から11日24時までに噴火が発生した場合には、以下の方向・距離に降灰及び小さな噴石の落下が予想されます。    時刻            火口からの方向 降灰の距離 小さな噴石の距離  11日06時から09時まで 南東      50km  3km       11日09時から12時まで 南東      50km  3km       11日12時から15時まで 南東      50km  3km       11日15時から18時まで 南東      50km  3km       11日18時から21時まで 南       60km  1km       11日21時から24時まで 南       40km  1km         期間中に噴火が発生した場合には、以下の市町村に降灰が予想されます。  宮崎県 :小林市、えびの市、宮崎市、都城市、日南市、三股町、高原町  鹿児島県:霧島市、曽於市、志布志市、大崎町    噴煙が火口縁上1000mまで上がった場合の火山灰及び小さな噴石の落下範囲を示しています。  噴火発生時、小さな噴石の落下が予想される範囲内では、屋内や頑丈な屋根の下などに移動してください。   PK![jma_feed/tests/test_feed.pyfrom jma_feed.feed import AtomFeed def describe_feed(): def test_id(expect, feed_samples): feed_sample = feed_samples[0] feed = AtomFeed(feed_sample) expect(feed.id) == 'urn:uuid:4e2e12c8-4601-3c0f-8c8a-75cc83dcf6ac' def test_title(expect, feed_samples): feed_sample = feed_samples[0] feed = AtomFeed(feed_sample) expect(feed.title) == '高頻度(定時)' def test_entry_id(expect, feed_samples): feed_sample = feed_samples[0] feed = AtomFeed(feed_sample) entry = feed.entries[0] expect(entry.id) == 'urn:uuid:d25c00b2-c23d-313c-830b-201eb7ada516' def test_entry_link(expect, feed_samples): feed_sample = feed_samples[0] feed = AtomFeed(feed_sample) entry = feed.entries[-1] expect( entry.link ) == 'http://www.data.jma.go.jp/developer/xml/data/352ef0d9-4f5d-36c7-bf0d-f2ffcc31c4e0.xml' PK!]\?xjma_feed/tests/test_report.pyfrom jma_feed.report import Report def describe_feed(): def test_mete1_report_control(expect, report_samples): report_sample = report_samples[0] report = Report(report_sample) expect(report.control.title) == '府県天気概況' expect(report.control.status) == '通常' def test_mete2_report_control(expect, report_samples): report_sample = report_samples[1] report = Report(report_sample) expect(report.control.title) == '気象警報・注意報' expect(report.control.editorial_office) == '和歌山地方気象台' def test_seis1_report_control(expect, report_samples): report_sample = report_samples[2] report = Report(report_sample) expect(report.control.title) == '震源・震度に関する情報' expect(report.control.date_time) == '2019-02-10T00:57:21Z' def test_volc1_report_control(expect, report_samples): report_sample = report_samples[3] report = Report(report_sample) expect(report.control.title) == '降灰予報(定時)' expect(report.control.publishing_office) == '気象庁地震火山部' def test_mete1_report_head(expect, report_samples): report_sample = report_samples[0] report = Report(report_sample) expect(report.head.title) == '天気概況' expect(report.head.info_type) == '発表' expect(report.head.headline_text) == '千葉県では、11日朝から11日昼過ぎまで大雪や電線等への着雪に注意してください。' def test_mete2_report_head(expect, report_samples): report_sample = report_samples[1] report = Report(report_sample) expect(report.head.info_kind) == '気象警報・注意報' expect(report.head.headline_information_list[0].type) == '気象警報・注意報(府県予報区等)' expect(report.head.headline_information_list[0].items[0].areas[0].name) == '和歌山県' def test_seis1_report_head(expect, report_samples): report_sample = report_samples[2] report = Report(report_sample) expect(report.head.report_date_time) == '2019-02-10T09:57:00+09:00' expect(report.head.serial) == '1' def test_volc1_report_head(expect, report_samples): report_sample = report_samples[3] report = Report(report_sample) expect(report.head.info_kind_version) == '1.1_0' expect(report.head.headline_information_list[0].items[0].areas_code_type) == '火山名' expect(report.head.headline_information_list[0].items[0].kinds[0].name) == '降灰予報(定時)' def test_mete1_report_body(expect, report_samples): report_sample = report_samples[0] report = Report(report_sample) expect(report.body.target_area.code) == '120000' def test_mete2_report_body(expect, report_samples): report_sample = report_samples[1] report = Report(report_sample) expect(report.body.warnings[0].items[0].change_status) == '警報・注意報種別に変化有' expect(report.body.warnings[-1].items[-1].kinds[-1].name) == '強風注意報' def test_seis1_report_body(expect, report_samples): report_sample = report_samples[2] report = Report(report_sample) expect(report.body.earthquakes[0].arrival_time) == '2019-02-10T09:54:00+09:00' expect(report.body.earthquakes[0].hypocenter.area.name) == '岩手県沖' expect(report.body.comments.forecast_comment.text) == 'この地震による津波の心配はありません。' def test_volc1_report_body(expect, report_samples): report_sample = report_samples[3] report = Report(report_sample) expect(report.body.volcano_infos[0].items[-1].kind.name) == '降灰予報(定時)' expect(report.body.ash_infos[-1].start_time) == '2019-02-11T21:00:00+09:00' expect(report.body.ash_infos[-1].items[-1].areas[0].name) == '宮崎県小林市' PK!"|+jma_feed/xml.pyimport urllib.error import urllib.request import xml.etree.ElementTree as ET class XmlDocument: """Model class which represents XML document / element.""" def __init__(self, target, ns_map): """Initialize class. Args: target (ElementTree.Element or str): XML element or URL """ self.ns_map = ns_map if isinstance(target, ET.Element): self.root = target elif isinstance(target, str): try: self.root = ET.fromstring(target) except ET.ParseError: try: xml_text = urllib.request.urlopen(target).read() self.root = ET.fromstring(xml_text) except (urllib.error.URLError, urllib.error.HTTPError): raise ValueError('target string must be valid URL or XML string.') else: raise ValueError('target parameter can take only Element or URL or XML string.') def _find_element(self, *xpaths): for xpath in xpaths: element = self.root.find(xpath, self.ns_map) if element is not None: return xpath, element return (None, None) def _find_elements(self, *xpaths): for xpath in xpaths: elements = self.root.findall(xpath, self.ns_map) if elements: return xpath, elements return (None, None) def _element(self, xpath): return self.root.find(xpath, self.ns_map) def _elements(self, xpath): return self.root.findall(xpath, self.ns_map) def _element_text(self, xpath): element = self._element(xpath) if element == None: return None return element.text def _element_attr(self, xpath, attr_name): element = self._element(xpath) if element == None: return None return element.get(attr_name) PK!F$BB#jma_feed-0.9.0.dist-info/LICENSE.md**The MIT License (MIT)** Copyright © 2019, Tomohiro Murota Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!HڽTUjma_feed-0.9.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!Hp: %!jma_feed-0.9.0.dist-info/METADATAZݏGyC\>LJ|dqLnf=k/OŀHy@l#9XXgG(~~U534kL*.>uOn;`̳r99 *'}7#,Gd $AQۺ,֍􍴎T׋&")n2W. @w>9q)N,)>)H]XV%S]f}o.T)> _dc(=hcE}=!x#bvF3uƮ\dBps5v#&`4 z,b_+=) UxKK8\>4Ő~~w=ݫp8d ,"hadAS2{4#u~(X#(;oJgիbN3r1!BpB@8& U1Exqf9_>::N9 %e`9I_b:>W:6;@8qJPd*PDB P"ЗMB2%/`BI˶ѱvemd̵0mHx"pp(l gi;@,tGi&KKAX4E()$=tKJL1%1)ukXadCtb,9eȅm*qҵnʭk-e<0'+GsP+b .,LhPa2dWubN`;Vhsj-& +nMP뱸k$F iVǒV|l5H kCʶ6L 2ST3j$a{loi %`#9q41l_uT($:aO:ursX :s%UZWBXE}pW+_\ճ飧OY?ynWͦ>~=|IΦqwGO>b˛C"v-71_w L[_Sm~RMe$~3ʴT]|Ho(Ki|$⨊x:` frL>hI2ZbyIx;uZjN}3hBMkyxp?PK!HFQjma_feed-0.9.0.dist-info/RECORDɒJ}? $.IQaC0$2ϓqr 5r$B]isj;Zѭg炐Ύ܌ >l"@ѓZI\0M4!e{ql+ZztC`A2㵵VRy--dw앰Xfi%Gh{T g 5Q́XP {º[̽s"ɱΆO UǿPK!.Y\ jma_feed/__init__.pyPK!%} jma_feed/feed.pyPK!Dg3G3G jma_feed/report.pyPK!ޙPb""lYjma_feed/tests/__init__.pyPK!4dUJJYjma_feed/tests/conftest.pyPK!$H_jma_feed/tests/resources/__init__.pyPK! ET~~)_jma_feed/tests/resources/sample_mete1.xmlPK!=eyLL)Ogjma_feed/tests/resources/sample_mete2.xmlPK!=O{{+`jma_feed/tests/resources/sample_regular.xmlPK!P P )$jma_feed/tests/resources/sample_seis1.xmlPK!|cdd)jma_feed/tests/resources/sample_volc1.xmlPK![ =jma_feed/tests/test_feed.pyPK!]\?x@jma_feed/tests/test_report.pyPK!"|+Pjma_feed/xml.pyPK!F$BB#Xjma_feed-0.9.0.dist-info/LICENSE.mdPK!HڽTU]jma_feed-0.9.0.dist-info/WHEELPK!Hp: %!]jma_feed-0.9.0.dist-info/METADATAPK!HFQgjma_feed-0.9.0.dist-info/RECORDPKaj