dark_links 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +54 -0
- data/README.md +22 -0
- data/Rakefile +9 -0
- data/dark_links.gemspec +25 -0
- data/lib/dark_links.rb +4 -0
- data/lib/dark_links/link_validator.rb +76 -0
- data/lib/dark_links/links_hstore_helpers.rb +13 -0
- data/lib/dark_links/version.rb +3 -0
- data/test/dark_links/link_validator_test.rb +126 -0
- data/test/test_helper.rb +5 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d9a194a52a3cc14b4890a8f5d8c9a08987ac0616331fd047152535c2fb7d9a60
|
4
|
+
data.tar.gz: 885db2e198cba358008d19eacf9e7d95dbaa93e0cfba9e68b622ea5c48b3e9a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 93e3cb0225a3a7fa53e633b2daedf5111eec0097736291034e817f8e0c99d73bf697d5f67675b795fe2799e5605560506378dd9509bf28351cf2d524709130f8
|
7
|
+
data.tar.gz: 168dbc17c0cb3850015a4527eca7a262c2fb7938a3ee9859f2c4e25fa906f86efce8fc260ebc5ad0f61208b81e6117b64f36fe517bb75f02db7a72c55a2be6c4
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/lomography/dark_links. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
|
4
|
+
|
5
|
+
# Contributor Code of Conduct
|
6
|
+
|
7
|
+
As contributors and maintainers of this project, and in the interest of
|
8
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
9
|
+
contribute through reporting issues, posting feature requests, updating
|
10
|
+
documentation, submitting pull requests or patches, and other activities.
|
11
|
+
|
12
|
+
We are committed to making participation in this project a harassment-free
|
13
|
+
experience for everyone, regardless of level of experience, gender, gender
|
14
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
15
|
+
body size, race, ethnicity, age, religion, or nationality.
|
16
|
+
|
17
|
+
Examples of unacceptable behavior by participants include:
|
18
|
+
|
19
|
+
* The use of sexualized language or imagery
|
20
|
+
* Personal attacks
|
21
|
+
* Trolling or insulting/derogatory comments
|
22
|
+
* Public or private harassment
|
23
|
+
* Publishing other's private information, such as physical or electronic
|
24
|
+
addresses, without explicit permission
|
25
|
+
* Other unethical or unprofessional conduct
|
26
|
+
|
27
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
28
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
29
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
30
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
31
|
+
threatening, offensive, or harmful.
|
32
|
+
|
33
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
34
|
+
fairly and consistently applying these principles to every aspect of managing
|
35
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
36
|
+
Conduct may be permanently removed from the project team.
|
37
|
+
|
38
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
39
|
+
when an individual is representing the project or its community.
|
40
|
+
|
41
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
42
|
+
reported by contacting a project maintainer at dev@lomography.com. All
|
43
|
+
complaints will be reviewed and investigated and will result in a response that
|
44
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
45
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
46
|
+
incident.
|
47
|
+
|
48
|
+
|
49
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
50
|
+
version 1.3.0, available at
|
51
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
52
|
+
|
53
|
+
[homepage]: http://contributor-covenant.org
|
54
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# dark_links
|
2
|
+
|
3
|
+
Dark_links provides a module to find broken urls in blobs of html and markdown markup.
|
4
|
+
Original code was written by [@srecnig](https://github.com/srecnig), gemification by [@michaelem](https://github.com/michaelem). If you're wondering, the name dark_links is a [reference](http://zeldawiki.org/Dark_Link).
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
Include ```DarkLinks::LinkValidator``` in your model or plain class and call the provided methods with the text you want to check for broken links.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
check_links("The Zelda series has a website: http://www.zelda.com/")
|
12
|
+
```
|
13
|
+
|
14
|
+
You will reccive a hash containing all the found links as keys and ```true``` (works) or ```false``` (broken) as values.
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
{ "http://www.zelda.com/" => true }
|
18
|
+
```
|
19
|
+
|
20
|
+
## License
|
21
|
+
|
22
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/dark_links.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dark_links/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'dark_links'
|
8
|
+
s.version = DarkLinks::VERSION
|
9
|
+
s.date = '2016-01-13'
|
10
|
+
s.summary = "Tries to find broken links."
|
11
|
+
s.description = "Provides concerns to find broken urls in blobs of markup and markdown."
|
12
|
+
s.authors = ["Michael Emhofer", "Martin Sereinig", "Markus Wegscheider"]
|
13
|
+
s.email = 'dev@lomography.com'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency 'httparty'
|
20
|
+
|
21
|
+
s.add_development_dependency 'byebug'
|
22
|
+
s.add_development_dependency 'minitest'
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'webmock'
|
25
|
+
end
|
data/lib/dark_links.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'uri'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module DarkLinks
|
6
|
+
module LinkValidator
|
7
|
+
def check_links( text )
|
8
|
+
new_links = {}
|
9
|
+
links = tokenize_links(text)[:link_tokens]
|
10
|
+
links.each do |token, url|
|
11
|
+
link_status = check_link(url)
|
12
|
+
if link_status == "OK"
|
13
|
+
new_links[url] = true
|
14
|
+
else
|
15
|
+
new_links[url] = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
new_links
|
19
|
+
end
|
20
|
+
|
21
|
+
def check_link( url )
|
22
|
+
begin
|
23
|
+
response = HTTParty.head(unescape_url(url))
|
24
|
+
|
25
|
+
if response.code >= 400
|
26
|
+
# maybe the server is just not allowing head requests (like instagram.com).
|
27
|
+
response = HTTParty.get(unescape_url(url))
|
28
|
+
end
|
29
|
+
|
30
|
+
if response.code < 400
|
31
|
+
"OK"
|
32
|
+
elsif response.code == 404
|
33
|
+
"Page could not be found"
|
34
|
+
elsif response.code >= 400 && response.code < 500
|
35
|
+
"Client Error"
|
36
|
+
elsif response.code >= 500 && response.code < 600
|
37
|
+
"Server Error"
|
38
|
+
else
|
39
|
+
"Unknowen Error"
|
40
|
+
end
|
41
|
+
rescue Timeout::Error, SocketError => e
|
42
|
+
"Can't find server"
|
43
|
+
rescue URI::InvalidURIError => e
|
44
|
+
"Is not a valid url"
|
45
|
+
rescue Errno::ECONNREFUSED => e
|
46
|
+
"The server is down."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def tokenize_links( text )
|
52
|
+
regex = %r{(http|https)://[^'\"[[:space:]]<]+}
|
53
|
+
tokens = {}
|
54
|
+
|
55
|
+
result = text.gsub( regex ) do |link|
|
56
|
+
append = ''
|
57
|
+
|
58
|
+
url = link.gsub(/[^\w\/-=&]\z/) do |char|
|
59
|
+
append = char
|
60
|
+
''
|
61
|
+
end
|
62
|
+
|
63
|
+
sha = Digest::SHA1.hexdigest(url)
|
64
|
+
tokens = tokens.merge( sha => unescape_url(url) )
|
65
|
+
|
66
|
+
"[[link:#{sha}]]#{append}"
|
67
|
+
end
|
68
|
+
{ body: result, link_tokens: tokens }
|
69
|
+
end
|
70
|
+
|
71
|
+
def unescape_url( url )
|
72
|
+
url = CGI.unescapeHTML( url )
|
73
|
+
CGI.unescape(url)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module DarkLinks
|
4
|
+
class LinkValidatorTest < Minitest::Test
|
5
|
+
def test_links_hash_should_reflect_link_status
|
6
|
+
stub_request(:any, "http://www.lomography.com/").to_return(status: 200)
|
7
|
+
stub_request(:any, "http://www.lomographybrrzl.com/").to_timeout
|
8
|
+
|
9
|
+
|
10
|
+
links = Text.new.check_links("visit us at http://www.lomography.com ")
|
11
|
+
assert_equal [true], links.values
|
12
|
+
|
13
|
+
links = Text.new.check_links("this text does not contain any links")
|
14
|
+
assert_equal [], links.values
|
15
|
+
|
16
|
+
links = Text.new.check_links("brzl brzl: http://www.lomographybrrzl.com")
|
17
|
+
assert_equal [false], links.values
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_links_with_errors
|
21
|
+
stub_request(:any, "http://www.lomography.com/").to_return(status: 200)
|
22
|
+
stub_request(:any, "http://www.lomography.com/brzlbrzl").to_return(status: 404)
|
23
|
+
stub_request(:any, "http://www.lomographybrrzl.com/").to_timeout
|
24
|
+
|
25
|
+
links = Text.new.check_links("wrong: http://www.lomographybrrzl.com, 404: http://www.lomography.com/brzlbrzl, ok: http://www.lomography.com/ ")
|
26
|
+
assert_equal false, links["http://www.lomographybrrzl.com"]
|
27
|
+
assert_equal false, links["http://www.lomography.com/brzlbrzl"]
|
28
|
+
assert_equal true, links["http://www.lomography.com/"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_link_with_internal_server_error
|
32
|
+
stub_request(:any, "http://www.lomography.com/server_error").to_return(status: 500)
|
33
|
+
|
34
|
+
links = Text.new.check_links("server error: http://www.lomography.com/server_error")
|
35
|
+
assert_equal false, links["http://www.lomography.com/server_error"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_escaped_link
|
39
|
+
stub_request(:any, "http://www.nasa.gov/hello?id=42&key=23").to_return(status: 200)
|
40
|
+
links = Text.new.check_links("Here is something that you might find in html: <a href=\"http://www.nasa.gov/hello?id=42&key=23\">nasa</a>")
|
41
|
+
assert_equal true, links["http://www.nasa.gov/hello?id=42&key=23"]
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_https_link
|
45
|
+
stub_request(:any, "https://www.nasa.gov/").to_return(status: 200)
|
46
|
+
links = Text.new.check_links("Here is something that you might find in html: <a href=\"https://www.nasa.gov/\">nasa</a>")
|
47
|
+
assert_equal true, links["https://www.nasa.gov/"]
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_server_that_only_allows_get
|
51
|
+
stub_request(:head, "http://www.lomography.com/").to_return(status: 405)
|
52
|
+
stub_request(:get, "http://www.lomography.com/").to_return(status: 200)
|
53
|
+
|
54
|
+
links = Text.new.check_links("ok: http://www.lomography.com/ ")
|
55
|
+
assert_equal true, links["http://www.lomography.com/"]
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def test_with_same_link_with_different_unicode_spaces
|
60
|
+
stub_request(:any, "http://www.lomography.com/").to_return(status: 200)
|
61
|
+
|
62
|
+
links = Text.new.check_links("link like this: \"http://www.lomography.com\u00A0\" is the same as link like this: \"http://www.lomography.com \"")
|
63
|
+
|
64
|
+
assert_equal true, links["http://www.lomography.com"]
|
65
|
+
assert_equal 1, links.count
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_link_with_connection_refused_error
|
69
|
+
stub_request(:head, "http://shop.lomography.jp/").to_raise(Errno::ECONNREFUSED)
|
70
|
+
|
71
|
+
links = Text.new.check_links("server error: http://shop.lomography.jp/")
|
72
|
+
|
73
|
+
assert_equal false, links["http://shop.lomography.jp/"]
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_real_world_test
|
77
|
+
urls = [
|
78
|
+
"http://www.w3.org/1999/xhtml",
|
79
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
|
80
|
+
"https://www.facebook.com/lomographyitalia/",
|
81
|
+
"http://www.thelomographer.com/static/facebook.black.png",
|
82
|
+
"https://www.instagram.com/lomographyitalia/",
|
83
|
+
"http://www.thelomographer.com/static/instagram.black.png",
|
84
|
+
"https://www.twitter.com/lomography",
|
85
|
+
"http://www.thelomographer.com/static/twitter.black.png",
|
86
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/it",
|
87
|
+
"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope",
|
88
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/header-top.jpg",
|
89
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/header.it.gif",
|
90
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif",
|
91
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/section1-3.jpg",
|
92
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/section1-2.jpg",
|
93
|
+
"https://www.facebook.com/events/120325625357735",
|
94
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/section2.jpg",
|
95
|
+
"http://www.humansofnaples.it/",
|
96
|
+
"https://shop.lomography.com/it/cameras/lomo-instant-wide",
|
97
|
+
"https://www.maratonafotograficabrescia.it/maratona-fotografica/brescia-speciale-tappa-istantanea-collaborazione-lomography/",
|
98
|
+
"http://www.thelomographer.com/2017/nl_local_events_it/images/section3.jpg",
|
99
|
+
"https://shop.lomography.com/it/lomo-instant-camera-murano",
|
100
|
+
"http://www.thelomographer.com/2017/nl_redesign_events/images/space.gif",
|
101
|
+
"https://microsites.lomography.com/25-years-of-lomography/get-involved/",
|
102
|
+
"http://www.thelomographer.com/static/footer_25years.gif",
|
103
|
+
"http://shop.lomography.com/it",
|
104
|
+
"https://www.lomography.it/about/stores",
|
105
|
+
"https://www.lomography.it/",
|
106
|
+
"https://www.lomography.it/magazine",
|
107
|
+
"http://www.thelomographer.com/static/lomography.png"
|
108
|
+
]
|
109
|
+
|
110
|
+
urls.each do |url|
|
111
|
+
stub_request(:any, url).to_return(status: 200)
|
112
|
+
end
|
113
|
+
|
114
|
+
text = "\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n <head>\r\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width,maximum-scale=1.0,initial-scale=1.0,minimum-scale=1.0\">\r\n <title>Eventi di fotografia istantanea in tutta Italia</title>\r\n <style type=\"text/css\">\r\n body { padding: 0; margin: 0; color: #4f5661; }\r\n img { outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }\r\n a img { border: none; }\r\n a { color: #4f5661; text-decoration: underline; }\r\n a:hover { color: #4f5661; }\r\n .ExternalClass * { line-height: 79%; }\r\n .c-ReadMessagePartBody .ExternalClass a:link { text-decoration: none; }\r\n @media only screen and (min-width: 600px) {\r\n table.large { width: 100%; max-width: 700px; }\r\n table.large img.responsive { width: 100%; height: auto; }\r\n }\r\n @media only screen and (max-width: 600px) {\r\n img.spacer { width: 100%; }\r\n img.responsive { width: 100%; height: auto; }\r\n table { width: 100% !important; }\r\n td.responsive { display: block !important; width: auto !important; }\r\n }\r\n </style>\r\n <!--[if gte mso 9]> <style> li { text-indent: -1em; } </style> <![endif]-->\r\n </head>\r\n <body bgcolor=\"#ffffff\" style=\"background-color: #ffffff; -webkit-text-size-adjust: none;\">\r\n <span class=\"preheader\" style=\"display: none; color: #ffffff;\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #ffffff;\">Siamo felici oggi di presentare alcuni eventi di fotografia istantanea che si svolgeranno presto in alcune città italiane: da segnare...</font></span>\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td align=\"center\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"20\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td valign=\"middle\" align=\"left\">\r\n <a href=\"https://www.facebook.com/lomographyitalia/\"><img width=\"24\" height=\"24\" alt=\"Facebook\" src=\"http://www.thelomographer.com/static/facebook.black.png\" /></a>\r\n <a href=\"https://www.instagram.com/lomographyitalia/\"><img width=\"24\" height=\"24\" alt=\"Instagram\" src=\"http://www.thelomographer.com/static/instagram.black.png\" /></a>\r\n <a href=\"https://www.twitter.com/lomography\"><img width=\"24\" height=\"24\" alt=\"Twitter\" src=\"http://www.thelomographer.com/static/twitter.black.png\" /></a>\r\n </td>\r\n <td valign=\"middle\" align=\"right\">\r\n <font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #4f5661;\"><a style=\"color: #4f5661; text-decoration: underline;\" href=\"http://www.thelomographer.com/2017/nl_local_events_it/it\">Visualizza nel browser</a></font> </td>\r\n </tr>\r\n</table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"large\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/header-top.jpg\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"large\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/header.it.gif\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #4f5661;\">Siamo felici oggi di presentare alcuni eventi di fotografia istantanea che si svolgeranno presto in alcune città italiane: da segnare in agenda e da non farseli perdere se siete in zona.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n\r\n\r\n\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 36px; line-height: 40px; color: #4f5661 !important; color: #4f5661;\">La bellezza ritrovata: Mostra Fotografica di Charley Fazio e i bambini siriani</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/section1-3.jpg\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #4f5661;\">Charley Fazio è un fotografo specializzato in progetti umanitari. Di recente si è recato a Killis, città presso il confine turco-siriano, dove è rimasto colpito dalla speranza e innocenza presente negli occhi dei bambini rifugiati. <br><br>Charley non si è limitato ad immortalare le vite dei ragazzi, ma li ha coinvolti in prima persona in un progetto fotografico. Ha infatti consegnato loro una Lomo'Instant Wide, chiedendogli di trasmettere attraverso le immagini la loro idea di bellezza: un'occasione unica per sentirsi speciali e per dare forma ai propri pensieri.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/section1-2.jpg\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #4f5661;\">La prima data sarà ospitata presso le sale nobiliari del Castello Visconteo di Voghera (PV) dal 1 al 15 ottobre 2017, per poi toccare, in forma itinerante, diverse città italiane ed europee, anche con lo scopo di promuovere i progetti delle Onlus a sostegno degli stessi bambini siriani, ai quali sono destinati i ricavi delle vendite delle istantanee.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\">\r\n <div>\r\n <!--[if mso]>\r\n <v:rect xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\" style=\"width: 270px;\" strokewidth=\"1px\" strokecolor=\"#7c9bd3\" fillcolor=\"#7c9bd3\">\r\n <v:textbox style=\"mso-fit-shape-to-text:t\" inset=\"14px,7px,14px,7px\">\r\n <center style=\"color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal;\">LEGGI DI PIÙ</center>\r\n </v:textbox>\r\n </v:rect>\r\n <![endif]-->\r\n <a href=\"http://www.lomography.it/magazine/332819-la-bellezza-ritrovata-a-shot-per-hope\" style=\"background-color: #7c9bd3; border: 1px solid #7c9bd3; border-radius: 14px; color: #ffffff; display: inline-block; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal; text-align: center; text-decoration: none; width: 320px; padding: 14px 0;\"><span style=\"display: inline-block; padding: 0 14px;\">LEGGI DI PIÙ</span></a>\r\n </div>\r\n </td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n\r\n\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 36px; line-height: 40px; color: #4f5661 !important; color: #4f5661;\">Instant - Humans of Naples x Lomography</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"https://www.facebook.com/events/120325625357735\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/section2.jpg\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #4f5661;\"><a style=\"color: #4f5661; text-decoration: underline;\" href=\"http://www.humansofnaples.it/\">Humans of Naples</a> è un progetto fotografico di Vincenzo Noletto, con il quale vuole raccontare le storie degli abitanti della città partenopea. <br><br>Il 22 settembre, dalle ore 19, Domenico e Vincenzo organizzano Instant, mostra fotografica vuota, in cui tutti i visitatori diventano soggetti fotografati e protagonisti della mostra stessa. Le foto saranno scattate con la <a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://shop.lomography.com/it/cameras/lomo-instant-wide\">Lomo’Instant Wide</a> e faranno parte della nuova sezione di \"Humans of Naples\". <br><br>Vi aspettano il 22 settembre allo Slash art/msic (via Vincenzo Bellini, 45; Napoli) dalle 19:00.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\">\r\n <div>\r\n <!--[if mso]>\r\n <v:rect xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" href=\"https://www.facebook.com/events/120325625357735\" style=\"width: 270px;\" strokewidth=\"1px\" strokecolor=\"#7c9bd3\" fillcolor=\"#7c9bd3\">\r\n <v:textbox style=\"mso-fit-shape-to-text:t\" inset=\"14px,7px,14px,7px\">\r\n <center style=\"color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal;\">EVENTO FB</center>\r\n </v:textbox>\r\n </v:rect>\r\n <![endif]-->\r\n <a href=\"https://www.facebook.com/events/120325625357735\" style=\"background-color: #7c9bd3; border: 1px solid #7c9bd3; border-radius: 14px; color: #ffffff; display: inline-block; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal; text-align: center; text-decoration: none; width: 320px; padding: 14px 0;\"><span style=\"display: inline-block; padding: 0 14px;\">EVENTO FB</span></a>\r\n </div>\r\n </td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n\r\n\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 36px; line-height: 40px; color: #4f5661 !important; color: #4f5661;\">Maratona Fotografica di Brescia – Speciale Tappa Istantanea</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\" class=\"\">\r\n <tr>\r\n <td class=\"responsive\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\"><a href=\"https://www.maratonafotograficabrescia.it/maratona-fotografica/brescia-speciale-tappa-istantanea-collaborazione-lomography/\"><img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/section3.jpg\" /></a></td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #4f5661;\">Il 17 settembre, durante la Maratona Fotografica di Brescia, c’è la possibilità di provare una Lomo’Instant, compilando <a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://www.maratonafotograficabrescia.it/maratona-fotografica/brescia-speciale-tappa-istantanea-collaborazione-lomography/\">questo form</a>. Al termine della Maratona Fotografica, verrà scelta la migliore istantanea e premiata con la nuova <a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://shop.lomography.com/it/lomo-instant-camera-murano\">Lomo’Instant Murano</a>.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\">\r\n <div>\r\n <!--[if mso]>\r\n <v:rect xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" href=\"https://www.maratonafotograficabrescia.it/maratona-fotografica/brescia-speciale-tappa-istantanea-collaborazione-lomography/\" style=\"width: 270px;\" strokewidth=\"1px\" strokecolor=\"#7c9bd3\" fillcolor=\"#7c9bd3\">\r\n <v:textbox style=\"mso-fit-shape-to-text:t\" inset=\"14px,7px,14px,7px\">\r\n <center style=\"color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal;\">LEGGI DI PIÙ</center>\r\n </v:textbox>\r\n </v:rect>\r\n <![endif]-->\r\n <a href=\"https://www.maratonafotograficabrescia.it/maratona-fotografica/brescia-speciale-tappa-istantanea-collaborazione-lomography/\" style=\"background-color: #7c9bd3; border: 1px solid #7c9bd3; border-radius: 14px; color: #ffffff; display: inline-block; font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 14px; line-height: 20px; font-weight: normal; text-align: center; text-decoration: none; width: 320px; padding: 14px 0;\"><span style=\"display: inline-block; padding: 0 14px;\">LEGGI DI PIÙ</span></a>\r\n </div>\r\n </td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"60\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#383653\" style=\"line-height: 0px; background-color: #383653;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" background=\"http://www.thelomographer.com/2017/nl_redesign_events/images/space.gif\" style=\"line-height: 0px; background-color: #ffffff; background-image: url('http://www.thelomographer.com/2017/nl_redesign_events/images/space.gif'); background-repeat: repeat-y; background-size: 100% auto;\" class=\"\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <a href=\"https://microsites.lomography.com/25-years-of-lomography/get-involved/\">\r\n <img width=\"600\" class=\"responsive\" alt=\"photo\" src=\"http://www.thelomographer.com/static/footer_25years.gif\" />\r\n </a>\r\n </td>\r\n </tr>\r\n</table>\r\n\r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#383653\" style=\"background-color: #383653;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#383653\" style=\"background-color: #383653;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 16px; line-height: 30px; color: #ffffff;\">\r\n<span style=\"font-family:sans-serif;\">\r\nVenticinque anni fa, il mondo della fotografia è cambiato per sempre. Unisciti a noi nel festeggiare i 25 anni di Lomography! Da competizioni a mostre, feste e molto altro ancora, abbiamo un sacco di novità in programma. Visita il <a style=\"color: #ffffff; text-decoration: underline;\" href=\"https://microsites.lomography.com/25-years-of-lomography/get-involved/\">microsito dei 25 Anni di Lomography </a> e partecipa anche tu!\r\n</span>\r\n</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#383653\" style=\"line-height: 0px; background-color: #383653;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"80\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #4f5661;\"><a style=\"color: #4f5661; text-decoration: underline;\" href=\"%{unsubscribe_link}\">Gestisci le tue impostazioni di ricezione</a><br/><a style=\"color: #4f5661; text-decoration: underline;\" href=\"http://shop.lomography.com/it\">Dai un’occhiata ai nostri prodotti</a><br/><a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://www.lomography.it/about/stores\">Visita uno dei nostri store</a><br/><a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://www.lomography.it\">Unisciti alla community</a><br/><a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://www.lomography.it/magazine\">Leggi il nostro magazine</a></font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #4f5661;\"><strong>Lomography Italy</strong>: Kaiserstrasse 34/12, 1070 Vienna, Austria, <a style=\"color: #4f5661; text-decoration: underline;\" href=\"tel:+431899440\">+43-1-899-440</a><br/></font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"left\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #4f5661;\">Nonostante il contenuto di questa newsletter sia stato creato con massima attenzione, non diamo garanzia delle correttezza e completezza delle informazioni date. La disponibilità dei prodotti può variare a seconda della località.</font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"10\" width=\"600\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" bgcolor=\"#ffffff\" style=\"background-color: #ffffff;\">\r\n <table border=\"0\" cellpadding=\"10\" cellspacing=\"0\" width=\"580\">\r\n <tr>\r\n <td class=\"responsive\" valign=\"top\" align=\"center\"><font style=\"font-family: -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', 'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; font-size: 13px; line-height: 26px; color: #4f5661;\"><a style=\"color: #4f5661; text-decoration: underline;\" href=\"https://www.lomography.it\"><img width=\"192\" height=\"42\" alt=\"Lomography\" src=\"http://www.thelomographer.com/static/lomography.png\" /></a></font></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n \r\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" bgcolor=\"#ffffff\" style=\"line-height: 0px; background-color: #ffffff;\">\r\n <tr>\r\n <td class=\"responsive\">\r\n <img width=\"600\" height=\"40\" class=\"spacer\" alt=\" \" src=\"http://www.thelomographer.com/2017/nl_local_events_it/images/spacer.gif\" />\r\n </td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n </body>\r\n</html>\r\n"
|
115
|
+
links = Text.new.check_links(text)
|
116
|
+
|
117
|
+
assert links.values.all? { |e| e }
|
118
|
+
assert_equal 30, links.count
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
class Text
|
124
|
+
include DarkLinks::LinkValidator
|
125
|
+
end
|
126
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dark_links
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Emhofer
|
8
|
+
- Martin Sereinig
|
9
|
+
- Markus Wegscheider
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2016-01-13 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: httparty
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: byebug
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: minitest
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: rake
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: webmock
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
description: Provides concerns to find broken urls in blobs of markup and markdown.
|
86
|
+
email: dev@lomography.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- CONTRIBUTING.md
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- dark_links.gemspec
|
95
|
+
- lib/dark_links.rb
|
96
|
+
- lib/dark_links/link_validator.rb
|
97
|
+
- lib/dark_links/links_hstore_helpers.rb
|
98
|
+
- lib/dark_links/version.rb
|
99
|
+
- test/dark_links/link_validator_test.rb
|
100
|
+
- test/test_helper.rb
|
101
|
+
homepage:
|
102
|
+
licenses: []
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.7.6
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Tries to find broken links.
|
124
|
+
test_files: []
|