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 +5 -1
- data/README.md +59 -3
- data/bin/nosy +13 -0
- data/lib/nosy.rb +29 -0
- data/lib/nosy/output.rb +49 -0
- data/lib/nosy/output/html_helpers.rb +162 -0
- data/nosy.gemspec +8 -5
- data/spec/nosy/output_spec.rb +140 -0
- data/spec/nosy_spec.rb +50 -0
- data/spec/spec_helper.rb +6 -0
- metadata +38 -10
data/.gitignore
CHANGED
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
|
data/bin/nosy
ADDED
@@ -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
|
data/lib/nosy.rb
CHANGED
@@ -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
|
data/lib/nosy/output.rb
ADDED
@@ -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
|
+
|
data/nosy.gemspec
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = 'nosy'
|
3
|
-
gem.version = '0.0.
|
4
|
-
gem.date = '2012-01-
|
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
|
-
|
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
|
data/spec/nosy_spec.rb
CHANGED
@@ -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
|
data/spec/spec_helper.rb
ADDED
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
|
+
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-
|
12
|
+
date: 2012-01-08 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sqlite3
|
16
|
-
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: *
|
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: &
|
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: *
|
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.
|
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: []
|