"""Import products, versions, guides, customize, courses, selector, winter-camp, seasonal data.""" import json, os, sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) DATA_DIR = '/opt/gw/hulai-website/data' def load(name): path = os.path.join(DATA_DIR, name) if os.path.exists(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) return None from app.database import SessionLocal db = SessionLocal() # === PRODUCTS === from app.models.product import ProductConfig, ProductVersion, ProductVersionHighlight, SummerCamp, SummerCampPrinciple, SummerCampActivity, SummerCampItinerary, SummerCampFaq, SelectionGuide d = load('products.json') if d and not db.query(ProductConfig).first(): cfg = ProductConfig(narrative=d.get('narrative',''), pricing_philosophy=d.get('pricingPhilosophy')) db.add(cfg) db.flush() for i, v in enumerate(d.get('versions', [])): ver = ProductVersion(config_id=cfg.id, version_id=v['id'], name=v['name'], days=v.get('days'), nights=v.get('nights'), audience=v.get('audience',''), description=v.get('description',''), tag=v.get('tag',''), sort_order=i) db.add(ver) db.flush() for h in v.get('highlights', []): db.add(ProductVersionHighlight(version_id=ver.id, text=h)) # Summer camp sc = d.get('summerCamp') if sc: camp = SummerCamp(config_id=cfg.id, name=sc.get('name',''), positioning=sc.get('positioning',''), days=sc.get('days',0), nights=sc.get('nights',0), sessions_json=sc.get('sessions',{}), difference_from_v9=sc.get('differenceFromV9','')) db.add(camp) db.flush() for p in sc.get('principles', []): db.add(SummerCampPrinciple(camp_id=camp.id, text=p)) for a in sc.get('coreActivities', []): db.add(SummerCampActivity(camp_id=camp.id, text=a)) for it in sc.get('itinerary', []): db.add(SummerCampItinerary(camp_id=camp.id, text=it)) for f in sc.get('faq', []): db.add(SummerCampFaq(camp_id=camp.id, question=f['question'], answer=f['answer'])) # Selection guide sg = d.get('selectionGuide') if sg: db.add(SelectionGuide(config_id=cfg.id, by_vacation_length=sg.get('byVacationLength',[]), by_child_age=sg.get('byChildAge',[]), by_preference=sg.get('byPreference',[]))) print('products imported') # === VERSIONS === from app.models.version import VersionConfig, VersionUpgrade, VersionHighlight, VersionCompare, VersionTimeline, VersionTimelineChange, VersionPhilosophy d = load('versions.json') if d and not db.query(VersionConfig).first(): stats = d.get('stats', {}) quote = d.get('quote', {}) cfg = VersionConfig(stats_iterations=stats.get('iterations',''), stats_years=stats.get('years',''), stats_guests=stats.get('guests',''), quote_text=quote.get('text',''), quote_author=quote.get('author','')) db.add(cfg) db.flush() for i, u in enumerate(d.get('upgrades2026', [])): db.add(VersionUpgrade(config_id=cfg.id, tag=u.get('tag',''), name=u.get('name',''), description=u.get('description',''), reason=u.get('reason',''), sort_order=i)) for i, h in enumerate(d.get('highlights', [])): db.add(VersionHighlight(config_id=cfg.id, label=h.get('label',''), text=h.get('text',''), sort_order=i)) cmp = d.get('compareV8V9') if cmp: db.add(VersionCompare(config_id=cfg.id, headers=cmp.get('headers',[]), rows=cmp.get('rows',[]))) for i, t in enumerate(d.get('timeline', [])): tl = VersionTimeline(config_id=cfg.id, version=t.get('version',''), date=t.get('date',''), title=t.get('title',''), reason=t.get('reason',''), sort_order=i) db.add(tl) db.flush() for c in t.get('changes', []): db.add(VersionTimelineChange(timeline_id=tl.id, type=c.get('type',''), text=c.get('text',''))) for i, p in enumerate(d.get('philosophy', [])): db.add(VersionPhilosophy(config_id=cfg.id, label=p.get('label',''), text=p.get('text',''), sort_order=i)) print('versions imported') # === GUIDES === from app.models.guide import GuideConfig, GuideSection d = load('guides.json') if d and not db.query(GuideConfig).first(): cfg = GuideConfig(page_intro=d.get('pageIntro','')) db.add(cfg) db.flush() for i, s in enumerate(d.get('sections', [])): extra = {k: v for k, v in s.items() if k not in ('id','title','subtitle','icon','content')} db.add(GuideSection(config_id=cfg.id, section_id=s['id'], title=s.get('title',''), subtitle=s.get('subtitle',''), icon=s.get('icon',''), content=s.get('content',''), data=extra if extra else None, sort_order=i)) print('guides imported') # === CUSTOMIZE CONFIG === from app.models.customize_config import CustomizeConfig d = load('customize.json') if d and not db.query(CustomizeConfig).first(): db.add(CustomizeConfig(trust_stats=d.get('trustStats',[]), durations=d.get('durations',[]), activities=d.get('activities',[]), budgets=d.get('budgets',[]), process=d.get('process',[]), contact=d.get('contact',{}))) print('customize imported') # === COURSES === from app.models.courses import CoursesConfig d = load('courses.json') if d and not db.query(CoursesConfig).first(): db.add(CoursesConfig(modules=d.get('modules',[]), age_groups=d.get('ageGroups',[]), faqs=d.get('faq',[]))) print('courses imported') # === SELECTOR === from app.models.selector import SelectorConfig d = load('selector.json') if d and not db.query(SelectorConfig).first(): rules = {} if d.get('scoring'): rules['scoring'] = d['scoring'] if d.get('matchReasons'): rules['matchReasons'] = d['matchReasons'] db.add(SelectorConfig(questions=d.get('questions',[]), rules=rules)) print('selector imported') # === WINTER CAMP === from app.models.winter_camp import WinterCampConfig, WinterCampHotel, WinterCampItinerary, WinterCampFaq d = load('winter-camp.json') if d and not db.query(WinterCampConfig).first(): cfg = WinterCampConfig(name=d.get('name',''), positioning=d.get('positioning',''), days=d.get('days',0), nights=d.get('nights',0), max_families=d.get('maxFamilies',0), total_sessions=d.get('totalSessions',0), age_range=d.get('ageRange',''), deposit=d.get('deposit',''), season=d.get('season',''), route=d.get('route',''), why_hulunbuir=d.get('whyHulunbuir',''), closing_note=d.get('closingNote',''), photographer=d.get('photographer',{}), winter_clothing=d.get('winterClothing',{}), camp_advantages=d.get('campAdvantages',[]), service_config=d.get('serviceConfig',[]), camp_essentials=d.get('campEssentials',[])) db.add(cfg) db.flush() for i, h in enumerate(d.get('hotels', [])): db.add(WinterCampHotel(name=h['name'], star=h.get('star',''), nights=h.get('nights',0), description=h.get('description',''), sort_order=i)) for i, day in enumerate(d.get('itinerary', [])): db.add(WinterCampItinerary(day=day.get('day',i+1), title=day.get('title',''), summary=day.get('summary',''), highlights=day.get('highlights',[]), hotel=day.get('hotel',''), sort_order=i)) for i, f in enumerate(d.get('faq', [])): db.add(WinterCampFaq(question=f.get('q',''), answer=f.get('a',''), sort_order=i)) print('winter-camp imported') # === SEASONAL PRODUCTS (autumn + winter) === from app.models.seasonal_product import SeasonalProductConfig, SeasonalProductVersion, SeasonalProductHighlight, SeasonalProductTimeline for season, filename in [('autumn', 'autumn-products.json'), ('winter', 'winter-products.json')]: d = load(filename) if d and not db.query(SeasonalProductConfig).filter_by(season=season).first(): cfg = SeasonalProductConfig(season=season, brand_name=d.get('brand',''), version_label=d.get('version',''), season_label=d.get('season',''), narrative=d.get('narrative',''), style=d.get('style',''), selection_guide=d.get('selectionGuide')) db.add(cfg) db.flush() for i, v in enumerate(d.get('versions', [])): db.add(SeasonalProductVersion(season=season, version_id=v['id'], name=v['name'], days=v.get('days'), nights=v.get('nights'), tag=v.get('tag',''), line=v.get('line',''), route=v.get('route',''), audience=v.get('audience',''), description=v.get('description',''), highlights=v.get('highlights',[]), itinerary=v.get('itinerary',[]), sort_order=i)) for cat_key, cat_name in [('highlights','shared'), ('southHighlights','south'), ('northHighlights','north')]: for i, h in enumerate(d.get(cat_key, [])): db.add(SeasonalProductHighlight(season=season, category=cat_name, title=h.get('title',''), description=h.get('description',''), sort_order=i)) for i, t in enumerate(d.get('timeline', [])): db.add(SeasonalProductTimeline(season=season, version=t.get('version',''), date=t.get('date',''), title=t.get('title',''), changes=t.get('changes',[]), reason=t.get('reason',''), sort_order=i)) print(f'{season}-products imported') # === CALENDAR === from app.models.calendar import CalendarMonth d = load('calendar.json') if d and not db.query(CalendarMonth).first(): months = d.get('months', d) if isinstance(d, dict) else d if isinstance(months, list): for m in months: db.add(CalendarMonth(year=m.get('year',2026), month=m.get('month',1), title=m.get('title',''), weather=m.get('weather',''), clothing=m.get('clothing',''), events=m.get('events',[]))) print('calendar imported') elif isinstance(months, dict) and 'months' in months: for m in months['months']: db.add(CalendarMonth(year=m.get('year',2026), month=m.get('month',1), title=m.get('title',''), weather=m.get('weather',''), clothing=m.get('clothing',''), events=m.get('events',[]))) print('calendar imported') db.commit() print('=== All product data imported ===') db.close()