runoff 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,69 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aigars Dzerviniks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-17 00:00:00.000000000 Z
11
+ date: 2014-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sequel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubyzip
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sqlite3
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: colorize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  description: runoff provides functionality to export all the Skype chat history or
@@ -75,7 +89,7 @@ executables:
75
89
  extensions: []
76
90
  extra_rdoc_files: []
77
91
  files:
78
- - .gitignore
92
+ - ".gitignore"
79
93
  - Gemfile
80
94
  - LICENSE.txt
81
95
  - README.md
@@ -83,23 +97,16 @@ files:
83
97
  - bin/runoff
84
98
  - lib/runoff.rb
85
99
  - lib/runoff/commands/all.rb
86
- - lib/runoff/commands/chat.rb
87
100
  - lib/runoff/commands/command.rb
88
- - lib/runoff/composition.rb
101
+ - lib/runoff/commands/some.rb
89
102
  - lib/runoff/file_writer.rb
90
103
  - lib/runoff/location.rb
91
104
  - lib/runoff/skype_data_format.rb
92
105
  - lib/runoff/version.rb
93
106
  - runoff.gemspec
94
- - test/all_test.rb
95
- - test/chat_test.rb
96
- - test/command_test.rb
97
- - test/composition_test.rb
98
- - test/file_writer_test.rb
99
- - test/location_test.rb
100
107
  - test/skype_data_format_test.rb
101
108
  - test/test_db.sqlite
102
- homepage: https://github.com/aidzis/runoff
109
+ homepage: https://github.com/aigarsdz/runoff
103
110
  licenses:
104
111
  - MIT
105
112
  metadata: {}
@@ -109,12 +116,12 @@ require_paths:
109
116
  - lib
110
117
  required_ruby_version: !ruby/object:Gem::Requirement
111
118
  requirements:
112
- - - '>='
119
+ - - ">="
113
120
  - !ruby/object:Gem::Version
114
121
  version: '0'
115
122
  required_rubygems_version: !ruby/object:Gem::Requirement
116
123
  requirements:
117
- - - '>='
124
+ - - ">="
118
125
  - !ruby/object:Gem::Version
119
126
  version: '0'
120
127
  requirements: []
@@ -124,11 +131,5 @@ signing_key:
124
131
  specification_version: 4
125
132
  summary: Tool to export Skype chat history from the SQLite database to text files
126
133
  test_files:
127
- - test/all_test.rb
128
- - test/chat_test.rb
129
- - test/command_test.rb
130
- - test/composition_test.rb
131
- - test/file_writer_test.rb
132
- - test/location_test.rb
133
134
  - test/skype_data_format_test.rb
134
135
  - test/test_db.sqlite
@@ -1,37 +0,0 @@
1
- module Runoff
2
- module Commands
3
- class Chat < Command
4
- # Public: Exports specified chats.
5
- #
6
- # args - Array containing skype username
7
- # options - Hash containing user provided options
8
- #
9
- # Examples
10
- #
11
- # Chat.process ['username'], { from: '~/main.db' }
12
- def self.process(args, options = {})
13
- if args.empty? && !options.has_key?('from')
14
- raise ArgumentError.new 'You must specify a username or a --from option'
15
- end
16
-
17
- composition = self.get_composition args[0], options[:from]
18
- destination = self.get_destination options[:destination]
19
- chatnames, raw_chatnames = composition.get_chatnames
20
-
21
- self.list_chatnames chatnames
22
- indecies = ask 'Which chats do you want to export? (Enter indecies) ', Array
23
- indecies = indecies.map { |index| index.to_i }
24
- selected_chatnames = []
25
-
26
- indecies.each { |index| selected_chatnames << raw_chatnames[index] }
27
- self.print_result composition.export_chats(selected_chatnames, destination)
28
- self.try_to_archive destination, options
29
-
30
- rescue ArgumentError => e
31
- puts e
32
- rescue IOError => e
33
- puts e
34
- end
35
- end
36
- end
37
- end
@@ -1,105 +0,0 @@
1
- require 'sequel'
2
- require 'set'
3
-
4
- module Runoff
5
- # Public: Provides interaction with a Skype database file.
6
- #
7
- # Examples
8
- #
9
- # composition = Composition.new 'path/to/the/main.db'
10
- # exported_files_count = composition.export 'export/folder'
11
- class Composition
12
- # Public: Returns a Set object of all the names of the exported files.
13
- attr_reader :exported_filenames
14
-
15
- # Public: Initialize a Composition object.
16
- #
17
- # main_db_file_path - A String with the path to the Skype database file.
18
- # skype_username - A String with Skype login.
19
- #
20
- # Raises IOError if the file cannot be found
21
- def initialize(optional_file_path, skype_username = nil)
22
- main_db_file_path = optional_file_path || Runoff::Location.default_skype_data_location(skype_username)
23
-
24
- raise IOError, "File doesn't exist" unless File.exists? main_db_file_path
25
-
26
- skype_database = Sequel.connect "sqlite://#{main_db_file_path}"
27
- @messages = skype_database.from :Messages
28
- @exported_filenames = Set.new
29
- @format = Runoff::SkypeDataFormat.new
30
- @file_writer = Runoff::FileWriter.new @format
31
- end
32
-
33
- # Public: Reads all chat records from database and runs the export process.
34
- #
35
- # destination_path - A String with folder path, where to put exported files.
36
- #
37
- # Examples
38
- #
39
- # export '/home/username/skype_backup'
40
- # # => 8
41
- #
42
- # Returns the count of the exported files.
43
- def export(destination_path)
44
- chat_records = @messages.select(:chatname, :timestamp, :from_dispname, :body_xml)
45
-
46
- run_export chat_records, destination_path
47
- end
48
-
49
- # Public: Gets parsed chatnames together with partly parsed chatnames.
50
- #
51
- # Examples
52
- #
53
- # get_chatnames
54
- # # => [['something-more', 'somethindg-else'],
55
- # ['#something/$more;6521032', '#something/$else;8971263']]
56
- #
57
- # Returns two Array objects containing parsed chatnames and partly parsed chatnames.
58
- def get_chatnames
59
- chatnames = @messages.select(:chatname)
60
- raw_chatnames = chatnames.map { |record| @format.partly_parse_chatname record[:chatname] }.uniq
61
- clean_chatnames = raw_chatnames.map { |chatname| @format.parse_chatname chatname }
62
-
63
- return clean_chatnames, raw_chatnames
64
- end
65
-
66
- # Public: Exports Skype chat history to text files for specified chats.
67
- #
68
- # chatnames - Array of chatnames, which will be exported
69
- # destination_path - A String with folder path, where to put exported files.
70
- #
71
- # Examples
72
- #
73
- # export_chats ['#something/$more;', '#something/$else;'], '~/skype_backup'
74
- # # => 2
75
- #
76
- # Returns the count of the exported files.
77
- def export_chats(chatnames, destination_path)
78
- pattern_chatnames = chatnames.map { |name| "#{name}%" }
79
- chat_records = @messages.where(Sequel.like(:chatname, *pattern_chatnames))
80
-
81
- run_export chat_records, destination_path
82
- end
83
-
84
- private
85
- # Internal: Performs the export process.
86
- #
87
- # chat_records - Array of chat records read from database
88
- #
89
- # Examples
90
- #
91
- # run_export [{chatname: '#sadsad/$kjhkjh;9878977', 123123213, 'Aidzis', ''}]
92
- # # => 1
93
- #
94
- # Returns the count of the exported files.
95
- def run_export(chat_records, destination_path)
96
- chat_records.each do |record|
97
- if filename = @file_writer.save_to_file(record, destination_path)
98
- @exported_filenames << filename
99
- end
100
- end
101
-
102
- @exported_filenames.count
103
- end
104
- end
105
- end
data/test/all_test.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
- require 'fileutils'
5
-
6
- class TestAll < MiniTest::Test
7
- def teardown
8
- Dir.glob('test/*.zip').each do |archive|
9
- File.delete archive
10
- end
11
-
12
- FileUtils.rm_rf 'test/tmp'
13
- end
14
-
15
- def test_must_output_an_error_message_if_no_username_or_from_option_is_provided
16
- assert_output "You must specify a username or a --from option\n" do
17
- Runoff::Commands::All.process []
18
- end
19
- end
20
-
21
- def test_must_output_result_of_the_command
22
- assert_output "Finished: 2 files were exported\n" do
23
- Runoff::Commands::All.process [], {
24
- from: 'test/test_db.sqlite',
25
- destination: 'test/tmp'
26
- }
27
- end
28
- end
29
-
30
- def test_must_put_exported_files_into_an_archive
31
- capture_io do
32
- Runoff::Commands::All.process [], { from: 'test/test_db.sqlite', destination: 'test/tmp' }
33
- end
34
-
35
- assert_equal 1, Dir["test/*.zip"].length, "test directory must contain 1 Zip file"
36
- end
37
- end
data/test/chat_test.rb DELETED
@@ -1,11 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
-
5
- class TestChat < MiniTest::Test
6
- def test_must_output_an_error_message_if_no_username_or_from_option_is_procided
7
- assert_output "You must specify a username or a --from option\n" do
8
- Runoff::Commands::Chat.process []
9
- end
10
- end
11
- end
data/test/command_test.rb DELETED
@@ -1,41 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
-
5
- class TestCommand < MiniTest::Test
6
- def test_must_create_a_composition_object_based_on_a_specified_path_to_database_file
7
- assert_instance_of Runoff::Composition, Runoff::Commands::Command.send(:get_composition, nil, 'test/test_db.sqlite')
8
- end
9
-
10
- def test_must_return_a_default_destination_path_if_no_optional_path_is_specified
11
- assert_equal "#{ENV['HOME']}/skype-backup", Runoff::Commands::Command.send(:get_destination, nil)
12
- end
13
-
14
- def test_must_return_a_custom_path_if_an_optional_path_is_specified
15
- path = Runoff::Commands::Command.send :get_destination, 'test/test_db.sqlite'
16
-
17
- assert_equal 'test/test_db.sqlite', path
18
- end
19
-
20
- def test_must_output_correct_message_based_on_the_exported_items_count
21
- assert_output "Finished: 1 file was exported\n" do
22
- Runoff::Commands::Command.send :print_result, 1
23
- end
24
-
25
- assert_output "Finished: 2 files were exported\n" do
26
- Runoff::Commands::Command.send :print_result, 2
27
- end
28
- end
29
-
30
- def test_must_output_a_list_of_available_chatnames
31
- chatnames = ['first-chatname', 'second-chatname']
32
-
33
- assert_output "[0] first-chatname\n[1] second-chatname\n\n" do
34
- Runoff::Commands::Command.send :list_chatnames, chatnames
35
- end
36
- end
37
-
38
- def test_does_not_create_an_archive_if_the_archive_option_is_set_to_false
39
- skip
40
- end
41
- end
@@ -1,58 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
- require 'fileutils'
5
-
6
- class TestComposition < MiniTest::Test
7
- def setup
8
- @composition = Runoff::Composition.new 'test/test_db.sqlite'
9
- end
10
-
11
- def teardown
12
- FileUtils.rm_rf 'test/tmp'
13
- end
14
-
15
- def test_must_raise_an_IOError_if_the_file_that_is_passed_to_the_constructor_does_not_exist
16
- assert_raises IOError do
17
- composition = Runoff::Composition.new 'not_existing.db'
18
- end
19
- end
20
-
21
- def test_must_respond_to_exported_filenames_method
22
- assert_respond_to @composition, :exported_filenames
23
- end
24
-
25
- def test_must_return_parsed_chatnames_together_with_partly_parsed_chatnames
26
- chatnames, raw_chatnames = @composition.get_chatnames
27
-
28
- assert_equal ['something-more', 'something-else'], chatnames
29
- assert_equal ['#something/$more;', '#something/$else;'], raw_chatnames
30
- end
31
-
32
- def test_must_return_a_count_of_the_exported_filenames
33
- file_count = @composition.send(
34
- :run_export,
35
- [{
36
- chatname: '#john/$elis;7687623',
37
- timestamp: 123123213,
38
- from_dispname: 'John',
39
- body_xml: ''
40
- }],
41
- 'test/tmp'
42
- )
43
-
44
- assert_equal 1, file_count
45
- end
46
-
47
- def test_must_return_a_count_of_the_exported_filenames_when_called_for_all_chats
48
- file_count = @composition.export 'test/tmp'
49
-
50
- assert_equal 2, file_count
51
- end
52
-
53
- def test_must_return_a_count_of_the_exported_filenames_when_called_for_specific_chats
54
- file_count = @composition.export_chats ['#something/$more;', '#something/$else;'], 'test/tmp'
55
-
56
- assert_equal 2, file_count
57
- end
58
- end
@@ -1,90 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
- require 'fileutils'
5
-
6
- class TestFileWriter < MiniTest::Test
7
- def setup
8
- @incorrect_chat_record = {
9
- chatname: '#john/$;521357125362',
10
- timestamp: 1366280218,
11
- from_dispname: 'John',
12
- body_xml: 'This is a text'
13
- }
14
-
15
- @chat_record = {
16
- chatname: '#braun/$drake;521357125362',
17
- timestamp: 1366280218,
18
- from_dispname: 'Braun',
19
- body_xml: 'This is a text.'
20
- }
21
-
22
- correct_format = get_correct_format_mock
23
- @correct_file_writer = Runoff::FileWriter.new correct_format
24
- incorrect_format = get_incorrect_format_mock
25
- @incorrect_file_writer = Runoff::FileWriter.new incorrect_format
26
- end
27
-
28
- def teardown
29
- FileUtils.rm_rf 'test/tmp'
30
-
31
- Dir.glob('test/*.zip').each do |archive|
32
- File.delete archive
33
- end
34
- end
35
-
36
- def test_must_write_chat_content_to_file
37
- @correct_file_writer.save_to_file @chat_record, 'test/tmp'
38
- @incorrect_file_writer.save_to_file @incorrect_chat_record, 'test/tmp'
39
-
40
- assert_equal 2, Dir['test/tmp/*.txt'].count
41
- end
42
-
43
- def test_must_append_to_a_file_if_the_filename_already_exists
44
- @additional_chat_record = @chat_record
45
-
46
- @correct_file_writer.save_to_file @chat_record, 'test/tmp'
47
- @incorrect_file_writer.save_to_file @incorrect_chat_record, 'test/tmp'
48
- @correct_file_writer.save_to_file @additional_chat_record, 'test/tmp'
49
-
50
- assert_equal 2, Dir['test/tmp/*.txt'].count
51
- end
52
-
53
- def test_must_create_a_zip_file_of_the_destination_directory
54
- output_directory = 'test/tmp'
55
- files = %w[first.txt second.txt]
56
-
57
- Dir.mkdir(output_directory) unless File.exists?(output_directory)
58
-
59
- files.each do |filename|
60
- file = File.new "#{output_directory}/#{filename}", 'w'
61
- file.close
62
- end
63
-
64
- Runoff::FileWriter.archive output_directory
65
-
66
- assert_equal 1, Dir['test/*.zip'].count
67
- end
68
-
69
- private
70
-
71
- def get_correct_format_mock
72
- correct_format = MiniTest::Mock.new
73
-
74
- correct_format.expect :get_filename, 'braun-drake.txt', [Hash]
75
- correct_format.expect :get_filename, 'braun-drake.txt', [Hash]
76
- correct_format.expect :build_entry, '[2013-04-18 13:16:58] Braun: This is a text.', [Hash]
77
- correct_format.expect :build_entry, '[2013-04-18 13:16:58] Braun: This is a text.', [Hash]
78
-
79
- correct_format
80
- end
81
-
82
- def get_incorrect_format_mock
83
- incorrect_format = MiniTest::Mock.new
84
-
85
- incorrect_format.expect :get_filename, 'john.txt', [Hash]
86
- incorrect_format.expect :build_entry, '[2013-04-18 13:16:58] John: This is a text.', [Hash]
87
-
88
- incorrect_format
89
- end
90
- end
@@ -1,29 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/unit'
3
- require 'runoff'
4
-
5
- class TestLocation < MiniTest::Test
6
- def test_must_return_a_default_path_depending_on_the_operating_system
7
- path = Runoff::Location.default_skype_data_location 'aidzis_skype'
8
-
9
- if RbConfig::CONFIG['host_os'] =~ /mingw/
10
- skip
11
- if File.exist?("#{ENV['APPDATA']}\\Skype")
12
- assert_match /\/Users\/[a-zA-Z0-9]+\/AppData\/Roaming\/Skype\/aidzis_skype\/main\.db/, path
13
- else
14
- assert_match /\/Users\/[a-zA-Z0-9]+\/AppData\/Local\/Packages\/[a-zA-Z0-9_\/\.]+\/aidzis_skype\/main\.db/, path
15
- end
16
- elsif RbConfig::CONFIG['host_os'] =~ /linux/
17
- assert_match /\/home\/[a-zA-Z0-9]+\/\.Skype\/aidzis_skype\/main\.db/, path
18
- else
19
- assert_match /~\/Library\/Application Support\/Skype\/aidzis_skype\/main\.db/, path
20
- end
21
- end
22
-
23
- def test_must_replace_backslashes_with_forward_slashes_and_remowe_drive_letter
24
- windows_path = 'C:\\Users\\user\\AppData\\Roaming\\Skype'
25
- unix_style_path = Runoff::Location.send :format_windows_path, windows_path
26
-
27
- assert_equal '/Users/user/AppData/Roaming/Skype', unix_style_path
28
- end
29
- end