#!/usr/bin/python

# Written by Robin H. Johnson <robbat2@gentoo.org>

app_name = "BitTorrent"
from BitTorrent.translation import _

from os.path import basename
import sys
import locale
import copy
import time
from sha import *
from os.path import *
from BitTorrent import version
from BTL.bencode import *
from BitTorrent.defaultargs import get_defaults
from BitTorrent import configfile
from BitTorrent.parseargs import parseargs, printHelp
from BitTorrent import BTFailure

defaults = []
defaults.extend([
    ('creation_date', 'OPTIONAL',
        _("unix timestamp of .torrent creation date")),
    ('modification_date', 'OPTIONAL',
        _("unix timestamp of .torrent modification date")),
    ('locale', 'OPTIONAL',
        _("locale for encoding")),
    ('title', 'OPTIONAL',
        _("optional human-readable title for entire .torrent")),
    ('comment', 'OPTIONAL',
        _("optional human-readable comment to put in .torrent")),
    ('tracker_list', 'OPTIONAL', 
        _("list of tracker urls")),
    ('extra_data_key', 'OPTIONAL',
        _("key for extra data to include in the .torrent data")),
    ('extra_data_string', 'OPTIONAL',
        _("string of extra data to include in the .torrent data")),
    ('extra_data_integer', 'OPTIONAL',
        _("integer-form extra data to include in the .torrent data")),
    ('extra_data_raw', 'OPTIONAL',
        _("bencoded extra data to include in the .torrent data")),
    ('created_by', 'OPTIONAL',
        _("specify the creator of the .torrent")),
    ('publisher', 'OPTIONAL',
        _("specify the publisher of the .torrent")),
    ('publisher_url', 'OPTIONAL',
        _("specify a URL for the publisher of the .torrent")),
    ('secure_publisher', 'OPTIONAL',
        _("specify the publisher of the .torrent (inside info)")),
    ('secure_publisher_url', 'OPTIONAL',
        _("specify a URL for the publisher of the .torrent (inside info)")),
    ('url_list', 'OPTIONAL',
        _("specify set of URLs for HTTP seeding")),
    ('encoding', 'OPTIONAL',
        _("specify an explicit encoding")),
    ('save',False,
        _("Save the .torrent after changing")),
    ('verbose',False,
        _("Print changes as they are made")),
    ('display',False,
        _("Display the metainfo (after any changes)")),
    ('display_raw_pieces',False,
        _("Include the raw pieces output in the metainfo display")),
    ])

processing = {
        'modification_date'     : [int,['modification date']],
        'creation_date'         : [int,['creation date']],
        'comment'               : [str,['comment']],
        'locale'                : [str,['locale']],
        'created_by'            : [str,['created by']],
        'encoding'              : [str,['encoding']],
        'publisher'             : [str,['publisher']],
        'publisher_url'         : [str,['publisher-url']],
        'secure_publisher'      : [str,['info','publisher']],
        'secure_publisher_url'  : [str,['info','publisher-url']],
        'title'                 : [str,['title']],
        'tracker_list'          : [list,['announce-list']],
        'url_list'              : [list,['url-list']],
        }

defconfig = dict([(name, value) for (name, value, doc) in defaults])
del name, value, doc

def getpos(metainfo,loc):
    l = loc[0]
    if len(loc) > 1:
        return getpos(metainfo[l],loc[1:])
    else:
        if l in metainfo:
            return metainfo[l]
        else:
            return None

def setpos(metainfo,loc,value):
    l = loc[0]
    if len(loc) > 1:
        setpos(metainfo[l],loc[1:],value)
    else:
        if value == 'DELETE-ME' and l in metainfo:
            del metainfo[l]
        else:
            metainfo[l] = value
    return metainfo

if __name__ == '__main__':

    config, args = configfile.parse_configuration_and_args(defaults,
                                                    'changetorrent-console',
                                                    sys.argv[1:], minargs=1)
    le = locale.getpreferredencoding()

    for name in config.keys():
        if config[name] == "OPTIONAL":
            config[name] = None
        if name in processing and processing[name][0] == int and config[name] == "NOW":
            config[name] = int(time.time())


    #print config

    c = 0
    if config['extra_data_string']:
        c += 1
    if config['extra_data_integer']:
        c += 1
    if config['extra_data_raw']:
        c += 1
    if c > 1:
        print _("You must only specify a single type of extra_data!")
        sys.exit(2)

    if len(args) < 1:
        print _("Usage: %s [OPTIONS] [TORRENTFILE [TORRENTFILE ... ] ]") % basename(sys.argv[0])
        print
        sys.exit(2) # common exit code for syntax error

    for f in args[0:]:
        h = open(f, 'rb')
        metainfo = bdecode(h.read())
        h.close()
        metainfo_initial = copy.deepcopy(metainfo)
        for k in processing.keys():
            if config[k]:
                (type,loc) = processing[k]
                l = False
                l_is_set = False
                if config[k] == "DELETE-ME":
                    l = None
                    l_is_set = True
                elif type == str:
                    l = config[k]
                    l_is_set = True
                elif type == int:
                    l = config[k]
                    l_is_set = True
                elif type == list:
                    try:
                        l = eval(config[k])
                        l_is_set = True
                    except SyntaxError, e:
                        print "Unable to parse input for list: %s" % e
                        raise e
                    if not isinstance(l,list):
                        print "%s input is not a list!" % (k)
                        sys.exit(2)
                if not l_is_set:
                    print "unknown error handling input for %s" % (k)
                    sys.exit(2)
                if getpos(metainfo,loc) != l:
                    if config['verbose']:
                        print 'Changing "%s" from "%s" to "%s"' % (loc,getpos(metainfo,loc),l)
                    metainfo = setpos(metainfo,loc,l)
        if metainfo != metainfo_initial and config['save']:
            if config['verbose']:
                print 'Saving '+f
            h = open(f, 'wb')
            h.write(bencode(metainfo))
            h.close()
        if config['display']:
            if not config['display_raw_pieces']:
                metainfo['info']['pieces'] = 'HIDDEN'
            print metainfo
        #if metainfo['announce'] != argv[1]:
        #    print _("old announce for %s: %s") % (f, metainfo['announce'])
        #    metainfo['announce'] = argv[1]
        #    h = open(f, 'wb')
        #    h.write(bencode(metainfo))
        #    h.close()
# vim: expandtab:
