o2o-site-AEO/solution/site/scripts/mockup/build_reading.py
Mina Choi 5e2def200b [chore] site/mockup: 번들 갱신·문서 정리 · 2안(사진) 빌더 스크립트 추가
- vendor/ 옛 해시 번들을 retired/ 로 옮기고 새 해시로 교체
- build_photo6.py 신설 — /s/stay6 "2안(사진)" 판, 슬러그별로 다시 구울 수 있다
  (python3 build_photo6.py <slug>)
- build_pension.py·build_reading.py·build_stay6.py·patch_stay.py 정리
- AUTOPLAY.md·README.md·audit-all.mjs 갱신
2026-09-23 13:18:51 +09:00

382 lines
30 KiB
Python

"""군산 읽기 — 이 도시를 갈래로 묶어 카로셀로 보여주는 소재 더미.
★ 왜 만들었나 (2026-09-14 대표 의견: "오늘의 한 장으로 군산을 소개하기는 무리다,
하루에 하나씩밖에 안 알려 주니까 — 엑셀을 보고 다시 짜라")
일력(`build_daily.py`)은 오늘·어제·내일 **세 장만** 화면에 선다. 나머지는 문서에만 남아
검색·AI 는 읽어도 손님은 못 본다. 도시를 소개하는 자리로는 그릇이 작다.
그래서 받은 자료(`gunsan_365_story_db.xlsx`)의 주제를 **갈래로 묶는다.**
일력은 그대로 두되, 이제 '매일 바뀌는 한 장' 이지 소개 자리가 아니다.
★ 화면 구성은 이 파일이 정하지 않는다 — **payload 는 갈래 전체를 그대로 담고**,
'한 화면에 몇 개를 어떻게 보여줄지' 는 `inject.js` `startReading()` 이 정한다.
처음엔 31개를 전부 세로로 펼쳤는데 "스크롤 압박" 이 됐다(같은 날 대표 의견) —
갈래마다 3~4개를 무작위로 뽑아 카로셀 하나로 붙이는 방식을 거쳐, 지금은
**갈래를 가리지 않고 전체에서 5~6개만 무작위로** 뽑는다(2026-09-14 대표: "34개중
15~19개인데 왜 34개라고 써놔?""그냥 5-6개 정도만 보여주는거 어때?""랜덤으로").
이 파일은 후보 전체를 만들 뿐이고, 추리고 섞고 세우는 일은 화면 쪽 책임이다.
★ **꼭지 수는 확인되는 사실만큼이다** — 채우려고 지어내지 않는다(레포 절대 규칙).
인물 57 · 가요 25 처럼 이 목록도 출처를 댈 수 있는 것까지가 한계다. 2026-09-14 기준 34가지.
★ 엑셀 52주제를 그대로 옮기지 않는다 — **이미 이 페이지에 선 것은 뺀다.**
· 인물 35주제 → `people` 57명이 이미 레일로 다 보인다
· 대중가요 21주제 → `songs` 25곡
· 축제 14주제 → `local.festivals` 10개
· 진포대첩·개항·세관·부잔교·『탁류』 연재·하굿둑·새만금 → `chronicle` 연표 7건
· 히로쓰 가옥·초원사진관·근대미술관·철길마을·우체통거리 등 → `local.attractions` 12곳
· 이성당·짬뽕집 → `local.restaurants` 31곳
같은 것을 두 번 세우면 페이지만 길어지고 손님은 같은 말을 두 번 읽는다.
**남은 것**이 여기 선다 — 문학 · 섬과 바다 · 역사 · 장소 · 음식과 생활, 2026-09-14 기준 34가지.
★ 엑셀의 문장을 그대로 쓰지 않는다. 한 주제를 운영 슬롯 7가지로 복제해 둔 시드라
"…를 소개한다" 로 끝나는 **우리끼리 쓰는 메모**다. 여기 문장은 손님이 읽는 말로 다시 썼다.
★ 2026-09-14 대표: "내용이 너무 적다, 특히 2줄인 것들은 최소 3~5줄로." 두 문장짜리
21꼭지를 네 문장으로 늘렸다 — 새로 보탠 문장은 널리 알려진 배경 설명이고, 없는 숫자를
지어내지는 않는다.
★ 2026-09-14 대표: "확인필요 없애고 링크는 네이버 링크로." 기관·위키 링크를 항목마다
따로 골라 달던 방식을 접고, **네이버 검색 링크 하나**로 통일했다(`naver()`).
개별 문서 URL(`terms.naver.com/entry.naver?docId=...`)은 짐작해서 적으면 없는 문서로
이어질 위험이 있어(레포 절대 규칙: 없는 사실은 안 짓는다) 쓰지 않는다 — 검색 링크는
제목을 그대로 넘기니 항상 관련 결과로 뜬다. 이 결정과 함께 '확인/확인필요' 구분도
화면·데이터 양쪽에서 뺐다.
★ 렌더러에는 이 섹션이 없다. 목업이라 **주입분(`inject.js` `startReading()`)이 그린다** —
렌더러를 고치면 전 사이트 재굽기가 따라온다(README 2.1). 제품으로 옮길 자리는 README 1.3.
입력: stay-payload-new.json (build_story.py 뒤)
출력: 같은 파일에 `reading` 섹션을 넣는다. 화면은 `inject.js` 가 그린다.
"""
import json
from pathlib import Path
from urllib.parse import quote
SP = Path(__file__).parent
SRC = SP / "stay-payload-new.json"
def naver(title):
"""개별 항목마다 실제 문서를 골라 링크하지 않는다 — 검색 링크 하나로 통일해서
'없는 문서를 짐작해 적는' 위험을 아예 없앤다(위 파일 머리 설명)."""
query = title if "군산" in title else f"{title} 군산"
return {"name": "네이버에서 찾아보기",
"url": "https://search.naver.com/search.naver?query=" + quote(query)}
# 갈래 — 화면에 이 순서로 선다.
GROUPS = [
("문학", "이 도시를 쓴 사람과 그 자리"),
("인물", "이 도시가 낳은 사람들"),
]
KEEP = {"문학", "인물"}
# (갈래, 제목, 글, 연도 또는 None)
# ★ 원문을 옮기지 않는다 — 시·소설·가사의 본문은 한 줄도 싣지 않고 제목과 배경만 쓴다.
ITEMS = [
# ── 문학 8 ────────────────────────────────────────────────────────────
("문학", "채만식 『탁류』",
"일제강점기 군산을 무대로 한 장편소설입니다. 쌀을 사고팔던 미두장을 중심으로, "
"가족을 지키려던 초봉이 시대의 소용돌이에 휩쓸려 무너지는 과정을 그렸습니다. "
"금강 하구의 흙탕물이라는 제목처럼, 개항장 군산의 실제 지명과 풍경 위에 이야기가 "
"펼쳐집니다.", 1937),
("문학", "백릉 채만식",
"1902년 옥구(지금의 군산) 임피에서 태어난 소설가입니다. 호는 백릉이고, 잡지에 "
"작품을 발표하며 문단에 나서 세태를 꼬집는 풍자 소설로 이름을 알렸습니다. "
"광복 뒤에는 고향 인근에 머물다 1950년 세상을 떠났습니다.", 1902),
("문학", "채만식문학관",
"금강 하구 옆, 작가가 나고 자란 임피 인근에 선 문학관입니다. 생애를 따라가는 "
"전시실과 『탁류』를 비롯한 작품의 여러 판본을 한자리에서 볼 수 있습니다. "
"군산이 낳은 다른 작가·시인을 소개하는 자리도 함께 있습니다.", None),
("문학", "『탁류』라는 제목",
"금강 하류의 흙탕물을 가리키는 말이자, 그 물살에 휩쓸려 가는 사람들을 함께 "
"가리키는 이중의 제목입니다. 맑았던 강물이 하구에 이르러 흐려지듯, 소설 속 "
"인물들도 도시의 욕망 앞에서 하나씩 무너져 갑니다. 신문에 회를 나눠 연재된 "
"소설이라, 그 시절 독자들은 다음 이야기를 기다리며 읽었습니다. 제목 하나에 "
"배경과 줄거리를 함께 담은 셈이라, 채만식문학관에서도 이 제목의 뜻부터 설명을 "
"시작합니다.", None),
("문학", "채만식의 풍자",
"웃기면서 찌르는 문장이 이 작가의 방식입니다. 『레디메이드 인생』·『태평천하』 같은 "
"다른 대표작에서도 이어지는 태도로, 식민지 도시의 부조리를 인물의 우스꽝스러운 "
"말과 행동으로 드러냅니다. 개항장 군산에서 본 것이 그 풍자의 바탕에 있습니다.",
None),
("문학", "탁류길",
"소설 속 공간을 실제 걷는 길로 이은 군산 스탬프투어 코스입니다. 미두장이 있던 "
"자리와 째보선창, 부잔교를 차례로 지나며 소설의 배경을 몸으로 확인합니다. "
"원도심 구간이라 머뭄에서 걸어 닿습니다.", None),
("문학", "조정래 『아리랑』과 아리랑길",
"구한말부터 광복까지, 만경강 들녘 농민들이 수탈에 맞서는 이야기를 그린 대하소설입니다. "
"군산·김제 일대가 무대라 스탬프투어에도 같은 이름의 코스가 있습니다. 여러 권에 "
"걸친 긴 이야기라, 한 도시가 아니라 호남평야 들녘 전체를 무대로 다룹니다. 아리랑길은 "
"실제 그 들녘과 마을 길을 따라 걷도록 짜여 있어, 소설이 그린 풍경을 걸음으로 "
"확인할 수 있습니다.", None),
("문학", "군산이 낳은 시인들",
"고은 · 이병훈 · 심호택 · 문효치 · 이연주 · 주하림. 일제강점기부터 지금까지 세대를 "
# ★ "아래 카드" 가 아니다 (2026-09-14 대표 지적). '인물 열전' 은 이 꼭지와 **형제 탭**이라
# 같은 줄 위쪽에 서 있다 — 아래로 내려가면 없다. 위치를 가리키는 말을 아예 뺀다:
# 탭 차림은 화면 폭과 탭 수에 따라 줄이 바뀌어서, 어느 방향으로도 단정하면 틀린다.
"이어 시인이 나온 도시입니다. 이름만으로는 알기 어려워, '인물 열전' 탭에서 "
"한 사람씩 생애와 활동을 봅니다.", None),
# ── 인물 22 ───────────────────────────────────────────────────────────
# ★ 2026-09-18 대표: "'군산 읽기'는 인물·문학만 담아 랜덤 대신 전체 노출하고
# 약 30개로 추린다." 인물 열전(57명)은 한 줄짜리 레일이라 읽을 거리가 못 된다 —
# 여기서는 사람마다 세 문장 안쪽으로 **읽는 글**로 세운다.
# ★ 확인되는 것만 적는다. 사람은 살아 있는 이가 많아 더 위험하다 — 출생연도·직업·
# 대표 이력처럼 널리 알려진 것만 쓰고, 일화나 숫자는 보태지 않는다.
("인물", "채만식을 잇는 이름들",
"군산은 소설가 채만식만 낳은 도시가 아닙니다. 시인 고은과 이병훈·심호택·문효치·"
"이연주·주하림이 이 도시에서 나고 자랐고, 언어학자 김선기와 철학자 고형곤도 "
"여기 사람입니다. 문학과 학문 쪽 이름이 유난히 촘촘한 도시입니다.", None),
("인물", "김선기",
"1907년 군산에서 태어난 언어학자입니다. 호는 무돌이고, 한글과 국어 연구에 "
"힘쓴 학자이자 교육자였습니다. 1992년에 세상을 떠났습니다.", 1907),
("인물", "고형곤",
"1906년 군산에서 태어난 철학자입니다. 선(禪)을 철학으로 풀어낸 연구로 알려졌고 "
"대학에서 오래 가르쳤습니다. 아들은 국무총리를 지낸 고건입니다.", 1906),
("인물", "고건",
"1938년 군산에서 태어난 행정가입니다. 서울시장을 지냈고 제30·35대 국무총리를 "
"두 차례 맡았습니다. 아버지가 철학자 고형곤이라, 한 집에서 학문과 행정이 "
"갈라져 나온 셈입니다.", 1938),
("인물", "임병찬",
"1851년 옥구(지금의 군산)에서 태어난 구한말 의병장입니다. 1906년 최익현과 함께 "
"전북 태인에서 거병했고, 붙잡혀 대마도로 유배됐습니다. 돌아온 뒤 다시 독립운동을 "
"이어 가다 거문도에 갇혀 단식 끝에 순국했습니다.", 1851),
("인물", "이수현",
"1895년 군산에서 태어난 독립운동가입니다. 호는 산남이고, 일제강점기 내내 "
"독립운동에 힘썼습니다.", 1895),
("인물", "반석평",
"조선 중종 때 문신입니다. 노비의 신분에서 학문을 익혀 문과에 급제하고 판서에 "
"올랐습니다. 신분이 사람의 끝을 정하던 시대에 드문 이력이라, 군산이 꼽는 "
"옛 인물 가운데 앞자리에 섭니다.", 1472),
("인물", "이길여",
"1932년 옥구(지금의 군산)에서 태어난 의료인입니다. 인천에 산부인과를 열어 "
"병원을 키웠고, 그 병원이 지금의 가천대 길병원입니다. 가천대학교를 세워 "
"총장을 맡고 있습니다.", 1932),
("인물", "강봉균",
"1943년 군산에서 태어난 경제 관료입니다. 재정경제부 장관을 지냈고 군산에서 "
"3선 국회의원을 했습니다. 2017년에 세상을 떠났습니다.", 1943),
("인물", "김관영",
"1969년 군산에서 태어났습니다. 회계사와 변호사를 거쳐 국회의원을 지냈고, "
"지금은 전북특별자치도지사입니다.", 1969),
("인물", "김의겸",
"1963년 군산에서 태어난 언론인입니다. 신문 기자로 오래 일하다 청와대 대변인을 "
"맡았고, 뒤에 국회의원이 됐습니다.", 1963),
("인물", "최길선",
"1946년 군산에서 태어난 조선업 경영인입니다. 현장에서 시작해 현대중공업 "
"회장까지 올랐습니다.", 1946),
("인물", "김수미",
"1949년 군산에서 태어난 배우입니다. 드라마 「전원일기」의 일용 엄니로 오래 "
"기억되고, 뒤에는 영화와 예능에서도 활동했습니다. 2024년에 세상을 떠났습니다.", 1949),
("인물", "송새벽",
"1979년 군산에서 태어난 배우입니다. 연극 무대를 거쳐 영화로 옮겨 왔고, 특유의 "
"말투와 표정으로 알려졌습니다.", 1979),
("인물", "박화요비",
"1982년 군산에서 태어난 가수입니다. R&B 를 주로 부르며 방송과 무대에서 오래 "
"활동해 왔습니다.", 1982),
("인물", "박경완",
"1972년 군산에서 태어난 야구 포수입니다. SK 와이번스에서 오래 뛰며 한국 야구를 "
"대표하는 포수로 꼽혔고, 은퇴 뒤에는 코치로 일했습니다.", 1972),
("인물", "차우찬",
"1987년 군산에서 태어난 야구 투수입니다. 삼성과 LG 에서 뛰었고 지금은 해설위원 "
"으로 경기를 중계합니다.", 1987),
("인물", "오지환",
"1990년 군산에서 태어난 야구 선수입니다. LG 트윈스 내야수로 오래 뛰었습니다.", 1990),
("인물", "노상래",
"1970년 군산에서 태어난 축구 선수입니다. 공격수로 뛰었고 은퇴 뒤에는 지도자로 "
"일했습니다.", 1970),
("인물", "박성현",
"1983년 군산에서 태어난 양궁 선수입니다. 군산 소룡초등학교에서 활을 처음 잡아 "
"올림픽 금메달까지 갔습니다. 이 도시에서 나온 가장 널리 알려진 운동 선수 "
"가운데 하나입니다.", 1983),
("인물", "김광선",
"1964년 군산에서 태어난 권투 선수입니다. 1988년 서울 올림픽 복싱 플라이급에서 "
"금메달을 땄습니다.", 1964),
("인물", "한왕용",
"1966년 군산에서 태어난 산악인입니다. 히말라야 8000m 급 14좌를 세계에서 열한 "
"번째로 모두 올랐습니다.", 1966),
("인물", "문호준",
"1997년 군산에서 태어난 프로게이머입니다. 카트라이더 리그에서 가장 많이 우승한 "
"선수로 꼽힙니다.", 1997),
# ── 섬과 바다 6 ───────────────────────────────────────────────────────
("섬과 바다", "고군산군도",
"예순 남짓한 섬이 모인 군도입니다. 새만금 방조제가 육지와 신시도를 잇고, 그 뒤로 "
"무녀도 · 선유도 · 장자도가 다리로 차례로 이어져 차로 들어갈 수 있습니다. "
"섬마다 성격이 달라 하루로는 다 못 봅니다.", None),
("섬과 바다", "선유도",
"고군산군도의 대표 섬입니다. 명사십리라 불리는 백사장을 걷고, 망주봉 아래 해변에서 "
"스카이라인(짚라인)을 탑니다. 대장봉에 오르면 다도해로 지는 해를 한눈에 봅니다. "
"머뭄에서 차로 한 시간 남짓입니다.", None),
("섬과 바다", "장자도",
"선유도와 다리로 이어진 작은 섬입니다. 어선이 드나드는 포구를 끼고 있고, "
"마을 뒤 대장봉으로 오르는 등산로가 여기서 시작합니다. 산길이 가팔라도 길지 "
"않아 왕복 한두 시간이면 오르내릴 수 있습니다. 정상에 서면 고군산군도의 섬들이 "
"바다 위에 늘어선 모습이 한눈에 들어옵니다.", None),
("섬과 바다", "무녀도",
"고군산군도의 섬 하나입니다. 춤추는 무녀의 형상을 닮았다는 이야기가 이름의 유래로 "
"전해지고, 작은 해수욕장이 딸려 있습니다. 신시도에서 선유도로 넘어가는 다리 길목에 "
"있어, 고군산군도를 도는 길에 자연히 거쳐 가게 됩니다. 관광객이 몰리는 선유도보다 "
"한적해, 잠시 차를 세우고 바다를 보기에 좋습니다.", None),
("섬과 바다", "신시도",
"새만금 방조제가 육지와 처음 맞닿는 섬입니다. 고군산군도에서 몸집이 큰 섬 가운데 "
"하나로, 대각산에 오르면 방조제와 인근 섬들이 한눈에 들어옵니다. 방조제 도로를 타고 "
"들어오면 가장 먼저 만나는 섬이라, 고군산군도 여행이 시작되는 자리이기도 합니다. "
"마을과 해변이 함께 있어, 다른 섬으로 건너가기 전에 잠깐 들러 쉬어 가기도 합니다.",
None),
("섬과 바다", "비응항",
"새만금 방조제가 시작하는 항구입니다. 젓갈과 수산물을 파는 상가가 늘어서 있고, "
"서해 관광의 관문으로 씁니다. 어선이 실어 온 수산물이 그날그날 상가로 올라와, "
"싱싱한 해산물을 바로 사거나 맛볼 수 있습니다. 항구 너머로 방조제가 곧게 뻗어 "
"있어, 바다 쪽으로 나가기 전 들르기 좋은 자리입니다.", None),
# ── 역사 7 (연표에 없는 것만) ─────────────────────────────────────────
("역사", "미곡 수탈과 군산항",
"일제강점기 호남평야에서 거둔 쌀이 이 항구로 모여 일본으로 나갔습니다. 부잔교와 "
"그 옆의 대형 창고들이 그 통로였고, 쌀값을 매기던 미두장이 도시 경제의 중심에 "
"있었습니다. 『탁류』가 그 시절 풍경을 그대로 배경 삼았습니다.", None),
("역사", "째보선창",
"내항 옆 선창입니다. 언청이 뱃사공의 사연이 이름의 유래로 전해지고, 『탁류』의 "
"인물들이 오가던 자리이기도 합니다. 지금은 배 대신 낡은 창고가 남았습니다.",
None),
("역사", "해망굴",
"일제강점기에 뚫린 굴로, 시내와 항구를 잇습니다. 차 한 대가 겨우 지날 만큼 좁아 "
"지금은 사람이 걸어서 통과해 반대편 항구 쪽으로 나옵니다. 굴 안은 서늘하고 어둑해 "
"걸어 지나가는 동안 도시의 소리가 잠깐 끊깁니다. 반대편으로 나오면 바로 내항이 "
"보여, 원도심과 항구를 잇는 지름길로 지금도 쓰입니다.", None),
("역사", "경암동 철길",
"1944년에 놓인 철길입니다. 인근 제지공장의 화물을 나르던 산업철도였고, 지금은 "
"열차가 다니지 않지만 선로가 집 앞 골목을 그대로 지나가는 풍경만 남았습니다. "
"선로 양옆으로 집과 가게가 바짝 붙어 있어, 열차가 다니던 시절에는 문을 열면 바로 "
"철길이었습니다. 지금은 옛 교복을 빌려 입고 사진을 찍거나 선로를 따라 걷는 자리로 "
"쓰입니다.", 1944),
("역사", "군산항",
"1899년 개항 이후 근대 산업항으로 자란 항구입니다. 만남과 이별, 물류와 근대사가 "
"한자리에 겹치며 도시의 성격이 여기서 정해졌습니다. 개항 뒤로는 쌀과 물자가 이 "
"항구를 거쳐 오갔고, 그만큼 많은 사람이 들고 났습니다. 지금 원도심에 남은 근대 "
"건축물 대부분이 이 항구를 중심으로 들어선 것들입니다.", 1899),
("역사", "군산 3·5 만세운동",
"1919년 3월 5일, 영명학교 학생들이 중심이 되어 원도심에서 벌인 만세운동입니다. "
"전국 3·1운동이 퍼져 가던 무렵 이 도시가 어떻게 호응했는지를 보여주는 사건입니다. "
"학생들은 미리 태극기와 독립선언서를 준비해 장날에 맞춰 거리로 나섰습니다. 지금도 "
"원도심을 걷다 보면 이 사건을 알리는 표지판과 기록을 곳곳에서 만납니다.", 1919),
("역사", "임피역",
"옛 모습을 그대로 간직한 목조 간이역입니다. 근대 철도 건축의 흔적으로 등록문화재가 "
"됐고, 지금은 열차가 서지 않고 자리만 지킵니다. 작은 대합실과 승강장이 지어질 "
"당시 모습 그대로 남아 있어, 옛 기차역의 분위기를 눈으로 확인할 수 있습니다. "
"원도심에서 조금 떨어져 있어, 차로 이동하는 여정에 잠시 들르기 좋은 자리입니다.",
None),
# ── 장소 10 (주변 명소 12곳에 없는 것만) ──────────────────────────────
("장소", "군산근대역사박물관",
"해양물류의 역사와 근대 생활 풍경을 층별로 나눠 보여주는 박물관입니다. 3층부터 "
"내려오며 항구도시의 근대사를 훑고, 도시를 걷기 전에 여기서 한 번 배경을 "
"잡고 나섭니다. 전시실 안에는 당시 거리와 상점을 재현한 공간도 있어, 사진으로만 "
"보던 풍경을 실제 크기로 걸어 볼 수 있습니다. 원도심 답사의 시작점으로 삼기 좋은 "
"위치라, 관람을 마치고 바로 근처 근대문화유산으로 이어 걷습니다.", None),
("장소", "군산 내항과 부잔교",
"조수 간만의 차가 큰 서해에서 배를 대기 위해 만든 뜬다리(부잔교)입니다. "
"물이 오르내려도 다리 자체가 함께 움직여 배가 늘 수평으로 닿습니다. "
"다리 위를 끝까지 걸어 나갔다 돌아옵니다.", 1926),
("장소", "동국사",
"국내에 남은 몇 안 되는 일본식 사찰 건축입니다. 대웅전 지붕과 마당의 배치에서 "
"일본 사찰 양식이 그대로 드러나, 개항기 흔적을 건물로 보여주는 자리입니다. "
"지금도 실제로 예불을 올리는 절이라, 관람 중에는 조용히 둘러보는 것이 예의입니다. "
"마당의 소철과 종루까지 그 시절 배치가 크게 바뀌지 않아, 사진에 담기 좋은 자리로도 "
"알려져 있습니다.", None),
("장소", "월명공원",
"시내와 바다를 함께 내려다보는 공원입니다. 수시탑과 문인들의 시비가 산책로를 "
"따라 서 있고, 계절마다 오르는 길의 풍경이 달라집니다. 정상 부근까지 차로 오를 "
"수 있어, 가볍게 걷고 싶은 사람과 전망만 보고 싶은 사람 모두에게 맞습니다. 밤에는 "
"시내 불빛이 내려다보여, 낮과는 다른 풍경을 봅니다.", None),
("장소", "은파호수공원",
"호수를 두르는 산책길입니다. 겨울이면 조명을 켠 벚나무 길이 볼거리가 되고, "
"봄에는 같은 길이 벚꽃길로 바뀝니다. 저녁에 한 바퀴 돌기 좋습니다.",
None),
("장소", "금강하굿둑",
"금강과 서해가 만나는 자리에 놓은 둑입니다. 강과 바다의 경계를 사람 손으로 그은 "
"곳이고, 둑 위로 충남 서천과 전북 군산을 잇는 길이 나 있습니다. 둑을 따라 걷거나 "
"차로 건너면서 한쪽은 강물, 다른 한쪽은 바닷물이 나뉘는 모습을 눈으로 확인할 수 "
"있습니다. 철새가 많이 모이는 자리로도 알려져 있어, 계절에 따라 다른 새를 "
"봅니다.", 1990),
("장소", "말랭이마을",
"경사진 언덕을 따라 계단식으로 집이 들어선 마을입니다. 골목 담장마다 그림이 "
"그려져 있고, 도시재생 사업으로 되살아난 자리입니다. 계단과 골목이 좁고 가팔라, "
"걷는 속도를 늦추고 천천히 둘러보게 됩니다. 언덕 위에서는 원도심과 항구 쪽 풍경이 "
"함께 내려다보입니다.", None),
("장소", "장미갤러리",
"근대역사문화거리 안의 전시 공간입니다. 쌀을 쌓아 두던 옛 창고 건물을 고쳐 써서, "
"건물 자체가 그 시절 물류의 흔적입니다. 높은 천장과 두꺼운 벽 같은 창고의 구조를 "
"그대로 살려, 전시 공간이면서 건물 자체도 볼거리입니다. 인근의 다른 근대 건축물과 "
"나란히 있어, 걸어서 함께 둘러보기 좋습니다.", None),
("장소", "진포해양테마공원",
"진포대첩의 기억을 항구 옆에 펼쳐 둔 공원입니다. 퇴역한 군함과 항공기를 실제로 "
"가져다 놓아, 전시장이 아니라 야외에서 크기를 몸으로 느낄 수 있습니다. 고려 말 "
"왜구를 화포로 물리친 진포대첩의 무대가 바로 이 앞바다입니다. 아이와 함께라면 "
"직접 올라타 볼 수 있는 전시물도 있어, 역사 이야기를 몸으로 체험하게 됩니다.",
None),
("장소", "군산예술의전당",
"지역 공연을 올리는 문화 시설입니다. 원도심 답사에서 벗어나 공연 한 편을 함께 "
"일정에 넣고 싶을 때 확인해 볼 자리입니다. 크고 작은 공연장이 함께 있어, 음악회부터 "
"연극까지 다양한 공연이 열립니다. 원도심에서 차로 이동해야 하는 거리라, 일정에 "
"여유가 있을 때 넣기 좋습니다.", None),
# ── 음식과 생활 3 ─────────────────────────────────────────────────────
("음식과 생활", "군산 짬뽕",
"개항 이후 이 도시에 자리 잡은 화교 공동체가 남긴 음식 문화입니다. 빈해원 · "
"국제반점처럼 오래된 중식당이 아직 그 자리를 지키고, 짬뽕 한 그릇에 항구도시의 "
"내력이 담겨 있다고들 말합니다. 항구를 오가던 뱃사람과 노동자들이 빠르고 든든하게 "
"먹을 수 있는 음식으로 자리 잡았다고 전해집니다. 가게마다 국물 색과 맛이 조금씩 "
"달라, 여러 곳을 비교해 먹어 보는 재미도 있습니다.", None),
("음식과 생활", "박대와 군산 밥상",
"서해에서 나는 박대라는 생선을 말려 구워 냅니다. 살이 도톰하고 기름기가 적어 "
"짭조름하게 구우면 밥반찬으로 잘 맞고, 이 지역 백반집 상에 자주 오릅니다. 예전에는 "
"흔해 서민 밥상에 자주 오르던 생선이었다고 전해집니다. 말려서 굽는 조리법이라 "
"오래 두고 먹을 수 있어, 지금도 반찬이나 선물용으로 찾는 사람이 많습니다.", None),
("음식과 생활", "이성당",
"국내에서 손꼽히게 오래된 빵집 가운데 하나입니다. 단팥빵과 야채빵이 대표 메뉴로, "
"갓 나오는 시간에 맞추지 않으면 줄을 서야 할 만큼 찾는 사람이 많습니다. 일제강점기 "
"부터 이어진 자리에서 지금까지 영업을 이어 오고 있어, 군산을 대표하는 오래된 "
"가게로 꼽힙니다. 이른 아침부터 줄이 늘어서는 날이 많아, 여유 있게 들르려면 시간을 "
"넉넉히 잡는 편이 낫습니다.", None),
]
payload = json.loads(SRC.read_text(encoding="utf-8"))
SECTIONS = payload["theme"]["sections"]
ITEMS = [row for row in ITEMS if row[0] in KEEP]
seen = [name for name, _note in GROUPS]
for group, *_rest in ITEMS:
assert group in seen, f"갈래에 없는 이름: {group}"
items = []
for group, title, body, year in ITEMS:
item = {"group": group, "title": title, "body": body, "source": naver(title)}
if year:
item["year"] = year
items.append(item)
# 2026-09-18 대표: "인물·문학만 담아 랜덤 대신 전체 노출하고 약 30개로 추린다."
# 무작위 5~6개를 뽑던 것을 되돌렸다 — 카로셀은 슬라이드 하나 = 꼭지 하나라 전체를 실어도
# 세로로 길어지지 않는다(전에 스크롤 압박이 났던 것은 31꼭지를 한 화면에 펼쳤을 때다).
# 그래서 부제에 개수를 다시 내걸 수 있다 — 화면에 그만큼 다 선다.
env = {"kind": "reading", "version": 1, "title": "군산 읽기",
"subtitle": "이 도시를 쓴 사람과 이 도시가 낳은 사람",
"groups": [{"name": name, "note": note} for name, note in GROUPS],
"items": items}
# 렌더러가 모르는 id 다 — payload 자체에는 이런 섹션이 없다. `#story` 탭 하나로 화면에
# 세우는 일은 inject.js `startReading()` 이 한다(2026-09-14부터, 독립 섹션이 아니라 탭이다).
# 여기 payload 로 두는 이유는 ① 고치는 자리가 스크립트 하나로 모이고 ② 문서(HTML)에 값이 남기 때문이다.
existing = next((s for s in SECTIONS if s["id"] == "reading"), None)
if existing is None:
existing = {"id": "reading", "name": "군산 읽기", "enabled": False, "locked": False}
SECTIONS.insert(next(i for i, s in enumerate(SECTIONS) if s["id"] == "story") + 1, existing)
existing["data"] = json.dumps(env, ensure_ascii=False)
SRC.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")
counts = {name: sum(1 for i in items if i["group"] == name) for name, _ in GROUPS}
print("군산 읽기 " + str(len(items)) + "가지 — "
+ " · ".join(f"{k} {v}" for k, v in counts.items())
+ " (화면에 전부 선다)")