Brooklyn/plasma/workspace/applets/digital-clock/plugin/timezonesi18n_generate.rb
2022-03-05 22:41:29 +05:00

114 lines
4.0 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env ruby
# frozen_string_literal: true
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
# SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>
# Generates timezone tables out of tzdata.zi backing data such that the pretty names may be translated.
require 'erb'
require 'ostruct'
# Wraps template rendering. Templating is implemented using the ERB template system.
class Template
def self.render(context)
erb = ERB.new(File.read("#{__dir__}/timezonesi18n_generated.h.erb"))
erb.result(context.instance_eval { binding })
end
end
# Context object for template rendering. Inside the template file anything defined in here may be used.
# For simplicity's sake continents and cities are not modeled as fully functional objects but rather use
# this context wrapper. Slightly less code.
class RenderContext < OpenStruct
def initialize(continents:, cities:)
super
end
def city_description(city)
return 'This is a generic time zone name, localize as needed' if city.start_with?('UTC')
'This is a city associated with particular time zone'
end
def continent_description(_continent)
'This is a continent/area associated with a particular timezone'
end
# prettify city name
def to_city_name(city)
city = city.tr('_', ' ')
{
'DumontDUrville' => 'Dumont dUrville',
'ComodRivadavia' => 'Comodoro Rivadavia'
# TODO do we want these? seeing as different transliterations are in use, one is just as bad as the other, surely
# 'Uzhgorod' => 'Uzhhorod' # the tz has the legacy transliteration
# 'Zaporozhye' => 'Zaporizhzhia'
# 'Kiev' => 'Kyiv'
}.fetch(city, city)
end
# prettify continent name
def to_contient_name(continent)
continent # leave unchanged, they are all lovely
end
end
raise 'tzdata.zi missing, your tzdata was possibly built without' unless File.exist?('/usr/share/zoneinfo/tzdata.zi')
data = File.read('/usr/share/zoneinfo/tzdata.zi')
continents = []
cities = []
data.split("\n").each do |line|
line = line.strip
next if line[0] == '#' # comment
# zi files have a tricky format. only look at lines that make sense for us (Zone entries and Link entries)
is_zone = line[0].downcase == 'z'
is_link = line[0].downcase == 'l'
next unless is_zone || is_link
line_parts = line.split(' ')
# Since we have 2 line formats, the location of the timezone is different in each
tz = is_zone ? line_parts[1] : line_parts[2]
parts = tz.split('/')
# some links are fishy single names we can't use (e.g. `L Europe/Warsaw Poland`)
next if parts.size < 2
continent = parts[0]
# some links also have fake continent values (e.g. `L America/Denver SystemV/MST7MDT`) followed by regions therein
next if %w[systemv us etc canada brazil mexico chile].any? { |x| x == continent.downcase }
city = parts[-1]
# some links are simply pointing at directions within a region/country
next if %w[north east south west].any? { |x| x == city.downcase }
# some links are abbreviations (e.g. `Australia/NSW` for new south wales)
# Australia has some more links for regions but we'd have to filter them individually and I can't be bothered.
next if city.size <= 3 && city.upcase == city
# some are Knox and also known as Knox_IN for reasons
next if city == 'Knox_IN'
continents << continent
cities << city
end
# make sure fake cities exist
(0..14).each do |i|
cities << format('UTC+%02d:00', i)
cities << format('UTC-%02d:00', i)
end
# The partial hours are from original code this script was built based on. They do not actually correspond to timezone
# links though, so I'm not sure how they work but keep them regardless since I hope there's magic going on somehwere.
cities += %w[UTC UTC+03:30 UTC+04:30 UTC+05:30 UTC+05:45 UTC+06:30 UTC+09:30 UTC-03:30 UTC-04:30]
cities = cities.sort_by(&:downcase).uniq
continents = continents.sort_by(&:downcase).uniq
data = Template.render(RenderContext.new(cities: cities, continents: continents))
File.write("#{__dir__}/timezonesi18n_generated.h", data)