sms-logparser 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e9efb4712d1d9d54c9904f57993ced13742bd51
4
- data.tar.gz: 2fa877596b733aac7a13a27cd76ac22902978564
3
+ metadata.gz: 484db0ec68fb533d509b336f6d5258947a1550cb
4
+ data.tar.gz: c826cb94003ff3beea5b579e1967a4f3a45cd548
5
5
  SHA512:
6
- metadata.gz: ecb5588a86ae77f592f67117172b4b1d259fec82d7bd6e80305c70de60032db646c8751734eed245d5d90867a1e875bf08e366465a1db23dade2400df1744b61
7
- data.tar.gz: 1202cb4ff8e9d3820682e5cb6bbc0b032c0a5168dfc32c963915b5055f5bfe7a344e64870eb10a1d972e3d0f413e236b5e243f1fcd7b06638b94ea7ab6e5f098
6
+ metadata.gz: f1638d239b7bd9ef872f92b2c87271de78eb6ffe46b187609c132607adb7921f2637d0605f3a101c9ae808678b0fe2f995d4dcaff5d868c5e145d8e50f019441
7
+ data.tar.gz: 53b8660b214c5a8cd97de7160372b8b5082a5b13c851db48702aae481f0e2151de7118b9fb4024e6979d4c33b318f33988b108625248842ef40e8c7669b0a210
data/README.md CHANGED
@@ -20,11 +20,11 @@ Or install it yourself as:
20
20
 
21
21
  Create the database table to track which logs have been parsed:
22
22
 
23
- $ sms-logparser create_parser_table
23
+ $ sms-logparser setup
24
24
 
25
25
  Make a test run:
26
26
 
27
- $ sms-logparser parse --simulate
27
+ $ sms-logparser parse --simulate --verbose
28
28
 
29
29
  ## Usage
30
30
 
@@ -40,6 +40,13 @@ Show the last parser runs:
40
40
 
41
41
  $ sms-logparser last_runs
42
42
 
43
+ # Development
44
+
45
+ - check out the git repo (git clone ...)
46
+ - implement your changes
47
+ - run the tests `rake test`
48
+ - bump the version number commit your changes and release a new version of the gem `rake release`
49
+
43
50
  ## Contributing
44
51
 
45
52
  1. Fork it
@@ -6,20 +6,22 @@ module SmsLogparser
6
6
  end
7
7
 
8
8
  def send(data)
9
- url = "#{@options[:api_base_path]}/"
10
- url += "#{data[:customer_id]}/"
11
- url += "#{data[:author_id]}/"
12
- url += "#{data[:project_id]}/"
13
- url += "#{data[:traffic_type]}/"
14
- url += "#{data[:bytes]}"
9
+ base_url = "#{@options[:api_base_path]}/"
10
+ base_url += "#{data[:customer_id]}/"
11
+ base_url += "#{data[:author_id]}/"
12
+ base_url += "#{data[:project_id]}"
13
+ urls = ["#{base_url}/#{data[:traffic_type]}/#{data[:bytes]}"]
14
+ urls << "#{base_url}/#{data[:visitor_type]}/1" if data[:visitor_type]
15
15
  unless @options[:simulate]
16
- begin
17
- RestClient.get(url)
18
- rescue
19
- raise "Can't send log to #{url}"
16
+ urls.each do |url|
17
+ begin
18
+ RestClient.get(url)
19
+ rescue
20
+ raise "Can't send request to #{url}"
21
+ end
20
22
  end
21
23
  end
22
- url
24
+ urls
23
25
  end
24
26
 
25
27
  end # class
@@ -1,9 +1,10 @@
1
1
  module SmsLogparser
2
2
  class Cli < Thor
3
3
 
4
- class_option :mysql_host, :default => 'localhost'
5
- class_option :mysql_user, :default => 'root'
6
- class_option :mysql_db, :default => 'Syslog'
4
+ class_option :mysql_host, :default => 'localhost', aliases: %w(-h)
5
+ class_option :mysql_user, :default => 'root', aliases: %w(-u)
6
+ class_option :mysql_password, aliases: %w(-p)
7
+ class_option :mysql_db, :default => 'Syslog', aliases: %w(-d)
7
8
 
8
9
  desc "version", "print cloudstack-cli version number"
9
10
  def version
@@ -12,8 +13,9 @@ module SmsLogparser
12
13
  map %w(-v --version) => :version
13
14
 
14
15
  desc "parse", "Check the database for pcache logs and send them to SMS"
15
- option :api_base_path, :default => 'http://dev.simplex.tv/creator/rest'
16
- option :simulate, :type => :boolean, :default => false
16
+ option :api_base_path, :default => 'http://dev.simplex.tv/creator/rest', aliases: %w(-a)
17
+ option :simulate, :type => :boolean, :default => false, aliases: %w(-s)
18
+ option :verbose, :type => :boolean, :default => false, aliases: %w(-v)
17
19
  def parse
18
20
  start_time = Time.now
19
21
  count = 0
@@ -23,18 +25,27 @@ module SmsLogparser
23
25
  api = Api.new(options)
24
26
  last_id = mysql.get_last_parse_id
25
27
  entries.each do |entry|
26
- if Parser.match(entry)
28
+ if Parser.match(entry['Message'])
27
29
  data = Parser.extract_data_from_msg(entry['Message'])
28
- url = api.send(data)
30
+ begin
31
+ urls = api.send(data)
32
+ rescue => e
33
+ say "Error: #{e.message}", :red
34
+ say "Aborting parser run...", :red
35
+ break
36
+ end
29
37
  last_id = entry['ID']
30
38
  count += 1
31
- debug_parser_output(data, url, entry) if options[:simulate]
39
+ verbose_parser_output(data, urls, entry) if options[:verbose]
32
40
  end
33
41
  end
34
42
  mysql.write_parse_result(last_id, count) unless options[:simulate]
35
- puts "Started: #{start_time.strftime('%d.%d.%Y %T')}"
36
- puts "Runtime: #{(Time.now - start_time).round(2)}s"
37
- puts "Matches: #{count}"
43
+ say "Started:\t", :cyan
44
+ say start_time.strftime('%d.%d.%Y %T')
45
+ say "Runtime:\t", :cyan
46
+ say "#{(Time.now - start_time).round(2)}s"
47
+ options[:simulate] ? say("Events found:\t", :cyan) : say("Events sent:\t", :cyan)
48
+ say count
38
49
  rescue => e
39
50
  say "Error: #{e.message}", :red
40
51
  end
@@ -73,14 +84,14 @@ module SmsLogparser
73
84
  end
74
85
 
75
86
  no_commands do
76
- def debug_parser_output(data, url, entry)
77
- puts
78
- say "Message ID: ", :green
87
+ def verbose_parser_output(data, urls, entry)
88
+ say "ID:\t", :cyan
79
89
  say entry['ID']
80
- say "URL: ", :green
81
- say url
82
- say "Data: ", :green
83
- say data
90
+ say "URL:\t", :cyan
91
+ say urls.join("\n\t")
92
+ say "Data:\t", :cyan
93
+ say data.map{|k,v| "#{k}:\t#{v}"}.join("\n\t")
94
+ puts "-" * 100
84
95
  puts
85
96
  end
86
97
  end
@@ -9,6 +9,7 @@ module SmsLogparser
9
9
  @client ||= Mysql2::Client.new(
10
10
  :host => @options[:mysql_host],
11
11
  :username => @options[:mysql_user],
12
+ :password => @options[:mysql_password],
12
13
  :database => @options[:mysql_db]
13
14
  )
14
15
  end
@@ -1,34 +1,55 @@
1
1
  module SmsLogparser
2
2
  class Parser
3
3
 
4
- def self.extract_data_from_msg(msg)
5
- m = msg.match /\/content\/(\d+)\/(\d+)\/(\d+)\/.+\.(\S+)\s.*\"\s\d+\s(\d+).+"(.*)"$/
4
+ def self.extract_data_from_msg(message)
5
+ m = message.match /\/content\/(\d+)\/(\d+)\/(\d+)\/(\w+\.\w+)\s.*\"\s\d+\s(\d+).+"(.*)"$/
6
6
  raise "No match found." unless m
7
+ traffic_type = Parser.get_traffic_type(m[6])
8
+ visitor_type = Parser.get_visitor_type(traffic_type, m[4])
7
9
  data = {
8
10
  :customer_id => m[1],
9
11
  :author_id => m[2],
10
12
  :project_id => m[3],
11
- :ext => m[4],
12
- :traffic_type => Parser.get_traffic_type(m[4]),
13
+ :file => m[4],
13
14
  :bytes => m[5],
14
- :user_agent => m[6]
15
+ :user_agent => m[6],
16
+ :traffic_type => traffic_type,
17
+ :visitor_type => visitor_type
15
18
  }
16
19
  end
17
20
 
18
- def self.match(entry)
19
- entry['Message'] =~ /\/content\/.*\.(f4v|flv|mp4|mp3|ts) .*/
21
+ def self.match(message)
22
+ message =~ /\/content\/.*\.(f4v|flv|mp4|mp3|ts|m3u8) .* (200|206)/
20
23
  end
21
24
 
25
+ # see https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
26
+ # for mobile browser detection
22
27
  def self.get_traffic_type(user_agent)
23
28
  case user_agent
24
29
  when /.*(iTunes).*/
25
30
  "TRAFFIC_PODCAST"
26
- when /.*(IEMobile|Mobile Safari|iPhone|iPod|iPad).*/
31
+ when /.*(Mobi|IEMobile|Mobile Safari|iPhone|iPod|iPad|Android|BlackBerry|Opera Mini).*/
27
32
  "TRAFFIC_MOBILE"
28
33
  else
29
34
  "TRAFFIC_WEBCAST"
30
35
  end
31
36
  end
32
37
 
38
+ def self.get_visitor_type(traffic_type, file)
39
+ return "VISITORS_MOBILE" if file == 'index.m3u8'
40
+ case traffic_type
41
+ when "TRAFFIC_PODCAST"
42
+ "VISITORS_PODCAST"
43
+ when "TRAFFIC_MOBILE"
44
+ if File.extname(file) != ".ts"
45
+ "VISITORS_MOBILE"
46
+ else
47
+ nil
48
+ end
49
+ else
50
+ "VISITORS_WEBCAST"
51
+ end
52
+ end
53
+
33
54
  end # class
34
55
  end # module
@@ -1,3 +1,3 @@
1
1
  module SmsLogparser
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/cli_spec.rb CHANGED
@@ -25,7 +25,7 @@ describe SmsLogparser::Cli do
25
25
  TestHelper.sms_logparser.setup
26
26
  parser.parse
27
27
  end
28
- out.must_match /.*Matches: 10$/
28
+ out.must_match /\s+10$/
29
29
  end
30
30
 
31
31
  it "skips over already parsed logs" do
@@ -37,7 +37,7 @@ describe SmsLogparser::Cli do
37
37
  parser.parse
38
38
  parser.parse
39
39
  end
40
- out.must_match /.*Matches: 0$/
40
+ out.must_match /\s+0$/
41
41
  end
42
42
 
43
43
  it "lists parser runs" do
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmsLogparser::Parser do
4
+
5
+ %w(f4v flv mp4 mp3 ts m3u8).each do |extension|
6
+ it "matches #{extension} files" do
7
+ SmsLogparser::Parser.match(
8
+ "GET /content/2/719/54986/file.#{extension} HTTP/1.1\" 200 6741309 "
9
+ ).wont_be_nil
10
+ end
11
+ end
12
+
13
+ %w(jpg js css m4a docx).each do |extension|
14
+ it "does not matche #{extension} files" do
15
+ SmsLogparser::Parser.match(
16
+ "GET /content/2/719/54986/file.#{extension} HTTP/1.1\" 200 6741309 "
17
+ ).must_be_nil
18
+ end
19
+ end
20
+
21
+ %w(200 206).each do |status|
22
+ it "does match status code #{status}" do
23
+ SmsLogparser::Parser.match(
24
+ "GET /content/2/719/54986/file.mp4 HTTP/1.1\" #{status} 50000 "
25
+ ).wont_be_nil
26
+ end
27
+ end
28
+
29
+ %w(404 500 304).each do |status|
30
+ it "does not match status code #{status}" do
31
+ SmsLogparser::Parser.match(
32
+ "GET /content/2/719/54986/file.mp4 HTTP/1.1\" #{status} 50000 "
33
+ ).must_be_nil
34
+ end
35
+ end
36
+
37
+ %w(contents public index CONTENT).each do |dir|
38
+ it "does not match directories other than /content" do
39
+ SmsLogparser::Parser.match(
40
+ "GET /#{dir}/2/719/54986/file.mp4 HTTP/1.1\" 200 50000 "
41
+ ).must_be_nil
42
+ end
43
+ end
44
+
45
+ [
46
+ "Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10",
47
+ "Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0",
48
+ "Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50",
49
+ "Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047",
50
+ "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)",
51
+ "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
52
+ ].each do |mobile_agent|
53
+ it "traffic type for mobile user agents is TRAFFIC_MOBILE (#{mobile_agent})" do
54
+ SmsLogparser::Parser.get_traffic_type(mobile_agent).must_equal "TRAFFIC_MOBILE"
55
+ end
56
+ end
57
+
58
+ it "should set visitor_type to VISITORS_MOBILE for index.m3u8 files" do
59
+ SmsLogparser::Parser.get_visitor_type(
60
+ "TRAFFIC_PODCAST", "index.m3u8"
61
+ ).must_equal "VISITORS_MOBILE"
62
+ end
63
+
64
+ it "should NOT set visitor_type to VISITORS_MOBILE for TRAFFIC_MOBILE and .ts files" do
65
+ SmsLogparser::Parser.get_visitor_type(
66
+ "TRAFFIC_MOBILE", "file.ts"
67
+ ).must_be_nil
68
+ end
69
+
70
+ it "should set visitor_type to VISITORS_MOBILE for TRAFFIC_MOBILE and file not .ts" do
71
+ SmsLogparser::Parser.get_visitor_type(
72
+ "TRAFFIC_MOBILE", "file.mp3"
73
+ ).must_equal "VISITORS_MOBILE"
74
+ end
75
+
76
+ it "should set visitor_type to VISITORS_PODCAST for TRAFFIC_PODCAST" do
77
+ SmsLogparser::Parser.get_visitor_type(
78
+ "TRAFFIC_PODCAST", "file.mp4"
79
+ ).must_equal "VISITORS_PODCAST"
80
+ end
81
+
82
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sms-logparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - niwo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-13 00:00:00.000000000 Z
11
+ date: 2014-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,6 +102,7 @@ files:
102
102
  - lib/sms-logparser/version.rb
103
103
  - sms-logparser.gemspec
104
104
  - spec/cli_spec.rb
105
+ - spec/parser_spec.rb
105
106
  - spec/spec_helper.rb
106
107
  homepage: https://github.com/swisstxt/sms-logparser
107
108
  licenses:
@@ -129,4 +130,5 @@ specification_version: 4
129
130
  summary: SMS Logparser
130
131
  test_files:
131
132
  - spec/cli_spec.rb
133
+ - spec/parser_spec.rb
132
134
  - spec/spec_helper.rb