root/platform/tdiary/util/posttdiary/posttdiary.rb @ 35240

Revision 35240, 6.0 kB (checked in by sho, 5 years ago)

stripped subject string.

Line 
1#!/usr/bin/env ruby
2$KCODE= 'u'
3#
4# posttdiary: update tDiary via e-mail. $Revision: 1.5 $
5#
6# Copyright (C) 2002, All right reserved by TADA Tadashi <sho@spc.gr.jp>
7# You can redistribute it and/or modify it under GPL2.
8#
9
10def usage
11        <<-TEXT.gsub( /^\t{2}/, '' )
12                #{File::basename __FILE__}: update tDiary via e-mail.
13                usage: ruby #{File::basename __FILE__} [options] <url> [user] [passwd]
14                arguments:
15                  url:    update.rb's URL of your diary.
16                  user:   user ID of your diary updating.
17                  passwd: password of your diary updating.
18                          If To: field of the mail likes "user-passwd@example.com",
19                          you can omit user and passwd arguments.
20                options:
21                  --image-path,   -i: directory of image saving into.
22                  --image-url,    -u: URL of image.
23                          You have to specify both options when using images.
24                  --image-format, -f: format of image tag specified image serial
25                          number as '$0' and image url as '$1'.
26                          default format is ' <img class="photo" src="$1" alt="">'.
27                  --use-subject,  -s: use mail subject to subtitle.
28                          and insert image between subtitle and body.
29        TEXT
30end
31
32def image_list( date, path )
33        image_path = []
34        Dir.foreach( path ) do |file|
35                if file =~ /(\d{8,})_(\d+)\./ and $1 == date then
36                        image_path[$2.to_i] = file
37                end
38        end
39        image_path
40end
41
42def bmp_to_png( bmp )
43        png = bmp.sub( /\.bmp$/, '.png' )
44        begin
45                require 'magick'
46                img = Magick::Image::new( bmp )
47                img.write( 'magick' => 'png', 'filename' => png )
48        rescue LoadError
49                system( "convert #{bmp} #{png}" )
50        end
51        if FileTest::exist?( png )
52                File::delete( bmp )
53                png
54        else
55                bmp
56        end
57end
58
59begin
60
61        raise usage if ARGV.length < 1
62
63        require 'getoptlong'
64        parser = GetoptLong::new
65        image_dir = nil
66        image_url = nil
67        image_format = ' <img class="photo" src="$1" alt="">'
68        use_subject = false
69        parser.set_options(
70                ['--image-path', '-i', GetoptLong::REQUIRED_ARGUMENT],
71                ['--image-url', '-u', GetoptLong::REQUIRED_ARGUMENT],
72                ['--image-format', '-f', GetoptLong::REQUIRED_ARGUMENT],
73                ['--use-subject', '-s', GetoptLong::NO_ARGUMENT]
74        )
75        begin
76                parser.each do |opt, arg|
77                        case opt
78                        when '--image-path'
79                                image_dir = arg
80                        when '--image-url'
81                                image_url = arg
82                        when '--image-format'
83                                image_format = arg
84                        when '--use-subject'
85                                use_subject = true
86                        end
87                end
88        rescue
89                raise usage
90        end
91        raise usage if (image_dir and not image_url) or (not image_dir and image_url)
92        image_dir = image_dir.sub( %r[/*$], '/' ) if image_dir
93        image_url = image_url.sub( %r[/*$], '/' ) if image_url
94        url = ARGV.shift
95        if %r|http://([^:/]+)(?::(\d+))?(/.*)| =~ url then
96                host = $1
97                port = ($2 || 80).to_i
98                cgi  = $3
99        else
100                raise 'bad url.'
101        end
102
103        user = ARGV.shift
104        pass = ARGV.shift
105
106        require 'base64'
107        require 'nkf'
108        image_name = nil
109
110        mail = NKF::nkf( '-m0 -Xwd', ARGF.read )
111        raise "#{File::basename __FILE__}: no mail text." if not mail or mail.length == 0
112
113        head, body = mail.split( /(?:\r?\n){2}/, 2 )
114
115        if head =~ %r|Content-Type:\s*Multipart/Mixed.*boundary="?(.*?)"?[\r\n]|im then
116                if not image_dir or not image_url then
117                        raise "no --image-path and --image-url options"
118                end
119
120                bound = "--" + $1
121                body_sub = body.split( Regexp.compile( Regexp.escape( bound ) ) )
122                body_sub.each do |b|
123                        sub_head, sub_body = b.split( /(?:\r?\n){2}/, 2 )
124
125                        next unless sub_head =~ /Content-Type:/i
126
127                        if sub_head =~ %r[^Content-Type:\s*text/plain]i then
128                                @body = sub_body
129                        elsif sub_head =~ %r[
130                                ^Content-Type:\s*
131                                (?:image/|application/octet-stream).+
132                                name="?.+(\.\w{3})"? (?# 1: extension)
133                        ]imx
134                                image_ext = $1.downcase
135                                now = Time::now
136                                list = image_list( now.strftime( "%Y%m%d" ), image_dir )
137                                image_name = now.strftime( "%Y%m%d" ) + "_" + list.length.to_s + image_ext
138                                File::umask( 022 )
139                                open( image_dir + image_name, "wb" ) do |s|
140                                        begin
141                                                s.print Base64::decode64( sub_body.strip )
142                                        rescue NameError
143                                                s.print decode64( sub_body.strip )
144                                        end
145                                end
146                                if /\.bmp$/i =~ image_name then
147                                        bmp_to_png( image_dir + image_name )
148                                        image_name.sub!( /\.bmp$/i, '.png' )
149                                end
150                                @image_name ||= []
151                                @image_name << image_name
152                        end
153                end
154        elsif head =~ /^Content-Type:\s*text\/plain/i
155                @body = body
156        else
157                raise "cannot read this mail"
158        end
159
160        if @image_name then
161                img_src = ""
162                @image_name.each do |i|
163                        serial = i.sub( /^\d+_(\d+)\..*$/n, '\1' )
164                        img_src += image_format.gsub( /\$0/, serial ).gsub( /\$1/, image_url + i )
165                end
166                if use_subject then
167                        @body = "#{img_src}\n#{@body}".sub( /(?:\r?\n|\r)+\z/, "\n" )
168                else
169                        @body = "#{@body}".sub( /(?:\r?\n|\r)+\z/, "\n" ) << img_src
170                end
171        end
172
173        addr = nil
174        if /^To:(.*)$/ =~ head then
175                addr = case to = $1.strip
176                when /.*?\s*<(.+)>/, /(.+?)\s*\(.*\)/
177                        $1
178                else
179                        to
180                end
181        end
182
183        if /([^-]+)-(.*)@/ =~ addr then
184                user ||= $1
185                pass ||= $2
186        end
187
188        raise "no user." unless user
189        raise "no passwd." unless pass
190
191        subject = ''
192        nextline = false
193        headlines = head.split( /(?:\r?\n|\r)+/ )
194        for n in 0 .. headlines.size-1
195                if nextline then
196                        if /^[ \t]/ =~ headlines[n] then
197                                s = headlines[n].sub( /^[ \t]/, '' )
198                                subject += NKF::nkf( '-wXd', s )
199                        else
200                                break
201                        end
202                end
203                if /^Subject:\s*(.+)$/i =~ headlines[n] then
204                        subject = NKF::nkf( '-wXd', $1 )
205                        nextline = true
206                end
207        end
208        subject.strip!
209        if use_subject then
210                title = ''
211                @body = "#{subject}\n#{@body}"
212        else
213                title = subject
214        end
215
216        require 'cgi'
217        require 'nkf'
218        data = "title=#{CGI::escape title}"
219        data << "&body=#{CGI::escape @body}"
220        data << "&append=true"
221
222        require 'net/http'
223        Net::HTTP.start( host, port ) do |http|
224                auth = ["#{user}:#{pass}"].pack( 'm' ).strip
225                res, = http.get( cgi, {
226                                'Authorization' => "Basic #{auth}",
227                                'Referer' => url })
228                if %r|<input type="hidden" name="csrf_protection_key" value="([^"]+)">| =~ res.body then
229                        data << "&csrf_protection_key=#{CGI::escape( CGI::unescapeHTML( $1 ) )}"
230                end
231                res, = http.post( cgi, data, {
232                                'Authorization' => "Basic #{auth}",
233                                'Referer' => url })
234        end
235
236rescue
237        $stderr.puts $!
238        $stderr.puts $@.join( "\n" )
239        File::delete( image_dir + image_name ) if image_dir and image_name and FileTest::exist?( image_dir + image_name )
240        exit 1
241end
Note: See TracBrowser for help on using the browser.