Class: FDroid::App

Inherits:
Object
  • Object
show all
Defined in:
lib/fdroid/App.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, packages, locale) ⇒ App

Returns a new instance of App.



23
24
25
26
27
28
29
# 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

Class Method Details

.available_locales(desired_locale, localized_data) ⇒ Array

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.

Parameters:

  • desired_locale (string)
  • localized_data (Hash)

Returns:

  • (Array)


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# 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

.format_description_to_html(string) ⇒ Object

Ensure newlines in descriptions are preserved (converted to “<br />” tags) Handles UNIX, Windows and MacOS newlines, with a one-to-one replacement



147
148
149
# File 'lib/fdroid/App.rb', line 147

def self.format_description_to_html(string)
  string.gsub(/(?:\n\r?|\r\n?)/, '<br />')
end

.localized(available_locales, localized, field) ⇒ string

Parameters:

  • available_locales (string)
  • localized (string)
  • field (string)

Returns:

  • (string)


155
156
157
158
159
160
161
162
163
164
165
# 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

.localized_graphic_list_paths(available_locales, localized, field) ⇒ Object

Similar to localized_graphic_path, but prefixes each item in the resulting array with “chosen_locale/field/”.



183
184
185
186
187
188
189
190
191
# 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

.localized_graphic_path(available_locales, localized, field) ⇒ Object

Prefixes the result with “chosen_locale/” before returning.

See Also:



169
170
171
172
173
174
175
176
177
# 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

.process_app_description(string) ⇒ Object

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.



129
130
131
132
133
134
135
136
# 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/”.

Parameters:

  • string (string)

Returns:

  • (string)


141
142
143
# File 'lib/fdroid/App.rb', line 141

def self.replace_fdroid_app_links(string)
  string.gsub /fdroid\.app:([\w._]*)/, '/packages/\1'
end

Instance Method Details

#descriptionObject



58
59
60
61
62
63
64
65
66
# 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

#iconObject



39
40
41
42
43
44
45
46
# 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

#nameObject

this must exist since all entries are sorted by name, it uses tildes since they sort last



50
51
52
# File 'lib/fdroid/App.rb', line 50

def name
  field('name') || App.localized(@available_locales, @app['localized'], 'name') || '~missing name~'
end

#package_nameObject



31
32
33
# File 'lib/fdroid/App.rb', line 31

def package_name
  field 'packageName'
end

#suggested_version_codeObject



68
69
70
71
72
73
74
# File 'lib/fdroid/App.rb', line 68

def suggested_version_code
  code = field('suggestedVersionCode')
  if code != nil
    code = Integer(code)
  end
  return code
end

#summaryObject



54
55
56
# File 'lib/fdroid/App.rb', line 54

def summary
  field('summary') || App.localized(@available_locales, @app['localized'], 'summary')
end

#to_dataHash

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.

Returns:

  • (Hash)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 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

#to_sObject



35
36
37
# File 'lib/fdroid/App.rb', line 35

def to_s
  package_name
end