sniffles 0.1.2 → 0.1.3
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.
- data/README.md +38 -5
- data/lib/sniffles/sniffers/advertising/gumgum.rb +24 -0
- data/lib/sniffles/sniffers/advertising/kontera.rb +24 -0
- data/lib/sniffles/sniffers/advertising/thedeck.rb +24 -0
- data/lib/sniffles/sniffers/advertising/tribalfusion.rb +24 -0
- data/lib/sniffles/sniffers/analytics/google_analytics.rb +1 -1
- data/lib/sniffles/sniffers/analytics/piwik.rb +24 -0
- data/lib/sniffles/sniffers/cms/bigcommerce.rb +24 -0
- data/lib/sniffles/sniffers/cms/flatpress.rb +35 -0
- data/lib/sniffles/sniffers/cms/invision.rb +35 -0
- data/lib/sniffles/sniffers/cms/joomla.rb +34 -0
- data/lib/sniffles/sniffers/cms/mybb.rb +24 -0
- data/lib/sniffles/sniffers/cms/prestashop.rb +28 -0
- data/lib/sniffles/sniffers/cms/shopify.rb +24 -0
- data/lib/sniffles/sniffers/cms/typepad.rb +28 -0
- data/lib/sniffles/sniffers/cms/vbulletin.rb +10 -2
- data/lib/sniffles/version.rb +1 -1
- data/sniffles.gemspec +4 -5
- data/spec/cassettes/blackhatworld_com.yml +3352 -0
- data/spec/cassettes/community_invisionpower_com.yml +2785 -0
- data/spec/cassettes/demo-store_prestashop_com.yml +852 -0
- data/spec/cassettes/demo_forum-software_org_mybb.yml +385 -0
- data/spec/cassettes/downlopedia_com.yml +1401 -0
- data/spec/cassettes/flatpress_org_home_blog.yml +368 -0
- data/spec/cassettes/invisionmodding_com.yml +2456 -0
- data/spec/cassettes/joomla_org.yml +733 -0
- data/spec/cassettes/metafilter_com.yml +1250 -0
- data/spec/cassettes/pandoramoa_com.yml +622 -0
- data/spec/cassettes/shop_angrybirds_com.yml +455 -0
- data/spec/cassettes/sixflags_com.yml +1028 -0
- data/spec/cassettes/softpedia_com.yml +3196 -0
- data/spec/cassettes/soulemama_typepad_com.yml +2645 -0
- data/spec/cassettes/tmz_com.yml +2927 -0
- data/spec/sniffles/sniffers/advertising/gumgum_spec.rb +18 -0
- data/spec/sniffles/sniffers/advertising/kontera_spec.rb +18 -0
- data/spec/sniffles/sniffers/advertising/thedeck_spec.rb +18 -0
- data/spec/sniffles/sniffers/advertising/tribalfusion_spec.rb +18 -0
- data/spec/sniffles/sniffers/analytics/google_analytics_spec.rb +7 -0
- data/spec/sniffles/sniffers/analytics/piwik_spec.rb +17 -0
- data/spec/sniffles/sniffers/cms/bigcommerce_spec.rb +18 -0
- data/spec/sniffles/sniffers/cms/flatpress_spec.rb +19 -0
- data/spec/sniffles/sniffers/cms/invision_spec.rb +26 -0
- data/spec/sniffles/sniffers/cms/joomla_spec.rb +19 -0
- data/spec/sniffles/sniffers/cms/mybb_spec.rb +18 -0
- data/spec/sniffles/sniffers/cms/prestashop_spec.rb +18 -0
- data/spec/sniffles/sniffers/cms/shopify_spec.rb +18 -0
- data/spec/sniffles/sniffers/cms/typepad_spec.rb +18 -0
- data/spec/sniffles/sniffers/cms/vbulletin_spec.rb +7 -1
- metadata +56 -64
data/README.md
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
# Sniffles
|
2
2
|
## Description
|
3
|
-
Sniffles parses HTML pages and searches for common patterns suggesting a page is using popular CMS
|
3
|
+
Sniffles parses HTML pages and searches for common patterns suggesting a page is using a popular CMS or advertising platform as well as CSS and JS libraries.
|
4
4
|
|
5
|
-
|
5
|
+
The master branch is continuously tested against Rubies 1.8.7, 1.9.2, and 1.9.3 thanks to the fantastic [Travis-CI](http://travis-ci.org/#!/ezkl/sniffles).
|
6
|
+
|
7
|
+
Current CI status: [](http://travis-ci.org/ezkl/sniffles)
|
8
|
+
|
9
|
+
|
10
|
+
### What is a sniffer?
|
11
|
+
This library uses the term **sniffer** to refer to a pattern that determines where a page is using a particular platform or library. A sniffer may also include methods to extract other metadata once a platform or library has been identified.
|
12
|
+
|
13
|
+
### Work in progress!
|
14
|
+
Sniffles should be considered a work in progress. Many of the matching patterns are little more than regular expressions matching commonly found "Powered by" text.
|
15
|
+
|
16
|
+
If you find a bug or want to add a feature to a sniffer, [open an issue](https://github.com/ezkl/sniffles/issues/new)! The URL of an example page that Sniffles misidentifies is help. Pull requests are, of course, greatly appreciated.
|
6
17
|
|
7
18
|
## Installation
|
8
19
|
Rubygems:
|
@@ -27,7 +38,7 @@ You can pass in a single sniffer:
|
|
27
38
|
Or multiple sniffers:
|
28
39
|
|
29
40
|
Sniffles.sniff(response.body, :google_analytics, :kissmetrics)
|
30
|
-
# => {:google_analytics=>{:found=>true, :ua=>"UA-185209-2"}, :kissmetrics=>{:found=>false}}
|
41
|
+
# => { :google_analytics=> { :found=>true, :ua=>"UA-185209-2"}, :kissmetrics=>{:found=>false} }
|
31
42
|
|
32
43
|
Or an entire group of sniffers:
|
33
44
|
|
@@ -39,12 +50,18 @@ Or an entire group of sniffers:
|
|
39
50
|
# :mixpanel=>{:found=>true},
|
40
51
|
# :quantcast=>{:found=>true}}
|
41
52
|
|
42
|
-
## Sniffers (v0.1.
|
53
|
+
## Sniffers (v0.1.3)
|
54
|
+
Here are a list of currently implemented sniffers, grouped by category. You can see a list of unimplemented sniffers by [filtering issues by "sniffer"](https://github.com/ezkl/sniffles/issues?labels=sniffer&state=open).
|
55
|
+
|
43
56
|
### Advertising
|
44
57
|
* AdMeld
|
45
58
|
* AdSense
|
46
59
|
* BuySellAds
|
47
60
|
* Casale
|
61
|
+
* GumGum
|
62
|
+
* Kontera
|
63
|
+
* TheDeck
|
64
|
+
* TribalFusion
|
48
65
|
|
49
66
|
### Analytics
|
50
67
|
* ChartBeat
|
@@ -52,16 +69,25 @@ Or an entire group of sniffers:
|
|
52
69
|
* Google Analytics
|
53
70
|
* KISSMetrics
|
54
71
|
* MixPanel
|
72
|
+
* Piwik
|
55
73
|
* Quantcast
|
56
74
|
|
57
75
|
### CMS
|
76
|
+
* BigCommerce
|
58
77
|
* Blogger
|
59
78
|
* CS-Cart
|
79
|
+
* FlatPress
|
80
|
+
* Invision
|
81
|
+
* Joomla
|
60
82
|
* MovableType
|
83
|
+
* MyBB
|
61
84
|
* osCommerce
|
62
85
|
* phpBB
|
63
86
|
* Posterous
|
87
|
+
* PrestaShop
|
88
|
+
* Shopify
|
64
89
|
* Tumblr
|
90
|
+
* TypePad
|
65
91
|
* Vanilla
|
66
92
|
* vBulletin
|
67
93
|
* WordPress
|
@@ -69,4 +95,11 @@ Or an entire group of sniffers:
|
|
69
95
|
* ZenCart
|
70
96
|
|
71
97
|
### Javascript
|
72
|
-
* jQuery
|
98
|
+
* jQuery
|
99
|
+
|
100
|
+
## Contributors
|
101
|
+
For a complete list see [github](https://github.com/ezkl/sniffles/contributors).
|
102
|
+
|
103
|
+
### Special Thanks
|
104
|
+
* [Jake Austwick](https://github.com/JakeAustwick)
|
105
|
+
* [dchuk](https://github.com/dchuk)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Gumgum
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /cdn\.gumgum\.com/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Kontera
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /kona\.kontera\.com/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Thedeck
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /connect\.decknetwork\.net/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Tribalfusion
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /a\.tribalfusion\.com/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Piwik
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match?(/Piwik\.getTracker/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Bigcommerce
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /config\.ShopPath/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Flatpress
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
if @output[:found] = found?
|
16
|
+
parse_version
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def found?
|
22
|
+
!!(meta_generator_content =~ /FlatPress/)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_version
|
26
|
+
version_capture = (meta_generator_content.match /FlatPress fp\-([\d]+\.[\d]+\.[\d]+)/)
|
27
|
+
@output[:version] = (version_capture ? version_capture[1] : false)
|
28
|
+
end
|
29
|
+
|
30
|
+
def meta_generator_content
|
31
|
+
text_at("//meta[@name='generator']/@content")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Invision
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
if @output[:found] = found?
|
16
|
+
parse_version
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def found?
|
22
|
+
!!(copyright_link =~ /Forum Software by IP\.Board/)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_version
|
26
|
+
version_capture = (copyright_link.match /Software by IP\.Board ([\d]+\.[\d]+\.[\d]+(?: Beta [\d]+))/)
|
27
|
+
@output[:version] = version_capture ? version_capture[1] : false
|
28
|
+
end
|
29
|
+
|
30
|
+
def copyright_link
|
31
|
+
text_at("//p[@id='copyright']/a")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Joomla
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
if @output[:found] = found?
|
16
|
+
parse_version
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def found?
|
22
|
+
!!(meta_generator_content =~ /Joomla!/)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_version
|
26
|
+
@output[:version] = (meta_generator_content =~ /Joomla! ([\d]+\.[\d]+)/ ? $1 : false)
|
27
|
+
end
|
28
|
+
|
29
|
+
def meta_generator_content
|
30
|
+
text_at("//meta[@name='generator']/@content")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Mybb
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
!!(@doc.text =~ /Powered By MyBB/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Prestashop
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
meta_generator_content == "PrestaShop"
|
21
|
+
end
|
22
|
+
|
23
|
+
def meta_generator_content
|
24
|
+
text_at("//meta[@name='generator']/@content")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Shopify
|
4
|
+
include Text
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
match? /cdn\.shopify\.com/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sniffles
|
2
|
+
module Sniffers
|
3
|
+
class Typepad
|
4
|
+
include HTML
|
5
|
+
|
6
|
+
attr_accessor :doc
|
7
|
+
attr_reader :output
|
8
|
+
|
9
|
+
def initialize(response_body)
|
10
|
+
@output = {}
|
11
|
+
parse(response_body) && process_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_document
|
15
|
+
@output[:found] = found?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def found?
|
20
|
+
meta_generator_content == "http://www.typepad.com/"
|
21
|
+
end
|
22
|
+
|
23
|
+
def meta_generator_content
|
24
|
+
text_at("//meta[@name='generator']/@content")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|