#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

# Gestionnaire de photos expédiées par e-mail
# Projet #ProgX
# 11/15/2003 - 17:44:18
# GNU-GPL v2, (C)2003 Romain GUY, romain.guy@jext.org 

################################################################################
# IMPORTS
################################################################################

import mimetools
import mimetypes
import MimeWriter
import mimify
import multifile
import MySQLdb
import os
import os.path
import poplib
import re
import socket
import string
import StringIO
import time
import urllib

################################################################################
# PROGRAMME
################################################################################

def getPOPParameters(config):
  pop3 = ['host', 'user', 'pass', '0', config['PHOTO_HOST'], config['PHOTO_URL']]
  params = ('Interlope_POP3_Host', 'Interlope_POP3_User', 'Interlope_POP3_Password')

  db = MySQLdb.connect(passwd = config['MYSQL_PASSWORD'], db = config['MYSQL_DB'],
                       host = config['MYSQL_HOST'], user = config['MYSQL_USER'])
  for i in range(len(params)):
    c = db.cursor()
    c.execute('SELECT value FROM functions WHERE name=%s', (params[i], ))
    pop3[i] = c.fetchone()[0]
    c.close()

  c = db.cursor()
  c.execute('SELECT categoryid FROM category WHERE title=%s', (config['CATEGORY'], ))
  pop3[3] = c.fetchone()[0]
  c.close()

  db.close()

  return tuple(pop3)

def getConfiguration():
  configuration = { "MYSQL_HOST": "localhost",
                    "MYSQL_DB": "progx",
                    "MYSQL_USER": "root",
                    "MYSQL_PASSWORD": "",
                    "CATEGORY": "photos",
                    "PHOTO_HOST": "localhost",
                    "PHOTO_URL": "/addImage.php" }

  if os.path.exists("../conf/interlope.conf"):
    confFile = open("../conf/interlope.conf")
    for line in confFile.readlines():
      match = re.search('^([^=]+)=(.*)$', line)
      if match:
        configuration[match.group(1)] = match.group(2)
    confFile.close()

  return configuration

def handleMails(config):
  whiteList = ("[^@]+@(jext|progx).org",)
  whiteExts = (".jpg", )

  pop3 = poplib.POP3(config[0])
  pop3.user(config[1])
  pop3.pass_(config[2])

  numMessages = len(pop3.list()[1])

  for i in range(numMessages):
    response, text, length = pop3.retr(i + 1)
    strio = StringIO.StringIO(string.join(text, "\n"))
    mail = mimetools.Message(strio)

    if string.lower(mail.getmaintype()) != "multipart":
      pop3.dele(i + 1)
      continue

    accepted = 0
    sender = mail.getheader("From")

    match = re.search('.*<([^>]+)>', sender)
    if match:
      for whiteDomain in whiteList:
        if re.search(whiteDomain, match.group(1)) is not None:
          accepted = 1
          break

    if accepted:
      title = mail.getheader("Subject")
      title = mimify.mime_decode_header(title)
  
      description = ""
      image       = None
      ext         = None

      file = multifile.MultiFile(strio)
      file.push(mail.getparam("boundary"))

      while file.next():
        submsg = mimetools.Message(file)
        type = submsg.gettype()

        if type == "text/plain":
          data = StringIO.StringIO()
          if submsg.getencoding() in ('7bit', '8bit'):
            data.write(file.read())
          else:
            mimetools.decode(file, data, submsg.getencoding())
          description = string.strip(data.getvalue())
          data.close()
        elif type == "application/octet-stream" or type == "image/jpeg":
          filename = submsg.getparam("name")
          if not filename:
            ext = mimetypes.guess_extension(submsg.gettype())
          else:
            ext = os.path.splitext(filename)[1]

          if ext and ext in whiteExts:
            data = StringIO.StringIO()
            if submsg.getencoding() in ('7bit', '8bit'):
              data.write(file.read())
            else:
              mimetools.decode(file, data, submsg.getencoding())
            image = data.getvalue()
            data.close()

      if image is not None and ext is not None:
        res = StringIO.StringIO()
        msg = MimeWriter.MimeWriter(res)
        msg.startmultipartbody("form-data")

        tatoo = str(int(time.time() + i))
        toPost = { 'title': title,
                   'comment': description,
                   'categoryid': str(config[3]),
                   'maxfilesize': tatoo,
                   'add': 'Ajouter' }

        for key, value in toPost.items():
          part = msg.nextpart()
          part.addheader("Content-Disposition", 'form-data; name="' + key + '"')
          writer = part.startbody("text/plain")
          writer.write(value)

        part = msg.nextpart()
        part.addheader("Content-Disposition", 'form-data; name="image"; filename="' + tatoo + ext + '"')
        writer = part.startbody("image/jpeg")
        writer.write(image)
        msg.lastpart()

        body = res.getvalue()
        res.close()
        end = string.find(body, "\n\n")
        name, value = string.split(re.sub("\n\s+", " ", body[:end]), ":")
        body = body[end + 1:]
        body = re.sub("Content-Type: text/plain\n", "", body)

        headers = { 'Accept': 'text/plain', 'Host': config[4], 'Accept-Encoding': 'identity' }

        headers[name] = string.strip(value)

        http = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        http.connect((config[4], 80))
        http.send("POST %s HTTP/1.1\r\n" % (config[5],))
        for name, value in headers.items():
          http.send("%s: %s\r\n" % (name, value));
        http.send("Content-Length: %i\r\n" % (len(body),));
        http.send(body)
        http.send("\r\n")

        data = http.recv(1024)
        http.close()

        pos = string.find(data, "\r\n\r\n")

        print "Image", i + 1, "/", numMessages, ":", data[pos + 4:]

      file.pop()

    pop3.dele(i + 1)

  print numMessages, "mails processed."
  pop3.quit()

if __name__ == '__main__':
  config   = getConfiguration()
  pop3conf = getPOPParameters(config)
  handleMails(pop3conf)

# fin de interlope.py
