sniffles 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: [![Build Status](https://secure.travis-ci.org/ezkl/sniffles.png?branch=master)](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
|