# $Id: quickml.rb,v 1.18 2004/04/21 04:41:15 eto Exp $
# Copyright (C) 2003-2004 Kouichirou Eto, All rights reserved.
# This is free software with ABSOLUTELY NO WARRANTY.
# You can redistribute it and/or modify it under the terms of the GNU GPL2.

require 'qwik/config'
require 'qwik/site'

class String
  def euctojis
    self.kconv(Kconv::JIS, Kconv::EUC)
  end
end

module QuickML
  class Config
    $qwik_dir = File.expand_path(File.dirname(__FILE__)+"/../..")
  end

  class QuickML
    def initialize (config, address, creator = nil, message_charset = nil)
      @config = config
      @address = address
      @name = get_name(@address)
      raise InvalidMLName unless QuickML.valid_name?(@name)
      @short_name = @name.split("@").first

      @return_address = generate_return_address

      init_files
      @member_added_p = false
      @added_members = []

      @logger = @config.logger
      @catalog = @config.catalog

      init_ml_config
      init_members
      init_count
      init_charset

      @message_charset = (message_charset or @charset)
      @logger.log "[#{@name}]: New ML by #{creator}" if newly_created?
    end

    def self.valid_name? (name)
      # do not allow '_' and '.' for short_name
      /^([0-9a-zA-Z-]+)(@[0-9a-zA-Z_.-]+)?$/ =~ name
    end

    private
    def init_files
      # original QuickML
      #name = @name
      #dir = @config.data_dir
      
      # for qwikWeb
      name = ""
      dir = File.join(@config.data_dir, @name)
      Dir.mkdir(dir) unless FileTest.directory?(dir)

      @members_file = File.join(dir, name + ",members")
      @count_file = File.join(dir, name + ",count")
      @forwardp_file = File.join(dir, name + ",forward")
      @alertedp_file = File.join(dir, name + ",alerted")
      @permanentp_file = File.join(dir, name + ",permanent")
      @unlimitedp_file = File.join(dir, name + ",unlimited")
      @charset_file = File.join(dir, name + ",charset")
      @ml_config_file = File.join(dir, name + ",config")
      @waiting_members_file = File.join(dir, name + ",waiting-members")
      @waiting_message_file = File.join(dir, name + ",waiting-message")
    end

    def generate_footer (member_list_p = false)
      footer = "\n-- \n" + _("qwik-> %s ", qwik_url()) + " ML-> #{@address}\n"
      footer << unsubscribe_info if member_added?
      footer << "\n" + member_list if member_added? or member_list_p
      footer
    end

    def qwik_url()
      "http://"+@config.domain+'/'+@name+'/'
    end

    def last_article_time # the mtime of the newest file in the directory
      max = maxfile = nil
      dir = File.dirname(@count_file)
      Dir.foreach(dir){|f|
	next if f =~ /^\./ || f =~ /,config/ || f =~ /,charset/
	file = File.join(dir, f)
	mt = File.mtime(file)
	if max.nil? || max < mt
	  max = mt 
	  maxfile = file
	end
      }
      max || Time.now
    end

    def qwik_post(subject, message)
      config = Qwik::Config.new
      sitename = self.name
#      @logger.log "[#{@name}]: sitename = #{sitename}"
      site = Qwik::Site.new(config, sitename)
      page = site.pages.find_title(subject)
      if page.nil?
	page = site.pages.create_new
	page.store("* "+subject+"\n")
      end
      page.append(message)
      @logger.log "[#{@name}]: QwikPost: #{page.key}"
    end

    def qwik_message(mail)
      body = mail.get_plain_body
      from = mail.mail_from
      "{{mail(#{from})\n#{body}\n}}\n".jistou8
    end

    def qwik_subject(mail)
      mail.get_clean_subject.euctou8
    end

    if !defined? _org_submit
      alias _org_submit _submit
      def _submit(mail)
	subject = qwik_subject(mail)
	message = qwik_message(mail)
	_org_submit(mail)
	qwik_post(subject, message)
      end
    end

    def send_confirmation (creator_address)
      header = []
      subject = Mail.encode_field(_("[%s] Confirmation: %s",
				    @short_name, @address))
      header.push(["To",	creator_address],
		  ["From",	confirmation_address],
		  ["Subject",	subject],
                  ["Content-Type", content_type])

      body = confirmation_message(@address)
      Mail.send_mail(@config.smtp_host, @config.smtp_port, @logger, 
		     :mail_from => '', 
		     :recipient => creator_address,
		     :header => header,
		     :body => body)
      @logger.log "[#{@name}]: Send confirmation: #{confirmation_address} #{creator_address}"
    end

    def confirmation_message(address)
      body = ""
      body += _("At the first, please read the agreement of this service.\n")
      body += _("http://qwik.jp/6.html\n")
      body += _("You have to agree this agreement to use this service.\n")
      body += _("If you agree, then,\n")
      body += _("Please simply reply this mail to create ML <%s>.\n",
               address)
      body
    end
  end

  class Mail
    def get_clean_subject()
      str = Mail.clean_subject(self["Subject"])
      str.sub!(/(?:Re:\s*)+/i, "")
      str.sub!(/^\s+/, '')
      str.sub!(/\s+$/, '')
      str
    end

    def plain_text_body?
      self["Content-Type"] == "" or
	%r!\btext/plain\b!i =~ self["Content-Type"] #/
    end

    def get_plain_body
      if multipart?
	parts = self.parts
	sub_mail = Mail.new
	sub_mail.read(parts.first)
	if sub_mail.content_type == "text/plain"
	  return sub_mail.body
	end
      elsif plain_text_body?
	return @body
      end
      nil
    end
  end

  class Sweeper
    private
    def ml_file? (filename)
      return false if File.file?(filename)
      return false if File.basename(filename) =~ /\./ # avoid the name with dot
      true
    end
  end
end
