runoff 0.3.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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