Class: Kabosu::DictManager
- Inherits:
-
Object
- Object
- Kabosu::DictManager
- Defined in:
- lib/kabosu/dict_manager.rb
Defined Under Namespace
Classes: DictNotFound, DownloadError
Constant Summary collapse
- EDITIONS =
%w[small core full].freeze
- EDITION_PRIORITY =
%w[full core small].freeze
- GITHUB_REPO =
"WorksApplications/SudachiDict"- GITHUB_API =
"https://api.github.com"
Instance Attribute Summary collapse
-
#dir ⇒ Object
readonly
Returns the value of attribute dir.
Class Method Summary collapse
-
.default_dir ⇒ Object
Default storage directory: ~/.kabosu/dict/.
Instance Method Summary collapse
-
#available_versions ⇒ Object
List available versions from GitHub releases.
-
#find(edition: nil) ⇒ Object
Find the best available dictionary path.
-
#initialize(dir: self.class.default_dir) ⇒ DictManager
constructor
A new instance of DictManager.
-
#install(edition = "core", version: nil) ⇒ Object
Download and extract a dictionary edition.
-
#installed ⇒ Object
List all installed dictionaries.
-
#latest_version ⇒ Object
Fetch the latest release tag from GitHub.
-
#remove(edition: nil, version: nil) ⇒ Object
Remove a specific dictionary edition, or an entire version.
Constructor Details
#initialize(dir: self.class.default_dir) ⇒ DictManager
Returns a new instance of DictManager.
22 23 24 |
# File 'lib/kabosu/dict_manager.rb', line 22 def initialize(dir: self.class.default_dir) @dir = dir end |
Instance Attribute Details
#dir ⇒ Object (readonly)
Returns the value of attribute dir.
26 27 28 |
# File 'lib/kabosu/dict_manager.rb', line 26 def dir @dir end |
Class Method Details
.default_dir ⇒ Object
Default storage directory: ~/.kabosu/dict/
18 19 20 |
# File 'lib/kabosu/dict_manager.rb', line 18 def self.default_dir File.join(Dir.home, ".kabosu", "dict") end |
Instance Method Details
#available_versions ⇒ Object
List available versions from GitHub releases.
148 149 150 151 152 |
# File 'lib/kabosu/dict_manager.rb', line 148 def available_versions uri = URI("#{GITHUB_API}/repos/#{GITHUB_REPO}/releases") response = http_get(uri, headers: { "Accept" => "application/json" }) JSON.parse(response.body).map { |r| r["tag_name"].sub(/\Av/, "") } end |
#find(edition: nil) ⇒ Object
Find the best available dictionary path. Prefers: latest version, then full > core > small.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/kabosu/dict_manager.rb', line 88 def find(edition: nil) candidates = installed raise DictNotFound, "No dictionaries installed. Run: rake kabosu:install" if candidates.empty? if edition edition = validate_edition(edition) match = candidates.find { |d| d[:edition] == edition } raise DictNotFound, "No #{edition} dictionary installed" unless match return match[:path] end # Group by version (already sorted newest-first), pick best edition by_version = candidates.group_by { |d| d[:version] } latest_version_dicts = by_version.values.first best = EDITION_PRIORITY.each do |ed| found = latest_version_dicts.find { |d| d[:edition] == ed } break found if found end best.is_a?(Hash) ? best[:path] : latest_version_dicts.first[:path] end |
#install(edition = "core", version: nil) ⇒ Object
Download and extract a dictionary edition.
manager.install("small")
manager.install("core", version: "20260116")
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/kabosu/dict_manager.rb', line 35 def install(edition = "core", version: nil) edition = validate_edition(edition) version ||= latest_version dest_dir = File.join(@dir, "sudachi-dictionary-#{version}") dic_path = File.join(dest_dir, "system_#{edition}.dic") if File.exist?(dic_path) $stderr.puts "Already installed: #{dic_path}" return dic_path end url = release_asset_url(version, edition) zip_path = File.join(@dir, "sudachi-dictionary-#{version}-#{edition}.zip") FileUtils.mkdir_p(@dir) download(url, zip_path) extract(zip_path, @dir) FileUtils.rm_f(zip_path) unless File.exist?(dic_path) raise DownloadError, "Expected #{dic_path} after extraction, but file not found" end $stderr.puts "Installed: #{dic_path}" dic_path end |
#installed ⇒ Object
List all installed dictionaries. Returns an array of hashes: { version:, edition:, path: }
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/kabosu/dict_manager.rb', line 67 def installed results = [] return results unless Dir.exist?(@dir) Dir.glob(File.join(@dir, "sudachi-dictionary-*")).sort.reverse.each do |version_dir| next unless File.directory?(version_dir) version = File.basename(version_dir).sub("sudachi-dictionary-", "") EDITIONS.each do |edition| dic = File.join(version_dir, "system_#{edition}.dic") next unless File.exist?(dic) results << { version: version, edition: edition, path: dic } end end results end |
#latest_version ⇒ Object
Fetch the latest release tag from GitHub.
138 139 140 141 142 143 144 145 |
# File 'lib/kabosu/dict_manager.rb', line 138 def latest_version uri = URI("#{GITHUB_API}/repos/#{GITHUB_REPO}/releases/latest") response = http_get(uri, headers: { "Accept" => "application/json" }) data = JSON.parse(response.body) tag = data["tag_name"] # Tags are like "v20260116" — strip the "v" prefix tag.sub(/\Av/, "") end |
#remove(edition: nil, version: nil) ⇒ Object
Remove a specific dictionary edition, or an entire version.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/kabosu/dict_manager.rb', line 114 def remove(edition: nil, version: nil) targets = installed targets = targets.select { |d| d[:version] == version } if version targets = targets.select { |d| d[:edition] == edition } if edition raise DictNotFound, "No matching dictionary found" if targets.empty? targets.each do |d| FileUtils.rm_f(d[:path]) $stderr.puts "Removed: #{d[:path]}" # Clean up empty version directories version_dir = File.dirname(d[:path]) dics_remaining = Dir.glob(File.join(version_dir, "system_*.dic")) if dics_remaining.empty? FileUtils.rm_rf(version_dir) $stderr.puts "Removed empty directory: #{version_dir}" end end end |