| 82 | |
| 83 | |
| 84 | def parse_page( |
| 85 | page: int, api_key: str, text: str, min_date: float, max_date: float |
| 86 | ) -> tuple[dict[str, str], tuple[dict[str, str], ...]]: |
| 87 | f: urllib2.urlopen | None = None |
| 88 | for _ in range(MAX_PAGE_REQUESTS): |
| 89 | try: |
| 90 | f = urllib2.urlopen( |
| 91 | compose_url(page, api_key, text, min_date, max_date), |
| 92 | timeout=MAX_PAGE_TIMEOUT, |
| 93 | ) |
| 94 | except TimeoutError: |
| 95 | continue |
| 96 | else: |
| 97 | break |
| 98 | |
| 99 | if f is None: |
| 100 | return { |
| 101 | "pages": "0", |
| 102 | "total": "0", |
| 103 | "page": "0", |
| 104 | "perpage": "0", |
| 105 | }, tuple() |
| 106 | |
| 107 | response = f.read() |
| 108 | root = ElementTree.fromstring(response) |
| 109 | |
| 110 | if root.attrib["stat"] != "ok": |
| 111 | raise OSError |
| 112 | |
| 113 | metadata = root.find("photos") |
| 114 | assert metadata is not None |
| 115 | |
| 116 | photos = tuple(photo.attrib for photo in root.iter("photo")) |
| 117 | |
| 118 | return metadata.attrib, photos |
| 119 | |
| 120 | |
| 121 | class PhotoDownloader: |