#===============================================================================
#
+# ショートカットキークラス
+#
+class MaveShortcuts
+
+ @@rsv = 'zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA9876543210'
+
+ def initialize
+ @fw = Hash.new
+ @rv = Hash.new
+ end
+
+ def assign(hint, instance)
+ hint.gsub(/[^0-9a-zA-Z]/, '').concat(@@rsv).each_byte {|key|
+ @rv[(@fw[key] = instance).object_id] = key and break unless(@fw[key])
+ }
+ end
+
+ def [](param)
+ param.is_a?(Integer) ? @fw[param] : @rv[param.object_id]
+ end
+
+ def release(instance)
+ @fw.delete(self[instance])
+ @rv.delete(instance.object_id)
+ end
+end
+
+#===============================================================================
+#
# 連番処理付き GDBM クラス
#
class SqGDBM < GDBM
- @@start = '100'
+ @@start = 100
@@sym = '#last#'
def initialize(*params)
super
- self[@@sym] = @@start unless(self[@@sym])
+ self[@@sym] ||= @@start.to_s
end
#-----------------------------------------------------------
#===============================================================================
#
-# フラグ処理用 GDBM クラス
+# フラグ処理/メール総数管理用 GDBM クラス
#
class FlagGDBM < GDBM
+ @@n_mail_sym = '#n_mail#' # メール総数
+
def initialize(*params)
@alloc_pos = -1
@pos_flag = {}
def get_flag(key, flag)
self[key] ? self[key][@pos_flag[flag]] : @default
end
+
+ def reset_n(sym = @@n_mail_sym)
+ self[sym] ||= 0.to_s
+ end
+
+ def get_n(sym = @@n_mail_sym)
+ self[sym]
+ end
+
+ def inc_n(sym = @@n_mail_sym)
+ self[sym] = (self[sym].to_i + 1).to_s
+ end
+
+ def dec_n(sym = @@n_mail_sym)
+ self[sym] = (self[sym].to_i - 1).to_s
+ end
end
#===============================================================================
@views[name] = view
end
+ def dirty
+ @dirty += 1
+ end
+
def dirty?
@clean < @dirty and @clean = @dirty
end
def regular
@accounts[@configs[:ACCOUNTS][@regular_nth][:NAME]]
end
+
def previous
begin
@regular_nth -= 1; @regular_nth %= @configs[:ACCOUNTS].size
end until(@accounts[@configs[:ACCOUNTS][@regular_nth][:NAME]].enable)
regular
end
+
def next
begin
@regular_nth += 1; @regular_nth %= @configs[:ACCOUNTS].size
[:READ, :FLAG, :NOTICE, :FOLD].each {|flag|
@flags_sq.alloc_flag(flag)
}
+ @flags_sq.get_n || @flags_sq.reset_n # メール総数
+ @flags_sq.get_n('#r_mail#') || @flags_sq.reset_n('#r_mail#') # 既読メール総数
# フォルダの設定ファイルを読む(folder_configs プロパティと、bind? メソッドが追加される)
begin
Digest::MD5.file(config_filename).to_s
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# 指定のメール連番のメールインスタンスを返す
#
sq ? MaveMail.new({:CONFIGS => @configs, :FILE => File.new(@path + '/' + @filename_sq[sq]), :FOLDER => self, :SQ => sq}) : nil
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# メールの概要を返す
#
]
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# フォルダ内にメールを追加する
#
@sq_rootsq.delete(old_rootsq)
end
end
+
+ # メール総数カウントアップ
+ @flags_sq.inc_n
+
@dirty += 1
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# フォルダ内にメールを上書きする
#
@dirty += 1
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# フォルダ内のメールを返す
#
}
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveFolder ----
#
# 各種フラグ処理
#
def read(sq)
- @flags_sq.set_flag(sq, :READ, ?R)
+ read?(sq) or @flags_sq.set_flag(sq, :READ, ?R) and @flags_sq.inc_n('#r_mail#')
@dirty += 1
+ #### folders.dirty
end
def read?(sq)
@flags_sq.get_flag(sq, :READ) == ?R
end
def unread(sq)
- @flags_sq.set_flag(sq, :READ, ?_)
+ read?(sq) and @flags_sq.set_flag(sq, :READ, ?_) and @flags_sq.dec_n('#r_mail#')
@dirty += 1
+ #### folders.dirty
end
def flag(sq)
#
class MaveFolders < MaveBaseModel
+ attr_reader :shortcuts
+
def initialize(params)
super
@folders = {}
+ @shortcuts = MaveShortcuts.new
begin
Dir.open(@configs[:ROOT_DIRECTORY]) {|dir|
dir.each {|name|
next if(name =~ /^[._]/ or !File.directory?(dir.path + '/' + name))
- @folders[name] = MaveFolder.new({:CONFIGS => @configs, :NAME => name})
+ open_folder(name)
}
}
rescue
end
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveFolders ----
#
# メールフォルダ「群」を通して、メールフォルダを作成/開く
#
def open_folder(name)
- @folders[name] || (@dirty += 1 and @folders[name] = MaveFolder.new({:CONFIGS => @configs, :NAME => name}))
+ unless(@folders[name])
+ it = @folders[name] = MaveFolder.new({:CONFIGS => @configs, :NAME => name})
+ @shortcuts.assign(it.configs[:SHORTCUT_HINT] + it.configs[:LIST_NAME] + it.name, it)
+ @dirty += 1
+ end
+ @folders[name]
end
def close_folder(name)
+ @shortcuts.release(@folders[name])
@folders[name].close; @dirty += 1; @folders[name] = nil
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveFolders ----
#
# メールフォルダを順に渡す
#
}
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveFolders ----
+ #
+ # メールフォルダの概要を返す
+ #
+ def abstract_of_folder(folder)
+ '%c %c) %s (%d/%d)' % [
+ ?.,
+ @shortcuts[folder],
+ folder.configs[:LIST_NAME],
+ (it = folder.flags_sq.get_n.to_i) - folder.flags_sq.get_n('#r_mail#').to_i,
+ it,
+ ]
+ end
+
+ #------------------------------------------ MaveFolders ----
#
- # フォルダの設定ファイルを上書きする
+ # ã\83¡ã\83¼ã\83«ã\83\95ã\82©ã\83«ã\83\80ã\81®è¨å®\9aã\83\95ã\82¡ã\82¤ã\83«ã\82\92ä¸\8aæ\9b¸ã\81\8dã\81\99ã\82\8b
#
def overwrite_folder_configs(folder, new_configs)
File.open(folder.config_filename, 'w') {|fw| fw.write(new_configs.read) }
@@debug_what_charset = false
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# キャラクタセット情報表示、切り替え(デバッグ用)
#
Digest::MD5.file(@file.path).to_s
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メールヘッダを解析
#
@body = it.new(@file, @content, @boundary)
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メールヘッダの行を順に渡す
#
}
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メールボディの行を順に渡す
#
- def body_each
- nth = -1; while(it = self[nth += 1])
+ def body_each(start = 0)
+ nth = start - 1; while(it = self[nth += 1])
yield(it)
end
end
- #-----------------------------------------------------------
+ def body_reverse_each(start = 0)
+ nth = start + 1; while(it = self[nth -= 1])
+ yield(it)
+ end
+ end
+
+ #--------------------------------------------- MaveMail ----
#
# メールの特定の行を返す
#
end
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メールの件名、送信者、宛先、同報、送信時刻などを返す
#
Time.rfc2822(@header['Date']) rescue nil
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# Message-ID を返す
#
@message_id || (@header['Message-id'] =~ /<[^>]+?>/ ? (@message_id = $&) : raise('Bad Message-ID.'))
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# In-Reply-To, References を返す
#
(it = @header['References']) and it.scan(/<[^>]+?>/) {|id| yield id }
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メールのサイズを返す
#
@file.lstat.size
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# マルチパートかどうかを返す
#
@content['type']['type'].index('multipart')
end
- #-----------------------------------------------------------
+ #--------------------------------------------- MaveMail ----
#
# メール情報を返す
#
@body_pos = pos
end
- #-----------------------------------------------------------
+ #--------------------------------------- MavePseudoMail ----
#
# メールもどきを正しいメール形式で順に渡す
#
}
end
- #-----------------------------------------------------------
+ #--------------------------------------- MavePseudoMail ----
#
# 各種メールもどきを順に渡す
#
}
end
- #-----------------------------------------------------------
+ #--------------------------------------- MavePseudoMail ----
#
# 新規メールもどき作成
#
def renew_message_each
end
- #-----------------------------------------------------------
+ #--------------------------------------- MavePseudoMail ----
#
# 返信メールもどき作成
#
def resend_message_each
end
- #-----------------------------------------------------------
+ #--------------------------------------- MavePseudoMail ----
#
# メールもどきの(再)編集
#
def initialize(params)
super
- @prompt = params[:PROMPT] || '>'
@text = params[:TEXT] || ''
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveTextBox ----
#
# 文字をクリアする
#
@dirty += 1
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveTextBox ----
#
# 文字を削除する
#
@dirty += 1
end
- #-----------------------------------------------------------
+ #------------------------------------------ MaveTextBox ----
#
# 通常文字を入力する
#
@dirty += 1
end
- def line
- @prompt + @text
+ #------------------------------------------ MaveTextBox ----
+ #
+ # 文字列をセットする
+ #
+ def set_text(text)
+ @text = text
+ @dirty += 1
end
end
@folders = params[:FOLDERS]
end
- #-----------------------------------------------------------
+ #------------------------------------- MaveCreateFolder ----
#
# 新規にフォルダを作成する
#
#===============================================================================
#
+# インクリメンタル検索モデルクラス
+#
+class MaveIncrementalSearch < MaveTextBox
+
+ def initialize(params)
+ super
+ end
+end
+
+#===============================================================================
+#
# ステータスモデルクラス
#
class MaveStatus < MaveBaseModel
@max_logs = 1000
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveStatus ----
#
# ログを追加
#
@views.update # 表示のリアルタイム更新
end
- #-----------------------------------------------------------
+ #------------------------------------------- MaveStatus ----
#
# ログを順に返す
#
class MaveTextPlainPart < MaveBasePart
def [](nth)
+ return(nil) if(nth < 0)
encoding = @content['transfer-encoding']['type'].upcase
if(encoding == 'BASE64' or encoding == 'QUOTED-PRINTABLE') ####
unless(@index)