#!/usr/bin/python
#
# webservice-office-zoho: display local or online documents by using the Zoho web service
#    Copyright 2010 Canonical Ltd.
#
#    This program is free software: you can redistribute it and/or modify it 
#    under the terms of the GNU General Public License version 3, as published 
#    by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful, but 
#    WITHOUT ANY WARRANTY; without even the implied warranties of 
#    MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.

'''Open local or online documents using the zoho web services'''

__author__ = 'jb@canonical.com'
__version__ = '0.2'

import getopt
import os.path
import sys
import webbrowser

import pycurl
import re

# unique api key
apikey = '9f950e366ef183c76e5543135f05acdb'

# individual urls for the various services
docURL    = 'http://export.writer.zoho.com/remotedoc.im'
sheetURL  = 'http://sheet.zoho.com/remotedoc.im'
showURL   = 'http://show.zoho.com/remotedoc.im'
onlineURL = 'http://viewer.zoho.com/api/view.do?url='
defaultDocURL = 'http://writer.zoho.com/home?serviceurl=%2Findex.do'
defaultSheetURL = 'http://sheet.zoho.com/login.do?serviceurl=%2Fhome.do'
defaultShowURL = 'http://show.zoho.com/login.do'
defaultURL = 'http://www.zoho.com'

def main(argv):
        ''' Main entry point '''
        # make sure we have the required command line arguments
        try:
                opts, args = getopt.getopt(argv, "hf::t:u:",
                                                ["help",
                                                 "filename=",
                                                 "type=",
                                                 "url="])

	except getopt.GetoptError:
		usage()

	# arguments present and correct
        filename = ''
        docType  = ''
        online   = ''

        for opt, arg in opts:
                if opt in ("-h", "--help"):
                        usage()
                elif opt in ("-f", "--filename"):
                        filename = arg
                elif opt in ("-t", "--type"):
                        docType = arg
                elif opt in ("-u", "--url"):
                        online = arg

        # wanting to display an online document, just pass the url
        if online:
                webURL = onlineURL + online
                webbrowser.open(webURL)
                sys.exit()

	# wanting to display a local document
        if docType:
                # first figure out what type of document and give a default
		# file extension
                if docType == 'doc':
                        offlineURL = docURL
			extension = "odt"
                elif docType == 'sheet':
                        offlineURL = sheetURL
			extension = "ods"
                elif docType == 'show':
                        offlineURL = showURL
			extension = "odp"
                else:
                        usage()

                # ensure that the passed in filename is actually a file, allow
		# an empty filename
                if not os.path.isfile(filename):
			if filename != "":
                        	unsupported(filename)
			# passed in no filename but a type, launch Zoho with
			# an empty document of that type
			else:
				filename = "/usr/share/webservice-office-zoho/empty-zoho-document." + extension
				try:
					f = open(filename)
				except IOError:
					print "Could not open file: " + filename
					sys.exit()

                # ensure that the filename and extension is more than 4 characters
		# if not use the default from above
                if len(filename) >= 4:
                        # find out the documents type
                        if filename[-4] == '.':
                                extension = filename[-3:].upper()
                        else:
                                extension = filename[-4:].upper()

        else:
                usage()

        # create a call back for the request
        response = requestCallback()

        # send the request to the API URL
        requestURL = (offlineURL + "?apikey=%s&output=editor" % apikey)
        curlObject = pycurl.Curl()
        curlObject.setopt(curlObject.POST, 1)
        curlObject.setopt(curlObject.URL, requestURL)

        # set the required data
        curlObject.setopt(curlObject.HTTPPOST,
                        [("content", (curlObject.FORM_FILE, filename)),
                         ("filename", filename), 
                         ("id", '99'),
                         ("format", extension)])

        # handle the call differently depending on what service we are using.
        if docType == 'doc':
                curlObject.setopt(curlObject.WRITEFUNCTION, response.callback)
        else:
        	curlObject.setopt(curlObject.HEADERFUNCTION, response.callback)
        curlObject.perform()
        curlObject.close()

        # display the document in a browser
        finalURL = ''
        if docType == 'doc':
                x = response.contents.split('\'')
                for i in x:
                        if i.startswith('http'):
                                finalURL = i
        else:
                x = response.contents.split('\n')
	        for i in x:
		        if i.startswith('Location: '):
		        	finalURL = i.replace('Location: ', '').strip()

        if finalURL:
                webbrowser.open(finalURL)
        else:
   		print "Document failed to be displayed using Zoho web services"

class requestCallback:
        ''' A class to hold call back information from the online web service '''
	def __init__(self):
		self.contents = ''

	def callback(self, buf):
		self.contents = self.contents + buf

def usage():
        ''' Print out usage information '''
        print "Usage: webservice-office-zoho [options]"
        print "Options:"
        print "  -f, --filename=        filename to view online"
        print "  -t, --type=            type of file to view: doc, sheet, or show"
        print "  -u, --url=             url of document to open if document is online"
        print "  -h, --help             print this message"
        sys.exit()

def unsupported(filename):
        ''' Print out an unsupported file message '''
        print "error: Unsupported file type or name: " + filename
        sys.exit()

if __name__ == "__main__":
        main(sys.argv[1:])

