goodbye_chatwork 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []