nosy 0.0.4 → 0.0.5

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/.gitignore CHANGED
@@ -1 +1,5 @@
1
- .DS_Store
1
+ .DS_Store
2
+ iphone-texts.html
3
+ iphone-texts.json
4
+ iphone-texts.csv
5
+
data/README.md CHANGED
@@ -12,6 +12,13 @@ Nosy returns an array of messages with the fields
12
12
  * imessage (Boolean)
13
13
  * date (contains a unix timestamp)
14
14
 
15
+ which can then be outputted to
16
+
17
+ * a html file (default)
18
+ * a json string
19
+ * a json document
20
+ * a csv documents
21
+
15
22
 
16
23
  ## Install
17
24
 
@@ -19,7 +26,37 @@ Nosy returns an array of messages with the fields
19
26
 
20
27
  Or add Nosy to your Gemfile and run `bundle install`.
21
28
 
29
+ ## From the command line
30
+
31
+ Nosy can be run from the command line using:
32
+
33
+ # Find, parse and output to an HTML file
34
+ $ nosy
35
+
36
+ # … to a JSON file
37
+ $ nosy json true
38
+
39
+ # … to a JSON string
40
+ $ nosy json false
41
+
42
+ # … to a CSV file
43
+ $ nosy csv
44
+
45
+ Note: This will only work on a Mac OSX system. Nosy (is nosy, and) will try to grab your iOS message database, parse it, and then export it, but only knows where the files are stored on a Mac system.
46
+
22
47
  ## Find and Parse
48
+ If you are on a Mac OSX system, Nosy (is nosy, and) will try to grab your iOS message database, parse it, and then export it.
49
+
50
+ all_texts = Nosy.hunt_and_parse
51
+
52
+ all_texts.each do |text|
53
+ text.receiver
54
+ text.sender
55
+ text.message
56
+ text.imessage
57
+ text.date
58
+ end
59
+
23
60
  If you are on a Mac OSX system, Nosy (is nosy, and) will try to grab your iOS message database and parse it.
24
61
 
25
62
  all_texts = Nosy.hunt_and_parse
@@ -78,7 +115,7 @@ Nosy can search through the texts in your iOS message database. Nosy searching s
78
115
  * imessage
79
116
  * date - supports a Unix timestamp and an optional leading operator [ < , > , <= , >= ]
80
117
 
81
- #
118
+ Note
82
119
 
83
120
  nosty_texts = Nosy.new(iphone_database_location)
84
121
 
@@ -89,7 +126,27 @@ Nosy can search through the texts in your iOS message database. Nosy searching s
89
126
  before_then_texts = nosty_texts.search(:date => "<1273175931")
90
127
 
91
128
  # Array of texts where I am the sender and the date is less than 1273175931
92
- before_then_texts = nosty_texts.search(:sender => "me", :date => "<1273175931")
129
+ before_then_texts = nosty_texts.search(:sender => "me", :date => "<1273175931")`
130
+
131
+ ## Outputting
132
+
133
+ If you provide nosy with an array of texts it will be able to output them to a html file, json string, json file, or csv. The method will return the location of the file.
134
+
135
+ # All texts to a json file
136
+ all_texts = Nosy.hunt_and_parse
137
+ Nosy.output(all_texts, "json", true)
138
+
139
+ # All texts to a json string
140
+ Nosy.output(all_texts, "json", false)
141
+
142
+ # Texts from me to a csv file
143
+ nosty_texts = Nosy.new(iphone_database_location)
144
+ my_sent_texts = nosty_texts.search(:sender => "me")
145
+ Nosy.output(my_sent_texts, "csv")
146
+
147
+ # Texts from me to a html file
148
+ Nosy.output(my_sent_texts, "html")
149
+
93
150
 
94
151
  ## Contributions
95
152
  Contributions, improvements, and suggestions more than welcome! Please!
@@ -101,7 +158,6 @@ Currently, Nosy is yet to...
101
158
  * Properly handle MMS (group and media) messages.
102
159
  * Let you search for two values in one key.
103
160
  * Let you hunt for the iOS message database on systems other than Mac OSX.
104
- * Support creating a backup file.
105
161
  * Run on Heroku due to its dependency on Sqlite3.
106
162
 
107
163
  ## Acknowledgment
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nosy'
4
+
5
+ if ARGV[0] == nil
6
+ p Nosy.hunt_parse_and_output
7
+ elsif ["html","json","csv"].include?(ARGV[0])
8
+ p Nosy.hunt_parse_and_output(ARGV[0], ARGV[1] == "true" ? true : false)
9
+ elsif ["hunt","find","locate"].include?(ARGV[0])
10
+ p Nosy.hunt
11
+ else
12
+ p Nosy.hunt_parse_and_output
13
+ end
@@ -1,4 +1,5 @@
1
1
  require "nosy/hunter"
2
+ require "nosy/output"
2
3
  require "nosy/parser"
3
4
  require "nosy/searcher"
4
5
 
@@ -12,6 +13,20 @@ module Nosy
12
13
  Parser.new.parse(Hunter.new.hunt)
13
14
  end
14
15
 
16
+ def self.hunt_parse_and_output(output_type="html", output_to_file=true)
17
+ if output_type == "json"
18
+ if output_to_file == true
19
+ Output.new.to_json(parse(Hunter.new.hunt), true)
20
+ else
21
+ Output.new.to_json(parse(Hunter.new.hunt), false)
22
+ end
23
+ elsif output_type == "csv"
24
+ Output.new.to_csv(parse(Hunter.new.hunt))
25
+ else
26
+ Output.new.to_html(parse(Hunter.new.hunt))
27
+ end
28
+ end
29
+
15
30
  def self.new(file)
16
31
  Searcher.new(file)
17
32
  end
@@ -23,4 +38,18 @@ module Nosy
23
38
  def self.parse(file)
24
39
  Parser.new.parse(file)
25
40
  end
41
+
42
+ def self.output(texts, output_type="html", output_to_file=true)
43
+ if output_type == "json"
44
+ if output_to_file == true
45
+ Output.new.to_json(texts, true)
46
+ else
47
+ Output.new.to_json(texts, false)
48
+ end
49
+ elsif output_type == "csv"
50
+ Output.new.to_csv(texts)
51
+ else
52
+ Output.new.to_html(texts)
53
+ end
54
+ end
26
55
  end
@@ -0,0 +1,49 @@
1
+ require 'nosy/output/html_helpers'
2
+ require 'json'
3
+ require 'csv'
4
+
5
+ module Nosy
6
+
7
+ class Output
8
+ include HtmlHelpers
9
+
10
+ def to_html( texts )
11
+ File.open("iphone-texts.html","w") do |f|
12
+ generate_html(f, texts)
13
+ end
14
+ "#{Dir.pwd}/iphone-texts.html"
15
+ end
16
+
17
+ def to_json( texts, file=false )
18
+ hash = to_hash(texts)
19
+
20
+ if file == true
21
+ File.open("iphone-texts.json","w") do |f|
22
+ f.write(hash.to_json)
23
+ end
24
+ "#{Dir.pwd}/iphone-texts.json"
25
+ else
26
+ hash.to_json
27
+ end
28
+ end
29
+
30
+ def to_csv( texts, output=nil )
31
+ CSV.open("iphone-texts.csv", "w") do |csv|
32
+ csv << ["id", "date", "sender", "receiver", "message", "imessage"]
33
+ texts.each_with_index do |text, index|
34
+ csv << [index+1, text.date, text.sender, text.receiver, text.message, text.imessage]
35
+ end
36
+ end
37
+ "#{Dir.pwd}/iphone-texts.csv"
38
+ end
39
+
40
+ def to_hash (texts)
41
+ hash = {}
42
+ texts.each_with_index do |m, index|
43
+ hash["#{index}"] = { date: m.date, sender: m.sender, receiver: m.receiver, message: m.message, imessage: m.imessage }
44
+ end
45
+ hash
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,162 @@
1
+ module Nosy
2
+
3
+ class Output
4
+
5
+ module HtmlHelpers
6
+
7
+ def generate_html(f, texts)
8
+ f.puts "<!doctype html><head>#{head}<style>#{css}</style></head><body><div id='container'>"
9
+ texts.each do |text|
10
+ if text.sender == "me"
11
+ f.puts "<article class='sending'>"
12
+ html_text(f, text)
13
+ f.puts "</article>"
14
+ else
15
+ f.puts "<article class='receiving'>"
16
+ html_text(f, text)
17
+ f.puts "</article>"
18
+ end
19
+ f.puts ""
20
+ f.puts "<hr />"
21
+ f.puts ""
22
+ end
23
+ f.puts "</div></body></html>"
24
+ end
25
+
26
+ def css
27
+ "/* http://meyerweb.com/eric/tools/css/reset/
28
+ v2.0 | 20110126
29
+ License: none (public domain)
30
+ */
31
+
32
+ html, body, div, span, applet, object, iframe,
33
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
34
+ a, abbr, acronym, address, big, cite, code,
35
+ del, dfn, em, img, ins, kbd, q, s, samp,
36
+ small, strike, strong, sub, sup, tt, var,
37
+ b, u, i, center,
38
+ dl, dt, dd, ol, ul, li,
39
+ fieldset, form, label, legend,
40
+ table, caption, tbody, tfoot, thead, tr, th, td,
41
+ article, aside, canvas, details, embed,
42
+ figure, figcaption, footer, header, hgroup,
43
+ menu, nav, output, ruby, section, summary,
44
+ time, mark, audio, video {
45
+ margin: 0;
46
+ padding: 0;
47
+ border: 0;
48
+ font-size: 100%;
49
+ font: inherit;
50
+ vertical-align: baseline;
51
+ }
52
+ /* HTML5 display-role reset for older browsers */
53
+ article, aside, details, figcaption, figure,
54
+ footer, header, hgroup, menu, nav, section {
55
+ display: block;
56
+ }
57
+ body {
58
+ line-height: 1;
59
+ }
60
+ ol, ul {
61
+ list-style: none;
62
+ }
63
+ blockquote, q {
64
+ quotes: none;
65
+ }
66
+ blockquote:before, blockquote:after,
67
+ q:before, q:after {
68
+ content: '';
69
+ content: none;
70
+ }
71
+ table {
72
+ border-collapse: collapse;
73
+ border-spacing: 0;
74
+ }
75
+
76
+ body{
77
+ background: #f9f8f6;
78
+ color: #606060;
79
+ font-family: Helvetica, Arial, sans-serif;
80
+ font-size: 18px;
81
+ line-height: 1.8333em;
82
+ padding: 40px 0;
83
+ word-wrap: break-word;
84
+ -webkit-font-smoothing: antialiased;
85
+ }
86
+
87
+ #container{
88
+ width: 400px;
89
+ margin: 0 auto;
90
+ padding: 0 40px;
91
+ }
92
+
93
+ hr {
94
+ border: none;
95
+ background-color: #ccc;
96
+ color: #ccc;
97
+ height: 1px;
98
+ margin: 45px 0;
99
+ }
100
+
101
+ article ul {
102
+ margin: 40px 0 0 0;
103
+ }
104
+
105
+ article ul li {
106
+ font-size: 0.6777em;
107
+ padding: 0px;
108
+ line-height: 1.7em;
109
+ }
110
+
111
+ article ul li.sender{
112
+ font-size: 1.555em;
113
+ font-weight: bold;
114
+ }
115
+
116
+ article.sending{
117
+ text-align: right;
118
+ }"
119
+ end
120
+
121
+ def head
122
+ "<meta charset='utf-8'>
123
+ <title>Texts</title>
124
+ <meta name='description' content=''>
125
+ <meta name='author' content='Nosy - pdud - Phil Dudley - iPhone Message (SMS/ iMessage) Exporter'>
126
+ <meta name='viewport' content='width=device-width, user-scalable=no'>
127
+ <!-- IE Fix for HTML5 Tags -->
128
+ <!--[if lt IE 9]>
129
+ <script src='http://html5shiv.googlecode.com/svn/trunk/html5.js'></script>
130
+ <![endif]-->"
131
+ end
132
+
133
+ def html_text (f, text)
134
+ f.puts "<p>#{text.message}</p>"
135
+ f.puts "<ul>"
136
+ sender_html(f, text)
137
+ f.puts "<li>#{Time.at(text.date).strftime('%A, %B %e, %Y at %l:%M%P')}</li>"
138
+ end
139
+
140
+ def sender_html(f, text)
141
+ if text.sender == "me"
142
+ f.puts "<li class='sender'>#{text.sender}</li>"
143
+ f.puts "<li>to #{text.receiver} via #{imessage_or_sms(f, text)}</li>"
144
+ else
145
+ f.puts "<li class='sender'>#{text.sender}</li>"
146
+ f.puts "<li>to #{text.receiver} via #{imessage_or_sms(f, text)}</li>"
147
+ end
148
+ end
149
+
150
+ def imessage_or_sms(f, text)
151
+ if text.imessage
152
+ "iMessage"
153
+ else
154
+ "SMS"
155
+ end
156
+ end
157
+
158
+ end
159
+ end
160
+ end
161
+
162
+
@@ -1,13 +1,16 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'nosy'
3
- gem.version = '0.0.4'
4
- gem.date = '2012-01-02'
5
- gem.summary = "Output, backup, and read all your iPhone text messages"
6
- gem.description = "Nosy fetches, parses and searches the iPhone's SMS database that is created on your machine each time you make a backup."
3
+ gem.version = '0.0.5'
4
+ gem.date = '2012-01-08'
5
+ gem.summary = "Output, backup, search, and read all your iPhone text messages"
6
+ gem.description = "Nosy fetches, parses and searches the iPhone's SMS database that is created on your machine each time you make a backup. It can export to HTML, CSV, or JSON."
7
7
  gem.authors = ["Philip Dudley"]
8
8
  gem.homepage = "https://github.com/pdud/Nosy"
9
9
  gem.email = 'pdudley89@gmail.com'
10
10
  gem.files = `git ls-files`.split("\n")
11
11
  gem.add_dependency("sqlite3", "~> 1.3.4")
12
+ gem.add_dependency("json", "~> 1.6.4")
12
13
  gem.add_development_dependency("rspec", "~> 2.6.0")
13
- end
14
+ gem.add_development_dependency("capybara", "~> 1.1.2")
15
+ gem.executables << 'nosy'
16
+ end
@@ -0,0 +1,140 @@
1
+ require 'nosy'
2
+ require 'spec_helper'
3
+
4
+ describe Nosy::Output, "#to_json( texts )" do
5
+
6
+ let(:texts) { Nosy.parse(File.join('spec', 'support', 'db', 'texts.sqlite'))}
7
+
8
+ context "#to_html" do
9
+
10
+ before(:each) do
11
+ @response = subject.to_html( texts )
12
+ visit(@response)
13
+ end
14
+
15
+ it "should return the location to the created file" do
16
+ @response.should == "#{Dir.pwd}/iphone-texts.html"
17
+ end
18
+
19
+ it "should create an html document with the correct texts messages" do
20
+ page.all('article')[0].should have_content texts[0].message
21
+ end
22
+
23
+ it "should create an html document with the correct sender" do
24
+ page.all('article ul li.sender')[0].should have_content texts[0].sender
25
+ page.all('article ul li.sender')[1].should have_content texts[1].sender
26
+ end
27
+
28
+ it "should create an html document with the correct receiver" do
29
+ page.all('article')[0].find('li')[1].should have_content texts[0].receiver
30
+ page.all('article')[0].find('li')[1].should have_content texts[1].receiver
31
+ end
32
+
33
+ it "should create an html document with the imessage indicator" do
34
+ page.all('article')[0].find('li')[1].should have_content "SMS"
35
+ page.all('article')[3].find('li')[1].should have_content "iMessage"
36
+ end
37
+
38
+ it "should create an html document with an easy to understand date" do
39
+ page.all('article')[0].should have_content "Thursday, May 6, 2010 at 3:58pm"
40
+ end
41
+
42
+ it "should include every text" do
43
+ page.all('article').length.should == texts.length
44
+ end
45
+
46
+ end
47
+
48
+ context "#to_json" do
49
+
50
+ let(:json_texts_output) { JSON.parse( subject.to_json( texts ) ) }
51
+
52
+ describe "Output" do
53
+
54
+ it "should return a parsable json document" do
55
+ json_texts_output['1'].should == {"date"=>1273176415, "sender"=>"+1234567890", "receiver"=>"me", "message"=>"Okie doke, i just have my fake final at 6 to do", "imessage"=>false}
56
+ end
57
+
58
+ it "should include every text" do
59
+ json_texts_output.length.should == texts.length
60
+ end
61
+
62
+ it "should have a parsable date field" do
63
+ json_texts_output['1']['date'].should == 1273176415
64
+ end
65
+
66
+ it "should have a parsable sender field" do
67
+ json_texts_output['1']['sender'].should == "+1234567890"
68
+ end
69
+
70
+ it "should have a parsable receiver field" do
71
+ json_texts_output['1']['receiver'].should == "me"
72
+ end
73
+
74
+ it "should have a parsable message field" do
75
+ json_texts_output['1']['message'].should == "Okie doke, i just have my fake final at 6 to do"
76
+ end
77
+
78
+ it "should have a parsable imessage field" do
79
+ json_texts_output['1']['imessage'].should == false
80
+ end
81
+ end
82
+
83
+ describe "Output to file" do
84
+
85
+ before(:each) do
86
+ @response = subject.to_json( texts, true )
87
+ file = File.open("iphone-texts.json")
88
+ @json_texts_file = JSON.parse( file.gets )
89
+ end
90
+
91
+ after(:each) { File.delete("iphone-texts.json") }
92
+
93
+ it "should return the location to the created file" do
94
+ @response.should == "#{Dir.pwd}/iphone-texts.json"
95
+ end
96
+
97
+ it "should create a parsable json file" do
98
+ @json_texts_file['1'].should == {"date"=>1273176415, "sender"=>"+1234567890", "receiver"=>"me", "message"=>"Okie doke, i just have my fake final at 6 to do", "imessage"=>false}
99
+ end
100
+
101
+ it "should have the same contents as the regular output" do
102
+ @json_texts_file.should == json_texts_output
103
+ end
104
+ end
105
+ end
106
+
107
+ context "#to_csv" do
108
+
109
+ let(:csv_texts_output) { CSV.parse( subject.to_csv( texts ) )}
110
+
111
+ describe "Output to file" do
112
+
113
+ before(:each) do
114
+ @response = subject.to_csv( texts, "file" )
115
+ @csv = CSV.read( "iphone-texts.csv", { :headers => true })
116
+ end
117
+
118
+ after(:each) { File.delete("iphone-texts.csv") }
119
+
120
+ it "should return the location to the created file" do
121
+ @response.should == "#{Dir.pwd}/iphone-texts.csv"
122
+ end
123
+
124
+ it "should create a csv file" do
125
+ @csv[0][0].should == 1.to_s
126
+ @csv[0][1].should == texts[0].date.to_s
127
+ @csv[0][2].should == texts[0].sender
128
+ @csv[0][3].should == texts[0].receiver
129
+ @csv[0][4].should == texts[0].message
130
+ @csv[0][5].should == texts[0].imessage.to_s
131
+ end
132
+
133
+ it "should include every text" do
134
+ @csv.length.should == texts.length
135
+ end
136
+
137
+ end
138
+ end
139
+
140
+ end
@@ -4,6 +4,7 @@ describe Nosy do
4
4
 
5
5
  let(:iphone_database) { File.join('spec', 'support', 'db', 'texts.sqlite') }
6
6
  let(:texts) { subject.new(iphone_database) }
7
+ let(:parsed_texts) { Nosy.parse(File.join('spec', 'support', 'db', 'texts.sqlite'))}
7
8
 
8
9
  describe "#hunt" do
9
10
 
@@ -29,6 +30,30 @@ describe Nosy do
29
30
 
30
31
  end
31
32
 
33
+ describe "#hunt_parse_and_output( output_type, to_file)" do
34
+
35
+ it "should by default get the database, parse it, and output it as an html file" do
36
+ Nosy.hunt_parse_and_output.should == Nosy::Output.new.to_html(Nosy::Parser.new.parse(Nosy::Hunter.new.hunt))
37
+ end
38
+
39
+ it "should get the database, parse it, and output it as json string" do
40
+ Nosy.hunt_parse_and_output("json", false).should == Nosy::Output.new.to_json(Nosy::Parser.new.parse(Nosy::Hunter.new.hunt), false)
41
+ end
42
+
43
+ it "should get the database, parse it, and output it as json file" do
44
+ Nosy.hunt_parse_and_output("json", true).should == Nosy::Output.new.to_json(Nosy::Parser.new.parse(Nosy::Hunter.new.hunt), true)
45
+ end
46
+
47
+ it "should get the database, parse it, and output it as an html file" do
48
+ Nosy.hunt_parse_and_output("html").should == Nosy::Output.new.to_html(Nosy::Parser.new.parse(Nosy::Hunter.new.hunt))
49
+ end
50
+
51
+ it "should get the database, parse it, and output it as a csv file" do
52
+ Nosy.hunt_parse_and_output("csv").should == Nosy::Output.new.to_csv(Nosy::Parser.new.parse(Nosy::Hunter.new.hunt))
53
+ end
54
+
55
+ end
56
+
32
57
  describe "#parse" do
33
58
 
34
59
  it "should return the same results as a parse" do
@@ -45,4 +70,29 @@ describe Nosy do
45
70
 
46
71
  end
47
72
 
73
+ describe "#output( output_type, to_file)" do
74
+
75
+
76
+ it "should by default output it as an html file" do
77
+ Nosy.output(parsed_texts).should == Nosy::Output.new.to_html(parsed_texts)
78
+ end
79
+
80
+ it "should output it as json string" do
81
+ Nosy.output(parsed_texts, "json", false).should == Nosy::Output.new.to_json(parsed_texts, false)
82
+ end
83
+
84
+ it "should output it as json file" do
85
+ Nosy.output(parsed_texts, "json", true).should == Nosy::Output.new.to_json(parsed_texts, true)
86
+ end
87
+
88
+ it "should output it as an html file" do
89
+ Nosy.output(parsed_texts, "html").should == Nosy::Output.new.to_html(parsed_texts)
90
+ end
91
+
92
+ it "should output it as a csv file" do
93
+ Nosy.output(parsed_texts, "csv").should == Nosy::Output.new.to_csv(parsed_texts)
94
+ end
95
+
96
+ end
97
+
48
98
  end
@@ -0,0 +1,6 @@
1
+ require 'capybara/rspec'
2
+
3
+ include Capybara::DSL
4
+ Capybara.default_driver = :selenium
5
+ Capybara.app_host = "file:///"
6
+ Capybara.save_and_open_page_path = File.dirname(__FILE__) + '/../tmp'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nosy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-02 00:00:00.000000000Z
12
+ date: 2012-01-08 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
16
- requirement: &70203490284220 !ruby/object:Gem::Requirement
16
+ requirement: &70361786273640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,21 @@ dependencies:
21
21
  version: 1.3.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70203490284220
24
+ version_requirements: *70361786273640
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &70361786272420 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.6.4
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70361786272420
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rspec
27
- requirement: &70203490283740 !ruby/object:Gem::Requirement
38
+ requirement: &70361786271660 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,34 +43,51 @@ dependencies:
32
43
  version: 2.6.0
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70203490283740
46
+ version_requirements: *70361786271660
47
+ - !ruby/object:Gem::Dependency
48
+ name: capybara
49
+ requirement: &70361786270900 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70361786270900
36
58
  description: Nosy fetches, parses and searches the iPhone's SMS database that is created
37
- on your machine each time you make a backup.
59
+ on your machine each time you make a backup. It can export to HTML, CSV, or JSON.
38
60
  email: pdudley89@gmail.com
39
- executables: []
61
+ executables:
62
+ - nosy
40
63
  extensions: []
41
64
  extra_rdoc_files: []
42
65
  files:
43
66
  - .gitignore
44
67
  - .rspec
45
68
  - README.md
69
+ - bin/nosy
46
70
  - lib/.DS_Store
47
71
  - lib/nosy.rb
48
72
  - lib/nosy/hunter.rb
73
+ - lib/nosy/output.rb
74
+ - lib/nosy/output/html_helpers.rb
49
75
  - lib/nosy/parser.rb
50
76
  - lib/nosy/parser/imessage.rb
51
77
  - lib/nosy/parser/message_support.rb
52
78
  - lib/nosy/parser/parse_checks.rb
53
79
  - lib/nosy/parser/smsmessage.rb
54
80
  - lib/nosy/searcher.rb
55
- - nosy-0.0.4.gem
81
+ - nosy-0.0.5.gem
56
82
  - nosy.gemspec
57
83
  - spec/.DS_Store
58
84
  - spec/nosy/.DS_Store
59
85
  - spec/nosy/hunter_spec.rb
86
+ - spec/nosy/output_spec.rb
60
87
  - spec/nosy/parser_spec.rb
61
88
  - spec/nosy/searcher_spec.rb
62
89
  - spec/nosy_spec.rb
90
+ - spec/spec_helper.rb
63
91
  - spec/support/.DS_Store
64
92
  - spec/support/db/.DS_Store
65
93
  - spec/support/db/empty_iphone_database.sqlite
@@ -92,5 +120,5 @@ rubyforge_project:
92
120
  rubygems_version: 1.8.10
93
121
  signing_key:
94
122
  specification_version: 3
95
- summary: Output, backup, and read all your iPhone text messages
123
+ summary: Output, backup, search, and read all your iPhone text messages
96
124
  test_files: []