docomo_web_mailer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +64 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/docomo_web_mailer.gemspec +76 -0
- data/lib/docomo_web_mailer.rb +478 -0
- data/lib/docomo_web_mailer/convert_mail.rb +49 -0
- data/test/helper.rb +18 -0
- data/test/test_docomo_web_mailer.rb +9 -0
- metadata +202 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.1"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
gem "mechanize", ">= 1.0"
|
14
|
+
gem "json", ">= 0"
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 nazoking@gmail.com
|
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.rdoc
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
= docomo_web_mailer
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
Docomo Web Mail Scraiper
|
6
|
+
|
7
|
+
Docomo Web Mail is http://dwmail.jp/
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* フォルダのリストを得ることが出来ます。
|
12
|
+
* フォルダ内のメールのリストを得ることが出来ます。
|
13
|
+
* メールのヘッダを得ることが出来ます。
|
14
|
+
* メールのmimeパートを得ることが出来ます。
|
15
|
+
* メールの添付ファイルを得ることが出来ます。
|
16
|
+
* 得たメールをsmtp用の文章に変換することが出来ます。
|
17
|
+
|
18
|
+
* メールを送ったり削除することは出来ません。
|
19
|
+
|
20
|
+
|
21
|
+
== SYNOPSIS:
|
22
|
+
|
23
|
+
メール転送の例
|
24
|
+
login_id , password = dwmail のid,password
|
25
|
+
your_smtp_server = smtpサーバ
|
26
|
+
forwarding_mail_address = 転送先
|
27
|
+
|
28
|
+
mailer = DocomoWebMailer.new
|
29
|
+
mailer.login( login_id, password )
|
30
|
+
maillist = mailer.mail_list_start(mailer.mail_label_list[:inbox],1000)
|
31
|
+
#nextmaillist = mailer.mail_list_get(maillist,1001,1000)
|
32
|
+
Net::SMTP.start( your_smtp_server, 25 ) {|smtp|
|
33
|
+
for mail in maillist
|
34
|
+
smtp.send_mail mailer.make_mail_to_smtp( mail ), mail.from, forwarding_mail_address
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
== REQUIREMENTS:
|
39
|
+
|
40
|
+
* mechanize >= 1.0
|
41
|
+
* json
|
42
|
+
|
43
|
+
== INSTALL:
|
44
|
+
|
45
|
+
* gem install docomo_web_mailer
|
46
|
+
|
47
|
+
== Contributing to docomo_web_mailer
|
48
|
+
|
49
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
50
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
51
|
+
* Fork the project
|
52
|
+
* Start a feature/bugfix branch
|
53
|
+
* Commit and push until you are happy with your contribution
|
54
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
55
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
56
|
+
|
57
|
+
== Copyright
|
58
|
+
|
59
|
+
nazoking@gmail.com
|
60
|
+
|
61
|
+
(The MIT License)
|
62
|
+
Copyright (c) 2010 nazoking. See LICENSE.txt for
|
63
|
+
further details.
|
64
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "docomo_web_mailer"
|
16
|
+
gem.homepage = "http://github.com/nazoking/docomo_web_mailer"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Docomo Web Mail Client}
|
19
|
+
gem.description = %Q{Docomo Web Mail ( http://dwmail.jp/ ) をRubyからいじることの出来るライブラリです。現在は受信のみ対応しており、送信や削除することは出来ません。 }
|
20
|
+
gem.email = "nazoking@gmail.com"
|
21
|
+
gem.authors = ["nazoking"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
gem.add_runtime_dependency 'mechanize', '> 1.0'
|
25
|
+
gem.add_runtime_dependency 'json'
|
26
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
Rake::TestTask.new(:test) do |test|
|
32
|
+
test.libs << 'lib' << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rcov/rcovtask'
|
38
|
+
Rcov::RcovTask.new do |test|
|
39
|
+
test.libs << 'test'
|
40
|
+
test.pattern = 'test/**/test_*.rb'
|
41
|
+
test.verbose = true
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "docomo_web_mailer #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{docomo_web_mailer}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["nazoking"]
|
12
|
+
s.date = %q{2010-11-19}
|
13
|
+
s.description = %q{Docomo Web Mail ( http://dwmail.jp/ ) をRubyからいじることの出来るライブラリです。現在は受信のみ対応しており、送信や削除することは出来ません。 }
|
14
|
+
s.email = %q{nazoking@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"docomo_web_mailer.gemspec",
|
27
|
+
"lib/docomo_web_mailer.rb",
|
28
|
+
"lib/docomo_web_mailer/convert_mail.rb",
|
29
|
+
"test/helper.rb",
|
30
|
+
"test/test_docomo_web_mailer.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/nazoking/docomo_web_mailer}
|
33
|
+
s.licenses = ["MIT"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = %q{1.3.7}
|
36
|
+
s.summary = %q{Docomo Web Mail Client}
|
37
|
+
s.test_files = [
|
38
|
+
"test/helper.rb",
|
39
|
+
"test/test_docomo_web_mailer.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
50
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<mechanize>, [">= 1.0"])
|
52
|
+
s.add_development_dependency(%q<json>, [">= 0"])
|
53
|
+
s.add_runtime_dependency(%q<mechanize>, ["> 1.0"])
|
54
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
57
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
58
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
59
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
60
|
+
s.add_dependency(%q<mechanize>, [">= 1.0"])
|
61
|
+
s.add_dependency(%q<json>, [">= 0"])
|
62
|
+
s.add_dependency(%q<mechanize>, ["> 1.0"])
|
63
|
+
s.add_dependency(%q<json>, [">= 0"])
|
64
|
+
end
|
65
|
+
else
|
66
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
67
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
69
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
70
|
+
s.add_dependency(%q<mechanize>, [">= 1.0"])
|
71
|
+
s.add_dependency(%q<json>, [">= 0"])
|
72
|
+
s.add_dependency(%q<mechanize>, ["> 1.0"])
|
73
|
+
s.add_dependency(%q<json>, [">= 0"])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,478 @@
|
|
1
|
+
#= ドコモWebメールクライアント
|
2
|
+
# ドコモWebメール
|
3
|
+
# http://dwmail.jp/
|
4
|
+
# のメールを読みます。
|
5
|
+
#
|
6
|
+
#==example
|
7
|
+
# メールを forwarding_mail_address へ転送する。
|
8
|
+
# mailer = DocomoWebMailer.new
|
9
|
+
# mailer.login( login_id, password )
|
10
|
+
# maillist = mailer.mail_list_start(mailer.mail_label_list[:inbox],10)
|
11
|
+
# #nextmaillist = mailer.mail_list_get(maillist,11,10)
|
12
|
+
# Net::SMTP.start( your_smtp_server, 25 ) {|smtp|
|
13
|
+
# for mail in maillist
|
14
|
+
# puts "#{mail.uid}:#{mail.subject} (#{mail.from})"
|
15
|
+
# smtp.send_mail mailer.make_mail_to_smtp( mail ), mail.from[0][1], forwarding_mail_address
|
16
|
+
# end
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
require 'rubygems'
|
20
|
+
require 'json'
|
21
|
+
require 'mechanize'
|
22
|
+
require 'cgi'
|
23
|
+
require 'base64'
|
24
|
+
|
25
|
+
class DocomoWebMailer
|
26
|
+
# メールボックスの最大値?
|
27
|
+
MAX_SIZE=10000
|
28
|
+
# コンストラクタ
|
29
|
+
def initialize()
|
30
|
+
@agent = Mechanize.new
|
31
|
+
@id = 0
|
32
|
+
@agent.user_agent_alias = 'Mac Safari'
|
33
|
+
end
|
34
|
+
# ログインする。失敗するとexception
|
35
|
+
def login(id,password)
|
36
|
+
page = @agent.get("http://dwmail.jp/")
|
37
|
+
form = page.form_with(:name => "f1")
|
38
|
+
raise "login error: cant find login form" unless form
|
39
|
+
form.field_with(:name => "uname").value = id
|
40
|
+
form.field_with(:name => "pass").value = password
|
41
|
+
res = @agent.submit(form)
|
42
|
+
raise "login error (id/pass illegal) " if res.form_with(:name => "f1")
|
43
|
+
end
|
44
|
+
# MailLabel のメールを得る。uid順。limit個。Maillistを返す。
|
45
|
+
# maillabel の値がSymbolならサーバフォルダ、文字列ならユーザフォルダ。
|
46
|
+
def mail_list_start(maillabel,limit)
|
47
|
+
place = [ A(:server_folder), A(maillabel) ]
|
48
|
+
if maillabel.is_a? MailLabel
|
49
|
+
place = [ A(maillabel.place), A(maillabel.index) ]
|
50
|
+
elsif maillabel.is_a? String
|
51
|
+
place[0]['$A']="user_folder"
|
52
|
+
end
|
53
|
+
Maillist.new( *rcp("mail_list_start",[ 1, T( nil, T(
|
54
|
+
# 得たいフォルダの場所
|
55
|
+
[ T(*place) ],
|
56
|
+
# 不明
|
57
|
+
[ ],
|
58
|
+
# 不明
|
59
|
+
[ T( A(:client_flag), A(:recent) ) ],
|
60
|
+
# 得たい付加情報?
|
61
|
+
[ A(:server_flag), A(:client_flag), A(:server_folder), A(:user_folder), A(:user_flag) ]
|
62
|
+
) ),
|
63
|
+
# 並び順と数?
|
64
|
+
T( T( A(:plain), A(:uid) ), A(:descending), nil, limit ),
|
65
|
+
# 不明
|
66
|
+
nil, MAX_SIZE, MAX_SIZE ]) )
|
67
|
+
end
|
68
|
+
# Maillistの続きのメールを得る。uid順。startからlimit個。新しいMaillistを返す。
|
69
|
+
def mail_list_get(maillist, start,limit )
|
70
|
+
Maillist.new( *rcp( "mail_list_get", [ maillist.sign, T( T( A(:plain), A(:uid) ), A(:descending), start, limit ), MAX_SIZE ] ) )
|
71
|
+
end
|
72
|
+
# uid で指定したメールの全パート情報を得る。Mailpartsを返す。
|
73
|
+
# uid は to_uid によって変換される
|
74
|
+
def mail_get_parts(uid)
|
75
|
+
Mailparts.new *rcp("mail_get_parts", [ to_uid(uid), [ T( A(:bodypref), [ "*/*" ] ), T( A(:bodyparse), A(:off) ) ], MAX_SIZE ])
|
76
|
+
end
|
77
|
+
# そのパートの添付ファイルを得る。String型のバイナリデータ。
|
78
|
+
# mimepart は Mimepart型
|
79
|
+
def attachment(mimepart)
|
80
|
+
url = "/pc/attachment.php?url=#{u(mimepart.attache_info)}"
|
81
|
+
url += "&df=#{u(mimepart.filename.to_s)}" if mimepart.filename
|
82
|
+
@agent.get_file(url)
|
83
|
+
end
|
84
|
+
# ラベル(フォルダ)の一覧 MailLabelList を得る。
|
85
|
+
def mail_label_list
|
86
|
+
MailLabelList.new( *rcp( "mail_label", [ [
|
87
|
+
T( A(:list), [ A(:server_folder) ], A(:ascending) ),
|
88
|
+
T( A(:list), [ A(:user_folder) ], A(:ascending) ),
|
89
|
+
T( A(:list), [ A(:user_flag) ], A(:ascending) )
|
90
|
+
], 10000 ] ) )
|
91
|
+
end
|
92
|
+
# uid で指定したメールのヘッダ(AllMailHeaders)を得る。
|
93
|
+
# uid は to_uid によって変換される
|
94
|
+
def mail_get_headers(maillistitem)
|
95
|
+
AllMailHeaders.new *rcp( "mail_get_headers", [ to_uid(maillistitem), A(:infinity) ] )
|
96
|
+
end
|
97
|
+
# uid で指定したメールのSMTP送信用テキストを作る
|
98
|
+
# uid は to_uid によって変換される
|
99
|
+
def make_mail_to_smtp(uid)
|
100
|
+
Builder.new(self).build( uid )
|
101
|
+
end
|
102
|
+
# uid で指定したメールにclient_flagをたてる。
|
103
|
+
# uid は to_uid によって変換される
|
104
|
+
def append_client_flag(uid,flag="flagged")
|
105
|
+
rcp( "mail_label", [ [ T( A(:append), T( A(:client_flag), A(flag) ), null, [ to_uid(uid) ] ) ], 10000 ] )
|
106
|
+
end
|
107
|
+
# uid で指定したメールからclient_flagを外す。
|
108
|
+
# uid は to_uid によって変換される
|
109
|
+
def remove_client_flag(uid,flag="flagged")
|
110
|
+
rcp( "mail_label", [ [ T( A(:remove), T( A(:client_flag), A(flag) ), null, [ to_uid(uid) ] ) ], 10000 ] )
|
111
|
+
end
|
112
|
+
# maillistitem を uid にする。文字列なら数値化、数値以外ならuidプロパティーの値を返す
|
113
|
+
def to_uid( maillistitem )
|
114
|
+
maillistitem = maillistitem.to_i if maillistitem.is_a? String
|
115
|
+
maillistitem = maillistitem.uid unless maillistitem.is_a? Numeric
|
116
|
+
maillistitem
|
117
|
+
end
|
118
|
+
|
119
|
+
def A(str) # :nodoc:
|
120
|
+
{'$A'=>str.to_s}
|
121
|
+
end
|
122
|
+
def T(*array) # :nodoc:
|
123
|
+
{'$T'=>array}
|
124
|
+
end
|
125
|
+
|
126
|
+
# SMTPサーバに送信するためのメールテキストを作成する。
|
127
|
+
# 他のメールソフト・メールライブラリで扱うための中間形式としても。
|
128
|
+
class Builder
|
129
|
+
@mailer
|
130
|
+
def initialize(mailer)
|
131
|
+
@mailer = mailer
|
132
|
+
end
|
133
|
+
# uid からメールテキストを作成する
|
134
|
+
# 引数 uid には to_uid が適用される。
|
135
|
+
def build(uid)
|
136
|
+
build_from @mailer.mail_get_headers(uid), @mailer.mail_get_parts(uid)
|
137
|
+
end
|
138
|
+
# header と parts からメールテキストを作成する
|
139
|
+
def build_from(headers,parts)
|
140
|
+
headers.multipart? ? make_mail_to_smtp_multipart( headers, parts ) : make_mail_to_smtp_singlepart( headers, parts.parts[0] )
|
141
|
+
end
|
142
|
+
|
143
|
+
# AllMailHeaders と Mimepart からメールのSMTP送信用テキストを作る(シングル)
|
144
|
+
def make_mail_to_smtp_singlepart(headers,part)
|
145
|
+
headers.to_s + "\n\n" + @mailer.attachment( part )
|
146
|
+
end
|
147
|
+
# AllMailHeaders と Mailparts からメールのSMTP送信用テキストを作る(マルチパート)
|
148
|
+
def make_mail_to_smtp_multipart(headers,parts)
|
149
|
+
raise "unknown type header #{text}" unless headers.content_type =~ /boundary=(.*)$/
|
150
|
+
boundary = $1.dup.strip.gsub(/^"(.*)"$/,'\1').gsub(/^'(.*)'$/,'\1')
|
151
|
+
|
152
|
+
headers.to_s +
|
153
|
+
"\n\n--#{boundary}\n" +
|
154
|
+
parts.parts.map{|part| part_to_mail(part).join("\n")}.join("\n--#{boundary}\n") +
|
155
|
+
"\n--#{boundary}--\n"
|
156
|
+
end
|
157
|
+
# Mimepart をsmtp bodyに
|
158
|
+
def part_to_mail(part)
|
159
|
+
body = @mailer.attachment( part )
|
160
|
+
content_type = part.content_type
|
161
|
+
is_text = content_type =~ /^text\//
|
162
|
+
mail = []
|
163
|
+
mail << "Content-Type: #{content_type}"
|
164
|
+
mail << "Content-Transfer-Encoding: #{is_text ? '8bit' : 'base64' }"
|
165
|
+
mail << "Content-ID: #{part.contentid}" if part.contentid
|
166
|
+
mail << "Content-Disposition: #{part.disposition_with_filename}" if part.disposition
|
167
|
+
mail << ""
|
168
|
+
mail << ( is_text ? body : Base64.encode64(body) )
|
169
|
+
mail
|
170
|
+
end
|
171
|
+
end
|
172
|
+
# rcp 1.0 にパラメータを投げる
|
173
|
+
def rcp( method,params )
|
174
|
+
@id += 1
|
175
|
+
result = Parser.rcp_to_ruby(JSON.parse(@agent.post("http://pc.dwmail.jp/api/base/rpc/1.0", {
|
176
|
+
:id => @id.to_s,
|
177
|
+
:method => method.to_s,
|
178
|
+
:params => params,
|
179
|
+
:version=>"1.1"
|
180
|
+
}.to_json ).body))
|
181
|
+
unless result["error"]
|
182
|
+
return result["result"]
|
183
|
+
else
|
184
|
+
require 'pp'
|
185
|
+
pp result['error']
|
186
|
+
pp params
|
187
|
+
raise "error ! #{result['error']}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
# rcp で返ってきたデータをRubyフレンドリーにする
|
191
|
+
class Parser
|
192
|
+
# rcp で返ってきたHashデータをRubyフレンドリーにする
|
193
|
+
def self.hash_to_ruby(data)
|
194
|
+
ret = {}
|
195
|
+
for k,v in data
|
196
|
+
ret[k]=rcp_to_ruby(v)
|
197
|
+
end
|
198
|
+
return ret
|
199
|
+
end
|
200
|
+
# rcp で返ってきたデータをRubyフレンドリーにする
|
201
|
+
def self.rcp_to_ruby(data)
|
202
|
+
case data
|
203
|
+
when Hash
|
204
|
+
if data.keys.size==1
|
205
|
+
case data.keys[0]
|
206
|
+
when '$T'
|
207
|
+
if data["$T"].is_a? Array
|
208
|
+
return TArray.new(data)
|
209
|
+
end
|
210
|
+
when '$A'
|
211
|
+
if data["$A"].is_a? String
|
212
|
+
return data["$A"].to_sym
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
if data['$R'] and data['$R'].is_a? String
|
217
|
+
# data type is data['$R']
|
218
|
+
case data['$R']
|
219
|
+
when 'mailheaders'
|
220
|
+
return Mailheaders.new( data )
|
221
|
+
when 'mailsummary'
|
222
|
+
return Mailsummary.new( data )
|
223
|
+
when 'mimepartspec'
|
224
|
+
return Mimepartspec.new( data )
|
225
|
+
end
|
226
|
+
end
|
227
|
+
return hash_to_ruby(data)
|
228
|
+
when Array
|
229
|
+
ret = []
|
230
|
+
for v in data
|
231
|
+
ret << rcp_to_ruby(v)
|
232
|
+
end
|
233
|
+
return ret
|
234
|
+
end
|
235
|
+
return data
|
236
|
+
end
|
237
|
+
end
|
238
|
+
# Structの用に扱えるハッシュ。{ '$R'=>クラス名, .... } 形式のハッシュを扱うために用いる
|
239
|
+
class RHash
|
240
|
+
def initialize(data)
|
241
|
+
raise "invalid parameta" unless data.is_a? Hash
|
242
|
+
@data = Parser.hash_to_ruby(data)
|
243
|
+
@data.delete('$R')
|
244
|
+
end
|
245
|
+
# ハッシュのキーをメソッドのようにも使える
|
246
|
+
def method_missing(sym, *args, &block)
|
247
|
+
if @data.has_key? sym.to_s
|
248
|
+
@data[sym.to_s]
|
249
|
+
else
|
250
|
+
@data.send sym, *args, &block
|
251
|
+
end
|
252
|
+
end
|
253
|
+
def inspect #:nodoc:
|
254
|
+
"#{self.class.to_s.split('::').last}"+@data.inspect
|
255
|
+
end
|
256
|
+
end
|
257
|
+
# { '$T'=> [ ] } 形式の配列データ
|
258
|
+
class TArray < Array
|
259
|
+
def initialize(data)
|
260
|
+
super(Parser.rcp_to_ruby(data['$T']))
|
261
|
+
end
|
262
|
+
def inspect #:nodoc:
|
263
|
+
"T"+super
|
264
|
+
end
|
265
|
+
end
|
266
|
+
# メールのヘッダ
|
267
|
+
# 主なプロパティーに次の値がある
|
268
|
+
# cc :: ccの宛先 ( ["ラベル","メールアドレス"]の配列 )
|
269
|
+
# from :: 差出人 ( ["ラベル","メールアドレス"]の配列 )
|
270
|
+
# bcc :: bccの宛先( ["ラベル","メールアドレス"]の配列 )
|
271
|
+
# to :: toの宛先 ( ["ラベル","メールアドレス"]の配列 )
|
272
|
+
# date :: 日付(エポック秒)
|
273
|
+
# subject :: メールタイトル(デコード済み)
|
274
|
+
# othres :: その他のヘッダ( [ "ヘッダ名:値" ] の配列 )
|
275
|
+
# in_replay_to :: 用途不明
|
276
|
+
# references :: 用途不明
|
277
|
+
# message_id :: メッセージID
|
278
|
+
class Mailheaders < RHash
|
279
|
+
def initialize(data)
|
280
|
+
super
|
281
|
+
end
|
282
|
+
end
|
283
|
+
# メールのサマリ。一覧表示などに使う
|
284
|
+
# 主なプロパティーに次の値がある
|
285
|
+
# bytes :: メールのバイト数
|
286
|
+
# mailheaders :: メールのヘッダ(Mailheadersクラス)
|
287
|
+
# uid :: ユニークid
|
288
|
+
# versionid :: 用途不明
|
289
|
+
# attachments :: 添付ファイル名のリスト
|
290
|
+
# created :: 受信日(エポック秒)
|
291
|
+
class Mailsummary < RHash
|
292
|
+
def initialize(data)
|
293
|
+
super
|
294
|
+
end
|
295
|
+
# メールのヘッダ(Mailheadersクラス)
|
296
|
+
def mailheaders
|
297
|
+
@data["mailheaders"]
|
298
|
+
end
|
299
|
+
def method_missing(sym, *args, &block)
|
300
|
+
if @data.has_key? sym.to_s
|
301
|
+
@data[sym.to_s]
|
302
|
+
elsif mailheaders.has_key? sym.to_s
|
303
|
+
mailheaders[sym.to_s]
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
# mimeパートのヘッダ
|
308
|
+
# 主なプロパティーに次の値がある
|
309
|
+
# conentid :: Content-ID
|
310
|
+
# bytes :: 用途不明
|
311
|
+
# content_type :: Content-Type
|
312
|
+
# disposition :: Content-Disposition
|
313
|
+
# filename :: ファイル名
|
314
|
+
# first_byte_offset :: 用途不明
|
315
|
+
# vertionid :: 用途不明
|
316
|
+
class Mimepartspec < RHash
|
317
|
+
def initialize(data)
|
318
|
+
super
|
319
|
+
end
|
320
|
+
# ファイル名付きのContent-Dispositionを得る
|
321
|
+
def disposition_with_filename
|
322
|
+
@data['filename'] ? "#{@data['disposition']}; filename=#{@data['filename']}" : @data['disposition']
|
323
|
+
end
|
324
|
+
end
|
325
|
+
# メールのリストのアイテム
|
326
|
+
class MailListItem
|
327
|
+
# リスト内での位置( 一番上が1 )
|
328
|
+
attr_reader :order
|
329
|
+
# メールのサマリ(Mailsummary)
|
330
|
+
attr_reader :summary
|
331
|
+
# 用途不明
|
332
|
+
attr_reader :flag
|
333
|
+
def initialize( order, summary, flag )
|
334
|
+
@order , @summary, @flag = order, summary, flag
|
335
|
+
end
|
336
|
+
# summary に委譲
|
337
|
+
def method_missing(sym, *args, &block)
|
338
|
+
@summary.send sym, *args, &block
|
339
|
+
end
|
340
|
+
end
|
341
|
+
# メールの一つのmimeパート
|
342
|
+
class Mimepart
|
343
|
+
# Mimepartspec
|
344
|
+
attr_reader :spec
|
345
|
+
# メール本文(HTML化されている)
|
346
|
+
attr_reader :body
|
347
|
+
# 用途不明。ヘッダが [ ["content-type", "text/plain"] ] のような形で入るようだ
|
348
|
+
attr_reader :inline_head
|
349
|
+
# attache を得るためのキー
|
350
|
+
attr_reader :attache_info
|
351
|
+
def initialize( specs, inline )
|
352
|
+
@spec, @attache_info = specs
|
353
|
+
@inline_head, @body = inline if inline
|
354
|
+
end
|
355
|
+
# spec に委譲
|
356
|
+
def method_missing(sym, *args, &block)
|
357
|
+
@spec.send sym, *args, &block
|
358
|
+
end
|
359
|
+
# より正しい content-type を得る( inline_head に content-type があればそちらを持ってくる )
|
360
|
+
def content_type_more(part)
|
361
|
+
for n,v in inline_head
|
362
|
+
return v if n == 'content-type'
|
363
|
+
end if inline_head
|
364
|
+
return @spec.content_type
|
365
|
+
end
|
366
|
+
end
|
367
|
+
# フォルダ内のメールのリスト
|
368
|
+
class Maillist < Array
|
369
|
+
# mail_list_get 時に使われるキー
|
370
|
+
attr_reader :sign
|
371
|
+
# :ok なら取得成功
|
372
|
+
attr_reader :status
|
373
|
+
# おそらくメールボックス内のメールの数。mail_list_get 時は無効
|
374
|
+
attr_reader :max_size
|
375
|
+
def initialize( status, sign, mails, max_size=nil )
|
376
|
+
@status, @sign, @max_size = status, sign, max_size
|
377
|
+
for mail in mails
|
378
|
+
self << MailListItem.new( *mail )
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
# メールの詳細情報。複数のmimeパートを含むデータ
|
383
|
+
class Mailparts
|
384
|
+
# :ok なら取得成功
|
385
|
+
attr_reader :status
|
386
|
+
# Mimepart の配列
|
387
|
+
attr_reader :parts
|
388
|
+
# ヘッダ
|
389
|
+
attr_reader :header
|
390
|
+
def initialize( status , header, parts )
|
391
|
+
@status , @header = status, header
|
392
|
+
@parts = parts.map{|data| Mimepart.new( *data )}
|
393
|
+
end
|
394
|
+
def [](num)
|
395
|
+
@parts[num]
|
396
|
+
end
|
397
|
+
end
|
398
|
+
# メールのヘッダ。素の形に近い( Mimepartspec などは利用しやすいが失われている情報が多い)
|
399
|
+
class AllMailHeaders
|
400
|
+
# :ok なら取得成功
|
401
|
+
attr_reader :status
|
402
|
+
# ヘッダ。[ ["ヘッダ名","ヘッダ値"] ... ] の形式で格納されている。
|
403
|
+
attr_reader :header
|
404
|
+
def initialize(status, header)
|
405
|
+
@status, @header = status, header
|
406
|
+
end
|
407
|
+
# メールのヘッダの形にして返す
|
408
|
+
def to_s
|
409
|
+
@header.map{|k,v| "#{k}: #{v}" }.join("\n")
|
410
|
+
end
|
411
|
+
# header に委譲
|
412
|
+
def method_missing(sym, *args, &block)
|
413
|
+
@header.send sym, *args, &block
|
414
|
+
end
|
415
|
+
# header から 対応する名前のヘッダの値を返す。複数ある場合は最初のものを返す。
|
416
|
+
def []( name )
|
417
|
+
@header.find{|n,a| n==name }[1]
|
418
|
+
end
|
419
|
+
# header から content-type の値を得る
|
420
|
+
def content_type
|
421
|
+
['content-type']
|
422
|
+
end
|
423
|
+
# マルチパートか否か
|
424
|
+
def multipart?
|
425
|
+
content_type =~ /^multipart\//
|
426
|
+
end
|
427
|
+
end
|
428
|
+
# メールのラベル(フォルダ)一つを表す
|
429
|
+
class MailLabel
|
430
|
+
# 場所。:server_folder, :user_folder, :user_flag がある
|
431
|
+
attr_reader :place
|
432
|
+
# システム名。place=server_folder の時は名前を表すシンボル、それ以外の時は連番
|
433
|
+
# 名前を表すシンボルは :draft, :inbox, :sent, :trash, :upload がある
|
434
|
+
attr_reader :index
|
435
|
+
# 名前。メルマガフォルダの時は __MM__ が接頭辞としてつく( 例: "__MM__雑誌" )
|
436
|
+
attr_reader :name
|
437
|
+
# フォルダ内のメールの数
|
438
|
+
attr_reader :num
|
439
|
+
# 用途不明
|
440
|
+
attr_reader :num2
|
441
|
+
def initialize(systemname, name, num, num2)
|
442
|
+
@name, @num, @num2 = name, num, num2
|
443
|
+
@place, @index = systemname
|
444
|
+
end
|
445
|
+
end
|
446
|
+
# メールのラベル(フォルダ)リストを表す
|
447
|
+
class MailLabelList
|
448
|
+
# サーバフォルダ(既定のフォルダ)のリスト。MailLabel の配列である。
|
449
|
+
attr_reader :server_folders
|
450
|
+
# 個人フォルダ(およびメルマガフォルダ)のリスト。MailLabel の配列である。
|
451
|
+
attr_reader :user_folders
|
452
|
+
# ユーザフラグのリスト(用途不明)。MailLabel の配列である。
|
453
|
+
attr_reader :user_flags
|
454
|
+
# 戻りステータス :ok なら異常なし(詳細不明)
|
455
|
+
attr_reader :status
|
456
|
+
def initialize(status, data)
|
457
|
+
@status = status
|
458
|
+
@server_folders,@user_folders,@user_flags = data.map{|a| a.map{|l| MailLabel.new(*l) }}
|
459
|
+
end
|
460
|
+
# 名前でラベル(フォルダ)を選ぶ
|
461
|
+
# nameがシンボルならサーバフォルダから、文字列ならユーザフォルダから選ぶ。
|
462
|
+
# 数字ならユーザフォルダのインデックスとして選ぶ。
|
463
|
+
def [](name)
|
464
|
+
if name.is_a? Symbol
|
465
|
+
return @server_folders.find{|a| a.index == name}
|
466
|
+
elsif name.is_a? Numeric
|
467
|
+
return @user_folders.find{|a| a.index == name}
|
468
|
+
else
|
469
|
+
return @user_folders.find{|a| a.name == name}
|
470
|
+
end
|
471
|
+
raise "invalid label key #{name}"
|
472
|
+
end
|
473
|
+
end
|
474
|
+
private
|
475
|
+
def u(str) #:nodoc:
|
476
|
+
CGI.escape(str)
|
477
|
+
end
|
478
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class DocomoWebMailer
|
2
|
+
def convert_mail(header)
|
3
|
+
text = headers.to_s
|
4
|
+
text += "\n\n"
|
5
|
+
if parts.parts.size == 1
|
6
|
+
data = mail_get_attache( parts.parts[0] )
|
7
|
+
text +="#{data}"
|
8
|
+
else
|
9
|
+
h = nil
|
10
|
+
raise "unknown type header #{text}" unless headers.find{|k,v| k == "content-type" and v =~ /boundary=(.*)$/}
|
11
|
+
boundary = $1.dup.strip.gsub(/^"(.*)"$/,'\1').gsub(/^'(.*)'$/,'\1')
|
12
|
+
for part in parts.parts
|
13
|
+
body = mail_get_attache( part )
|
14
|
+
header = []
|
15
|
+
header << "--#{boundary}"
|
16
|
+
content_type = part.content_type
|
17
|
+
if part.inline_head and part.inline_head.find{|n,v| n == 'content-type'}
|
18
|
+
content_type = part.inline_head.find{|n,v| n == 'content-type'}[1]
|
19
|
+
end
|
20
|
+
puts "content_type=#{content_type}"
|
21
|
+
header << "Content-Type: #{content_type}"
|
22
|
+
is_text = content_type =~ /^text\//
|
23
|
+
if is_text
|
24
|
+
header << "Content-Transfer-Encoding: 8bit"
|
25
|
+
else
|
26
|
+
header << "Content-Transfer-Encoding: base64"
|
27
|
+
end
|
28
|
+
header << "Content-ID: #{part.contentid}" if part.contentid
|
29
|
+
if part.disposition
|
30
|
+
if part.filename
|
31
|
+
header << "Content-Disposition: #{part.disposition}; filename=#{part.filename}"
|
32
|
+
else
|
33
|
+
header << "Content-Disposition: #{part.disposition}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
header << ""
|
37
|
+
if is_text
|
38
|
+
header << body
|
39
|
+
else
|
40
|
+
header << Base64.encode64(body)
|
41
|
+
end
|
42
|
+
header << ""
|
43
|
+
text += header.join("\n")
|
44
|
+
end
|
45
|
+
text +="--#{boundary}--\n"
|
46
|
+
end
|
47
|
+
text
|
48
|
+
end
|
49
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'docomo_web_mailer'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docomo_web_mailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- nazoking
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-19 00:00:00 +09:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
name: shoulda
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
requirement: *id001
|
34
|
+
type: :development
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
prerelease: false
|
37
|
+
name: bundler
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 23
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 0
|
47
|
+
- 0
|
48
|
+
version: 1.0.0
|
49
|
+
requirement: *id002
|
50
|
+
type: :development
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
prerelease: false
|
53
|
+
name: jeweler
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 1
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 5
|
63
|
+
- 1
|
64
|
+
version: 1.5.1
|
65
|
+
requirement: *id003
|
66
|
+
type: :development
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
prerelease: false
|
69
|
+
name: rcov
|
70
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirement: *id004
|
80
|
+
type: :development
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
prerelease: false
|
83
|
+
name: mechanize
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 15
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 0
|
93
|
+
version: "1.0"
|
94
|
+
requirement: *id005
|
95
|
+
type: :development
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
prerelease: false
|
98
|
+
name: json
|
99
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
requirement: *id006
|
109
|
+
type: :development
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
prerelease: false
|
112
|
+
name: mechanize
|
113
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
hash: 15
|
119
|
+
segments:
|
120
|
+
- 1
|
121
|
+
- 0
|
122
|
+
version: "1.0"
|
123
|
+
requirement: *id007
|
124
|
+
type: :runtime
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
prerelease: false
|
127
|
+
name: json
|
128
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
requirement: *id008
|
138
|
+
type: :runtime
|
139
|
+
description: !binary |
|
140
|
+
RG9jb21vIFdlYiBNYWlsICggaHR0cDovL2R3bWFpbC5qcC8gKSDjgpJSdWJ5
|
141
|
+
44GL44KJ44GE44GY44KL44GT44Go44Gu5Ye65p2l44KL44Op44Kk44OW44Op
|
142
|
+
44Oq44Gn44GZ44CC54++5Zyo44Gv5Y+X5L+h44Gu44G/5a++5b+c44GX44Gm
|
143
|
+
44GK44KK44CB6YCB5L+h44KE5YmK6Zmk44GZ44KL44GT44Go44Gv5Ye65p2l
|
144
|
+
44G+44Gb44KT44CCIA==
|
145
|
+
|
146
|
+
email: nazoking@gmail.com
|
147
|
+
executables: []
|
148
|
+
|
149
|
+
extensions: []
|
150
|
+
|
151
|
+
extra_rdoc_files:
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.rdoc
|
154
|
+
files:
|
155
|
+
- .document
|
156
|
+
- Gemfile
|
157
|
+
- LICENSE.txt
|
158
|
+
- README.rdoc
|
159
|
+
- Rakefile
|
160
|
+
- VERSION
|
161
|
+
- docomo_web_mailer.gemspec
|
162
|
+
- lib/docomo_web_mailer.rb
|
163
|
+
- lib/docomo_web_mailer/convert_mail.rb
|
164
|
+
- test/helper.rb
|
165
|
+
- test/test_docomo_web_mailer.rb
|
166
|
+
has_rdoc: true
|
167
|
+
homepage: http://github.com/nazoking/docomo_web_mailer
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
post_install_message:
|
171
|
+
rdoc_options: []
|
172
|
+
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
hash: 3
|
181
|
+
segments:
|
182
|
+
- 0
|
183
|
+
version: "0"
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
hash: 3
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
version: "0"
|
193
|
+
requirements: []
|
194
|
+
|
195
|
+
rubyforge_project:
|
196
|
+
rubygems_version: 1.3.7
|
197
|
+
signing_key:
|
198
|
+
specification_version: 3
|
199
|
+
summary: Docomo Web Mail Client
|
200
|
+
test_files:
|
201
|
+
- test/helper.rb
|
202
|
+
- test/test_docomo_web_mailer.rb
|