#!/usr/bin/python
"""
 * setup.py - script to install playlistmanager
 * (C) 2007 by Kristian Mueller <kristian-m@kristian-m.de>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""

from distutils.core import setup
import distutils.command.install_data

import os
import sys
import platform
import glob
import logging

VERSION_NUMBER = '0.05'

NAME = 'tvmagnet'
DESCRIPTION = 'Aggregate and Share Media'
LONG_DESCRIPTION = 'Aggregate and Share Media'
AUTHOR = 'MWG Media Wedding GmbH'
AUTHOR_EMAIL = 'development@tvmagnet.com'
URL = 'http://tvmagnet.com'
LICENSE = 'GPL_v2'

BINARY_FILE_ENDINGS = [".png", ".jpeg", ".jpg", ".so", ".glade", ".pyd"] 
IGNORE_ON_SUBSTRING = ".svn" 

if not "Windows" in platform.uname():
    # modules we do not need in our distribution
    IGNORED_MODULES = ["tvm_unittests", 
                   "win32", 
                   "python-dateutil-1.4.1", 
                   "tests", 
                   "pyotr-0.2",
                   "tvm.web",]
    BINARY_FOLDERS = ["src/tvm/desktop_client/plugins/player/ui/theme", "lib/otr"]
    DATA_START_PATH = "src/tvm/"
else:
    # modules we do not need in our distribution
    IGNORED_MODULES = ["tvm_unittests", 
                   "python-dateutil-1.4.1", 
                   "tests", 
                   "pyotr-0.2",
                   "tvm.web",]
    BINARY_FOLDERS = ["src\\tvm\\desktop_client\\plugins\\player\\ui\\theme", "lib\\otr"]
    BINARY_FILE_ENDINGS.append(".py")
    BINARY_FILE_ENDINGS.append(".dll")
    DATA_START_PATH = "src\\tvm\\"

################################################################################
## Tools for file search #######################################################
################################################################################

# path to this file
root_path = os.path.realpath(os.path.dirname(__file__))
root_depth = len(root_path.split(os.path.sep)) 

def _find_packages():
    """
    returning a list of the files
    e.g. ['otr', 'tvm', 'tvm.tools',] 
    """
    results = []
    
    for path, subdirs, files in os.walk(root_path):
        # get path relative to project root/src
        current_path = os.path.sep.join(path.split(os.path.sep)[root_depth+1:])
        current_module = current_path.replace(os.path.sep, ".")
                    
        # determine if we actually have a module here 
        # and add package to results (if new)   
        if "__init__.py" in files:
            if current_module not in results:
                ignore = False
                for ignored_module in IGNORED_MODULES:
                    if current_module.startswith(ignored_module) or \
                                                    len(current_module) <= 0:
                        ignore = True
                if not ignore:
                    results.append(current_module)
    return results

def _find_package_dirs(packages):
    """
    returning a dictionary of the project package directory and names 
    e.g. {'otr' : 'lib/otr', 'tvm' : 'src/tvm'}
    """
    results = {}
    
    for path, subdirs, files in os.walk(root_path):
        # get path relative to project root/src
        current_module_path = os.path.sep.join(path.split(os.path.sep)[root_depth+1:])
        current_path = os.path.sep.join(path.split(os.path.sep)[root_depth:])
        current_module = current_module_path.replace(os.path.sep, ".")

        if not results.has_key(current_module) and \
                    current_module in packages and "__init__.py" in files:            
            results[current_module] = current_path
            
    return results

def _find_packages_data_files(packages, package_dirs):
    """
    ## This is not used in sdist in current versions of distutils
    ## see: http://markmail.org/message/3ko2b5nufihe6g6o
    ## using data_files instead :-(
    
    returning a dictionary of datafiles specific with packages
    e.g. {'tvm': ['desktop_client/magnets/*/*.png',
            'desktop_client/plugins/*/ui/*.png',
            'desktop_client/plugins/*/ui/*.glade',],
            }
    """
    return {}

def _find_data_files():
    """
    returning a list of the project data files 
    e.g. [("bitmaps", ["bm/large.gif", "bm/small.gif"]),
            ("fonts", glob.glob("fonts/*.fnt"))
        ]
    """
    results = {}
    for type in BINARY_FILE_ENDINGS:
        results[type] = [] 
    results["bin_folder"] = []
       
    for path, subdirs, files in os.walk(root_path):
        # get path relative to project root/src
        current_module_path = os.path.sep.join(path.split(os.path.sep)[root_depth+1:])
        current_path = os.path.sep.join(path.split(os.path.sep)[root_depth:])
        current_module = current_module_path.replace(os.path.sep, ".")
        
        for ending in BINARY_FILE_ENDINGS:
            for file in files:
                found_file = "%s%s%s" % (current_path, os.path.sep, file)
                found_file = os.path.sep.join(found_file.split(os.path.sep)[0:])
                
                if found_file.endswith(ending):				
                    if found_file.startswith(DATA_START_PATH) and \
                                    not IGNORE_ON_SUBSTRING in found_file:
                        if not results.has_key(current_path):
                            results[current_path] = []
                        results[current_path].append(found_file)
                for folder_filter in BINARY_FOLDERS:
                    if found_file.startswith(folder_filter) and \
                                    not IGNORE_ON_SUBSTRING in found_file:
                        if not results.has_key(current_path):
                            results[current_path] = []
                        results[current_path].append(found_file) 

    results_list = []

    # reformat to list of tuples with lists ... (to strange setup format)  
    for path in results.keys():
        # print "ending is: %s - results are: |%s|" % (path, results[path])
        new_path = os.path.sep.join(path.split(os.path.sep)[1:])
        results_list.append((new_path, results[path]))
    
    results_list.append(("bin_folder", results["bin_folder"]))

    # prevent exception on empty list
    if len(results) <= 0:
        return [""]

    return results_list

def _find_modules_in_path(start_path):
    modules = []
    
    for path, subdirs, files in os.walk(start_path):
        current_module_path = os.path.sep.join(path.split(os.path.sep)[root_depth+1:])
        current_path = os.path.sep.join(path.split(os.path.sep)[root_depth:])    
        current_module = current_module_path.replace(os.path.sep, ".")

        for file in files:
            if file.endswith(".py") and not file.startswith("__init__"):
                file = ".".join(file.split(".")[:-1])   # remove ".py"
                modules.append(".".join([current_module, file]))

    return modules

            
package_list = _find_packages()
package_dir_dict = _find_package_dirs(package_list)
package_data_dict = _find_packages_data_files(package_list, package_dir_dict)
data_file_list = _find_data_files()
includes = ["cairo", 
                "pango", 
                "pangocairo", 
                "atk",
                "gobject",
                "tvm", 
                "src", 
                "shutil", 
                "sqlalchemy.databases.sqlite",
                "netifaces",
                "otr", 
                "asyncore",
                "tvm.tools.libmms",]
includes.extend(_find_modules_in_path(root_path + "\\src\\tvm\\desktop_client"))


################################################################################
## Setup for non Windows systems ###############################################
################################################################################
# On Windows we will have to use py2exe 
# so this is for any other architecture 
if not "Windows" in platform.uname():
## code from http://wiki.python.org/moin/Distutils/Tutorial
    class smart_install_data(distutils.command.install_data.install_data):
        """need to change self.install_dir to the actual library dir"""
        def run(self):
            install_cmd = self.get_finalized_command('install')
            self.install_dir = getattr(install_cmd, 'install_lib')
            return distutils.command.install_data.install_data.run(self)

    setup(name = NAME,
            description = DESCRIPTION,
            long_description = LONG_DESCRIPTION,
            author = AUTHOR,
            author_email = AUTHOR_EMAIL,
            url = URL,
            version = VERSION_NUMBER,
            license = LICENSE,
            scripts = ['src/tvmagnet'],
            
            # from http://wiki.python.org/moin/Distutils/Tutorial
            cmdclass = { 'install_data':    smart_install_data },

            # Packages
            packages = package_list,
            package_dir = package_dir_dict,
            package_data = package_data_dict,
            data_files = data_file_list,
    )

################################################################################
## Setup for Windows Systems ###################################################
################################################################################
if "Windows" in platform.uname():
    import py2exe

    sys.path.insert(0, root_path+"\\src")
    sys.path.insert(0, root_path+"\\lib")
    
    ## Files that will end up in the actual directory
    data_file_list.extend([
        ("etc/gtk-2.0", glob.glob("C:\\gtk\\etc\\gtk-2.0\\*")),
        ("etc/pango", glob.glob("C:\\gtk\\etc\\pango\\*")),
        ("lib/pango/1.6.0/modules", glob.glob("C:\\GTK\\lib\\pango\\1.6.0\\modules\\*.*")),
        ("lib/gtk-2.0/2.10.0/loaders", glob.glob("C:\\gtk\\lib\\gtk-2.0\\2.10.0\\loaders\\*.*")),
        ("lib/gtk-2.0/2.10.0/engines", glob.glob("C:\\gtk\\lib\\gtk-2.0\\2.10.0\\engines\\*.*")),
        ("lib/otr", glob.glob("lib\\otr\\*")),
        ("lib/M2Crypto/SSL", glob.glob("lib\\win32\\M2Crypto\\SSL\\*")),
        ("lib/M2Crypto/PGP", glob.glob("lib\\win32\\M2Crypto\\PGP\\*")),
        ("lib/M2Crypto", glob.glob("lib\\win32\\M2Crypto\\*.*")),
        ("lib/M2Crypto", glob.glob("lib\\win32\\M2Crypto\\*.*")),
        ("lib", glob.glob("src\\mplayer.exe")),
        ("lib", glob.glob("lib\\libmms.dll")),
        ("", glob.glob("lib\\jpeg62.dll")),
    ])

    setup(
        name='tvmagnet',

        options = {"py2exe": {
                    "optimize": 2,
                    "excludes": "",
                    "includes": includes,
                    "packages" : ["encodings"]
                    }},
                            
        packages = package_list,
        package_dir = package_dir_dict,
        package_data = package_data_dict,
        data_files = data_file_list,

        windows = [{"script": "src/tvm/desktop_client/tv_magnet.py",
                    "icon_resources": [(1, "src/tvmagnet.ico")],
                    "other_resources": [],
                    }]
    )
