goodbye_chatwork 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cdfc6ab916b0f822c28c98093f6d1cf3a4aa57a1
4
+ data.tar.gz: a373385369d5d3f549f31737701999ccd2caee3c
5
+ SHA512:
6
+ metadata.gz: 5ff81823a9fe44bb45d0d79419992fb4c12461177fb86d19b81dc4c7c2de8bfcd0d429ad48777ffaa70fd2e2b615ae4efa8ed8fa942e7fe6c573f48c33887030
7
+ data.tar.gz: 889a1c4805158ab7a5918d6831172c541e210e9087b608dab04f71f7d9b3af87edaa8be0294924f44bb09cb00310b53e3de4925667c1e65c94bf306cb7e16d96
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in goodbye_chatwork.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 swdyh
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,29 @@
1
+ # GoodbyeChatwork
2
+
3
+ This is Chatwork(chatwork.com) log exporter. This can be used also when you can not use API.
4
+
5
+ ## Installation
6
+
7
+ $ gem install goobye_chatwork
8
+
9
+ ## Usage
10
+
11
+ show chat room list (output: room_id room_name count)
12
+
13
+ $ goodbye_chatwork -i example@example.com -p your_password
14
+ 11111 chatroom1 24
15
+ 11112 chatroom1 42
16
+
17
+ export logs (chat logs only: -e option)
18
+
19
+ $ goodbye_chatwork -i example@example.com -p your_password -e room_id
20
+
21
+ export logs (chat logs and attachment files: -x option)
22
+
23
+ $ goodbye_chatwork -i example@example.com -p your_password -x room_id
24
+
25
+ ## Information
26
+
27
+ Copyright (c) 2014 swdyh
28
+ MIT License
29
+ https://github.com/swdyh/goodbye_chatwork
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'fileutils'
5
+ require 'goodbye_chatwork'
6
+
7
+ opts = ARGV.getopts('i:p:e:x:d:h')
8
+ email = opts['i']
9
+ password = opts['p']
10
+
11
+ if opts['h'] || !email || !password
12
+ puts <<-EOS
13
+ Usage: goodbye_chatwork
14
+ -i your chatwork id
15
+ -p your chatwork password
16
+ -e room id (export chat logs)
17
+ -x room id (export chat logs and download attachment files)
18
+ -d dir
19
+
20
+ Example:
21
+ show room list
22
+
23
+ $ goodbye_chatwork -i example@example.com -p your_password
24
+
25
+ export logs (-e: chat logs only)
26
+
27
+ $ goodbye_chatwork -i example@example.com -p your_password -e room_id
28
+
29
+ export logs (-x: chat logs and attachment files)
30
+
31
+ $ goodbye_chatwork -i example@example.com -p your_password -x room_id
32
+ EOS
33
+ exit
34
+ end
35
+
36
+ gcw = GoobyeChatwork::Client.new(email, password, verbose: true)
37
+ gcw.login
38
+ list = gcw.room_list
39
+ if opts['x'] || opts['e']
40
+ log_dir = opts['d'] || 'chatwork_logs'
41
+ unless File.exists?(log_dir)
42
+ gcw.info "mkdir #{log_dir}"
43
+ FileUtils.mkdir_p log_dir
44
+ end
45
+ room_id = opts['x'] || opts['e']
46
+ room = list.find { |i| i[0] == room_id.to_s }
47
+ unless room
48
+ puts 'no room'
49
+ exit 1
50
+ end
51
+ room_name = room[1].gsub(/[[:cntrl:]\s\/\:]/, '')
52
+ out = File.join(log_dir, "#{room_id}_#{room_name}.csv")
53
+ file_dir = File.join(log_dir, "#{room_id}_files_#{room_name}")
54
+ if opts['x']
55
+ gcw.export_csv(room_id, out, { include_file: true, dir: file_dir })
56
+ else
57
+ gcw.export_csv(room_id, out)
58
+ end
59
+ else
60
+ puts list.map { |i| i.join(' ') }
61
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'goodbye_chatwork/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "goodbye_chatwork"
8
+ spec.version = GoodbyeChatwork::VERSION
9
+ spec.authors = ["swdyh"]
10
+ spec.email = ["youhei@gmail.com"]
11
+ spec.summary = %q{export Chatwork(chatwork.com) logs}
12
+ spec.description = %q{This is Chatwork(chatwork.com) log exporter. This can be used also when you can not use API.}
13
+ spec.homepage = "https://github.com/swdyh/goodbye_chatwork"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_runtime_dependency "faraday"
24
+ spec.add_runtime_dependency "faraday-cookie_jar"
25
+ end
@@ -0,0 +1,163 @@
1
+ require "goodbye_chatwork/version"
2
+ require 'csv'
3
+ require 'fileutils'
4
+ require 'open-uri'
5
+ require 'json'
6
+ require 'faraday'
7
+ require 'faraday-cookie_jar'
8
+
9
+ module GoodbyeChatwork
10
+ class Client
11
+ REQUEST_INTERVAL = 1
12
+ CHAT_SIZE = 40
13
+
14
+ def initialize(id, pw, opt = {})
15
+ @verbose = opt[:verbose]
16
+ @id = id
17
+ @pw = pw
18
+ @opt = opt
19
+ @interval = opt[:inverval] || REQUEST_INTERVAL
20
+ @base_url = opt[:base_url] || 'https://www.chatwork.com'
21
+ @token = nil
22
+ @client = Faraday.new @base_url do |builder|
23
+ builder.request :url_encoded
24
+ builder.use :cookie_jar
25
+ builder.adapter Faraday.default_adapter
26
+ end
27
+ end
28
+
29
+ def login
30
+ @client.post '/login.php', email: @id, password: @pw, autologin: 'on'
31
+ r = @client.get '/'
32
+ self.wait
33
+ self.info "login as #{@id} ..."
34
+ @token = r.body.match(/var ACCESS_TOKEN = '(.+)'/).to_a[1]
35
+ @myid = r.body.match(/var myid = '(.+)'/).to_a[1]
36
+ raise 'no token' unless @token
37
+ self.init_load
38
+ self.get_account_info
39
+ self
40
+ end
41
+
42
+ def init_load
43
+ self.info "load initial data..."
44
+ r = @client.get "/gateway.php?cmd=init_load&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja&rid=0&type=&new=1"
45
+ self.wait
46
+ d = JSON.parse(r.body)['result']
47
+ @contacts = d['contact_dat']
48
+ @rooms = d['room_dat']
49
+ end
50
+
51
+ def get_account_info
52
+ aids = @contacts.values.map { |i| i['aid'] }
53
+ mids = @rooms.values.map { |i| i['m'].keys }.flatten.uniq.map(&:to_i)
54
+ diff_ids = (mids - aids).sort
55
+ pdata = 'pdata=' + JSON.generate({ aid: diff_ids, get_private_data: 0 })
56
+ self.info 'load account info'
57
+ r = @client.post "/gateway.php?cmd=get_account_info&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja", pdata
58
+ self.wait
59
+ begin
60
+ d = JSON.parse(r.body)['result']['account_dat']
61
+ @contacts.merge!(d)
62
+ rescue Exception => e
63
+ self.info e.to_s
64
+ end
65
+ self.wait
66
+ end
67
+
68
+ def old_chat room_id, first_chat_id = 0
69
+ self.info "get old caht #{first_chat_id}- ..."
70
+ res = @client.get "https://www.chatwork.com/gateway.php?cmd=load_old_chat&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja&room_id=#{room_id}&last_chat_id=0&first_chat_id=#{first_chat_id}&jump_to_chat_id=0&unread_num=0&file=1&desc=1"
71
+ self.wait
72
+ r = JSON.parse(res.body)
73
+ r['result']['chat_list'].sort_by { |i| - i['id'] }
74
+ end
75
+
76
+ def account(aid)
77
+ @contacts[aid.to_s]
78
+ end
79
+
80
+ def file_download(file_id, opt = {})
81
+ info = self.file_info file_id
82
+ if !info[:url] || !info[:filename]
83
+ self.info "download error #{file_id}"
84
+ return
85
+ end
86
+
87
+ d = open(info[:url]).read
88
+ self.info "download #{info[:filename]} ..."
89
+ fn = "#{file_id}_#{info[:filename]}".force_encoding('utf-8')
90
+ out = fn
91
+ if opt[:dir]
92
+ unless File.exists?(opt[:dir])
93
+ self.info "mkdir #{opt[:dir]}"
94
+ FileUtils.mkdir_p opt[:dir]
95
+ end
96
+ out = File.join(opt[:dir], fn)
97
+ end
98
+ open(out, 'w') { |f| f.write d }
99
+ end
100
+
101
+ def file_info(file_id)
102
+ self.info "get file info #{file_id} ..."
103
+ r = @client.get "https://www.chatwork.com/gateway.php?cmd=download_file&bin=1&file_id=#{file_id}"
104
+ self.wait
105
+ b = r.headers['Content-disposition'].match(/filename="=\?UTF-8\?B\?(.+)\?="/).to_a[1]
106
+ { url: r.headers['Location'], filename: b.unpack('m')[0] }
107
+ end
108
+
109
+ def export_csv(room_id, out, opt = {})
110
+ self.info "export logs #{room_id} ..."
111
+ CSV.open(out, "wb") do |csv|
112
+ fid = 0
113
+ loop do
114
+ r = self.old_chat(room_id, fid)
115
+ r.each do |i|
116
+ if opt[:include_file]
117
+ fid = i['msg'].match(/\[download\:([^\]]+)\]/).to_a[1]
118
+ if fid
119
+ begin
120
+ file_download fid, dir: opt[:dir]
121
+ rescue Exception => e
122
+ self.info "download error #{fid} #{e.to_s}"
123
+ end
124
+ end
125
+ end
126
+ ac = self.account(i['aid'])
127
+ csv << [Time.at(i['tm']).iso8601,
128
+ (ac ? ac['name'] : i['aid']), i['msg']]
129
+ end
130
+ break if r.size < CHAT_SIZE
131
+ fid = r.last['id']
132
+ end
133
+ end
134
+ self.info "create #{out}"
135
+ end
136
+
137
+ def room_list
138
+ @rooms.to_a.sort_by { |i| i[0].to_i }.map do |i|
139
+ name = i[1]['n']
140
+ member_ids = i[1]['m'].keys
141
+ c = i[1]['c']
142
+ if !name && member_ids.size == 1 && member_ids.first == @myid
143
+ [i[0], 'mychat', c]
144
+ elsif name
145
+ [i[0], name, c]
146
+ elsif member_ids.size == 2 && member_ids.include?(@myid)
147
+ ac = self.account(member_ids.find { |i| i != @myid }) || {}
148
+ [i[0], ac['name'], c]
149
+ else
150
+ [i[0], '...', c]
151
+ end
152
+ end
153
+ end
154
+
155
+ def info(d)
156
+ STDERR.puts([Time.now.iso8601, d].flatten.join(' ')) if @verbose
157
+ end
158
+
159
+ def wait
160
+ sleep(@interval + rand)
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,3 @@
1
+ module GoodbyeChatwork
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: goodbye_chatwork
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - swdyh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: faraday
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: faraday-cookie_jar
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: This is Chatwork(chatwork.com) log exporter. This can be used also when
70
+ you can not use API.
71
+ email:
72
+ - youhei@gmail.com
73
+ executables:
74
+ - goodbye_chatwork
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/goodbye_chatwork
84
+ - goodbye_chatwork.gemspec
85
+ - lib/goodbye_chatwork.rb
86
+ - lib/goodbye_chatwork/version.rb
87
+ homepage: https://github.com/swdyh/goodbye_chatwork
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.0.14
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: export Chatwork(chatwork.com) logs
111
+ test_files: []