jekyll-fdroid 0.2.0 → 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5223ec6f44fa3c3131928d083cee93e06c28045b
4
- data.tar.gz: 1acae1bbdda2af1529df4d8fc955e27d6e428514
2
+ SHA256:
3
+ metadata.gz: f72286c732de382d651b8377c0083ed8faeb58cab5a865dd8e72978dd84e1a60
4
+ data.tar.gz: 57873902b7c8d5249f269293afc0b2d172db25c1371f37b70ec959f00192dfcc
5
5
  SHA512:
6
- metadata.gz: 52dd3848f495b9cf4a2c973faf5f3324e90bdacacbd21545e63a93a455771c4d1522739aba09968727e8e48f4d7bc496320142138ec9425cc7ce420fcad98bf6
7
- data.tar.gz: c6227570b89a1c4edad316e55678bca5bd1278f28511d3474f41f58d6eda57bcd625c760626bebde750f80a960b6dd8fb828a08c87ca82ca1bc62e10d6469e78
6
+ metadata.gz: 551e0cba8c4add0d485a7dec9e12d95107b6be1a38620a730e58fe9174b648a861aa054dac69e9e519058adb6dc010c89843958fed78f3ba581ce1ccad4991d6
7
+ data.tar.gz: '0098617770f3bd1f3bbeddfd0278a9dcdf2cf50f1cc2ed5c8c842051210f7ea36e2f8ad6d59112237b94724bf223b97036031cfb1d271bffd602261153545b87'
@@ -39,21 +39,21 @@ module FDroid
39
39
  localized = App.localized_graphic_path(@available_locales, @app['localized'], 'icon')
40
40
  if localized
41
41
  "#{package_name}/#{localized}"
42
- else
42
+ elsif field('icon')
43
43
  "icons-640/#{field('icon')}"
44
44
  end
45
45
  end
46
46
 
47
47
  def name
48
- App.localized(@available_locales, @app['localized'], 'name') || field('name')
48
+ field('name') || App.localized(@available_locales, @app['localized'], 'name')
49
49
  end
50
50
 
51
51
  def summary
52
- App.localized(@available_locales, @app['localized'], 'summary') || field('summary')
52
+ field('summary') || App.localized(@available_locales, @app['localized'], 'summary')
53
53
  end
54
54
 
55
55
  def description
56
- desc = App.localized(@available_locales, @app['localized'], 'description') || field('description')
56
+ desc = field('description') || App.localized(@available_locales, @app['localized'], 'description')
57
57
 
58
58
  if desc != nil
59
59
  desc = App.process_app_description(desc)
@@ -70,7 +70,6 @@ module FDroid
70
70
  return code
71
71
  end
72
72
 
73
-
74
73
  # Generates a hash of dumb strings to be used in templates.
75
74
  # If a specific value is not present, then it will have a nil value.
76
75
  # If a value can be localized, then it will choose the most appropriate
@@ -79,39 +78,42 @@ module FDroid
79
78
  # @return [Hash]
80
79
  def to_data
81
80
  {
82
- # These fields are taken as is from the metadata. If not present, they are
83
- 'package_name' => package_name,
84
- 'author_email' => field('authorEmail'),
85
- 'author_name' => field('authorName'),
86
- 'author_website' => field('authorWebSite'),
87
- 'bitcoin' => field('bitcoin'),
88
- 'donate' => field('donate'),
89
- 'flattr' => field('flattr'),
90
- 'categories' => field('categories'),
91
- 'anti_features' => field('anti_features'),
92
- 'suggested_version_code' => suggested_version_code,
93
- 'suggested_version_name' => @packages.detect { |p| p.version_code == suggested_version_code }&.version_name,
94
- 'issue_tracker' => field('issueTracker'),
95
- 'changelog' => field('changelog'),
96
- 'license' => field('license'),
97
- 'source_code' => field('sourceCode'),
98
- 'website' => field('webSite'),
99
- 'added' => field('added'),
100
- 'last_updated' => field('lastUpdated'),
101
- 'whats_new' => App.process_app_description(App.localized(@available_locales, @app['localized'], 'whatsNew')),
102
-
103
- 'icon' => icon,
104
- 'title' => name,
105
- 'summary' => summary,
106
-
107
- 'description' => description,
108
- 'feature_graphic' => App.localized_graphic_path(@available_locales, @app['localized'], 'featureGraphic'),
109
- 'phone_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'phoneScreenshots'),
110
- 'seven_inch_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'sevenInchScreenshots'),
111
-
112
- 'packages' => @packages.sort.reverse.map { |p| p.to_data },
113
-
114
- 'beautiful_url' => "/packages/#{package_name}"
81
+ # These fields are taken as is from the metadata. If not present, they are
82
+ 'package_name' => package_name,
83
+ 'author_email' => field('authorEmail'),
84
+ 'author_name' => field('authorName'),
85
+ 'author_website' => field('authorWebSite'),
86
+ 'translation' => field('translation'),
87
+ 'bitcoin' => field('bitcoin'),
88
+ 'litecoin' => field('litecoin'),
89
+ 'donate' => field('donate'),
90
+ 'flattrID' => field('flattrID'),
91
+ 'liberapayID' => field('liberapayID'),
92
+ 'categories' => field('categories'),
93
+ 'anti_features' => field('anti_features'),
94
+ 'suggested_version_code' => suggested_version_code,
95
+ 'suggested_version_name' => @packages.detect { |p| p.version_code == suggested_version_code }&.version_name,
96
+ 'issue_tracker' => field('issueTracker'),
97
+ 'changelog' => field('changelog'),
98
+ 'license' => field('license'),
99
+ 'source_code' => field('sourceCode'),
100
+ 'website' => field('webSite'),
101
+ 'added' => field('added'),
102
+ 'last_updated' => field('lastUpdated'),
103
+ 'whats_new' => App.process_app_description(App.localized(@available_locales, @app['localized'], 'whatsNew')),
104
+
105
+ 'icon' => icon,
106
+ 'title' => name,
107
+ 'summary' => summary,
108
+
109
+ 'description' => description,
110
+ 'feature_graphic' => App.localized_graphic_path(@available_locales, @app['localized'], 'featureGraphic'),
111
+ 'phone_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'phoneScreenshots'),
112
+ 'seven_inch_screenshots' => App.localized_graphic_list_paths(@available_locales, @app['localized'], 'sevenInchScreenshots'),
113
+
114
+ 'packages' => @packages.sort.reverse.map { |p| p.to_data },
115
+
116
+ 'beautiful_url' => "/packages/#{package_name}"
115
117
  }
116
118
  end
117
119
 
@@ -134,11 +136,10 @@ module FDroid
134
136
  string.gsub /fdroid\.app:([\w._]*)/, '/packages/\1'
135
137
  end
136
138
 
137
- # Ensure double newlines "\n\n" are converted to "<br />" tags.
139
+ # Ensure newlines in descriptions are preserved (converted to "<br />" tags)
140
+ # Handles UNIX, Windows and MacOS newlines, with a one-to-one replacement
138
141
  def self.format_description_to_html(string)
139
- string
140
- .gsub("\n\n", '<br />')
141
- .gsub(/\r?\n/, ' ')
142
+ string.gsub(/(?:\n\r?|\r\n?)/, '<br />')
142
143
  end
143
144
 
144
145
  # @param [string] available_locales
@@ -156,34 +157,30 @@ module FDroid
156
157
 
157
158
  return nil
158
159
  end
159
-
160
+
160
161
  # Prefixes the result with "chosen_locale/" before returning.
161
162
  # @see localized
162
163
  def self.localized_graphic_path(available_locales, localized, field)
163
164
  return nil unless available_locales != nil
164
-
165
165
  available_locales.each do |l|
166
166
  if localized[l].key?(field)
167
167
  return "#{l}/#{localized[l][field]}"
168
168
  end
169
169
  end
170
-
171
170
  return nil
172
171
  end
173
-
172
+
174
173
  # Similar to localized_graphic_path, but prefixes each item in the resulting array
175
174
  # with "chosen_locale/field/".
176
175
  # @see localized
177
176
  # @see localized_graphic_path
178
177
  def self.localized_graphic_list_paths(available_locales, localized, field)
179
178
  return nil unless available_locales != nil
180
-
181
179
  available_locales.each do |l|
182
180
  if localized[l].key?(field)
183
181
  return localized[l][field].map { |val| "#{l}/#{field}/#{val}" }
184
182
  end
185
183
  end
186
-
187
184
  return nil
188
185
  end
189
186
 
@@ -70,6 +70,5 @@ module FDroid
70
70
 
71
71
  @repo = Repo.new(index['repo'])
72
72
  end
73
-
74
73
  end
75
- end
74
+ end
@@ -23,7 +23,7 @@ module FDroid
23
23
  @package = package
24
24
  end
25
25
 
26
- def <=> (other)
26
+ def <=>(other)
27
27
  self.version_code <=> other.version_code
28
28
  end
29
29
 
@@ -42,19 +42,23 @@ module FDroid
42
42
  end
43
43
 
44
44
  {
45
- 'version_name' => version_name,
46
- 'version_code' => version_code,
47
45
  'added' => added,
46
+ 'anti_features' => @package['antiFeatures'],
48
47
  'apk_name' => @package['apkName'],
48
+ 'file_extension' => File.extname(@package['apkName'].to_s).strip.upcase[1..-1],
49
49
  'hash' => @package['hash'],
50
50
  'hash_type' => @package['hashType'],
51
- 'min_sdk_version' => @package['minSdkVersion'],
52
51
  'max_sdk_version' => @package['maxSdkVersion'],
53
- 'target_sdk_version' => @package['targetSdkVersion'],
54
- 'native_code' => @package['nativecode'],
52
+ 'min_sdk_version' => @package['minSdkVersion'],
53
+ 'nativecode' => @package['nativecode'],
54
+ 'srcname' => @package['srcname'],
55
55
  'sig' => @package['sig'],
56
+ 'signer' => @package['signer'],
56
57
  'size' => @package['size'],
58
+ 'target_sdk_version' => @package['targetSdkVersion'],
57
59
  'uses_permission' => permission,
60
+ 'version_name' => version_name,
61
+ 'version_code' => version_code,
58
62
  }
59
63
  end
60
64
 
@@ -62,7 +66,7 @@ module FDroid
62
66
  if @package['uses-permission'] == nil then
63
67
  []
64
68
  else
65
- @package['uses-permission'].map {|perm| Permission.new(perm).to_data }
69
+ @package['uses-permission'].map { |perm| Permission.new(perm).to_data }
66
70
  end
67
71
  end
68
72
 
@@ -72,4 +76,4 @@ module FDroid
72
76
  @app.key?(name) ? name : nil
73
77
  end
74
78
  end
75
- end
79
+ end
@@ -24,9 +24,9 @@ module FDroid
24
24
 
25
25
  def to_data
26
26
  {
27
- 'permission' => @permission,
28
- 'min_sdk' => @min_sdk,
27
+ 'permission' => @permission,
28
+ 'min_sdk' => @min_sdk,
29
29
  }
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -24,7 +24,7 @@ module FDroid
24
24
  def name
25
25
  @repo['name']
26
26
  end
27
-
27
+
28
28
  def address
29
29
  @repo['address']
30
30
  end
@@ -36,10 +36,13 @@ module FDroid
36
36
  def description
37
37
  @repo['description']
38
38
  end
39
-
39
+
40
+ def timestamp
41
+ @repo['timestamp']
42
+ end
43
+
40
44
  def date
41
45
  added = Date.strptime("#{@repo['timestamp'] / 1000}", '%s')
42
46
  end
43
-
44
47
  end
45
- end
48
+ end
@@ -16,16 +16,15 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ class FDroidBrowsingPage < ReadYamlPage
20
+ def initialize(site, base)
21
+ @site = site
22
+ @base = base
23
+ @dir = "packages"
24
+ @name = "index.html"
19
25
 
20
- class FDroidBrowsingPage < ReadYamlPage
21
- def initialize(site, base)
22
- @site = site
23
- @base = base
24
- @dir = "packages"
25
- @name = "index.html"
26
-
27
- self.process(@name)
28
- self.read_yaml((File.expand_path "../../_pages", File.dirname(__FILE__)), 'browse.html')
29
- end
30
- end
26
+ self.process(@name)
27
+ self.read_yaml((File.expand_path "../../_pages", File.dirname(__FILE__)), 'browse.html')
28
+ end
29
+ end
31
30
  end
@@ -16,164 +16,165 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ module Filters
20
+ # Convert an Android SDK level into an Android version.
21
+ #
22
+ # input - Android SDK Level.
23
+ #
24
+ # Returns the Android version.
25
+ def android_sdk_level_to_version(input)
26
+ sdkLevel = @@AndroidSdkLevelToVersionRelation[input]
27
+ if not sdkLevel.nil?
28
+ return sdkLevel
29
+ end
30
+ return '?'
31
+ end
19
32
 
20
- module Filters
33
+ # Hash with relation between Android SDK Level and Android version
34
+ # https://source.android.com/setup/build-numbers
35
+ @@AndroidSdkLevelToVersionRelation = {
36
+ '1' => '1.0',
37
+ '2' => '1.1',
38
+ '3' => '1.5',
39
+ '4' => '1.6',
40
+ '5' => '2.0',
41
+ '6' => '2.0.1',
42
+ '7' => '2.1',
43
+ '8' => '2.2',
44
+ '9' => '2.3',
45
+ '10' => '2.3.3',
46
+ '11' => '3.0',
47
+ '12' => '3.1',
48
+ '13' => '3.2',
49
+ '14' => '4.0',
50
+ '15' => '4.0.3',
51
+ '16' => '4.1',
52
+ '17' => '4.2',
53
+ '18' => '4.3',
54
+ '19' => '4.4',
55
+ '20' => '4.4W',
56
+ '21' => '5.0',
57
+ '22' => '5.1',
58
+ '23' => '6.0',
59
+ '24' => '7.0',
60
+ '25' => '7.1',
61
+ '26' => '8.0',
62
+ '27' => '8.1',
63
+ }
21
64
 
22
- # Convert an Android SDK level into an Android version.
23
- #
24
- # input - Android SDK Level.
25
- #
26
- # Returns the Android version.
27
- def android_sdk_level_to_version(input)
28
- sdkLevel = @@AndroidSdkLevelToVersionRelation[input]
29
- if not sdkLevel.nil?
30
- return sdkLevel
31
- end
32
- return '?'
33
- end
65
+ # Convert a file size to a human-readable String.
66
+ # Source: https://codereview.stackexchange.com/q/9107
67
+ #
68
+ # input - File size in Bytes.
69
+ #
70
+ # Returns human-readable String.
71
+ def file_size_human_readable(input)
72
+ input = input.to_f
73
+ i = PREFIX.length - 1
74
+ while input > 512 && i > 0
75
+ i -= 1
76
+ input /= 1024
77
+ end
78
+ return ((input > 9 || input.modulo(1) < 0.1 ? '%d' : '%.1f') % input) + ' ' + PREFIX[i]
79
+ end
80
+ PREFIX = %W(TiB GiB MiB KiB B).freeze
34
81
 
35
- # Hash with relation between Android SDK Level and Android version
36
- @@AndroidSdkLevelToVersionRelation = {
37
- '1' => '1.0',
38
- '2' => '1.1',
39
- '3' => '1.5',
40
- '4' => '1.6',
41
- '5' => '2.0',
42
- '6' => '2.0.1',
43
- '7' => '2.1',
44
- '8' => '2.2',
45
- '9' => '2.3',
46
- '10' => '2.3.3',
47
- '11' => '3.0',
48
- '12' => '3.1',
49
- '13' => '3.2',
50
- '14' => '4.0',
51
- '15' => '4.0.3',
52
- '16' => '4.1',
53
- '17' => '4.2',
54
- '18' => '4.3',
55
- '19' => '4.4',
56
- '20' => '4.4W',
57
- '21' => '5.0',
58
- '22' => '5.1',
59
- '23' => '6.0',
60
- '24' => '7.0',
61
- '25' => '7.1'
62
- }
82
+ # Convert a SPDX license identifier to its full name.
83
+ #
84
+ # input - SPDX license identifier.
85
+ #
86
+ # Returns full license name.
87
+ def get_license_name(input)
88
+ if input.nil? or input.empty?
89
+ return 'Unknown'
90
+ end
91
+ spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input]
92
+ if input.end_with? "+"
93
+ spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input.chomp('+')]
94
+ end
95
+ if not spdxLicense.nil?
96
+ if input.end_with? "+"
97
+ return spdxLicense['name'] + ' or later version'
98
+ end
99
+ return spdxLicense['name']
100
+ end
101
+ return input
102
+ end
63
103
 
64
- # Convert a file size to a human-readable String.
65
- # Source: https://codereview.stackexchange.com/q/9107
66
- #
67
- # input - File size in Bytes.
68
- #
69
- # Returns human-readable String.
70
- def file_size_human_readable(input)
71
- input = input.to_f
72
- i = PREFIX.length - 1
73
- while input > 512 && i > 0
74
- i -= 1
75
- input /= 1024
76
- end
77
- return ((input > 9 || input.modulo(1) < 0.1 ? '%d' : '%.1f') % input) + ' ' + PREFIX[i]
78
- end
79
- PREFIX = %W(TiB GiB MiB KiB B).freeze
104
+ # Convert a SPDX license identifier to its URL on GNU.org.
105
+ #
106
+ # input - SPDX license identifier.
107
+ #
108
+ # Returns URL on GNU.org.
109
+ def get_license_url(input)
110
+ if input.nil? or input.empty?
111
+ return ''
112
+ end
113
+ if input.end_with? "+"
114
+ input = input.chomp('+')
115
+ end
116
+ spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input]
117
+ if not spdxLicense.nil?
118
+ return spdxLicense['url']
119
+ end
120
+ return 'https://spdx.org/licenses/' + input + '.html'
121
+ end
80
122
 
81
- # Convert a SPDX license identifier to its full name.
82
- #
83
- # input - SPDX license identifier.
84
- #
85
- # Returns full license name.
86
- def get_license_name(input)
87
- if input.nil? or input.empty?
88
- return 'Unknown'
89
- end
90
- spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input]
91
- if input.end_with? "+"
92
- spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input.chomp('+')]
93
- end
94
- if not spdxLicense.nil?
95
- if input.end_with? "+"
96
- return spdxLicense['name'] + ' or later version'
97
- end
98
- return spdxLicense['name']
99
- end
100
- return input
101
- end
102
-
103
- # Convert a SPDX license identifier to its URL on GNU.org.
104
- #
105
- # input - SPDX license identifier.
106
- #
107
- # Returns URL on GNU.org.
108
- def get_license_url(input)
109
- if input.nil? or input.empty?
110
- return ''
111
- end
112
- if input.end_with? "+"
113
- input = input.chomp('+')
114
- end
115
- spdxLicense = @@SpdxLicenseNameToGnuUrlRelation[input]
116
- if not spdxLicense.nil?
117
- return spdxLicense['url']
118
- end
119
- return 'https://spdx.org/licenses/' + input + '.html'
120
- end
121
-
122
- # Hash with relation between SPDX license identifier and its full name and URL, mostly on GNU.org.
123
- # For the beginning, I only used OSI approved and frequently used licenses.
124
- @@SpdxLicenseNameToGnuUrlRelation = {
125
- 'AGPL-3.0' => {
126
- 'name' => 'GNU Affero General Public License v3.0',
127
- 'url' => 'https://www.gnu.org/licenses/license-list.html#AGPLv3.0'
128
- },
129
- 'Apache-2.0' => {
130
- 'name' => 'Apache License 2.0',
131
- 'url' => 'https://www.gnu.org/licenses/license-list.html#apache2'
132
- },
133
- 'BSD-2-Clause' => {
134
- 'name' => 'BSD 2-clause "Simplified" License',
135
- 'url' => 'https://www.gnu.org/licenses/license-list.html#FreeBSD'
136
- },
137
- 'BSD-3-Clause' => {
138
- 'name' => 'BSD 3-clause "New" or "Revised" License',
139
- 'url' => 'https://www.gnu.org/licenses/license-list.html#ModifiedBSD'
140
- },
141
- 'GPL-2.0' => {
142
- 'name' => 'GNU General Public License v2.0',
143
- 'url' => 'https://www.gnu.org/licenses/license-list.html#GPLv2'
144
- },
145
- 'GPL-3.0' => {
146
- 'name' => 'GNU General Public License v3.0',
147
- 'url' => 'https://www.gnu.org/licenses/license-list.html#GNUGPLv3'
148
- },
149
- 'ISC' => {
150
- 'name' => 'ISC License',
151
- 'url' => 'https://www.gnu.org/licenses/license-list.en.html#ISC'
152
- },
153
- 'LGPL-2.1' => {
154
- 'name' => 'GNU Lesser General Public License v2.1',
155
- 'url' => 'https://www.gnu.org/licenses/license-list.html#LGPLv2.1'
156
- },
157
- 'LGPL-3.0' => {
158
- 'name' => 'GNU Lesser General Public License v3.0',
159
- 'url' => 'https://www.gnu.org/licenses/license-list.html#LGPLv3'
160
- },
161
- 'MIT' => {
162
- 'name' => 'MIT License',
163
- 'url' => 'https://www.gnu.org/licenses/license-list.html#X11License'
164
- },
165
- 'MPL-1.1' => {
166
- 'name' => 'Mozilla Public License 1.1',
167
- 'url' => 'https://www.gnu.org/licenses/license-list.html#MPL'
168
- },
169
- 'MPL-2.0' => {
170
- 'name' => 'Mozilla Public License 2.0',
171
- 'url' => 'https://www.gnu.org/licenses/license-list.html#MPL-2.0'
172
- }
173
- }
174
- end
123
+ # Hash with relation between SPDX license identifier and its full name and URL, mostly on GNU.org.
124
+ # For the beginning, I only used OSI approved and frequently used licenses.
125
+ @@SpdxLicenseNameToGnuUrlRelation = {
126
+ 'AGPL-3.0' => {
127
+ 'name' => 'GNU Affero General Public License v3.0',
128
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#AGPLv3.0'
129
+ },
130
+ 'Apache-2.0' => {
131
+ 'name' => 'Apache License 2.0',
132
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#apache2'
133
+ },
134
+ 'BSD-2-Clause' => {
135
+ 'name' => 'BSD 2-clause "Simplified" License',
136
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#FreeBSD'
137
+ },
138
+ 'BSD-3-Clause' => {
139
+ 'name' => 'BSD 3-clause "New" or "Revised" License',
140
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#ModifiedBSD'
141
+ },
142
+ 'GPL-2.0' => {
143
+ 'name' => 'GNU General Public License v2.0',
144
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#GPLv2'
145
+ },
146
+ 'GPL-3.0' => {
147
+ 'name' => 'GNU General Public License v3.0',
148
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#GNUGPLv3'
149
+ },
150
+ 'ISC' => {
151
+ 'name' => 'ISC License',
152
+ 'url' => 'https://www.gnu.org/licenses/license-list.en.html#ISC'
153
+ },
154
+ 'LGPL-2.1' => {
155
+ 'name' => 'GNU Lesser General Public License v2.1',
156
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#LGPLv2.1'
157
+ },
158
+ 'LGPL-3.0' => {
159
+ 'name' => 'GNU Lesser General Public License v3.0',
160
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#LGPLv3'
161
+ },
162
+ 'MIT' => {
163
+ 'name' => 'MIT License',
164
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#X11License'
165
+ },
166
+ 'MPL-1.1' => {
167
+ 'name' => 'Mozilla Public License 1.1',
168
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#MPL'
169
+ },
170
+ 'MPL-2.0' => {
171
+ 'name' => 'Mozilla Public License 2.0',
172
+ 'url' => 'https://www.gnu.org/licenses/license-list.html#MPL-2.0'
173
+ }
174
+ }
175
+ end
175
176
  end
176
177
 
177
178
  Liquid::Template.register_filter(
178
- Jekyll::Filters
179
+ Jekyll::Filters
179
180
  )
@@ -16,18 +16,16 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ class FDroidLastUpdatedPackagesTag < Liquid::Tag
20
+ def initialize(tag_name, text, tokens)
21
+ super
22
+ end
19
23
 
20
- class FDroidLastUpdatedPackagesTag < Liquid::Tag
21
-
22
- def initialize(tag_name, text, tokens)
23
- super
24
- end
25
-
26
- def render(context)
27
- template = Liquid::Template.parse(IO.read((File.expand_path "../../_layouts/sidebar-lastupdated-packages.html", File.dirname(__FILE__))))
28
- template.render(context)
29
- end
30
- end
24
+ def render(context)
25
+ template = Liquid::Template.parse(IO.read((File.expand_path "../../_layouts/sidebar-lastupdated-packages.html", File.dirname(__FILE__))))
26
+ template.render(context)
27
+ end
28
+ end
31
29
  end
32
30
 
33
31
  Liquid::Template.register_tag('fdroid_show_last_updated_packages', Jekyll::FDroidLastUpdatedPackagesTag)
@@ -16,18 +16,16 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ class FDroidLatestPackagesTag < Liquid::Tag
20
+ def initialize(tag_name, text, tokens)
21
+ super
22
+ end
19
23
 
20
- class FDroidLatestPackagesTag < Liquid::Tag
21
-
22
- def initialize(tag_name, text, tokens)
23
- super
24
- end
25
-
26
- def render(context)
27
- template = Liquid::Template.parse(IO.read((File.expand_path "../../_layouts/sidebar-latest-packages.html", File.dirname(__FILE__))))
28
- template.render(context)
29
- end
30
- end
24
+ def render(context)
25
+ template = Liquid::Template.parse(IO.read((File.expand_path "../../_layouts/sidebar-latest-packages.html", File.dirname(__FILE__))))
26
+ template.render(context)
27
+ end
28
+ end
31
29
  end
32
30
 
33
31
  Liquid::Template.register_tag('fdroid_show_latest_packages', Jekyll::FDroidLatestPackagesTag)
@@ -16,53 +16,52 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ class FDroidPackagesGenerator < Generator
20
+ attr_accessor :alreadyBuilt
19
21
 
20
- class FDroidPackagesGenerator < Generator
21
- attr_accessor :alreadyBuilt
22
+ safe true
23
+ priority :highest
22
24
 
23
- safe true
24
- priority :highest
25
+ def generate(site)
26
+ # generator will only run on first build, not because of auto-regeneration
27
+ if @alreadyBuilt != true
28
+ @alreadyBuilt = true
25
29
 
26
- def generate(site)
27
- # generator will only run on first build, not because of auto-regeneration
28
- if @alreadyBuilt != true
29
- @alreadyBuilt = true
30
+ # Add plugin's SASS directory so site's list of SASS directories
31
+ if site.config["sass"].nil? || site.config["sass"].empty?
32
+ site.config["sass"] = Hash.new
33
+ end
34
+ if site.config["sass"]["load_paths"].nil? || site.config["sass"]["load_paths"].empty?
35
+ site.config["sass"]["load_paths"] = ["_sass", (File.expand_path "../../_sass", File.dirname(__FILE__))]
36
+ else
37
+ site.config["sass"]["load_paths"] << (File.expand_path "../../_sass", File.dirname(__FILE__))
38
+ end
30
39
 
31
- # Add plugin's SASS directory so site's list of SASS directories
32
- if site.config["sass"].nil? || site.config["sass"].empty?
33
- site.config["sass"] = Hash.new
34
- end
35
- if site.config["sass"]["load_paths"].nil? || site.config["sass"]["load_paths"].empty?
36
- site.config["sass"]["load_paths"] = ["_sass", (File.expand_path "../../_sass", File.dirname(__FILE__))]
37
- else
38
- site.config["sass"]["load_paths"] << (File.expand_path "../../_sass", File.dirname(__FILE__))
39
- end
40
+ # Enable pagination
41
+ if site.config["pagination"].nil? || site.config["pagination"].empty?
42
+ site.config["pagination"] = Hash.new
43
+ end
44
+ site.config["pagination"]["enabled"] = true
40
45
 
41
- # Enable pagination
42
- if site.config["pagination"].nil? || site.config["pagination"].empty?
43
- site.config["pagination"] = Hash.new
44
- end
45
- site.config["pagination"]["enabled"] = true
46
+ index = FDroid::IndexV1.download(site.config["fdroid-repo"], site.active_lang || 'en_US')
46
47
 
47
- index = FDroid::IndexV1.download(site.config["fdroid-repo"], site.active_lang || 'en_US')
48
+ Jekyll::LunrJsSearch::Indexer.new.generate(site, index.apps)
48
49
 
49
- Jekyll::LunrJsSearch::Indexer.new.generate(site, index.apps)
50
-
51
- # Generate detail page for every package
52
- site.collections["packages"] = Collection.new(site, "packages")
53
- index.apps.each do |package|
54
- # This page needs to be created twice, once for site.pages, and once for site.collections.
55
- # If not, then the i18n code in jekyll-polyglot will end up processing the page twice, as
56
- # it iterates over all pages and all packages. The end result is a double prefix for "/en/en"
57
- # for any links in the page.
58
- # https://gitlab.com/fdroid/jekyll-fdroid/issues/38
59
- site.pages << FDroidPackageDetailPage.new(site, site.source, package)
60
- site.collections["packages"].docs << FDroidPackageDetailPage.new(site, site.source, package)
61
- end
62
- # Generate browsing pages
63
- site.includes_load_paths << (File.expand_path "../../_includes", File.dirname(__FILE__))
64
- site.pages << FDroidBrowsingPage.new(site, site.source)
65
- end
66
- end
67
- end
50
+ # Generate detail page for every package
51
+ site.collections["packages"] = Collection.new(site, "packages")
52
+ index.apps.each do |package|
53
+ # This page needs to be created twice, once for site.pages, and once for site.collections.
54
+ # If not, then the i18n code in jekyll-polyglot will end up processing the page twice, as
55
+ # it iterates over all pages and all packages. The end result is a double prefix for "/en/en"
56
+ # for any links in the page.
57
+ # https://gitlab.com/fdroid/jekyll-fdroid/issues/38
58
+ site.pages << FDroidPackageDetailPage.new(site, site.source, package)
59
+ site.collections["packages"].docs << FDroidPackageDetailPage.new(site, site.source, package)
60
+ end
61
+ # Generate browsing pages
62
+ site.includes_load_paths << (File.expand_path "../../_includes", File.dirname(__FILE__))
63
+ site.pages << FDroidBrowsingPage.new(site, site.source)
64
+ end
65
+ end
66
+ end
68
67
  end
@@ -16,12 +16,10 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
-
20
19
  class FDroidPackageDetailPage < ReadYamlPage
21
-
22
20
  # @param [Jekyll::Site] site
23
21
  # @param [string] base
24
- # @param [FDfroid::App] package
22
+ # @param [FDroid::App] package
25
23
  def initialize(site, base, package)
26
24
  @site = site
27
25
  @base = base
@@ -18,22 +18,24 @@
18
18
  require_relative '../fdroid/IndexV1'
19
19
 
20
20
  module Jekyll
21
+ # Used to output the repo name/timestamp used to generate this F-Droid site.
22
+ class FDroidRepoInfoTag < Liquid::Tag
23
+ @@repotag = ''
21
24
 
22
- # Used to output the repo name/timestamp used to generate this F-Droid site.
23
- class FDroidRepoInfoTag < Liquid::Tag
25
+ def initialize(tag_name, text, tokens)
26
+ super
27
+ end
24
28
 
25
- def initialize(tag_name, text, tokens)
26
- super
27
- end
28
-
29
- def render(context)
30
- site = context.registers[:site]
31
- url = site.config['fdroid-repo']
32
- index = FDroid::IndexV1.download(url, 'en')
33
-
34
- "#{index.repo.name} #{index.repo.date}"
35
- end
36
- end
29
+ def render(context)
30
+ if @@repotag == ''
31
+ site = context.registers[:site]
32
+ url = site.config['fdroid-repo']
33
+ index = FDroid::IndexV1.download(url, 'en')
34
+ @@repotag = "#{index.repo.name} #{index.repo.date}"
35
+ end
36
+ return @@repotag
37
+ end
38
+ end
37
39
  end
38
40
 
39
41
  Liquid::Template.register_tag('fdroid_repo_info', Jekyll::FDroidRepoInfoTag)
@@ -16,71 +16,81 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module Jekyll
19
+ class SearchForm
20
+ def self.render_form(context, search_form_template_path, result_item_template_contents)
21
+ site = context.registers[:site]
22
+ repo_timestamp = FDroid::IndexV1.download(site.config['fdroid-repo'], 'en').repo.timestamp
19
23
 
20
- class SearchForm
21
- def self.render_form(context, search_form_template_path, result_item_template_contents)
22
- context['result_item_template'] = result_item_template_contents
23
- context['search_id'] = rand(1000000)
24
-
25
- template = Liquid::Template.parse(IO.read((File.expand_path( search_form_template_path, File.dirname(__FILE__)))))
26
- template.render(context)
27
- end
28
- end
29
-
30
- # As the user types, a list of results is shown below the text input (floating above other content).
31
- # When an item is selected, it will navigate to that packages page.
32
- # Designed to be used in a sidebar widget.
33
-
34
- class DropDownWithTemplate < Liquid::Block
35
- def render(context)
36
- search_form_template_path = "../../_layouts/search-autocomplete.html"
37
- SearchForm.render_form(context, search_form_template_path, super.to_s)
38
- end
24
+ context['result_item_template'] = result_item_template_contents
25
+
26
+ # If an app developer is able to guess this at the time that they write their app descriptions, then they could
27
+ # potentially try and inject a new template which hijacks the search results template. This is due to the way in
28
+ # which JS is used to find the relevant `<script type="x-tmpl-mustache" id="...-{{ search_id }}">` template.
29
+ # Thus, make it random, and include the repo timestamp. They'd need to guess a random number correctly, and it
30
+ # will change every day that the repo is republished.
31
+ context['search_id'] = "#{rand(1000000)}.#{repo_timestamp}"
32
+
33
+ context['repo_timestamp'] = repo_timestamp
34
+
35
+ template = Liquid::Template.parse(IO.read((File.expand_path(search_form_template_path, File.dirname(__FILE__)))))
36
+ template.render(context)
37
+ end
38
+ end
39
+
40
+ # As the user types, a list of results is shown below the text input (floating above other content).
41
+ # When an item is selected, it will navigate to that packages page.
42
+ # Designed to be used in a sidebar widget.
43
+
44
+ class DropDownWithTemplate < Liquid::Block
45
+ def render(context)
46
+ search_form_template_path = "../../_layouts/search-autocomplete.html"
47
+ SearchForm.render_form(context, search_form_template_path, super.to_s)
39
48
  end
49
+ end
50
+
51
+ class DefaultDropDown < Liquid::Tag
52
+ def render(context)
53
+ search_form_template_path = "../../_layouts/search-autocomplete.html"
54
+
55
+ result_item_template_path = "../../_includes/search-autocomplete-default-result-template.html"
56
+ result_item_template = IO.read((File.expand_path(result_item_template_path, File.dirname(__FILE__))))
40
57
 
41
- class DefaultDropDown < Liquid::Tag
42
- def render(context)
43
- search_form_template_path = "../../_layouts/search-autocomplete.html"
44
-
45
- result_item_template_path = "../../_includes/search-autocomplete-default-result-template.html"
46
- result_item_template = IO.read((File.expand_path(result_item_template_path, File.dirname(__FILE__))))
47
-
48
- SearchForm.render_form(context, search_form_template_path, result_item_template)
49
- end
50
- end
51
-
52
- # As the user types, a div is populated with search results.
53
- # Differs from DropDownAutocomplete in that once you move focus away from the text input, the results
54
- # are still displayed.
55
- # Designed for a fully fledged search form on its own page.
56
-
57
- # For each result result, this will render the template found between
58
- # the {% fdroid_search_full_with_template %}{% endfdroid_search_full_with_template %} tags.
59
- class FullSearchWithTemplate < Liquid::Block
60
- def render(context)
61
- search_form_template_path = "../../_layouts/search-full.html"
62
- SearchForm.render_form(context, search_form_template_path, super.to_s)
63
- end
64
- end
65
-
66
- # For each search result, this will render the contents of
67
- # "_includes/search-full-default-result-template.html" from this plugin.
68
- class DefaultFullSearch < Liquid::Tag
69
- def initialize(tag_name, argument, tokens)
70
- super
71
- @empty_search_id = argument.strip
72
- end
73
-
74
- def render(context)
75
- search_form_template_path = "../../_layouts/search-full.html"
76
-
77
- result_item_template_path = "../../_includes/search-full-default-result-template.html"
78
- result_item_template = IO.read((File.expand_path(result_item_template_path, File.dirname(__FILE__))))
79
-
80
- context['empty_search_id'] = @empty_search_id
81
- SearchForm.render_form(context, search_form_template_path, result_item_template)
82
- end
83
- end
58
+ SearchForm.render_form(context, search_form_template_path, result_item_template)
59
+ end
60
+ end
61
+
62
+ # As the user types, a div is populated with search results.
63
+ # Differs from DropDownAutocomplete in that once you move focus away from the text input, the results
64
+ # are still displayed.
65
+ # Designed for a fully fledged search form on its own page.
66
+
67
+ # For each result result, this will render the template found between
68
+ # the {% fdroid_search_full_with_template %}{% endfdroid_search_full_with_template %} tags.
69
+ class FullSearchWithTemplate < Liquid::Block
70
+ def render(context)
71
+ search_form_template_path = "../../_layouts/search-full.html"
72
+ SearchForm.render_form(context, search_form_template_path, super.to_s)
73
+ end
74
+ end
75
+
76
+ # For each search result, this will render the contents of
77
+ # "_includes/search-full-default-result-template.html" from this plugin.
78
+ class DefaultFullSearch < Liquid::Tag
79
+ def initialize(tag_name, argument, tokens)
80
+ super
81
+ @empty_search_id = argument.strip
82
+ end
83
+
84
+ def render(context)
85
+ search_form_template_path = "../../_layouts/search-full.html"
86
+
87
+ result_item_template_path = "../../_includes/search-full-default-result-template.html"
88
+ result_item_template = IO.read((File.expand_path(result_item_template_path, File.dirname(__FILE__))))
89
+
90
+ context['empty_search_id'] = @empty_search_id
91
+ SearchForm.render_form(context, search_form_template_path, result_item_template)
92
+ end
93
+ end
84
94
  end
85
95
 
86
96
  Liquid::Template.register_tag('fdroid_search_autocomplete', Jekyll::DefaultDropDown)
@@ -18,23 +18,22 @@
18
18
  # Found at https://github.com/ggreer/jekyll-gallery-generator/blob/master/lib/jekyll-gallery-generator.rb#L69
19
19
 
20
20
  module Jekyll
21
+ class ReadYamlPage < Page
22
+ # We need do define it ourself because the templates are in the plugin's directory
23
+ def read_yaml(base, name, opts = {})
24
+ begin
25
+ self.content = File.read(File.join(base.to_s, name.to_s), (site ? site.file_read_opts : {}).merge(opts))
26
+ if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
27
+ self.content = $POSTMATCH
28
+ self.data = SafeYAML.load($1)
29
+ end
30
+ rescue SyntaxError => e
31
+ Jekyll.logger.warn "YAML Exception reading #{File.join(base.to_s, name.to_s)}: #{e.message}"
32
+ rescue Exception => e
33
+ Jekyll.logger.warn "Error reading file #{File.join(base.to_s, name.to_s)}: #{e.message}"
34
+ end
21
35
 
22
- class ReadYamlPage < Page
23
- # We need do define it ourself because the templates are in the plugin's directory
24
- def read_yaml(base, name, opts = {})
25
- begin
26
- self.content = File.read(File.join(base.to_s, name.to_s), (site ? site.file_read_opts : {}).merge(opts))
27
- if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
28
- self.content = $POSTMATCH
29
- self.data = SafeYAML.load($1)
30
- end
31
- rescue SyntaxError => e
32
- Jekyll.logger.warn "YAML Exception reading #{File.join(base.to_s, name.to_s)}: #{e.message}"
33
- rescue Exception => e
34
- Jekyll.logger.warn "Error reading file #{File.join(base.to_s, name.to_s)}: #{e.message}"
35
- end
36
-
37
- self.data ||= {}
38
- end
39
- end
36
+ self.data ||= {}
37
+ end
38
+ end
40
39
  end
@@ -8,11 +8,11 @@ require "v8"
8
8
  require "json"
9
9
 
10
10
  class V8::Object
11
- def to_json
12
- @context['JSON']['stringify'].call(self)
13
- end
11
+ def to_json
12
+ @context['JSON']['stringify'].call(self)
13
+ end
14
14
 
15
- def to_hash
16
- JSON.parse(to_json, :max_nesting => false)
17
- end
18
- end
15
+ def to_hash
16
+ JSON.parse(to_json, :max_nesting => false)
17
+ end
18
+ end
@@ -15,7 +15,6 @@ require 'v8'
15
15
  module Jekyll
16
16
  module LunrJsSearch
17
17
  class Indexer
18
-
19
18
  # @param [Jekyll::Site] site
20
19
  # @param [Array<App>] packages
21
20
  # @return [Object]
@@ -44,11 +43,11 @@ module Jekyll
44
43
 
45
44
  packages.each_with_index do |package, i|
46
45
  doc = {
47
- 'id' => i,
48
- 'packageName' => package.package_name,
49
- 'icon' => package.icon,
50
- 'name' => package.name,
51
- 'summary' => package.summary
46
+ 'id' => i,
47
+ 'packageName' => package.package_name,
48
+ 'icon' => package.icon,
49
+ 'name' => package.name,
50
+ 'summary' => package.summary
52
51
  }
53
52
 
54
53
  ctx['builder'].add(doc)
@@ -63,22 +62,23 @@ module Jekyll
63
62
  filename = File.join(@js_dir, 'index.json')
64
63
 
65
64
  total = {
66
- "docs" => @docs,
67
- "index" => @index.to_hash
65
+ "docs" => @docs,
66
+ "index" => @index.to_hash
68
67
  }
69
68
 
70
69
  filepath = File.join(site.dest, filename)
71
- File.open(filepath, "w") {|f| f.write(JSON.dump(total))}
70
+ File.open(filepath, "w") { |f| f.write(JSON.dump(total)) }
72
71
  Jekyll.logger.info "Lunr:", "Index ready (lunr.js v#{@lunr_version})"
73
72
  added_files = [filename]
74
73
 
75
74
  site_js = File.join(site.dest, @js_dir)
76
75
  extras = [
77
- 'assets/fdroid-search-autocomplete.js',
78
- 'bower_components/lunr.js/lunr.js',
79
- 'bower_components/mustache.js/mustache.min.js',
80
- 'bower_components/awesomplete/awesomplete.min.js',
81
- 'bower_components/awesomplete/awesomplete.css'
76
+ 'assets/fdroid-search-autocomplete.js',
77
+ 'assets/fdroid-search-autocomplete-init.js',
78
+ 'bower_components/lunr.js/lunr.js',
79
+ 'bower_components/mustache.js/mustache.min.js',
80
+ 'bower_components/awesomplete/awesomplete.min.js',
81
+ 'bower_components/awesomplete/awesomplete.css'
82
82
  ]
83
83
  Jekyll.logger.info "Lunr:", "Added required assets to #{@js_dir}"
84
84
  extras.each do |path|
@@ -5,12 +5,12 @@
5
5
  #
6
6
 
7
7
  module Jekyll
8
- module LunrJsSearch
9
- class SearchIndexFile < Jekyll::StaticFile
10
- # Override write as the index.json index file has already been created
11
- def write(dest)
12
- true
13
- end
14
- end
15
- end
16
- end
8
+ module LunrJsSearch
9
+ class SearchIndexFile < Jekyll::StaticFile
10
+ # Override write as the index.json index file has already been created
11
+ def write(dest)
12
+ true
13
+ end
14
+ end
15
+ end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-fdroid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nico Alt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-25 00:00:00.000000000 Z
11
+ date: 2017-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll-include-cache
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.50.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.50.0
97
111
  description: Browse packages of a F-Droid repository.
98
112
  email: nicoalt@posteo.org
99
113
  executables: []
@@ -138,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
152
  version: '0'
139
153
  requirements: []
140
154
  rubyforge_project:
141
- rubygems_version: 2.5.2.1
155
+ rubygems_version: 2.7.7
142
156
  signing_key:
143
157
  specification_version: 4
144
158
  summary: F-Droid - Free and Open Source Android App Repository