한메일 다운로드 스크립트(루비 Ver.)

158cm의 이미지

주석도 없고, 형편없는 코드지만..

이 프로그램은 한메일 계정에서 메일을 받아서 내용을 UTF8으로
변경하고 저장하는.. 루비로 작성된 스크립트입니다.

** Mailbox 형식의 메일함을 사용합니다.

필요한 모듈은 tmail(http://www.loveruby.net/ja/prog/tmail.html)입니다.

행복하세요~~. 이상.

#!/usr/bin/env ruby
$KCODE = 'U'

require 'net/https'
Net::HTTP.version_1_2
require 'tmail/mail'
require 'iconv'

class HTTPConnection

    def initialize
        @header = {}
        @cookie = {}
    end

    def update_header
        @header['Cookie'] = ''
        @cookie.each { |k, v| @header['Cookie'] << "#{k}=#{v}; " }
    end

    def update_cookie(set_cookie)
        set_cookie.split('; ').each { |str|
            if str =~ %r{^.*, [^=]+=} then str.gsub!(%r{^.*, }, '') end
            e = str.split('=')
            @cookie.update({ e[0] => e[1] })
        }
        self.update_header()
    end

    def get(url)
        uri = URI::parse(url.strip)
        uri.path = '/' if uri.path.empty?
        uri.path << "?#{uri.query}" if uri.query

        conn = Net::HTTP.new(uri.host, uri.port)
        conn.use_ssl = uri.scheme == "https" ? true : false
        response = conn.get2(uri.path, @header)

        update_cookie(response['set-cookie']) if response.key?('set-cookie')
        self.get($1) if response.body =~
            %r{<META http-equiv="refresh" content="\d; ?url=([^"]+)">}i
        case response
        when Net::HTTPOK
            return response.body
        when Net::HTTPFound
            self.get("#{response['location']}")
        end
    end

end

class String

    def to_utf8(from)
        begin
            retval = Iconv.open('UTF-8', from.to_s.upcase) { |obj|
                obj.iconv(self)
            }
        rescue Iconv::IllegalSequence => err
            return nil
        end
        retval
    end

end

class Filter

    def initialize(regexp, header, action, priority=1)
        @regexp = Regexp.new(regexp)
        @header = header
        @act = action
        @priority = priority
    end
    attr_reader :act, :priority

    def compare(letter)
        true if @regexp.match(letter[@header].to_s)
        letter.parts { |part|
            true if @regexp.match(part[@header].to_s)
        } if letter.multipart?
        false
    end

    class << Filter
        def execution(act, letter)
            letter.send :"#{act}"
        end
    end

end

class Letter

    def initialize(reference)
        @baseurl = reference.base_url
        @identity = reference.cur_letter
        @inbox = reference.cur_inbox
        @remove = reference.remove
        @letter = TMail::Mail.parse(reference.fetch.call(@identity, @inbox))
        self.to_utf8 if $utf8
    end
    attr_reader :letter

    def remove
        @remove.call(@identity, @inbox)
    end

    def to_utf8_header(letter)
        letter.each_header { |hdr, val|
            if val.to_s =~ %r{=\?([\w_-]+)\?(\w)\?(.*)\?=}
                charset = $1; encoded = $2; str = $3
                next if charset =~ %r{utf-8}i
                decoded = case encoded
                when /B/i
                    str.unpack('m')
                when /Q/i
                    str.unpack('M')
                end
                utf8_str = decoded.to_s.to_utf8(charset).strip
                next if utf8_str.nil?
                letter[hdr] = "=?UTF-8?B?#{utf8_str.to_a.pack('m').delete("\n")}?="
            else
                utf8_str = letter[hdr].to_s.to_utf8(letter.type_param('charset', 'EUCKR'))
                next if utf8_str.nil?
                letter[hdr] = "#{utf8_str.strip}"
            end
        }
    end

    def to_utf8_body(letter)
        return if not letter.main_type =~ %r{text}i
        utf8_str = letter.body_port.ropen.read_all.to_utf8(letter.type_param('charset', 'EUCKR'))
        utf8_str.gsub!(%r{^(.*)<!--.*}im, '\1') if letter.sub_type =~ %r{html}i and
            @letter['X-Mailer'].to_s =~ %r{Daum Web Mailer}i
        utf8_str.gsub!(%r{(?<=<META)(.*charset=)[A-Z0-9\-_]+}im, '\1utf-8') if
            letter.sub_type =~ %r{html}i
        letter.body_port.wopen { |f| f.write(utf8_str) }
        letter.set_content_type(letter.main_type, letter.sub_type, {'charset'=>'utf-8'})
    end

    def to_utf8
        self.to_utf8_header(@letter)
        if @letter.multipart?
            letters = @letter.parts
            letters.each { |l|
                self.to_utf8_header(l)
                self.to_utf8_body(l)
            }
        else
            self.to_utf8_body(@letter)
        end
    end

    def to_disk
        begin
            fname = "#{$maildir}/new/#{Time.now.to_i}.M#{Time.now.usec}.#{`hostname`}".chomp
            f = File.new(fname, File::CREAT|File::TRUNC|File::RDWR, 0600)
            f.write(@letter.to_s)
        rescue
            File.delete(fname)
        ensure
            f.close if f
            self.remove
        end
    end

end

class DAUM

    def initialize(connection, uid, pwd)
        @conn = connection
        @letters = []
        configure = Struct.new("CONFIGURE", :base_url, :cur_letter, :cur_inbox, :inboxs, :fetch, :remove)
        #base_url = 자신의 계정이 있는 호스트의 이름.. -_-;
        @reference = configure.new('http://wwl536.daum.net/Mail-bin/', '', '', {
            'INBOX' => '%B9%DE%C0%BA%C6%ED%C1%F6%BA%B8%B0%FC%C7%D4',
            'TRASH' => '%C8%DE%C1%F6%C5%EB' },
            self.fetch_letter,
            self.remove_letter)
        self.login(uid, pwd)
    end
    attr_reader :reference, :letters
    def login(uid, pwd)
        @conn.get("https://logins.daum.net/Mail-bin/login.cgi?id=#{uid}&pw=#{pwd}&checkip=")
        @conn.get("#{@reference.base_url}mail_left.cgi")
    end

    def fetch_list
        @letters.clear unless @letters.empty?
        @reference.cur_inbox = @reference.inboxs['INBOX']
        pnum = 1
        end_of_page = true
        loop {
            end_of_page = true
            @conn.get("#{@reference.base_url}mail_list?FOLDER=#{@reference.cur_inbox}&mpage=#{pnum}").to_s.scan(/(?<=CHECKID" value=")[\w\d]+/) { |identity|
                end_of_page = false
                @reference.cur_letter = identity
                @letters << Letter.new(@reference)
            }
            break if end_of_page
            pnum += 1
        }
        @reference.cur_letter = ''
        @reference.cur_inbox = ''
    end

    def fetch_letter
        Proc.new { |letter, inbox|
            str = @conn.get("#{@reference.base_url}view_mail?MSGID=#{letter}&FOLDER=#{inbox}")
            str =~ %r{href="([^\"]+download)}m
            @conn.get($1).each_line { |l|
                str << l.delete("\r")
            }
        }
    end

    def remove_letter
        Proc.new { |letter, inbox|
            @conn.get("#{@reference.base_url}mail_manage?ORGFOLDER=#{inbox}&FOLDER=#{inbox}&CHECKID=#{letter}&HOWTO=delete")
        }
    end

    def empty_trash
        @conn.get("#{@reference.base_url}mail_manage?HOWTO=empty&ORGFOLDER=#{@reference.inboxs['TRASH']}")
    end

end

Process.daemon

#아이디
uid = ''
#비밀번호
pwd = ''
$utf8 = true
$maildir = ENV['MAIL']

$filters = []

daum = DAUM.new(HTTPConnection.new, uid, pwd)

loop {
    count = 0
    daum.fetch_list
    daum.letters.each { |l|
        count += 1
        act = 'to_disk'
        unless $filters.empty?
            f = $filters.select { |f| f.compare(l.letter) }
            if f.length == 1
                act = f[0].act
            elsif f.length > 1
                t = f.max { |n, m| n.priority <=> m.priority }
                act = t.act
            end
        end

        Filter.execution(act, l)
    }
    daum.empty_trash if count
    sleep(1200)
}
Forums: 

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.