Python win32com SaveAs2 error when I try to save file - python

def convert_to_word():
target = pwd + "/open.doc"
source = pwd + "/template.html"
pythoncom.CoInitialize()
app = win32com.client.Dispatch("Word.Application")
pythoncom.CoInitialize()
# try:
app.Documents.Open(source)
app.Documents.SaveAs2(target,FileFormat=0)
app.Documents.Open(source)
app.Selection.WholeStory()
app.Selection.Fields.Unlink()
app.Documents.Save()
# except Exception as e:
# print(e)
# finally:
app.ActiveDocument.Close()
I need to save html file to .doc, but it report a error <unknown>.SaveAs2 which I cant solve.
Can anyone help me ? Thanks

My first answer on stackoverflow ...
I had had same troubles then I have found solution:
Your code seems to be almost OK. You just need to store your opened document to a variable and then use SaveAs2 function on the variable.
my_doc = app.Documents.Open(source)
my_doc.SaveAs2(target, FileFormat=0)

Related

How to skip one part of a single loop iteration in Python

I am creating about 200 variables within a single iteration of a python loop (extracting fields from excel documents and pushing them to a SQL database) and I am trying to figure something out.
Let's say that a single iteration is a single Excel workbook that I am looping through in a directory. I am extracting around 200 fields from each workbook.
If one of these fields I extract (lets say field #56 out of 200) and it isn't in proper format (lets say the date was filled out wrong ie. 9/31/2015 which isnt a real date) and it errors out with the operation I am performing.
I want the loop to skip that variable and proceed to creating variable #57. I don't want the loop to completely go to the next iteration or workbook, I just want it to ignore that error on that variable and continue with the rest of the variables for that single loop iteration.
How would I go about doing something like this?
In this sample code I would like to continue extracting "PolicyState" even if ExpirationDate has an error.
Some sample code:
import datetime as dt
import os as os
import xlrd as rd
files = os.listdir(path)
for file in files: #Loop through all files in path directory
filename = os.fsdecode(file)
if filename.startswith('~'):
continue
elif filename.endswith( ('.xlsx', '.xlsm') ):
try:
book = rd.open_workbook(os.path.join(path,file))
except KeyError:
print ("Error opening file for "+ file)
continue
SoldModelInfo=book.sheet_by_name("SoldModelInfo")
AccountName=str(SoldModelInfo.cell(1,5).value)
ExpirationDate=dt.datetime.strftime(xldate_to_datetime(SoldModelInfo.cell(1,7).value),'%Y-%m-%d')
PolicyState=str(SoldModelInfo.cell(1,6).value)
print("Insert data of " + file +" was successful")
else:
continue
Use multiple try blocks. Wrap each decode operation that might go wrong in its own try block to catch the exception, do something, and carry on with the next one.
try:
book = rd.open_workbook(os.path.join(path,file))
except KeyError:
print ("Error opening file for "+ file)
continue
errors = []
SoldModelInfo=book.sheet_by_name("SoldModelInfo")
AccountName=str(SoldModelInfo.cell(1,5).value)
try:
ExpirationDate=dt.datetime.strftime(xldate_to_datetime(SoldModelInfo.cell(1,7).value),'%Y-%m-%d')
except WhateverError as e:
# do something, maybe set a default date?
ExpirationDate = default_date
# and/or record that it went wrong?
errors.append( [ "ExpirationDate", e ])
PolicyState=str(SoldModelInfo.cell(1,6).value)
...
# at the end
if not errors:
print("Insert data of " + file +" was successful")
else:
# things went wrong somewhere above.
# the contents of errors will let you work out what
As suggested you could use multiple try blocks on each of your extract variable, or you could streamline it with your own custom function that handles the try for you:
from functools import reduce, partial
def try_funcs(cell, default, funcs):
try:
return reduce(lambda val, func: func(val), funcs, cell)
except Exception as e:
# do something with your Exception if necessary, like logging.
return default
# Usage:
AccountName = try_funcs(SoldModelInfo.cell(1,5).value, "some default str value", str)
ExpirationDate = try_funcs(SoldModelInfo.cell(1,7).value), "some default date", [xldate_to_datetime, partial(dt.datetime.strftime, '%Y-%m-%d')])
PolicyState = try_funcs(SoldModelInfo.cell(1,6).value, "some default str value", str)
Here we use reduce to repeat multiple functions, and pass partial as a frozen function with arguments.
This can help your code look tidy without cluttering up with lots of try blocks. But the better, more explicit way is just handle the fields you anticipate might error out individually.
So, basically you need to wrap your xldate_to_datetime() call into try ... except
import datetime as dt
v = SoldModelInfo.cell(1,7).value
try:
d = dt.datetime.strftime(xldate_to_datetime(v), '%Y-%m-%d')
except TypeError as e:
print('Could not parse "{}": {}'.format(v, e)

Use API to write to json file

I am facing this problem while I try to loop tweet_id using the API and write it to tweet_json.txt, the output for all data is Failed which I know is wrong
Before it was working good but when I try to Run all the code again it starts to show failed
for tweet_id in df['tweet_id']:
try:
tweet = api.get_status(tweet_id, tweet_mode = 'extended')
with open('tweet_json.txt', 'a+') as file:
json.dump(tweet._json, file)
file.write('\n')
print (tweet_id, 'success')
except:
print (tweet_id, 'Failed')
Your except is swallowing whatever exception is causing your code to die. Until you comment out the except or make it more specific you won't know if your problem is the Twitter API or file I/O or something else. Good luck!
A quick step forward would be to adjust your exception handler so that it writes the exception. I like to use the format_exc function to get my stack traces so i can write it with a logger, or however i want to handle it.
from traceback import format_exc
try:
a = "" + 1
except Exception as ex:
print("Exception encountered! \n %s " % format_exc())

How to get tables from .mdb using meza?

I'm using meza to read .mdb (MSAccess database) files.
from meza import io
try:
self.data = list(io.read_mdb(self.db_path, table=self.table))
except TypeError as e:
raise
io.read_mdb returns generator object (if table param is specified it returns all rows from specified database if not from first). However - it also prints all table names to the console when I ran this code snippet.
QUESTION:
Is there a way how to fetch all table names with meza?
or
Is there a way how to catch 'unwanted' tables console output?
i tried this, but without success:
with open(here_path + os.sep + "temp.txt", "w") as f:
with redirect_stdout(f):
try:
x = list(io.read_mdb(path))
except TypeError as e:
raise
Then I would just read tables from file temp.txt
EDIT:
edit based on reubano answer:
def show_tables_linux(path):
tables = subprocess.check_output(["mdb-tables", path])
return tables.decode().split()
above function returns list of tables.
You'd be better off using the mdbtools command mdb-tables.
mdb-tables test.mdb

Syntax error in python2 script using ldap module

Learning python (was chosen for its ldap module) for a new script that has been tossed my way. I'm getting a sytntax error when I try using a ldif. I was getting Syntax errors on the attrs I was trying to assign until I moved it further up the script to near the search fields. I'm not exactly sure why I am getting the syntax error:
File "UserGroupModify.py", line 66
attrs = {}
^
SyntaxError: invalid syntax
~/Scripts/Termination-Script$ python2 UserGroupModify.py
File "UserGroupModify.py", line 69
ldif = modlist.addModlist(attrs)
^
SyntaxError: invalid syntax
The code currently looks like the following (including previous things I had tried all with syntax errors of their own when I tried to use them). Getting it to log in and search for the user was easy enough, but modifying the user is where I am having a hard time. The current code is uncommented and is from an example I found online.
#!/usr/bin/env python2
import ldap
import getpass
import ldap.modlist as modlist
## first you must open a connection to the server
try:
#Ignore self signed certs
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
username = raw_input("LDAP Login: ")
passwd = getpass.getpass()
userlook = raw_input("User to lookup: ")
l = ldap.initialize("ldaps://ldap.example.com:636/")
# Bind/authenticate with a user with apropriate rights to add objects
l.simple_bind_s("uid="+username+",ou=people,dc=example,dc=com", ""+passwd+"")
except ldap.LDAPError, e:
print(e)
# The dn of our existing entry/object
dn = "ou=People,dc=example,dc=com"
searchScope = ldap.SCOPE_SUBTREE
searchAttribute = ["uid"]
#retrieveAttributes = ["ou=Group"]
retrieveAttributes = ["ou"]
#searchFilter = "uid=*"
searchFilter = "(uid="+userlook+")"
#mod_attrs = [(ldap.MOD_REPLACE, 'ou', 'former-people' )]
attrs = {}
attrs['member'] = ['uid="+userlook+",ou=former-people,dc=example,dc=com']
try:
#ldap_result_id = l.search(dn, searchScope, searchFilter, retrieveAttributes)
ldap_result_id = l.search(dn, searchScope, searchFilter, retrieveAttributes)
while 1:
result_type, result_data = l.result(ldap_result_id, 0)
if (result_data == []):
break
else:
## here you don't have to append to a list
## you could do whatever you want with the individual entry
## The appending to list is just for illustration.
if result_type == ldap.RES_SEARCH_ENTRY:
print(result_data)
# Some place-holders for old and new values
#old={'Group':'l.result(ldap_result_id, 0)'}
#new={'Group':'uid="+userlook+",ou=former-people,dc=example,dc=com'}
#newsetting = {'description':'I could easily forgive his pride, if he had not mortified mine.'}
#print(old)
#print(new)
# Convert place-holders for modify-operation using modlist-module
#ldif = modlist.modifyModlist(old,new)
# Do the actual modification
#l.modify_s(dn,ldif)
#l.modify_s('uid="+userlook+,ou=People,dc=example,dc=com', mod_attrs)
#l.modify_s('uid="+userlook+",ou=People', mod_attrs)
#moved up due to SyntaxError
#attrs = {}
#attrs['member'] = ['uid="+userlook+",ou=former-people,dc=example,dc=com']
# Convert our dict to nice syntax for the add-function using modlist-module
ldif = modlist.addModlist(attrs)
# Do the actual synchronous add-operation to the ldapserver
l.add_s(dn,ldif)
# Its nice to the server to disconnect and free resources when done
l.unbind_s()
except ldap.LDAPError, e:
print(e)
Any direction pointing on what's causing the error would be greatly appreciated. Thanks
It's a syntax error to have try without except. Because there's a whole lot of unindented code before the except, Python doesn't see it as part of the try. Make sure everything between try and except is indented.
You haven't ended your try block by the time you reach this line
ldif = modlist.addModlist(attrs)
since the accompanying except is below. However, you reduced the indentation level and this is causing the syntax error since things in the same block should have the same indentation.

lxml + loads of files = random SerialisationError: IO_WRITE

I'm using lxml and python 3 to parse many files and merge files that belong together.
The files are actually stored in pairs of two (that are also merged first) inside zip files but i don't think that matters here.
We're talking about 100k files that are about 900MB in zipped form.
My problems is that my script works fine but at somepoint (for multiple runs it's not always the same point so it shouldn't be a problem with a certain file) i get this error:
File "C:\Users\xxx\workspace\xxx\src\zip2xml.py", line 110, in
_writetonorm
normroot.getroottree().write(norm_file_path) File "lxml.etree.pyx", line 1866, in lxml.etree._ElementTree.write
(src/lxml\lxml.etree.c:46006) File "serializer.pxi", line 481, in
lxml.etree._tofilelike (src/lxml\lxml.etree.c:93719) File
"serializer.pxi", line 187, in lxml.etree._raiseSerialisationError
(src/lxml\lxml.etree.c:90965) lxml.etree.SerialisationError: IO_WRITE
I have no idea what causes this error.
The entire code is a little cumbersome so i hope the relevant areas suffice:
def _writetonorm(self, outputpath):
'''Writes the current XML to a file.
It'll update the file if it already exists and create the file otherwise'''
#Find Name
name = None
try:
name = self._xml.xpath("xxx")[0].text.rstrip().lstrip()
except Exception as e:
try:
name = self._xml.xpath("xxx")[0].text.rstrip().lstrip()
except Exception as e:
name = "damn it!"
if name != None:
#clean name a bit
name = name[:35]
table = str.maketrans(' /#*"$!&<>-:.,;()','_________________')
name = name.translate(table)
name = name.lstrip("_-").rstrip("_-")
#generate filename
norm_file_name = name + ".xml"
norm_file_path = os.path.join(outputpath, norm_file_name)
#Check if we have that completefile already. If we do, update it.
if os.path.isfile(norm_file_path):
norm_file = etree.parse(norm_file_path, self._parser)
try:
normroot = norm_file.getroot()
except:
print(norm_file_path + "is broken !!!!")
time.sleep(10)
else:
normroot = etree.Element("norm")
jurblock = etree.Element("jurblock")
self._add_jurblok_attributes(jurblock)
jurblock.insert(0, self._xml)
normroot.insert(0, jurblock)
try:
normroot.getroottree().write(norm_file_path) #here the Exception occurs
except Exception as e:
print(norm_file_path)
raise e
I know that my exception handling isn't great but this is just a proof of work for now.
Can anyone tell me why the error happens ?
Looking at the file that causes the error it's not wellformed but I suspect that is because the error happened and it was fine before the latest iteration.
It seems to have been a mistake to use maped network drives for this. No such Exception when letting it work with the files locally.
Learned something :)

Categories

Resources