Edycja dokumentów biurowych za pomocą Zoho Remote API
3 October 2009
Comments
W poprzednim artykule opisałem API udostępniane przez zoho.com. Teraz zajmiemy się wykorzystaniem Zoho Remote API do edycji dokumentów w naszej aplikacji webowej napisanej we frameworku Django.
pyCurl i Zoho Remote API
Wykorzystanie Remote API polega na wysłaniu wieloczęściowych (multipart) żądań post z potrzebnymi danymi i zawartością pliku do edycji/podglądu. W Pythonie najlepiej do tego użyć biblioteki pycurl. Oto przykład "otwierający" dokument w edytorze Zoho:import pycurl
apikey = 'TWOJ KLUCZ API'
class Bodyfetcher:
def __init__(self):
self.contents = ''
def body_callback(self, buf):
self.contents = self.contents + buf
t = Bodyfetcher()
c = pycurl.Curl()
c.setopt(c.POST, 1)
# wysyłamy żądanie na podany URL API
c.setopt(c.URL, "http://export.writer.zoho.com/remotedoc.im?apikey=%s&output=editor" % apikey)
# przekazujemy dane
c.setopt(c.HTTPPOST, [("content", (c.FORM_FILE, "a.odt")), ("filename", 'a.odt'), ("id", '13'), ("format", 'odt'), ("saveurl", 'http://localhost/')])
c.setopt(c.WRITEFUNCTION, t.body_callback)
c.perform()
c.close()
# JS otwierający edytor
print t.contents
Aplikacja Django - edycja dokumentów
Pełen kod, projekt Django omawianej poniżej aplikacji można pobrać i przetestować samemu. Należy aby w settings.py ustawić swój własny klucz API Zoho, oraz podać ścieżkę do site_media. Do tego syncdb i dodanie paru dokumentów w Panelu Admina
Powyższy fragment kodu z pycurl można wykorzystać w widokach Django do stworzenia aplikacji do edycji dokumentów dostępnych na naszym serwerze. Wykorzystamy taki prosty model zbierający dokumenty biurowe:
class Document(models.Model):
title = models.CharField(max_length=255, verbose_name='Title')
description = models.TextField(verbose_name='Description')
file = models.FilePathField(verbose_name='File', blank=True, null=True, path=settings.MEDIA_ROOT + 'documents/')
doctype = models.CharField(max_length=10, verbose_name='Type', choices=[('doc', 'Document'), ('sheet', 'Sheet'), ('slide', 'Slides')])
class Meta:
verbose_name = 'Document'
verbose_name_plural = 'Documents'
def __unicode__(self):
return self.title
#!/usr/bin/python
import pycurl
from django.shortcuts import render_to_response
from django.conf import settings
from django.template import RequestContext
from django.http import HttpResponseRedirect,HttpResponse
from django.views.generic.list_detail import object_list
from documents.models import *
def show_index(request):
"""
List all documents
"""
return object_list(
request,
Document.objects.all(),
paginate_by = 50,
allow_empty = True,
template_name = 'show_index.html',
extra_context = {})
class Bodyfetcher:
def __init__(self):
self.contents = ''
def body_callback(self, buf):
self.contents = self.contents + buf
def view_doc(request, did):
"""
Display the document in read-only
"""
doc = Document.objects.get(id=did)
ext = str(doc.file.split('.')[-1])
fname = str(doc.file.split('/')[-1])
t = Bodyfetcher()
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.URL, "http://export.writer.zoho.com/remotedoc.im?apikey=%s&output=view" % settings.APIKEY)
c.setopt(c.HTTPPOST, [("content", (c.FORM_FILE, str(doc.file))), ("filename", fname), ("id", str(doc.id)), ("format", ext)])
c.setopt(c.VERBOSE, 1)
c.setopt(c.WRITEFUNCTION, t.body_callback)
c.perform()
c.close()
zoho = t.contents
return render_to_response(
'view_doc.html',
{'doc': doc, 'zoho': zoho},
context_instance=RequestContext(request))
def edit_doc(request, did):
"""
Display the document in Zoho editor
"""
doc = Document.objects.get(id=did)
ext = str(doc.file.split('.')[-1])
fname = str(doc.file.split('/')[-1])
t = Bodyfetcher()
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.URL, "http://export.writer.zoho.com/remotedoc.im?apikey=%s&output=editor" % settings.APIKEY)
c.setopt(c.HTTPPOST, [("content", (c.FORM_FILE, str(doc.file))), ("filename", fname), ("id", str(doc.id)), ("format", ext), ("saveurl", 'http://localhost:8080/doc/save_file/')])
c.setopt(c.WRITEFUNCTION, t.body_callback)
c.perform()
c.close()
zoho = t.contents
return render_to_response(
'edit_doc.html',
{'doc': doc, 'zoho': zoho},
context_instance=RequestContext(request))
def edit_doc_in_frame(request, did):
"""
Show the document in editor embeded in an iframe
"""
doc = Document.objects.get(id=did)
ext = str(doc.file.split('.')[-1])
fname = str(doc.file.split('/')[-1])
t = Bodyfetcher()
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.URL, "http://export.writer.zoho.com/remotedoc.im?apikey=%s&output=id" % settings.APIKEY)
c.setopt(c.HTTPPOST, [("content", (c.FORM_FILE, str(doc.file))), ("filename", fname), ("id", str(doc.id)), ("format", ext), ("saveurl", 'http://localhost:8080/doc/save_file/')])
c.setopt(c.WRITEFUNCTION, t.body_callback)
c.perform()
c.close()
zoho = t.contents
return render_to_response(
'edit_doc_in_frame.html',
{'doc': doc, 'zoho': zoho},
context_instance=RequestContext(request))
def save_file(request):
"""
Save POSTed file
"""
if request.POST:
data = request.POST.copy()
doc = Document.objects.get(id=data['id'])
ext = str(doc.file.split('.')[-1])
fname = str(doc.file.split('/')[-1])
if fname == data['filename']:
#ok
# referer check would be recommended here etc.
print 'saving file'
content = request.FILES['content'].read()
f = open(str(doc.file), 'wb')
f.write(content)
f.close()
return HttpResponse('ok')
Edycja arkuszy i prezentacji
Remote API dla Zoho Sheet i Zoho Show jest prostsze. API pozwala otworzyć plik do edycji, lecz nie zwraca kodu JS, który otworzy edytor, lecz zwraca adres edytora w nagłówku Location odpowiedzi - na który można przekierować użytkownika, lub otworzyć edytor w ramce. Widok obsługujący arkusze wygląda tak:class Headerfetcher:
def __init__(self):
self.contents = ''
def body_callback(self, buf):
self.contents = self.contents + buf
def edit_sheet(request, did, inframe=False):
"""
Display the sheet in Zoho editor
"""
doc = Document.objects.get(id=did)
ext = str(doc.file.split('.')[-1])
fname = str(doc.file.split('/')[-1])
t = Headerfetcher()
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.URL, "http://sheet.zoho.com/remotedoc.im?apikey=%s&output=editor" % settings.APIKEY)
c.setopt(c.HTTPPOST, [("content", (c.FORM_FILE, str(doc.file))), ("filename", fname), ("id", str(doc.id)), ("format", ext), ("saveurl", 'http://localhost:8080/doc/save_file/')])
c.setopt(c.HEADERFUNCTION, t.body_callback)
c.perform()
c.close()
x = t.contents.split('
')
for i in x:
if i.startswith('Location: '):
zoho = i.replace('Location: ', '').strip()
if inframe:
return render_to_response(
'edit_sheet_in_frame.html',
{'doc': doc, 'zoho': zoho},
context_instance=RequestContext(request))
else:
return HttpResponseRedirect(zoho)
return HttpResponse('ZohoError :(')
Za pomocą Remote API można zaimplementować obsługę plików z pakietów biurowych. Zaprezentowane API pozwala na edycję plików, jak i odczyt i zapis w różnych formatach (w tym także HTML, PDF dla dokumentów). Za pomocą API Zoho View można także zaimplementować szybki podgląd dla tych plików. Jeżeli interesuje ciebie wykorzystanie logiki biznesowej obsługiwanej przez Zoho Sheet czy Reports to powinieneś zainteresować się Data API (dane muszą być przetrzymywane na serwerze Zoho w tym przypadku).
RkBlog
Comment article