jekyll-fdroid 0.2.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
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