How to upload documents with new python-gdata (2.0.16)? - python

With python-gdata 2.0.14, I used the following pieces of code to create and upload documents:
# To create a document
import gdata.docs
import gdata.docs.client
from gdata.data import MediaSource
gdClient = gdata.docs.client.DocsClient(source="my-app")
gdClient.ssl = True
gdClient.ClientLogin("login", "pa$$word", gdClient.source)
ms = MediaSource(file_path="temp.html", content_type="text/html")
entry = gdClient.Upload(ms, "document title")
print "uploaded, url is", entry.GetAlternateLink().href
and
# To update a document
entry.title.text = "updated title"
entry = gdClient.Update(entry, media_source=ms, force=True)
print "updated, url is", entry.GetAlternateLink().href
However, this code does no longer work with python-gdata 2.0.16 because DocsClient class does no more have Upload and Update functions.
I tried to use this
# Try to create a document
gdClient = gdata.docs.client.DocsClient(source="my-app")
gdClient.ssl = True
gdClient.ClientLogin("login", "pa$$word", gdClient.source)
ms = MediaSource(file_path="temp.html", content_type="text/html")
entry = gdata.docs.data.Resource(type=gdata.docs.data.DOCUMENT_LABEL, title="document title")
self.resource = gdClient.CreateResource(entry, media=ms)
… but I get this error:
gdata.client.Unauthorized: Unauthorized - Server responded with: 401, 'Token invalid'
Can anybody tell me where's my mistake and how should I use that new API?
P.S. The documentation hasn't been updated and still uses the old-style code.

I was having issues with this recently too. This worked for me:
import gdata.docs.data
import gdata.docs.client
client = gdata.docs.client.DocsClient(source='your-app')
client.api_version = "3"
client.ssl = True
client.ClientLogin("your#email.com", "password", client.source)
filePath = "/path/to/file"
newResource = gdata.docs.data.Resource(filePath, "document title")
media = gdata.data.MediaSource()
media.SetFileHandle(filePath, 'mime/type')
newDocument = client.CreateResource(newResource, create_uri=gdata.docs.client.RESOURCE_UPLOAD_URI, media=media)
Edit: Added the packages to import to avoid confusion

Related

Access email from a particular folder in Outlook, within a specific date range (user Input) using "exchangelib" in Python

Summary of the requirement :
To access emails from a specific folder in Outlook within a user given date range,
ex: all mails from June or all mails from 23-June-2020 to 15-July-2020
So far we have tried the following but the issues are :
Date range is not giving correct output
It is taking too long to give output, also sometimes returning with a timeout error.
The Code:
from exchangelib import Credentials, Account, DELEGATE, Configuration, IMPERSONATION, FaultTolerance,EWSDateTime,EWSTimeZone,Message
import datetime
import pandas as pd
new_password = "your password"
credentials = Credentials(username = 'username', password = new_password)
config = Configuration(server ='outlook.office365.com', credentials = credentials)
account = Account(primary_smtp_address ='username', credentials = credentials, autodiscover = False, config = config, access_type = DELEGATE)
#first approach.....................................
conversation_id = []
datetime_received = []
has_attachment = []
Senders = []
for i in account.inbox.all().order_by('-datetime_received')[:40]:
if isinstance(i, Message):
if i.datetime_received:
if ((i.datetime_received).year == 2020):
if ((i.datetime_received).month == 7):
if i.conversation_id:
print("conversation id: ", i.conversation_id.id)
conversation_id.append(i.conversation_id.id)
if not i.conversation_id:
conversation_id.append("Not available")
if i.sender:
print("Sender name : ", i.sender.name)
Senders.append(i.sender.name)
if not i.sender:
Senders.append("not available")
if i.datetime_received:
print("Time : ", i.datetime_received.date)
datetime_received.append(i.datetime_received.date)
if not i.datetime_received:
datetime_received.append("not available")
if i.has_attachments:
print("Has attachment: ", i.has_attachments)
has_attachment.append(i.has_attachments)
if not i.has_attachments:
has_attachment.append("not available")
# second approach.....................................................................
items_for_2019 = account.inbox.filter(start__range=(
tz.localize(EWSDateTime(2019, 8, 1)),
tz.localize(EWSDateTime(2020, 1, 1))
))
for i in items_for_2019:
print("")
#third approach.........................................................................
for item in account.inbox.filter(datetime_received__range=(tz.localize(EWSDateTime(2019, 8, 1)),tz.localize(EWSDateTime(2020, 1, 1)))):
print(item.sender.name)
first approach is working for specific month but extremely slow
second and third approach giving wrong output
A little guidance would be highly appreciated.
The start field belongs to CalendarItem. It is not a valid field for Message objects. That's why your 2nd approach does not work.
Your 3rd approach should work. Which output do you see, and what did you expect?
If your queries are taking a long time, try to limit the fields you are fetching for each item, by using the .only() QuerySet method.

Pyuno indexing issue that I would like an explanation for

The following python libreoffice Uno macro works but only with the try..except statement.
The macro allows you to select text in a writer document and send it to a search engine in your default browser.
The issue, is that if you select a single piece of text,oSelected.getByIndex(0) is populated but if you select multiple pieces of text oSelected.getByIndex(0) is not populated. In this case the data starts at oSelected.getByIndex(1) and oSelected.getByIndex(0) is left blank.
I have no idea why this should be and would love to know if anyone can explain this strange behaviour.
#!/usr/bin/python
import os
import webbrowser
from configobj import ConfigObj
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE
from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
def fs3Browser(*args):
#get the doc from the scripting context which is made available to all scripts
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()
doc = XSCRIPTCONTEXT.getDocument()
parentwindow = doc.CurrentController.Frame.ContainerWindow
oSelected = model.getCurrentSelection()
oText = ""
try:
for i in range(0,4,1):
print ("Index No ", str(i))
try:
oSel = oSelected.getByIndex(i)
print (str(i), oSel.getString())
oText += oSel.getString()+" "
except:
break
except AttributeError:
mess = "Do not select text from more than one table cell"
heading = "Processing error"
MessageBox(parentwindow, mess, heading, INFOBOX, BUTTONS_OK)
return
lookup = str(oText)
special_c =str.maketrans("","",'!|##"$~%&/()=?+*][}{-;:,.<>')
lookup = lookup.translate(special_c)
lookup = lookup.strip()
configuration_dir = os.environ["HOME"]+"/fs3"
config_filename = configuration_dir + "/fs3.cfg"
if os.access(config_filename, os.R_OK):
cfg = ConfigObj(config_filename)
#define search engine from the configuration file
try:
searchengine = cfg["control"]["ENGINE"]
except:
searchengine = "https://duckduckgo.com"
if 'duck' in searchengine:
webbrowser.open_new('https://www.duckduckgo.com//?q='+lookup+'&kj=%23FFD700 &k7=%23C9C4FF &ia=meanings')
else:
webbrowser.open_new('https://www.google.com/search?/&q='+lookup)
return None
def MessageBox(ParentWindow, MsgText, MsgTitle, MsgType, MsgButtons):
ctx = XSCRIPTCONTEXT.getComponentContext()
sm = ctx.ServiceManager
si = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
mBox = si.createMessageBox(ParentWindow, MsgType, MsgButtons, MsgTitle, MsgText)
mBox.execute()
Your code is missing something. This works without needing an extra try/except clause:
selected_strings = []
try:
for i in range(oSelected.getCount()):
oSel = oSelected.getByIndex(i)
if oSel.getString():
selected_strings.append(oSel.getString())
except AttributeError:
# handle exception...
return
result = " ".join(selected_strings)
To answer your question about the "strange behaviour," it seems pretty straightforward to me. If the 0th element is empty, then there are multiple selections which may need to be handled differently.

Reading specific test steps from Quality Center with python

I am working with Quality Center via OTA COM library. I figured out how to connect to server, but I am lost in OTA documentation on how to work with it. What I need is to create a function which takes a test name as an input and returns number of steps in this test from QC.
For now I am this far in this question.
import win32com
from win32com.client import Dispatch
# import codecs #to store info in additional codacs
import re
import json
import getpass #for password
qcServer = "***"
qcUser = "***"
qcPassword = getpass.getpass('Password: ')
qcDomain = "***"
qcProject = "***"
td = win32com.client.Dispatch("TDApiOle80.TDConnection.1")
#Starting to connect
td.InitConnectionEx(qcServer)
td.Login(qcUser,qcPassword)
td.Connect(qcDomain, qcProject)
if td.Connected == True:
print "Connected to " + qcProject
else:
print "Connection failed"
#Path = "Subject\Regression\C.001_Band_tones"
mg=td.TreeManager
npath="Subject\Regression"
tsFolder = td.TestSetTreeManager.NodeByPath(npath)
print tsFolder
td.Disconnect
td.Logout
print "Disconnected from " + qcProject
Any help on descent python examples or tutorials will be highly appreciated. For now I found this and this, but they doesn't help.
Using the OTA API to get data from Quality Center normally means to get some element by path, create a factory and then use the factory to get search the object. In your case you need the TreeManager to get a folder in the Test Plan, then you need a TestFactory to get the test and finally you need the DesignStepFactory to get the steps. I'm no Python programmer but I hope you can get something out of this:
mg=td.TreeManager
npath="Subject\Test"
tsFolder = mg.NodeByPath(npath)
testFactory = tsFolder.TestFactory
testFilter = testFactory.Filter
testFilter["TS_NAME"] = "Some Test"
testList = testFactory.NewList(testFilter.Text)
test = testList.Item(1) # There should be only 1 item
print test.Name
stepFactory = test.DesignStepFactory
stepList = stepFactory.NewList("")
for step in stepList:
print step.StepName
It takes some time to get used to the QC OTA API documentation but I find it very helpful. Nearly all of my knowledge comes from the examples in the API documentation—for your problem there are examples like "Finding a unique test" or "Get a test object with name and path". Both examples are examples to the Test object. Even if the examples are in VB it should be no big thing to adapt them to Python.
I figured out the solution, if there is a better way to do this you are welcome to post it.
import win32com
from win32com.client import Dispatch
import getpass
def number_of_steps(name):
qcServer = "***"
qcUser = "***"
qcPassword = getpass.getpass('Password: ')
qcDomain = "***"
qcProject = "***"
td = win32com.client.Dispatch("TDApiOle80.TDConnection.1")
#Starting to connect
td.InitConnectionEx(qcServer)
td.Login(qcUser, qcPassword)
td.Connect(qcDomain, qcProject)
if td.Connected is True:
print "Connected to " + qcProject
else:
print "Connection failed"
mg = td.TreeManager # Tree manager
folder = mg.NodeByPath("Subject\Regression")
testList = folder.FindTests(name) # Make a list of tests matching name (partial match is accepted)
if testList is not None:
if len(testList) > 1:
print "There are multiple tests matching this name, please check input parameter\nTests matching"
for test in testList:
print test.name
td.Disconnect
td.Logout
return False
if len(testList) == 1:
print "In test %s there is %d steps" % (testList[0].Name, testList[0].DesStepsNum)
else:
print "There are no test with this test name in Quality Center"
td.Disconnect
td.Logout
return False
td.Disconnect
td.Logout
print "Disconnected from " + qcProject
return testList[0].DesStepsNum # Return number of steps for given test

Updating Evernote notes with Python

I'm trying to update a note in Evernote.
I set a filter, get notes list and I can also change the note's title.
But when I try to change note content, nothing happens.
from evernote.api.client import EvernoteClient
import evernote.edam.type.ttypes as Types
from evernote.edam.notestore.ttypes import NoteFilter, NotesMetadataResultSpec
client = EvernoteClient(token="xxxxx", sandbox=True)
note_store = client.get_note_store()
updated_filter = NoteFilter(words='abaco')
result_list = note_store.findNotesMetadata(updated_filter, 0, 10000, NotesMetadataResultSpec(includeTitle=True))
for note in result_list.notes:
print "----- TITLE -----\n%s\n----- GUID -----\n%s\n----- CONTENT -----\n%s" % (note.title, note.guid, note_store.getNoteContent(note.guid))
note.title = "pippo"
note.guid = note.guid
note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'
note.content += '<en-note>Note updated</en-note>'
note = note_store.updateNote(note)
I receive no error but the note is not updated.
I'm using Python 2.7.
Thanks in advance!
The return value of NoteStore#findNotesMetadata is NotesMetadataList that contains NoteMetadata, not Note object. In order to update notes, you should call NoteStore#getNote first, update the field and call NoteStore#updateNote.

Python evernote api Error

Trying to build app that connects with Evernote API, in Python/Django. For the below code i get the following error message: " 'Store' object has no attribute 'NoteFilter' " from http://dev.evernote.com/documentation/reference/NoteStore.html#Svc_NoteStore One can see, that NoteFilter is attribute of NoteStore.
def list(request):
nbname="mihkel's notebook"
client = EvernoteClient(token=token, sandbox=False)
note_store = client.get_note_store()
notebooks = note_store.listNotebooks()
for nb in notebooks:
if nbname == nb.name:
nb = nb
filter = note_store.NoteFilter()
filter.notebookGuid = nb.guid
notelist = note_store.findNotes(token,filter,0,10)
break
return render_to_response('list.html', {'nb': nb, 'notelist':notelist})
Solution:
from evernote.edam.notestore import NoteStore
....
....
def list.. :
...
Filter = NoteStore.NoteFilter()
notestore/ttypes.py has the definition for NoteFilter
Some of the examples in the API code import like this
import evernote.edam.notestore.NoteStore as NoteStore
import evernote.edam.type.ttypes as Types
Not sure if this would be an acceptable way to correct, but I added this:
import evernote.edam.notestore.ttypes as NoteStoreTypes
and created my filter like this:
filter = NoteStoreTypes.NoteFilter()

Categories