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: []
         
     |