manifique 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 00df9b37b792f5e1f1fe570552ee34831f59ce5c5ece2f8adb77b0343436df0b
4
+ data.tar.gz: a26c16c6d67d0f03647f97214f000296765dd79eb6c5614f39be334f421ce14f
5
+ SHA512:
6
+ metadata.gz: 871ce502960bbeda400047e7d4bd793fc1e7819ffa4d5ec4707102d0e0db1937a3de406a94656fe16736e5f7e20997e5ad7419cf8512efa63732eb79ea3c2fc5
7
+ data.tar.gz: 7397a7bd3d96f6f78fd46a2c002702c2c47cd0c5c52409d8099dc0fc3e4175c0e2ebaf67c9668e95df3c41c98d78bdda83c547bd7773b37a7f9e58bb892e656f
data/.drone.yml ADDED
@@ -0,0 +1,9 @@
1
+ kind: pipeline
2
+ name: default
3
+
4
+ steps:
5
+ - name: specs
6
+ image: ruby
7
+ commands:
8
+ - bundle install --jobs=3 --retry=3
9
+ - rake spec
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .rspec_status
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at sebastian@kip.pe. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in manifique.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ manifique (1.0.0)
5
+ faraday (~> 2.9.0)
6
+ faraday-follow_redirects (= 0.3.0)
7
+ nokogiri (~> 1.16.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.8.6)
13
+ public_suffix (>= 2.0.2, < 6.0)
14
+ bigdecimal (3.1.6)
15
+ coderay (1.1.3)
16
+ crack (0.4.6)
17
+ bigdecimal
18
+ rexml
19
+ diff-lcs (1.5.1)
20
+ faraday (2.9.0)
21
+ faraday-net_http (>= 2.0, < 3.2)
22
+ faraday-follow_redirects (0.3.0)
23
+ faraday (>= 1, < 3)
24
+ faraday-net_http (3.0.2)
25
+ hashdiff (1.1.0)
26
+ method_source (1.0.0)
27
+ nokogiri (1.16.0-aarch64-linux)
28
+ racc (~> 1.4)
29
+ nokogiri (1.16.0-arm-linux)
30
+ racc (~> 1.4)
31
+ nokogiri (1.16.0-arm64-darwin)
32
+ racc (~> 1.4)
33
+ nokogiri (1.16.0-x86-linux)
34
+ racc (~> 1.4)
35
+ nokogiri (1.16.0-x86_64-darwin)
36
+ racc (~> 1.4)
37
+ nokogiri (1.16.0-x86_64-linux)
38
+ racc (~> 1.4)
39
+ pry (0.14.2)
40
+ coderay (~> 1.1)
41
+ method_source (~> 1.0)
42
+ public_suffix (5.0.4)
43
+ racc (1.7.3)
44
+ rake (13.1.0)
45
+ rexml (3.2.6)
46
+ rspec (3.12.0)
47
+ rspec-core (~> 3.12.0)
48
+ rspec-expectations (~> 3.12.0)
49
+ rspec-mocks (~> 3.12.0)
50
+ rspec-core (3.12.2)
51
+ rspec-support (~> 3.12.0)
52
+ rspec-expectations (3.12.3)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.12.0)
55
+ rspec-mocks (3.12.6)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.12.0)
58
+ rspec-support (3.12.1)
59
+ webmock (3.19.1)
60
+ addressable (>= 2.8.0)
61
+ crack (>= 0.3.2)
62
+ hashdiff (>= 0.4.0, < 2.0.0)
63
+
64
+ PLATFORMS
65
+ aarch64-linux
66
+ arm-linux
67
+ arm64-darwin
68
+ x86-linux
69
+ x86_64-darwin
70
+ x86_64-linux
71
+
72
+ DEPENDENCIES
73
+ bundler (~> 2.5.5)
74
+ manifique!
75
+ pry (~> 0.14.2)
76
+ rake (~> 13.1.0)
77
+ rspec (~> 3.12)
78
+ webmock (~> 3.19.1)
79
+
80
+ BUNDLED WITH
81
+ 2.5.5
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard :rspec, cmd: 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/manifique/(.+)\.rb$}) { |m| "spec/manifique/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2024 Kosmos Infrastructure Foundation (KIF)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice (including the next
11
+ paragraph) shall be included in all copies or substantial portions of the
12
+ Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ [![Build Status](https://drone.kosmos.org/api/badges/5apps/manifique/status.svg)](https://drone.kosmos.org/5apps/manifique)
2
+
3
+ # Manifique
4
+
5
+ Manifique fetches metadata of Web applications, like e.g. name, description,
6
+ and app icons. It prefers information from Web App Manifest files, and falls
7
+ back to parsing HTML if necessary.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'manifique'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install manifique
22
+
23
+ ## Usage
24
+
25
+ First, initialize a Manifique agent for the web app you want to get metadata
26
+ for. Its URL is the only required argument:
27
+
28
+ ```ruby
29
+ agent = Manifique::Agent.new(url: "https://kosmos.social")
30
+ ```
31
+
32
+ Now you can fetch its metadata:
33
+
34
+ ```ruby
35
+ metadata = agent.fetch_metadata
36
+ ```
37
+
38
+ ### Selecting icons
39
+
40
+ Let's select an icon that we like:
41
+
42
+ ```ruby
43
+ icon = metadata.select_icon(type: "image/png", sizes: "96x96")
44
+ ```
45
+
46
+ Or maybe just iOS icons? They're pretty convenient for postprocessing after all.
47
+
48
+ ```ruby
49
+ icon = metadata.select_icon(purpose: "apple-touch-icon", sizes: "180x180")
50
+ ```
51
+
52
+ ## Development
53
+
54
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
55
+ `rake spec` to run the specs once, or `bundle exec guard` to watch all source
56
+ files and run their specs automatically.
57
+
58
+ You can also run `bin/console` for an interactive prompt that will allow you to
59
+ experiment.
60
+
61
+ To install this gem onto your local machine, run `bundle exec rake install`. To
62
+ release a new version, update the version number in `version.rb`, and then run
63
+ `bundle exec rake release`, which will create a git tag for the version, push
64
+ git commits and tags, and push the `.gem` file to
65
+ [rubygems.org](https://rubygems.org).
66
+
67
+ ## Contributing
68
+
69
+ Bug reports and pull requests are welcome on the
70
+ [Kosmos Gitea](https://gitea.kosmos.org/5apps/manifique) or on
71
+ [GitHub](https://github.com/5apps/manifique). Please add specs for any changes
72
+ or additions.
73
+
74
+ ## Code of Conduct
75
+
76
+ Everyone interacting in this project’s codebase, issue trackers, and chat
77
+ rooms is expected to follow the [code of
78
+ conduct](https://gitea.kosmos.org/5apps/manifique/src/branch/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "manifique"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,33 @@
1
+ require 'uri'
2
+ require "manifique/web_client"
3
+
4
+ module Manifique
5
+ class Agent
6
+
7
+ def initialize(options={})
8
+ @options = options
9
+
10
+ if url_valid?(options[:url])
11
+ @url = options[:url]
12
+ else
13
+ raise "No valid URL specified"
14
+ end
15
+ end
16
+
17
+ def fetch_metadata
18
+ web_client = WebClient.new(url: @url)
19
+ web_client.fetch_metadata
20
+ end
21
+
22
+ private
23
+
24
+ def url_valid?(str)
25
+ return false unless str.class == String
26
+ url = URI.parse(str)
27
+ url.kind_of?(URI::HTTP) || url.kind_of?(URI::HTTPS)
28
+ rescue URI::InvalidURIError
29
+ false
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module Manifique
2
+ class Error < ::StandardError
3
+ attr_reader :type, :url
4
+
5
+ def initialize(msg="Encountered an error", type="generic", url)
6
+ @type = type
7
+ @url = url
8
+ super(msg)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,181 @@
1
+ module Manifique
2
+ class Metadata
3
+
4
+ attr_accessor :url, :from_web_manifest, :from_html,
5
+ :name, :short_name, :description, :icons,
6
+ :theme_color, :background_color, :display,
7
+ :start_url, :scope, :share_target
8
+
9
+ def initialize(data={})
10
+ self.url = data[:url]
11
+ self.from_web_manifest = Set.new
12
+ self.from_html = Set.new
13
+ self.icons = []
14
+ end
15
+
16
+ def load_from_web_manifest(manifest)
17
+ [ :name, :short_name, :description, :icons,
18
+ :theme_color, :background_color, :display,
19
+ :start_url, :scope, :share_target ].map(&:to_s).each do |prop|
20
+ next unless manifest[prop] && !manifest[prop].to_s.empty?
21
+ self.send("#{prop}=", manifest[prop])
22
+ self.from_web_manifest.add(prop)
23
+ end
24
+ end
25
+
26
+ def load_from_html(html)
27
+ @html = html
28
+ parse_title_from_html
29
+ parse_meta_elements_from_html
30
+ parse_display_mode_from_html
31
+ parse_icons_from_html
32
+ end
33
+
34
+ def select_icon(options={})
35
+ if options[:type].nil? && options[:sizes].nil? && options[:purpose].nil?
36
+ raise ArgumentError, "Tell me what to do!"
37
+ end
38
+
39
+ results = icons.dup
40
+
41
+ if options[:purpose]
42
+ results.reject! { |r| r["purpose"] != options[:purpose] }
43
+ end
44
+
45
+ if options[:type]
46
+ results.reject! { |r| r["type"] != options[:type] }
47
+ end
48
+
49
+ if options[:sizes]
50
+ results.reject! { |r| r["sizes"].nil? }
51
+ results.sort! { |a, b| sizes_to_i(b["sizes"]) <=> sizes_to_i(a["sizes"]) }
52
+
53
+ if icon = select_exact_size(results, options[:sizes])
54
+ return icon
55
+ else
56
+ return select_best_size(results, options[:sizes])
57
+ end
58
+ end
59
+
60
+ results.first
61
+ end
62
+
63
+ def to_json
64
+ # TODO serialize into JSON
65
+ end
66
+
67
+ private
68
+
69
+ def parse_title_from_html
70
+ return if self.name
71
+
72
+ if title = @html.at_css("title") and !title.text.empty?
73
+ self.name = title.text
74
+ self.from_html.add "name"
75
+ end
76
+ end
77
+
78
+ def parse_meta_elements_from_html
79
+ {
80
+ description: "description",
81
+ theme_color: "theme-color"
82
+ }.each do |prop, name|
83
+ next if self.send("#{prop}")
84
+ if value = get_meta_element_value(name)
85
+ self.send "#{prop}=", value
86
+ self.from_html.add prop.to_s
87
+ end
88
+ end
89
+ end
90
+
91
+ def parse_display_mode_from_html
92
+ return if self.display
93
+
94
+ if get_meta_element_value("apple-mobile-web-app-capable") == "yes"
95
+ self.display = "standalone"
96
+ self.from_html.add "display"
97
+ end
98
+ end
99
+
100
+ def get_meta_element_value(name)
101
+ if el = @html.at_css("meta[name=#{name}]") and !el.attributes["content"].value.empty?
102
+ el.attributes["content"].value
103
+ end
104
+ end
105
+
106
+ def parse_icons_from_html
107
+ parse_link_icons_from_html
108
+ parse_apple_touch_icons_from_html
109
+ parse_mask_icon_from_html
110
+ end
111
+
112
+ def parse_link_icons_from_html
113
+ return if self.icons.any?
114
+
115
+ if icon_links = @html.css("link[rel=icon]")
116
+ icon_links.each do |link|
117
+ icon = {}
118
+ icon["src"] = link.attributes["href"].value rescue nil
119
+ next unless is_adequate_src(icon["src"])
120
+ icon["sizes"] = link.attributes["sizes"].value rescue nil
121
+ icon["type"] = link.attributes["type"].value rescue get_icon_type(icon["src"])
122
+ self.icons.push icon
123
+ self.from_html.add "icons"
124
+ end
125
+ end
126
+ end
127
+
128
+ def parse_apple_touch_icons_from_html
129
+ if icon_links = @html.css("link[rel=apple-touch-icon]")
130
+ icon_links.each do |link|
131
+ icon = { "purpose" => "apple-touch-icon" }
132
+ icon["src"] = link.attributes["href"].value rescue nil
133
+ next unless is_adequate_src(icon["src"])
134
+ icon["sizes"] = link.attributes["sizes"].value rescue nil
135
+ icon["type"] = link.attributes["type"].value rescue get_icon_type(icon["src"])
136
+ self.icons.push icon
137
+ self.from_html.add "icons"
138
+ end
139
+ end
140
+ end
141
+
142
+ def parse_mask_icon_from_html
143
+ if mask_icon_link = @html.at_css("link[rel=mask-icon]")
144
+ icon = { "purpose" => "mask-icon" }
145
+ icon["src"] = mask_icon_link.attributes["href"].value rescue nil
146
+ return unless is_adequate_src(icon["src"])
147
+ icon["type"] = link.attributes["type"].value rescue get_icon_type(icon["src"])
148
+ icon["color"] = mask_icon_link.attributes["color"].value rescue nil
149
+ self.icons.push icon
150
+ self.from_html.add "icons"
151
+ end
152
+ end
153
+
154
+ def is_data_url?(src)
155
+ !!src.match(/^data:/)
156
+ end
157
+
158
+ def is_adequate_src(src)
159
+ !src.to_s.empty? && !is_data_url?(src)
160
+ end
161
+
162
+ def get_icon_type(src)
163
+ extension = src.match(/\.([a-zA-Z]+)$/)[1]
164
+ "image/#{extension}"
165
+ end
166
+
167
+ def sizes_to_i(str)
168
+ str.match(/(\d+)x/)[1].to_i
169
+ end
170
+
171
+ def select_exact_size(results, sizes)
172
+ results.select{|r| r["sizes"] == sizes}[0]
173
+ end
174
+
175
+ def select_best_size(results, sizes)
176
+ results.reject! { |r| sizes_to_i(r["sizes"]) < sizes_to_i(sizes) }
177
+ results.last
178
+ end
179
+
180
+ end
181
+ end
@@ -0,0 +1,3 @@
1
+ module Manifique
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,71 @@
1
+ require 'json'
2
+ require 'faraday'
3
+ require 'faraday/follow_redirects'
4
+ require 'nokogiri'
5
+ require 'manifique/metadata'
6
+ require 'manifique/errors'
7
+
8
+ module Manifique
9
+ class WebClient
10
+
11
+ def initialize(options={})
12
+ @options = options
13
+ @url = options[:url]
14
+ @metadata = Metadata.new(url: @url)
15
+ end
16
+
17
+ def fetch_metadata
18
+ fetch_website
19
+
20
+ if manifest = fetch_web_manifest
21
+ @metadata.load_from_web_manifest(manifest)
22
+ end
23
+ @metadata.load_from_html(@html)
24
+
25
+ @metadata
26
+ end
27
+
28
+ private
29
+
30
+ def fetch_website
31
+ res = do_get_request @url
32
+ @html = Nokogiri::HTML(res.body)
33
+ rescue
34
+ false
35
+ end
36
+
37
+ def fetch_web_manifest
38
+ return false unless manifest_url = discover_web_manifest_url(@html)
39
+
40
+ unless manifest_url.match(/^https?\:\/\//)
41
+ # Link is just the manifest path, not an absolute URL
42
+ manifest_url = [@url.gsub(/\/$/, ''), manifest_url.gsub(/^\//, '')].join('/')
43
+ end
44
+
45
+ res = do_get_request manifest_url
46
+
47
+ JSON.parse(res.body)
48
+ end
49
+
50
+ def do_get_request(url)
51
+ conn = Faraday.new do |faraday|
52
+ faraday.response :follow_redirects
53
+ faraday.adapter Faraday.default_adapter
54
+ end
55
+ res = conn.get url
56
+ if res.status < 400
57
+ res
58
+ else
59
+ raise Manifique::Error.new "Failed with HTTP status #{res.status}", "http_#{res.status}", url
60
+ end
61
+ rescue Faraday::ConnectionFailed, Faraday::TimeoutError, Faraday::SSLError
62
+ raise Manifique::Error.new "Failed to connect", "connection_failed", url
63
+ end
64
+
65
+ def discover_web_manifest_url(html)
66
+ html.at_css("link[rel=manifest]").attributes["href"].value
67
+ rescue
68
+ false
69
+ end
70
+ end
71
+ end
data/lib/manifique.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "manifique/version"
2
+
3
+ module Manifique
4
+ autoload :Agent, "manifique/agent"
5
+ end
data/manifique.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "manifique/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "manifique"
7
+ spec.version = Manifique::VERSION
8
+ spec.licenses = ["MIT"]
9
+ spec.authors = ["Râu Cao"]
10
+ spec.email = ["raucao@kosmos.org"]
11
+ spec.summary = "Fetch metadata and icons of Web applications"
12
+ spec.description = "Fetch and process metadata and icons of Web applications from Web App Manifest files, with fallbacks to HTML elements/attributes}"
13
+ spec.homepage = "https://gitea.kosmos.org/5apps/manifique"
14
+ spec.metadata = {
15
+ "bug_tracker_uri" => "https://gitea.kosmos.org/5apps/manifique/issues",
16
+ "source_code_uri" => "https://gitea.kosmos.org/5apps/manifique"
17
+ }
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_development_dependency "bundler", "~> 2.5.5"
29
+ spec.add_development_dependency "rake", "~> 13.1.0"
30
+ spec.add_development_dependency "rspec", "~> 3.12"
31
+ spec.add_development_dependency "webmock", "~> 3.19.1"
32
+ spec.add_development_dependency "pry", "~> 0.14.2"
33
+
34
+ spec.add_runtime_dependency "faraday", "~> 2.9.0"
35
+ spec.add_runtime_dependency "faraday-follow_redirects", "0.3.0"
36
+ spec.add_runtime_dependency "nokogiri", "~> 1.16.0"
37
+ end
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: manifique
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Râu Cao
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.5.5
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.5.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 13.1.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 13.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.19.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.19.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.14.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.14.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.9.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.9.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday-follow_redirects
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.3.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.3.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: nokogiri
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.16.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.16.0
125
+ description: Fetch and process metadata and icons of Web applications from Web App
126
+ Manifest files, with fallbacks to HTML elements/attributes}
127
+ email:
128
+ - raucao@kosmos.org
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".drone.yml"
134
+ - ".gitignore"
135
+ - CODE_OF_CONDUCT.md
136
+ - Gemfile
137
+ - Gemfile.lock
138
+ - Guardfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - bin/console
143
+ - bin/setup
144
+ - lib/manifique.rb
145
+ - lib/manifique/agent.rb
146
+ - lib/manifique/errors.rb
147
+ - lib/manifique/metadata.rb
148
+ - lib/manifique/version.rb
149
+ - lib/manifique/web_client.rb
150
+ - manifique.gemspec
151
+ homepage: https://gitea.kosmos.org/5apps/manifique
152
+ licenses:
153
+ - MIT
154
+ metadata:
155
+ bug_tracker_uri: https://gitea.kosmos.org/5apps/manifique/issues
156
+ source_code_uri: https://gitea.kosmos.org/5apps/manifique
157
+ post_install_message:
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubygems_version: 3.5.5
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Fetch metadata and icons of Web applications
176
+ test_files: []