class FDroid::App
Public Class Methods
Given the desired_locale, searches through the list of localized_data entries and finds those with keys which match either:
* The desired locale exactly * The same language as the desired locale (but different region) * Any English language (so if the desired language is not there it will suffice)
These will be sorted in order of preference:
* Exact matches (language and region) * Language portion matches but region is absent/doesn't match. * en-US * en * en-*
It is intentionally liberal in searching for either “_” or “-” to separate language and region, because they both mean (in different context) to split langugae on the left, and region on the right, and it is cheap to do so.
@param [string] desired_locale @param [Hash] localized_data @return [Array]
# File lib/fdroid/App.rb, line 213 def self.available_locales(desired_locale, localized_data) parts = desired_locale.split(/[_-]/) desired_lang = parts[0] locales = localized_data.keys.select do |available_locale| parts = available_locale.split(/[_-]/) available_lang = parts[0] available_lang == desired_lang || available_lang == 'en' end measure_locale_goodness = lambda do |locale| parts = locale.split(/[_-]/) lang = parts[0] region = parts.length > 1 ? parts[1] : nil if locale == desired_locale return 1 elsif lang == desired_lang return 2 elsif locale == 'en-US' return 3 elsif lang == 'en' && region.nil? return 4 elsif lang == 'en' return 5 end end locales.sort do |a, b| measure_locale_goodness.call(a) <=> measure_locale_goodness.call(b) end end
Ensure newlines in descriptions are preserved (converted to “<br />” tags) Handles UNIX, Windows and MacOS newlines, with a one-to-one replacement
# File lib/fdroid/App.rb, line 147 def self.format_description_to_html(string) string.gsub(/(?:\n\r?|\r\n?)/, '<br />') end
@param [string] available_locales
@param [string] localized @param [string] field @return [string]
# File lib/fdroid/App.rb, line 155 def self.localized(available_locales, localized, field) return nil unless available_locales != nil available_locales.each do |l| if localized[l].key?(field) return localized[l][field] end end return nil end
Similar to localized_graphic_path
, but prefixes each item in the resulting array with “chosen_locale/field/”. @see localized @see localized_graphic_path
# File lib/fdroid/App.rb, line 183 def self.localized_graphic_list_paths(available_locales, localized, field) return nil unless available_locales != nil available_locales.each do |l| if localized[l].key?(field) return localized[l][field].map { |val| "#{l}/#{field}/#{val}" } end end return nil end
Prefixes the result with “chosen_locale/” before returning. @see localized
# File lib/fdroid/App.rb, line 169 def self.localized_graphic_path(available_locales, localized, field) return nil unless available_locales != nil available_locales.each do |l| if localized[l].key?(field) return "#{l}/#{localized[l][field]}" end end return nil end
# File lib/fdroid/App.rb, line 23 def initialize(app, packages, locale) # Sort packages in reverse-chronological order @packages = packages.map { |p| Package.new(p) } @app = app @locale = locale @available_locales = app.key?('localized') ? App.available_locales(locale, app['localized']) : nil end
Any transformations which are required to turn the “description” into something which is displayable via HTML is done here (e.g. replacing “fdroid.app:” schemes, formatting new lines, etc.
# File lib/fdroid/App.rb, line 129 def self.process_app_description(string) if string == nil return nil end string = self.replace_fdroid_app_links(string) self.format_description_to_html(string) end
Finds all “fdroid.app:” schemes in a particular string, and replaces with “/packages/”. @param [string] string @return [string]
# File lib/fdroid/App.rb, line 141 def self.replace_fdroid_app_links(string) string.gsub /fdroid\.app:([\w._]*)/, '/packages/\1' end
Public Instance Methods
# File lib/fdroid/App.rb, line 58 def description desc = field('description') || App.localized(@available_locales, @app['localized'], 'description') if desc != nil desc = App.process_app_description(desc) end return desc end
# File lib/fdroid/App.rb, line 39 def icon localized = App.localized_graphic_path(@available_locales, @app['localized'], 'icon') if localized "#{package_name}/#{localized}" elsif field('icon') "icons-640/#{field('icon')}" end end
this must exist since all entries are sorted by name, it uses tildes since they sort last
# File lib/fdroid/App.rb, line 50 def name field('name') || App.localized(@available_locales, @app['localized'], 'name') || '~missing name~' end
# File lib/fdroid/App.rb, line 31 def package_name field 'packageName' end
# File lib/fdroid/App.rb, line 68 def suggested_version_code code = field('suggestedVersionCode') if code != nil code = Integer(code) end return code end
# File lib/fdroid/App.rb, line 54 def summary field('summary') || App.localized(@available_locales, @app['localized'], 'summary') end
Generates a hash of dumb strings to be used in templates. If a specific value is not present, then it will have a nil value. If a value can be localized, then it will choose the most appropriate translation based on @available_locales and @locale. The 'packages' key is an array of Package.to_data
hashes. @return [Hash]
# File lib/fdroid/App.rb, line 82 def to_data { # These fields are taken as is from the metadata. If not present, they are 'package_name' => package_name, 'author_email' => field('authorEmail'), 'author_name' => field('authorName'), 'author_website' => field('authorWebSite'), 'translation' => field('translation'), 'bitcoin' => field('bitcoin'), 'litecoin' => field('litecoin'), 'donate' => field('donate'), 'flattrID' => field('flattrID'), 'liberapayID' => field('liberapayID'), 'categories' => field('categories'), 'anti_features' => field('antiFeatures'), 'suggested_version_code' => suggested_version_code, 'suggested_version_name' => @packages.detect { |p| p.version_code == suggested_version_code }&.version_name, 'issue_tracker' => field('issueTracker'), 'changelog' => field('changelog'), 'license' => field('license'), 'source_code' => field('sourceCode'), 'website' => field('webSite'), 'added' => field('added'), 'last_updated' => field('lastUpdated'), 'whats_new' => App.process_app_description(App.localized(@available_locales, @app['localized'], 'whatsNew')), 'icon' => icon, 'title' => name, 'summary' => summary, 'description' => description, 'feature_graphic' => App.localized_graphic_path(@available_locales, @app['localized'], 'featureGraphic'), 'phone_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'phoneScreenshots'), 'seven_inch_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'sevenInchScreenshots'), 'ten_inch_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'tenInchScreenshots'), 'tv_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'tvScreenshots'), 'wear_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'wearScreenshots'), 'packages' => @packages.sort.reverse.map { |p| p.to_data }, 'beautiful_url' => "/packages/#{package_name}" } end
# File lib/fdroid/App.rb, line 35 def to_s package_name end
Private Instance Methods
# File lib/fdroid/App.rb, line 247 def field(name) if @app.key?(name) value = @app[name] case value when Fixnum then return value when Float then return value when Integer then return value when Array then return value.map { |i| Loofah.scrub_fragment(i, :escape).to_html(:save_with => 0) } else return Loofah.scrub_fragment(value, :escape).to_html(:save_with => 0) end end end