juno-email 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +1 -0
- data/bin/juno-convert +49 -0
- data/juno-email.gemspec +27 -0
- data/lib/juno.rb +5 -0
- data/lib/juno/folder.rb +72 -0
- data/lib/juno/installation.rb +22 -0
- data/lib/juno/message.rb +51 -0
- data/lib/juno/user.rb +87 -0
- data/lib/juno/version.rb +3 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 271b4c877991a58e0eee563366865ccb26176978
|
4
|
+
data.tar.gz: 6e1211ec9dea1ec64aeadf355af9d978f86de9d9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 35840b00eea843d95cf7701887b7d7942622d005af23cc6eb94d106f4cf63d7c8cf1afe3def088c8b23f0ed09cf8d5bc3cf11390c46165b46da7e05f5cc78bc0
|
7
|
+
data.tar.gz: 79ffd54b251b6f53a7be1d4ecee8bd6df453aaafb3fac2871e39c3f07b20d72970420f2bcd3207604fd83c8d9f3da50ab4f7c68874612325a8e9b38e8448b698
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jonathan Hinkle
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# juno-email
|
2
|
+
|
3
|
+
juno-convert is a tool for converting mail from the Juno email
|
4
|
+
client to the mbox format.
|
5
|
+
|
6
|
+
Once you have mbox files, you can import them into many mail programs,
|
7
|
+
such as [Thunderbird](http://www.mozilla.org/thunderbird/) (using the
|
8
|
+
excellent [ImportExportTools add-on](https://addons.mozilla.org/thunderbird/addon/importexporttools/))
|
9
|
+
or OS X's Mail app.
|
10
|
+
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
$ gem install juno-email
|
15
|
+
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
tl;dr:
|
20
|
+
|
21
|
+
$ juno-convert --source path/to/juno --destination path/for/output
|
22
|
+
|
23
|
+
Details:
|
24
|
+
|
25
|
+
juno-convert [options]
|
26
|
+
-s, --source Path to Juno directory. Required.
|
27
|
+
-d, --destination Path to output directory. Required.
|
28
|
+
-o, --overwrite Overwrite files in output directory.
|
29
|
+
-v, --version Display version.
|
30
|
+
-h, --help Display this help message.
|
31
|
+
|
32
|
+
More details:
|
33
|
+
|
34
|
+
* `--source` is the path in which the user folders are located. They look
|
35
|
+
like USER0000, USER0001, etc.
|
36
|
+
* `--destination` is where you want the mbox files to be output. If destination
|
37
|
+
is `foo/bar`, `bar` will be created if it doesn't already exist.
|
38
|
+
* `--overwrite` means that if the program wants to create `foo.mbox` and there's
|
39
|
+
already a `foo.inbox` there, it wil be overwritten. Without this option, the
|
40
|
+
program will abort if it runs into such a situation.
|
41
|
+
|
42
|
+
## It doesn't work!!
|
43
|
+
|
44
|
+
The tool needs Ruby 1.9 or greater. You can check your version with `ruby -v`.
|
45
|
+
|
46
|
+
That's not the problem? Okay, let's make things better! I only had access to
|
47
|
+
one user's emails from Juno 4.0.11, so I can easily believe there are plenty
|
48
|
+
of edge cases I haven't run across. If you could [open an issue](https://github.com/hynkle/juno-email/issues/new)
|
49
|
+
with as much detail as you have, we can get started on figuring it out and
|
50
|
+
making this tool better for everyone. Be sure to include your operating system
|
51
|
+
and your ruby version (`ruby -v`).
|
52
|
+
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it ( http://github.com/<my-github-username>/juno/fork )
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/juno-convert
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'slop'
|
4
|
+
require 'pathname'
|
5
|
+
require 'juno'
|
6
|
+
|
7
|
+
opts = Slop.parse(help: true) do
|
8
|
+
banner "Usage: #{File.basename(__FILE__)} [options]"
|
9
|
+
|
10
|
+
on 's', 'source=', 'Path to Juno directory. Required.'
|
11
|
+
on 'd', 'destination=', 'Path to output directory. Required.'
|
12
|
+
on 'o', 'overwrite', 'Overwrite files in output directory.'
|
13
|
+
|
14
|
+
on 'v', 'version', 'Display version.' do
|
15
|
+
puts Juno::VERSION
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
command_help = opts.help
|
21
|
+
opts = opts.to_hash
|
22
|
+
|
23
|
+
unless opts[:source] && opts[:destination]
|
24
|
+
abort "ERROR: Missing required arguments.\n\n#{command_help}"
|
25
|
+
end
|
26
|
+
|
27
|
+
opts[:source] = Pathname.new(opts[:source]).expand_path
|
28
|
+
opts[:destination] = Pathname.new(opts[:destination]).expand_path
|
29
|
+
|
30
|
+
unless opts[:source].directory?
|
31
|
+
abort "ERROR: Source must be a directory."
|
32
|
+
end
|
33
|
+
|
34
|
+
unless opts[:destination].directory? || opts[:destination].parent.directory?
|
35
|
+
abort "ERROR: Destination must be a directory."
|
36
|
+
end
|
37
|
+
|
38
|
+
juno = Juno::Installation.new(opts[:source])
|
39
|
+
|
40
|
+
juno.users.each do |user|
|
41
|
+
opts[:destination].mkdir unless opts[:destination].directory?
|
42
|
+
user_dir = opts[:destination].join("#{user.login} (#{user.path_id})")
|
43
|
+
user_dir.mkdir unless user_dir.directory?
|
44
|
+
|
45
|
+
user.folders.each do |folder|
|
46
|
+
mbox_path = user_dir.join("#{folder.name}.mbox")
|
47
|
+
folder.write_mbox(mbox_path, overwrite: opts[:overwrite])
|
48
|
+
end
|
49
|
+
end
|
data/juno-email.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'juno/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'juno-email'
|
8
|
+
spec.version = Juno::VERSION
|
9
|
+
spec.authors = ['Jonathan Hinkle']
|
10
|
+
spec.email = ['hello@hynkle.com']
|
11
|
+
spec.summary = %q{convert mail from the Juno email client to mbox format}
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'slop'
|
21
|
+
spec.add_dependency 'inifile'
|
22
|
+
spec.add_dependency 'ruby-ole'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'pry'
|
27
|
+
end
|
data/lib/juno.rb
ADDED
data/lib/juno/folder.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'ole/base'
|
3
|
+
require 'ole/storage'
|
4
|
+
require 'juno/message'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module Juno
|
8
|
+
class Folder
|
9
|
+
|
10
|
+
def initialize(name, path)
|
11
|
+
@name = name
|
12
|
+
@path = Pathname.new(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def messages
|
16
|
+
return @messages if defined? @messages
|
17
|
+
ole = Ole::Storage.new(@path.to_s)
|
18
|
+
@messages = ole.root.children.map do |message_dirent|
|
19
|
+
|
20
|
+
# This condition is met once per folder, when
|
21
|
+
# the dirent's name_utf16 is "directory"
|
22
|
+
next if message_dirent.children.nil?
|
23
|
+
|
24
|
+
body = message_dirent.children[0].read
|
25
|
+
|
26
|
+
headers = message_dirent.children[1].read
|
27
|
+
|
28
|
+
# Some emails have a weird numeric "header" separated
|
29
|
+
# from the other headers by two newlines. To the best
|
30
|
+
# of my knowledge, this is invalid so let's just drop it.
|
31
|
+
headers.sub!(/\n\n\d+\Z/, '')
|
32
|
+
|
33
|
+
headers = headers.lines
|
34
|
+
headers.each(&:chomp!)
|
35
|
+
headers.reject!(&:empty?)
|
36
|
+
|
37
|
+
# This condition is for emails from Juno, including advertisements
|
38
|
+
# and announcements. These emails are a bit unusual in that they
|
39
|
+
# lack a date header, so instead of dealing with whatever problems
|
40
|
+
# that might cause, they're of so little interest to anybody that
|
41
|
+
# we might as well just throw them away.
|
42
|
+
next if headers.any?{|h| h =~ /^X-UNTD-MSG:\s+internal/}
|
43
|
+
|
44
|
+
Message.new(headers, body)
|
45
|
+
end
|
46
|
+
|
47
|
+
@messages.compact!
|
48
|
+
@messages
|
49
|
+
end
|
50
|
+
|
51
|
+
def name
|
52
|
+
@name
|
53
|
+
end
|
54
|
+
|
55
|
+
def contains_duplicate_messages?
|
56
|
+
@contains_duplicate_messages ||= Set.new(messages).count != messages.count
|
57
|
+
end
|
58
|
+
|
59
|
+
def write_mbox(path, opts={})
|
60
|
+
if path.exist? && !opts[:overwrite]
|
61
|
+
raise "#{path} already exists"
|
62
|
+
end
|
63
|
+
|
64
|
+
path.open('w') do |f|
|
65
|
+
messages.each do |message|
|
66
|
+
f.puts message.to_mbox
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'juno/user'
|
3
|
+
|
4
|
+
module Juno
|
5
|
+
class Installation
|
6
|
+
|
7
|
+
def initialize(root_pathname, opts={})
|
8
|
+
@root = Pathname.new(root_pathname)
|
9
|
+
@opts = opts
|
10
|
+
end
|
11
|
+
|
12
|
+
def users
|
13
|
+
return @users if defined? @users
|
14
|
+
@users = Pathname.glob(@root + 'USER*').select do |p|
|
15
|
+
p.directory? && p.basename.to_s.match(/^USER\d{4}$/)
|
16
|
+
end.map do |user_path|
|
17
|
+
User.new(user_path)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/juno/message.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Juno
|
2
|
+
class Message
|
3
|
+
|
4
|
+
def initialize(headers, body)
|
5
|
+
@headers = headers
|
6
|
+
@body = body
|
7
|
+
end
|
8
|
+
|
9
|
+
def headers
|
10
|
+
@headers
|
11
|
+
end
|
12
|
+
|
13
|
+
def body
|
14
|
+
@body
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_eml
|
18
|
+
[@headers.join(?/), @body].join(?/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
to_eml
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_mbox
|
26
|
+
# a message in mbox is delineated by a line that starts with "From "
|
27
|
+
from_line = headers.detect{|f| f.match(/^From:/)}.sub(/^From:\s+/, 'From ')
|
28
|
+
|
29
|
+
# We need to escape any lines that start with "From " in the body,
|
30
|
+
# so that they aren't mistaken for the start of a new message.
|
31
|
+
# To prevent ambiguity, we also alter any body lines that start
|
32
|
+
# with ">From" to ">>From".
|
33
|
+
escaped_body = body.gsub(/^(>?From )/, '>\1')
|
34
|
+
|
35
|
+
[from_line, headers.join($/), escaped_body].join($/)
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
self.headers == other.headers && self.body == other.body
|
40
|
+
end
|
41
|
+
|
42
|
+
def hash
|
43
|
+
to_s.hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def eql?(other)
|
47
|
+
self == other
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/juno/user.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'inifile'
|
3
|
+
require 'date'
|
4
|
+
require 'set'
|
5
|
+
require 'juno/folder'
|
6
|
+
|
7
|
+
module Juno
|
8
|
+
class User
|
9
|
+
|
10
|
+
def initialize(root_pathname)
|
11
|
+
@root = Pathname.new(root_pathname)
|
12
|
+
end
|
13
|
+
|
14
|
+
def path_id
|
15
|
+
@path_id ||= @root.basename
|
16
|
+
end
|
17
|
+
|
18
|
+
def login
|
19
|
+
# ini_config['User Profile']['Login'] contains the same value
|
20
|
+
@login ||= ini_config['UserInfo']['User']
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_name
|
24
|
+
@fullname ||= ini_config['User Profile']['Full name']
|
25
|
+
end
|
26
|
+
|
27
|
+
def last_connection
|
28
|
+
return @last_connection if defined? @last_connection
|
29
|
+
|
30
|
+
date = ini_config['History']['Last Connection Time']
|
31
|
+
@last_connection = if date.nil? || !date.match(/^\d+\/\d+\/\d+$/)
|
32
|
+
nil
|
33
|
+
else
|
34
|
+
day, month, year = date.split('/').map(&:to_i)
|
35
|
+
Date.new(year, month, day)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def juno_version
|
40
|
+
@juno_version ||= ini_config['Configuration']['Juno Version']
|
41
|
+
end
|
42
|
+
|
43
|
+
def folders
|
44
|
+
return @folders if defined? @folders
|
45
|
+
|
46
|
+
director_path = @root.join('director.frm')
|
47
|
+
unless director_path.file?
|
48
|
+
raise "missing expected director.frm at #{director_path}"
|
49
|
+
end
|
50
|
+
|
51
|
+
@folders = []
|
52
|
+
|
53
|
+
@folders = director_path.readlines(encoding: 'ASCII-8BIT').map do |line|
|
54
|
+
matchdata = line.match(/^(\S+) (fold\d{4}\.frm)\b/)
|
55
|
+
next unless matchdata
|
56
|
+
name = matchdata[1]
|
57
|
+
name.gsub!('\_', ' ') # spaces in folder names are represented as '\ '
|
58
|
+
name.gsub!('\\\\', '\\') # backslashes in folder names are represented as '\\'
|
59
|
+
filename = matchdata[2]
|
60
|
+
Folder.new(name, @root.join(filename))
|
61
|
+
end
|
62
|
+
|
63
|
+
@folders.compact!
|
64
|
+
end
|
65
|
+
|
66
|
+
def contains_duplicate_messages?
|
67
|
+
@contains_duplicate_messages ||= Set.new(all_messages).count != all_messages.count
|
68
|
+
end
|
69
|
+
|
70
|
+
def all_messages
|
71
|
+
folders.flat_map(&:messages)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def ini_config
|
77
|
+
return @ini_config if defined? @ini_config
|
78
|
+
|
79
|
+
ini_path = @root.join('juno.ini')
|
80
|
+
unless ini_path.file?
|
81
|
+
raise "missing expected junio.ini at #{ini_path}"
|
82
|
+
end
|
83
|
+
@ini_config = IniFile.load(ini_path)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/lib/juno/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: juno-email
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Hinkle
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: inifile
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby-ole
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- hello@hynkle.com
|
100
|
+
executables:
|
101
|
+
- juno-convert
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- bin/juno-convert
|
111
|
+
- juno-email.gemspec
|
112
|
+
- lib/juno.rb
|
113
|
+
- lib/juno/folder.rb
|
114
|
+
- lib/juno/installation.rb
|
115
|
+
- lib/juno/message.rb
|
116
|
+
- lib/juno/user.rb
|
117
|
+
- lib/juno/version.rb
|
118
|
+
homepage: ''
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.2.0
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: convert mail from the Juno email client to mbox format
|
142
|
+
test_files: []
|