#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ---------------------------------------------------------------
# Import photo galleries from Coppermine to SmugMug
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Author: Niko Schmuck
# Created: 14-Jul-2009
# ---------------------------------------------------------------
# NOTE:
#  * Category names in SmugMug can only contain [a-Z0-9-]
#  * Ignoring user-generated albums from Coppermine (cid<999)
# ---------------------------------------------------------------

import os
import sys
import uuid

import MySQLdb   # http://mysql-python.sourceforge.net/
import pysmug    # http://code.google.com/p/pysmug/

# -- Adapt to your Coppermine installation
cpg_basedir = "/var/www/photos.foobar.de/web/albums"
cpg_host    = "localhost"
cpg_user    = "cpg_master"
cpg_passwd  = "secret"
cpg_db      = "coppermine"
cpg_prefix  = "cpg_"

# -- Get DB Connection
conn = MySQLdb.connect(host=cpg_host, user=cpg_user, passwd=cpg_passwd, db=cpg_db, 
                       charset="latin1", use_unicode=False)
cursor = conn.cursor(MySQLdb.cursors.DictCursor)

# -- Login to SmugMug
m = pysmug.login()

# -- Get existing SmugMug categories
print "Get categories from SmugMug ..."
catsWithId = m.categories_get()["Categories"]
categories = {}
for cat in catsWithId:
    categories[cat["Name"]] = cat["id"]


# -- Loop over all coppermine categories and create in SmugMug if not yet exist
print "Syncing categories with Coppermine ..."
cpgCategories = {}
cursor.execute("SELECT cid, name FROM %scategories WHERE cid < 999" % cpg_prefix)
result_set = cursor.fetchall()
for row in result_set:
    catName = unicode(row["name"], "utf-8")
    cpgCategories[row["cid"]] = catName
    # if it does not yet exist create new category in SmugMug
    if not categories.has_key(catName):
        print "Creating new category:", catName
        newCat = m.categories_create(name=catName)["Category"]
        categories[catName] = newCat["id"]


# -- Get existing SmugMug albums
print "Get albums from SmugMug ..."
albumsWithId = m.albums_get()["Albums"]
albums = {}
for album in albumsWithId:
    albums[album["Title"]] = album["id"]


# -- Loop over all coppermine albums and create SmugMug album if not yet existing
print "Syncing SmugMug albums with Coppermine ..."
cpgAlbums = {}
cursor.execute("SELECT aid, title, description, pos, category FROM %salbums WHERE category < 999" % cpg_prefix)
result_set = cursor.fetchall()
for row in result_set:
    albumTitle = row["title"]
    albumTitleUnicode = unicode(albumTitle, 'utf-8')
    albumDesc = row["description"]
    catName = cpgCategories[row["category"]]
    cpgAlbums[row["aid"]] = (albumTitle, albumDesc, catName)
    # if it does not yet exist create new album in SmugMug
    if not albums.has_key(albumTitleUnicode):
        print "Creating new album:", albumTitle
        newAlbum = m.albums_create(title=albumTitle, description=albumDesc, categoryId=categories[catName],
                                   SortMethod="DateTimeOriginal", public=True, printable=False)["Album"]
        albums[albumTitleUnicode] = newAlbum["id"]


# -- Loop over all photos (album-by-album)
for albumId in cpgAlbums.keys():
    b = pysmug.SmugBatch(m.sessionId, secure=False)
    
    cursor.execute("SELECT aid, filepath, filename, title, caption, keywords FROM %spictures WHERE aid = %d ORDER BY aid, position" % (cpg_prefix, albumId))
    result_set = cursor.fetchall()
    for row in result_set:
        albumName = unicode(cpgAlbums[row["aid"]][0], "utf-8")
        if not albums.has_key(albumName):
            print "WARN: Could not locate album of name", albumName
            continue
        # Construct image caption consisting of title (and eventually filename)
        caption = ""
        if row["title"]:
            caption = row["title"]
        else:
            caption = row["filename"].split('.')[0]
        if row["caption"]:
            caption += " " + row["caption"]
        keywords = row["keywords"]
        # read in raw image
        filename = os.path.join(cpg_basedir, row["filepath"] + row["filename"])
        image = open(filename, "rb").read()
        print "Import photo %s into album %s" % (filename, albumName)
        b.images_upload(filename=filename, data=image, caption=caption, keywords=keywords, albumId=albums[albumName])
    
    # do the batch upload
    images = list(b())
    print "*** Imported %d photos into album" % len(images)

cursor.close()
conn.close()