Introduce model/ and repository/ structure under lib/

Models: Message, WikiPage, Game (typed structs instead of raw hashes)
Repositories: MessageBoard, OnlineUsers, WikiClient, CatalogClient
bbs.rb uses attribute access (page.title, game.play_path, …) throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 09:37:57 +02:00
parent 75d1063572
commit 6856b073f6
8 changed files with 68 additions and 38 deletions

21
lib/model/game.rb Normal file
View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
class Game
attr_reader :title, :platform, :author, :desc,
:play_path, :download_path, :source_path, :docs_path,
:release_count
def initialize(entry)
sw = entry['software'] || {}
latest = entry['latestRelease'] || {}
@title = sw['title'].to_s
@platform = sw['platform'].to_s
@author = sw['author'].to_s
@desc = sw['desc'].to_s
@play_path = latest['htmlFolderPath'].to_s
@download_path = latest['cartridgePath'].to_s
@source_path = latest['sourcePath'].to_s
@docs_path = latest['docsFolderPath'].to_s
@release_count = (entry['releases'] || []).length
end
end

3
lib/model/message.rb Normal file
View File

@@ -0,0 +1,3 @@
# frozen_string_literal: true
Message = Struct.new(:timestamp, :username, :text)

3
lib/model/wiki_page.rb Normal file
View File

@@ -0,0 +1,3 @@
# frozen_string_literal: true
WikiPage = Struct.new(:id, :path, :title, :description, :created_at, :locale, keyword_init: true)

View File

@@ -3,6 +3,7 @@
require 'net/http'
require 'json'
require 'uri'
require_relative '../model/game'
class CatalogClient
API_URL = 'https://games.teletype.hu/api/software'
@@ -14,8 +15,9 @@ class CatalogClient
http.use_ssl = uri.scheme == 'https'
http.open_timeout = 12
http.read_timeout = 12
data = JSON.parse(http.get(uri.path).body)
data.is_a?(Hash) ? (data['softwares'] || []) : data
data = JSON.parse(http.get(uri.path).body)
entries = data.is_a?(Hash) ? (data['softwares'] || []) : data
entries.filter_map { |e| Game.new(e) if e.is_a?(Hash) }
rescue => e
warn "Catalog fetch error: #{e}"
[]

View File

@@ -3,10 +3,9 @@
require 'csv'
require 'time'
require 'fileutils'
require_relative '../model/message'
class MessageBoard
Message = Struct.new(:timestamp, :username, :text)
def initialize(path)
@path = path
@messages = []
@@ -36,9 +35,7 @@ class MessageBoard
def load_csv
return unless File.exist?(@path)
CSV.foreach(@path) do |row|
@messages << Message.new(*row)
end
CSV.foreach(@path) { |row| @messages << Message.new(*row) }
rescue => e
warn "MessageBoard load error: #{e}"
end

View File

@@ -3,6 +3,7 @@
require 'net/http'
require 'json'
require 'uri'
require_relative '../model/wiki_page'
class WikiClient
BASE_URL = 'https://wiki.teletype.hu'
@@ -17,7 +18,16 @@ class WikiClient
id path title description createdAt locale
}}}
GQL
graphql(query).dig('data', 'pages', 'list') || []
(graphql(query).dig('data', 'pages', 'list') || []).map do |p|
WikiPage.new(
id: p['id'],
path: p['path'],
title: p['title'],
description: p['description'],
created_at: p['createdAt'],
locale: p['locale']
)
end
rescue => e
warn "Wiki list error: #{e}"
[]