#!/usr/bin/python2
# -*- coding: utf-8 -*-
###############################################################################
# conkyTransmission.py is a simple python script to gather
# details of Deluge torrents for use in conky.
#
# Author: Kaivalagi
# Created: 13/10/2008
#
#Modified:

from datetime import datetime
import transmissionrpc
from optparse import OptionParser
import codecs
import logging
import os
import sys

class CommandLineParser:

    parser = None

    def __init__(self):

        self.parser = OptionParser()
        self.parser.add_option("-s","--server", dest="server", type="string", default="127.0.0.1", metavar="SERVER", help=u"[default: %default] The server to connect to where the transmission daemon is running")
        self.parser.add_option("-p","--port", dest="port", type="int", default=9091, metavar="PORT", help=u"[default: %default] The port to connect to where the transmission daemon is running")
        self.parser.add_option("-U","--username", dest="username", type="string", default="", metavar="USERNAME", help=u"[default: %default] Username to use when connecting")
        self.parser.add_option("-P","--password", dest="password", type="string", default="", metavar="PASSWORD", help=u"[default: %default] Password to use when connecting")        
        self.parser.add_option("-S","--showsummary",dest="showsummary", default=False, action="store_true", help=u"Display summary output. This is affected by the --activeonly option.")
        self.parser.add_option("-H","--hidetorrentdetail",dest="hidetorrentdetail", default=False, action="store_true", help=u"Hide torrent detail output, if used no torrent details are output.")
        self.parser.add_option("-t","--torrenttemplate",dest="torrenttemplate", type="string", metavar="FILE", help=u"Template file determining the format for each torrent. Use the following placeholders: [name], [state], [totaldone], [totalsize], [progress], [nofiles], [downloadrate], [uploadrate], [eta], [currentpeers], [currentseeds], [totalpeers], [totalseeds], [ratio].")
        self.parser.add_option("-T","--summarytemplate",dest="summarytemplate", type="string", metavar="FILE", help=u"Template file determining the format for summary output. Use the following placeholders: [notorrents], [totalprogress], [totaldone], [totalsize], [totaldownloadrate], [totaluploadrate], [totaleta], [currentpeers], [currentseeds], [totalpeers], [totalseeds], [totalratio].")
        self.parser.add_option("-a", "--activeonly", dest="activeonly", default=False, action="store_true", help=u"If set only info for torrents in an active state will be displayed.")
        self.parser.add_option("-l","--limit",dest="limit", default=0, type="int", metavar="NUMBER", help=u"[default: %default] Define the maximum number of torrents to display, zero means no limit.")
        self.parser.add_option("-w","--maxwidth",dest="maxwidth", default=0, type="int", metavar="CHARS", help=u"[default: %default] Define the maximum numb
er of characters for name output, zero means no limit.")
        self.parser.add_option("-b","--sortby",dest="sortby", default="eta"
, type="string", metavar="SORTTYPE", help=u"Define the sort method for output, can be \"progress\", \"queue\", \"eta\", \"download\", \"upload\" and \"ratio\". Also note that a torrent's state supersedes anything else for sorting, in the order, from top to bottom: downloading, seeding, queued, paused, unknown)")
        self.parser.add_option("-v","--verbose",dest="verbose", default=False, action="store_true", help=u"Request verbose output, no a good idea when running through conky!")
        self.parser.add_option("-V", "--version", dest="version", default=False, action="store_true", help=u"Displays the version of the script.")
        self.parser.add_option("--errorlogfile", dest="errorlogfile", type="string", metavar="FILE", help=u"If a filepath is set, the script appends errors to the filepath.")
        self.parser.add_option("--infologfile", dest="infologfile", type="string", metavar="FILE", help=u"If a filepath is set, the script appends info to the filepath.")

    def parse_args(self):
        (options, args) = self.parser.parse_args()
        return (options, args)

    def print_help(self):
        return self.parser.print_help()

class TorrentData:

    def __init__(self, name, state, statecode, totaldone, totalsize, progress, nofiles, downloadrate, downloadtext, uploadrate, uploadtext, eta, etatext, currentpeers, currentseeds, totalpeers, totalseeds, ratio, queueorder, sortby):
        self.name = name
        self.state = state
        self.statecode = statecode
        self.totaldone = totaldone
        self.totalsize = totalsize
        self.progress = progress
        self.nofiles = nofiles
        self.downloadrate = downloadrate
        self.downloadtext = downloadtext
        self.uploadrate = uploadrate
        self.uploadtext = uploadtext
        self.eta = eta
        self.etatext = etatext
        self.currentpeers = currentpeers
        self.currentseeds = currentseeds
        self.totalpeers = totalpeers
        self.totalseeds = totalseeds
        self.ratio = ratio
        self.queueorder = queueorder
        self.sortby = sortby

    def __cmp__(self, other):
        if self.sortby == "progress":
            return cmp(self.getProgressOrder(self.statecode,self.progress) , self.getProgressOrder(other.statecode,other.progress))
        elif self.sortby == "queue":
            return cmp(self.getQueueOrder(self.statecode,self.queueorder) , self.getQueueOrder(other.statecode,other.queueorder))
        elif self.sortby == "eta":
            return cmp(self.getETAOrder(self.statecode,self.eta) , self.getETAOrder(other.statecode,other.eta))
        elif self.sortby == "download":
            return cmp(self.getRateOrder(self.statecode,self.downloadrate) , self.getRateOrder(other.statecode,other.downloadrate))
        elif self.sortby == "upload":
            return cmp(self.getRateOrder(self.statecode,self.uploadrate) , self.getRateOrder(other.statecode,other.uploadrate))
        elif self.sortby == "ratio":
            return cmp(self.getRatioOrder(self.statecode,self.ratio) , self.getRatioOrder(other.statecode,other.ratio))
        else:
            return 0

    def __str__(self):
        return str(self.name + " - " + self.eta)

    def getProgressOrder(self,statecode,progress):
        return (statecode*10000.0)+float(progress.rstrip("%"))

    def getQueueOrder(self,statecode,queueorder):
        if queueorder <> -1:
            queueorder = 1000 - queueorder
        return (statecode*10000.0)+float(queueorder)

    def getETAOrder(self,statecode,eta):
        try:
            if eta <> -1:
                eta = (100000000 - eta)/100
            return (statecode*10000000.0)+float(eta)
        except:
            return 0

    def getRateOrder(self,statecode,rate):
        try:
            return (statecode*1000000.0)+float(rate)
        except:
            return 0

    def getRatioOrder(self,statecode,ratio):
        try:
            return (statecode*10000.0)+(100.0*float(ratio))
        except:
            return 0

class TransmissionInfo:

    uri = None
    options = None
    sessionstate = None
    sessionstatefound = False

    STATE_DOWNLOADING = 4
    STATE_SEEDING = 3
    STATE_QUEUED = 2
    STATE_PAUSED = 1
    STATE_UNKNOWN = 0
        
    def __init__(self, options):

        try:

            #disable all logging within Deluge functions, only output info from this script
            logging.disable(logging.FATAL)

            self.options = options

            # sort out the server option
            self.options.server = self.options.server.replace("localhost", "127.0.0.1")

            # create the rpc and client objects
            self.client = transmissionrpc.Client(self.options.server, self.options.port) #, self.options.username, self.options.password)

        except Exception,e:
            self.logError("TransmissionInfo Init:Unexpected error:" + e.__str__())

    def getTorrentTemplateOutput(self, template, name, state, totaldone, totalsize, progress, nofiles, downloadrate, uploadrate, eta, currentpeers, cur