Python-UNO bridge: change PDF export options - python
I'm trying to generate a PDF from an odt file using Python and the OpenOffice UNO bridge.
It works fine so far, the only problem i'm facing are the export options.
By default, OO is using the existing PDF export settings (the one used the last time, or the default if the first time). But I need set these settings manually, for example "UseTaggedPDF" has to be true.
This is part of the code where i export the PDF:
try:
properties=[]
p = PropertyValue()
p.Name = "FilterName"
p.Value = "writer_pdf_Export"
properties.append(p)
p = PropertyValue()
p.Name = "UseTaggedPDF"
p.Value = True
properties.append(p)
document.storeToURL(outputUrl, tuple(properties))
finally:
document.close(True)
The PDF is generated but not tagged. What's wrong with this?
Finaly found the solution on http://www.oooforum.org/forum/viewtopic.phtml?t=70949
try:
# filter data
fdata = []
fdata1 = PropertyValue()
fdata1.Name = "UseTaggedPDF"
fdata1.Value = True
fdata.append(fdata1)
fdata.append(fdata1)
args = []
arg1 = PropertyValue()
arg1.Name = "FilterName"
arg1.Value = "writer_pdf_Export"
arg2 = PropertyValue()
arg2.Name = "FilterData"
arg2.Value = uno.Any("[]com.sun.star.beans.PropertyValue", tuple(fdata) )
args.append(arg1)
args.append(arg2)
document.storeToURL(outputUrl, tuple(args))
finally:
document.close(True)
Related
How can I save the headers and values in Html <script> as a table in the csv file?
I'm new to writing code. Using slenium and beautifulsoup, I managed to reach the script I want among dozens of scripts on the web page. I am looking for script [17]. When these codes are executed, the script [17] gives a result as follows. the last part of my codes html=driver.page_source soup=BeautifulSoup(html, "html.parser") scripts=soup.find_all("script") x=scripts[17] print(x) result, output note: The list of dates is ahead of the script [17]. slide the bar. Dummy Data Dummy Data <script language="JavaScript"> var theHlp='/yardim/matris.asp';var theTitle = 'Piyasa Değeri';var theCaption='Cam (TL)';var lastmod = '';var h='<a class=hisselink href=../Hisse/HisseAnaliz.aspx?HNO=';var e='<a class=hisselink href=../endeks/endeksAnaliz.aspx?HNO=';var d='<center><font face=symbol size=1 color=#FF0000><b>ß</b></font></center>';var u='<center><font face=symbol size=1 color=#008000><b>İ</b></font></center>';var n='<center><font face=symbol size=1 color=#00A000><b>=</b></font></center>';var fr='<font color=#FF0000>';var fg='<font color=#008000>';var theFooter=new Array();var theCols = new Array();theCols[0] = new Array('Hisse',4,50);theCols[1] = new Array('2012.12',1,60);theCols[2] = new Array('2013.03',1,60);theCols[3] = new Array('2013.06',1,60);theCols[4] = new Array('2013.09',1,60);theCols[5] = new Array('2013.12',1,60);theCols[6] = new Array('2014.03',1,60);theCols[7] = new Array('2014.06',1,60);theCols[8] = new Array('2014.09',1,60);theCols[9] = new Array('2014.12',1,60);theCols[10] = new Array('2015.03',1,60);theCols[11] = new Array('2015.06',1,60);theCols[12] = new Array('2015.09',1,60);theCols[13] = new Array('2015.12',1,60);theCols[14] = new Array('2016.03',1,60);theCols[15] = new Array('2016.06',1,60);theCols[16] = new Array('2016.09',1,60);theCols[17] = new Array('2016.12',1,60);theCols[18] = new Array('2017.03',1,60);theCols[19] = new Array('2017.06',1,60);theCols[20] = new Array('2017.09',1,60);theCols[21] = new Array('2017.12',1,60);theCols[22] = new Array('2018.03',1,60);theCols[23] = new Array('2018.06',1,60);theCols[24] = new Array('2018.09',1,60);theCols[25] = new Array('2018.12',1,60);theCols[26] = new Array('2019.03',1,60);theCols[27] = new Array('2019.06',1,60);theCols[28] = new Array('2019.09',1,60);theCols[29] = new Array('2019.12',1,60);theCols[30] = new Array('2020.03',1,60);var theRows = new Array(); theRows[0] = new Array ('<b>'+h+'30>ANA</B></a>','1,114,919,783.60','1,142,792,778.19','1,091,028,645.38','991,850,000.48','796,800,000.38','697,200,000.34','751,150,000.36','723,720,000.33','888,000,000.40','790,320,000.36','883,560,000.40','927,960,000.42','737,040,000.33','879,120,000.40','914,640,000.41','927,960,000.42','1,172,160,000.53','1,416,360,000.64','1,589,520,000.72','1,552,500,000.41','1,972,500,000.53','2,520,000,000.67','2,160,000,000.58','2,475,000,000.66','2,010,000,000.54','2,250,000,000.60','2,077,500,000.55','2,332,500,000.62','3,270,000,000.87','2,347,500,000.63'); theRows[1] = new Array ('<b>'+h+'89>DEN</B></a>','55,200,000.00','55,920,000.00','45,960,000.00','42,600,000.00','35,760,000.00','39,600,000.00','40,200,000.00','47,700,000.00','50,460,000.00','45,300,000.00','41,760,000.00','59,340,000.00','66,600,000.00','97,020,000.00','81,060,000.00','69,300,000.00','79,800,000.00','68,400,000.00','66,900,000.00','66,960,000.00','71,220,000.00','71,520,000.00','71,880,000.00','60,600,000.00','69,120,000.00','62,640,000.00','57,180,000.00','89,850,000.00','125,100,000.00','85,350,000.00'); theRows[2] = new Array ('<b>'+h+'269>SIS</B></a>','4,425,000,000.00','4,695,000,000.00','4,050,000,000.00','4,367,380,000.00','4,273,120,000.00','3,644,720,000.00','4,681,580,000.00','4,913,000,000.00','6,188,000,000.00','5,457,000,000.00','6,137,000,000.00','5,453,000,000.00','6,061,000,000.00','6,954,000,000.00','6,745,000,000.00','6,519,000,000.00','7,851,500,000.00','8,548,500,000.00','9,430,000,000.00','9,225,000,000.00','10,575,000,000.00','11,610,000,000.00','9,517,500,000.00','13,140,000,000.00','12,757,500,000.00','13,117,500,000.00','11,677,500,000.00','10,507,500,000.00','11,857,500,000.00','9,315,000,000.00'); theRows[3] = new Array ('<b>'+h+'297>TRK</B></a>','1,692,579,200.00','1,983,924,800.00','1,831,315,200.00','1,704,000,000.00','1,803,400,000.00','1,498,100,000.00','1,803,400,000.00','1,884,450,000.00','2,542,160,000.00','2,180,050,000.00','2,069,200,000.00','1,682,600,000.00','1,619,950,000.00','1,852,650,000.00','2,040,600,000.00','2,315,700,000.00','2,641,200,000.00','2,938,800,000.00','3,599,100,000.00','4,101,900,000.00','5,220,600,000.00','5,808,200,000.00','4,689,500,000.00','5,375,000,000.00','3,787,500,000.00','4,150,000,000.00','3,662,500,000.00','3,712,500,000.00','4,375,000,000.00','3,587,500,000.00'); var thetable=new mytable();thetable.tableWidth=650;thetable.shownum=false;thetable.controlaccess=true;thetable.visCols=new Array(true,true,true,true,true);thetable.initsort=new Array(0,-1);thetable.inittable();thetable.refreshTable();</script> My purpose is to extract this output into a table and save it as a csv file. How can i extract this script as i want? all dates should be on top, all names should be on the far right, all values should be between the two. Hisse 2012.12 2013.3 2013.4 ... ANA 1,114,919,783.60 1,142,792,778.19 1,091,028,645.38 ... DEN 55,200,000.00 55,920,000.00 45,960,000.00 .... . . .
Solution The custom-function process_scripts() will produce what you are looking for. I am using the dummy data given below (at the end). First we check that the code does what it is expected and so we create a pandas dataframe to see the output. You could also open this Colab Jupyter Notebook and run it on Cloud for free. This will allow you to not worry about any installation or setup and simply focus on examining the solution itself. 1. Processing A Single Script ## Define CSV file-output folder-path OUTPUT_PATH = './output' ## Process scripts dfs = process_scripts(scripts = [s], output_path = OUTPUT_PATH, save_to_csv = False, verbose = 0) print(dfs[0].reset_index(drop=True)) Output: Name 2012.12 ... 2019.12 2020.03 0 ANA 1,114,919,783.60 ... 3,270,000,000.87 2,347,500,000.63 1 DEN 55,200,000.00 ... 125,100,000.00 85,350,000.00 2 SIS 4,425,000,000.00 ... 11,857,500,000.00 9,315,000,000.00 3 TRK 1,692,579,200.00 ... 4,375,000,000.00 3,587,500,000.00 [4 rows x 31 columns] 2. Processing All the Scripts You can process all your scripts using the custom-define function process_scripts(). The code is given below. ## Define CSV file-output folder-path OUTPUT_PATH = './output' ## Process scripts dfs = process_scripts(scripts, output_path = OUTPUT_PATH, save_to_csv = True, verbose = 0) ## To clear the output dir-contents #!rm -f $OUTPUT_PATH/* I did this on Google Colab and it worked as expected. 3. Making Paths in OS-agnostic Manner Making paths for windows or unix based systems could be very different. The following shows you a method to achieve that without having to worry about which OS you will run the code. I have used the os library here. However, I would suggest you to look at the Pathlib library as well. # Define relative path for output-folder OUTPUT_PATH = './output' # Dynamically define absolute path pwd = os.getcwd() # present-working-directory OUTPUT_PATH = os.path.join(pwd, os.path.abspath(OUTPUT_PATH)) 4. Code: custom function process_scripts() Here we use the regex (regular expression) library, along with pandas for organizing the data in a tabular format and then writing to csv file. The tqdm library is used to give you a nice progressbar while processing multiple scripts. Please see the comments in the code to know what to do if you are running it not from a jupyter notebook. The os library is used for path manipulation and creation of output-directory. #pip install -U pandas #pip install tqdm import pandas as pd import re # regex import os from tqdm.notebook import tqdm # Use the following line if not using a jupyter notebook # from tqdm import tqdm def process_scripts(scripts, output_path='./output', save_to_csv: bool=False, verbose: int=0): """Process all scripts and return a list of dataframes and optionally write each dataframe to a CSV file. Parameters ---------- scripts: list of scripts output_path (str): output-folder-path for csv files save_to_csv (bool): default is False verbose (int): prints output for verbose>0 Example ------- OUTPUT_PATH = './output' dfs = process_scripts(scripts, output_path = OUTPUT_PATH, save_to_csv = True, verbose = 0) ## To clear the output dir-contents #!rm -f $OUTPUT_PATH/* """ ## Define regex patterns and compile for speed pat_header = re.compile(r"theCols\[\d+\] = new Array\s*\([\'](\d{4}\.\d{1,2})[\'],\d+,\d+\)") pat_line = re.compile(r"theRows\[\d+\] = new Array\s*\((.*)\).*") pat_code = re.compile("([A-Z]{3})") # Calculate zfill-digits zfill_digits = len(str(len(scripts))) print(f'Total scripts: {len(scripts)}') # Create output_path if not os.path.exists(output_path): os.makedirs(output_path) # Define a list of dataframes: # An accumulator of all scripts dfs = [] ## If you do not have tqdm installed, uncomment the # next line and comment out the following line. #for script_num, script in enumerate(scripts): for script_num, script in enumerate(tqdm(scripts, desc='Scripts Processed')): ## Extract: Headers, Rows # Rows : code (Name: single column), line-data (multi-column) headers = script.strip().split('\n', 0)[0] headers = ['Name'] + re.findall(pat_header, headers) lines = re.findall(pat_line, script) codes = [re.findall(pat_code, line)[0] for line in lines] # Clean data for each row lines_data = dict() for line, code in zip(lines, codes): line_data = line.replace("','", "|").split('|') line_data[-1] = line_data[-1].replace("'", "") line_data[0] = code lines_data.update({code: line_data.copy()}) if verbose>0: print('{}: {}'.format(script_num, codes)) ## Load data into a pandas-dataframe # and write to csv. df = pd.DataFrame(lines_data).T df.columns = headers dfs.append(df.copy()) # update list # Write to CSV if save_to_csv: num_label = str(script_num).zfill(zfill_digits) script_file_csv = f'Script_{num_label}.csv' script_path = os.path.join(output_path, script_file_csv) df.to_csv(script_path, index=False) return dfs 5. Dummy Data ## Dummy Data s = """ <script language="JavaScript"> var theHlp='/yardim/matris.asp';var theTitle = 'Piyasa Değeri';var theCaption='Cam (TL)';var lastmod = '';var h='<a class=hisselink href=../Hisse/HisseAnaliz.aspx?HNO=';var e='<a class=hisselink href=../endeks/endeksAnaliz.aspx?HNO=';var d='<center><font face=symbol size=1 color=#FF0000><b>ß</b></font></center>';var u='<center><font face=symbol size=1 color=#008000><b>İ</b></font></center>';var n='<center><font face=symbol size=1 color=#00A000><b>=</b></font></center>';var fr='<font color=#FF0000>';var fg='<font color=#008000>';var theFooter=new Array();var theCols = new Array();theCols[0] = new Array('Hisse',4,50);theCols[1] = new Array('2012.12',1,60);theCols[2] = new Array('2013.03',1,60);theCols[3] = new Array('2013.06',1,60);theCols[4] = new Array('2013.09',1,60);theCols[5] = new Array('2013.12',1,60);theCols[6] = new Array('2014.03',1,60);theCols[7] = new Array('2014.06',1,60);theCols[8] = new Array('2014.09',1,60);theCols[9] = new Array('2014.12',1,60);theCols[10] = new Array('2015.03',1,60);theCols[11] = new Array('2015.06',1,60);theCols[12] = new Array('2015.09',1,60);theCols[13] = new Array('2015.12',1,60);theCols[14] = new Array('2016.03',1,60);theCols[15] = new Array('2016.06',1,60);theCols[16] = new Array('2016.09',1,60);theCols[17] = new Array('2016.12',1,60);theCols[18] = new Array('2017.03',1,60);theCols[19] = new Array('2017.06',1,60);theCols[20] = new Array('2017.09',1,60);theCols[21] = new Array('2017.12',1,60);theCols[22] = new Array('2018.03',1,60);theCols[23] = new Array('2018.06',1,60);theCols[24] = new Array('2018.09',1,60);theCols[25] = new Array('2018.12',1,60);theCols[26] = new Array('2019.03',1,60);theCols[27] = new Array('2019.06',1,60);theCols[28] = new Array('2019.09',1,60);theCols[29] = new Array('2019.12',1,60);theCols[30] = new Array('2020.03',1,60);var theRows = new Array(); theRows[0] = new Array ('<b>'+h+'30>ANA</B></a>','1,114,919,783.60','1,142,792,778.19','1,091,028,645.38','991,850,000.48','796,800,000.38','697,200,000.34','751,150,000.36','723,720,000.33','888,000,000.40','790,320,000.36','883,560,000.40','927,960,000.42','737,040,000.33','879,120,000.40','914,640,000.41','927,960,000.42','1,172,160,000.53','1,416,360,000.64','1,589,520,000.72','1,552,500,000.41','1,972,500,000.53','2,520,000,000.67','2,160,000,000.58','2,475,000,000.66','2,010,000,000.54','2,250,000,000.60','2,077,500,000.55','2,332,500,000.62','3,270,000,000.87','2,347,500,000.63'); theRows[1] = new Array ('<b>'+h+'89>DEN</B></a>','55,200,000.00','55,920,000.00','45,960,000.00','42,600,000.00','35,760,000.00','39,600,000.00','40,200,000.00','47,700,000.00','50,460,000.00','45,300,000.00','41,760,000.00','59,340,000.00','66,600,000.00','97,020,000.00','81,060,000.00','69,300,000.00','79,800,000.00','68,400,000.00','66,900,000.00','66,960,000.00','71,220,000.00','71,520,000.00','71,880,000.00','60,600,000.00','69,120,000.00','62,640,000.00','57,180,000.00','89,850,000.00','125,100,000.00','85,350,000.00'); theRows[2] = new Array ('<b>'+h+'269>SIS</B></a>','4,425,000,000.00','4,695,000,000.00','4,050,000,000.00','4,367,380,000.00','4,273,120,000.00','3,644,720,000.00','4,681,580,000.00','4,913,000,000.00','6,188,000,000.00','5,457,000,000.00','6,137,000,000.00','5,453,000,000.00','6,061,000,000.00','6,954,000,000.00','6,745,000,000.00','6,519,000,000.00','7,851,500,000.00','8,548,500,000.00','9,430,000,000.00','9,225,000,000.00','10,575,000,000.00','11,610,000,000.00','9,517,500,000.00','13,140,000,000.00','12,757,500,000.00','13,117,500,000.00','11,677,500,000.00','10,507,500,000.00','11,857,500,000.00','9,315,000,000.00'); theRows[3] = new Array ('<b>'+h+'297>TRK</B></a>','1,692,579,200.00','1,983,924,800.00','1,831,315,200.00','1,704,000,000.00','1,803,400,000.00','1,498,100,000.00','1,803,400,000.00','1,884,450,000.00','2,542,160,000.00','2,180,050,000.00','2,069,200,000.00','1,682,600,000.00','1,619,950,000.00','1,852,650,000.00','2,040,600,000.00','2,315,700,000.00','2,641,200,000.00','2,938,800,000.00','3,599,100,000.00','4,101,900,000.00','5,220,600,000.00','5,808,200,000.00','4,689,500,000.00','5,375,000,000.00','3,787,500,000.00','4,150,000,000.00','3,662,500,000.00','3,712,500,000.00','4,375,000,000.00','3,587,500,000.00'); var thetable=new mytable();thetable.tableWidth=650;thetable.shownum=false;thetable.controlaccess=true;thetable.visCols=new Array(true,true,true,true,true);thetable.initsort=new Array(0,-1);thetable.inittable();thetable.refreshTable();</script> """ ## Make a dummy list of scripts scripts = [s for _ in range(10)]
According to the provided <script> in your question, you can do something like code below to have a list of Dates for each name ANA, DEN ..: for _ in range(1, len(aaa.split("<b>'"))-1): s = aaa.split("<b>'")[_].split("'") print(_) lst = [] for i in s: if "</B>" in i: name = i.split('>')[1].split("<")[0] print("{} = ".format(name), end="") if any(j.isdigit() for j in i) and ',' in i: lst.append(i) print(lst) It's just an example code, so it's not that beautiful :) Hope this will help you.
Memory scanner for any program in Python
I am trying to create a memory scanner. similar to Cheat Engine. but only for extract information. I know how to get the pid (in this case is "notepad.exe"). But I don't have any Idea about how to know wicht especific adress belong to the program that I am scanning. Trying to looking for examples. I could see someone it was trying to scan every adress since one point to other. But it's to slow. Then I try to create a batch size (scan a part of memory and not one by one each adress). The problem is if the size is to short. still will take a long time. and if it is to long, is possible to lose many adress who are belong to the program. Because result from ReadMemoryScan is False in the first Adress, but It can be the next one is true. Here is my example. import ctypes as c from ctypes import wintypes as w import psutil from sys import stdout write = stdout.write import numpy as np def get_client_pid(process_name): pid = None for proc in psutil.process_iter(): if proc.name() == process_name: pid = int(proc.pid) print(f"Found '{process_name}' PID = ", pid,f" hex_value = {hex(pid)}") break if pid == None: print('Program Not found') return pid pid = get_client_pid("notepad.exe") if pid == None: sys.exit() k32 = c.WinDLL('kernel32', use_last_error=True) OpenProcess = k32.OpenProcess OpenProcess.argtypes = [w.DWORD,w.BOOL,w.DWORD] OpenProcess.restype = w.HANDLE ReadProcessMemory = k32.ReadProcessMemory ReadProcessMemory.argtypes = [w.HANDLE,w.LPCVOID,w.LPVOID,c.c_size_t,c.POINTER(c.c_size_t)] ReadProcessMemory.restype = w.BOOL GetLastError = k32.GetLastError GetLastError.argtypes = None GetLastError.restype = w.DWORD CloseHandle = k32.CloseHandle CloseHandle.argtypes = [w.HANDLE] CloseHandle.restype = w.BOOL processHandle = OpenProcess(0x10, False, int(pid)) # addr = 0x0FFFFFFFFFFF data = c.c_ulonglong() bytesRead = c.c_ulonglong() start = 0x000000000000 end = 0x7fffffffffff batch_size = 2**13 MemoryData = np.zeros(batch_size, 'l') Size = MemoryData.itemsize*MemoryData.size index = 0 Data_address = [] for c_adress in range(start,end,batch_size): result = ReadProcessMemory(processHandle,c.c_void_p(c_adress), MemoryData.ctypes.data, Size, c.byref(bytesRead)) if result: # Save adress Data_address.extend(list(range(c_adress,c_adress+batch_size))) e = GetLastError() CloseHandle(processHandle) I decided from 0x000000000000 to 0x7fffffffffff Because cheat engine scan this size. I am still a begginer with this kind of this about memory scan. maybe there are things that I can do to improve the efficiency.
I suggest you take advantage of existing python libraries that can analyse Windows 10 memory. I'm no specialist but I've found Volatility. Seems to be pretty useful for your problem. For running that tool you need Python 2 (Python 3 won't work). For running python 2 and 3 in the same Windows 10 machine, follow this tutorial (The screenshots are in Spanish but it can easily be followed). Then see this cheat sheet with main commands. You can dump the memory and then operate on the file. Perhaps this leads you to the solution :) At least the most basic command pslist dumps all the running processes addresses.
psutil has proc.memory_maps() pass the result as map to this function TargetProcess eaxample 'Calculator.exe' def get_memSize(self,TargetProcess,map): for m in map: if TargetProcess in m.path: memSize= m.rss break return memSize if you use this function, it returns the memory size of your Target Process my_pid is the pid for 'Calculator.exe' def getBaseAddressWmi(self,my_pid): PROCESS_ALL_ACCESS = 0x1F0FFF processHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, my_pid) modules = win32process.EnumProcessModules(processHandle) processHandle.close() base_addr = modules[0] # for me it worked to select the first item in list... return base_addr to get the base address of your prog so you search range is from base_addr to base_addr + memSize
How do you delete a virtual disk with pyvmomi
I am trying to write a Python program using the pyvmomi library to "erase" a virtual hard drive associated with a VM. The way this is done manually is to remove the virtual disk and create a new virtual disk with the same specs. I am expecting that I will need to do the same thing with pyvmomi so I have started down that path. My issue is that I can use ReconfigVM_Task to remove the virtual drive but that leaves the VMDK file itself. I originally tried using DeleteVStorageObject_Task (since DeleteVirtualDisk_Task is deprecated) to remove the virtual disk file but that requires the ID of the object (the VMDK file) which I am unable to find anywhere. Theoretically that's available from the VirtualDisk property vDiskId but that is null. In further research it seems to only be populated for first class disks. So I am instead trying to delete the VMDK file directly using DeleteDatastoreFile_Task but when I do that I end up with a XXXX-flat.vmdk file in the datastore so it seems to not actually delete the file. Any idea on where I'm going wrong here or how to better do this? The VMWare SDK documentation for pyvmomi is...lacking. Thanks!
You'll have to perform a ReconfigVM_Task operation. The keypoint for this is that the file operation should be destroy. Here's the raw output from performing the operation in the UI: spec = vim.vm.ConfigSpec() spec_deviceChange_0 = vim.vm.device.VirtualDeviceSpec() spec_deviceChange_0.fileOperation = 'destroy' spec_deviceChange_0.device = vim.vm.device.VirtualDisk() spec_deviceChange_0.device.shares = vim.SharesInfo() spec_deviceChange_0.device.shares.shares = 1000 spec_deviceChange_0.device.shares.level = 'normal' spec_deviceChange_0.device.capacityInBytes = 8589934592 spec_deviceChange_0.device.storageIOAllocation = vim.StorageResourceManager.IOAllocationInfo() spec_deviceChange_0.device.storageIOAllocation.shares = vim.SharesInfo() spec_deviceChange_0.device.storageIOAllocation.shares.shares = 1000 spec_deviceChange_0.device.storageIOAllocation.shares.level = 'normal' spec_deviceChange_0.device.storageIOAllocation.limit = -1 spec_deviceChange_0.device.storageIOAllocation.reservation = 0 spec_deviceChange_0.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo() spec_deviceChange_0.device.backing.backingObjectId = '' spec_deviceChange_0.device.backing.fileName = '[kruddy_2TB_01] web01/web01_2.vmdk' spec_deviceChange_0.device.backing.split = False spec_deviceChange_0.device.backing.writeThrough = False spec_deviceChange_0.device.backing.datastore = search_index.FindByUuid(None, "datastore-14", True, True) spec_deviceChange_0.device.backing.eagerlyScrub = True spec_deviceChange_0.device.backing.contentId = 'e26f44020e7897006bec81b1fffffffe' spec_deviceChange_0.device.backing.thinProvisioned = False spec_deviceChange_0.device.backing.diskMode = 'persistent' spec_deviceChange_0.device.backing.digestEnabled = False spec_deviceChange_0.device.backing.sharing = 'sharingNone' spec_deviceChange_0.device.backing.uuid = '6000C292-7895-54ee-a55c-49d0036ef1bb' spec_deviceChange_0.device.controllerKey = 200 spec_deviceChange_0.device.unitNumber = 0 spec_deviceChange_0.device.nativeUnmanagedLinkedClone = False spec_deviceChange_0.device.capacityInKB = 8388608 spec_deviceChange_0.device.deviceInfo = vim.Description() spec_deviceChange_0.device.deviceInfo.summary = '8,388,608 KB' spec_deviceChange_0.device.deviceInfo.label = 'Hard disk 2' spec_deviceChange_0.device.diskObjectId = '148-3000' spec_deviceChange_0.device.key = 3000 spec_deviceChange_0.operation = 'remove' spec.deviceChange = [spec_deviceChange_0] spec.cpuFeatureMask = [] managedObject.ReconfigVM_Task(spec)
Kyle Ruddy got me pointed in the right direction. Here's a code snippit showing how I made it work for future people searching for information on how to do this: #Assuming dev is already set to the vim.vm.device.VirtualDisk you want to delete... virtual_hdd_spec = vim.vm.device.VirtualDeviceSpec() virtual_hdd_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy virtual_hdd_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove virtual_hdd_spec.device = dev spec = vim.vm.ConfigSpec() spec.deviceChange = [virtual_hdd_spec] WaitForTask(vm.ReconfigVM_Task(spec=spec)) The API documentation for this is at https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.device.VirtualDeviceSpec.html
config parser not returning correct variable - leaves out ( ) around words
I have a script that takes some data in an excel file and sorts it and adds some colors to some key things.... I'm using an external .ini file because it needs to change sometimes based on the users needs for the day the ini file basically looks like this [section] #Color 1 color01 = ('00FCC84E') cat1 = ('Item1','Item2') #Color 2 color02 = ('00F4426E') cat2 = ('Thingy Size 5/16') My Script portion that uses Config Parser does this import configparser from configparser import ConfigParser from ast import literal_eval config = ConfigParser() config.read("MyFile.ini") config.sections() def variables(section): dict1 = {} options = config.options(section) for option in options: try: dict1[option] = config.get(section, option) if dict1[option] == -1: DebugPrint("skip: %s" % option) except: print("exception on %s!" % option) dict1[option] = None return dict1 color01V = literal_eval(config['ConfigFile']['color01']) color02V = literal_eval(config['ConfigFile']['color02']) cat01V = literal_eval(config['ConfigFile']['cat1']) cat02V = literal_eval(config['ConfigFile']['cat2']) print(cat01V) print(cat02V) this returns ('Item1','Item2') Thingy Size 5/16 Why does the 2nd string return without the () and how do I fix it. I actually NEED the () to appear when I use the variable later
Have you tried putting value of "cat1" in quotations? [section] color01 = ('00FCC84E') cat1 = "('Item1','Item2')" ... cat2 = "('Thingy Size 5/16')"
multipath iSCSI cleanup code
I know only the very basics of python. I have this project for my INFORMATION STORAGE AND MANAGEMENT subject. I have to give an explanation the following code. I searched every command used in this script but could not find most of them. The code can be found here: import glob import json import os import re import string import sys from oslo.config import cfg from nova import context from nova.db.sqlalchemy import api as db_api from nova.db.sqlalchemy import models from nova import utils CONF = cfg.CONF def usage(): print(""" Usage: python %s --config-file /etc/nova/nova.conf Note: This script intends to clean up the iSCSI multipath faulty devices hosted by VNX Block Storage.""" % sys.argv[0]) class FaultyDevicesCleaner(object): def __init__(self): # Get host name of Nova computer node. self.host_name = self._get_host_name() def _get_host_name(self): (out, err) = utils.execute('hostname') return out def _get_ncpu_emc_target_info_list(self): target_info_list = [] # Find the targets used by VM on the compute node bdms = db_api.model_query(context.get_admin_context(), models.BlockDeviceMapping, session = db_api.get_session()) bdms = bdms.filter(models.BlockDeviceMapping.connection_info != None) bdms = bdms.join(models.BlockDeviceMapping.instance).filter_by( host=string.strip(self.host_name)) for bdm in bdms: conn_info = json.loads(bdm.connection_info) if 'data' in conn_info: if 'target_iqns' in conn_info['data']: target_iqns = conn_info['data']['target_iqns'] target_luns = conn_info['data']['target_luns'] elif 'target_iqn' in conn_info['data']: target_iqns = [conn_info['data']['target_iqn']] target_luns = [conn_info['data']['target_lun']] else: target_iqns = [] target_luns = [] for target_iqn, target_lun in zip(target_iqns, target_luns): if 'com.emc' in target_iqn: target_info = { 'target_iqn': target_iqn, 'target_lun': target_lun, } target_info_list.append(target_info) return target_info_list def _get_ncpu_emc_target_info_set(self): target_info_set = set() for target_info in self._get_ncpu_emc_target_info_list(): target_iqn = target_info['target_iqn'] target_lun = target_info['target_lun'] target_info_key = "%s-%s" % (target_iqn.rsplit('.', 1)[0], target_lun) # target_iqn=iqn.1992-04.com.emc:cx.fnm00130200235.a7 # target_lun=203 # target_info_key=iqn.1992-04.com.emc:cx.fnm00130200235-203 target_info_set.add(target_info_key) return target_info_set def _get_target_info_key(self, path): temp_tuple = path.split('-lun-', 1) target_lun = temp_tuple[1] target_iqn = temp_tuple[0].split('-iscsi-')[1] target_info_key = "%s-%s" % (target_iqn.rsplit('.', 1)[0], target_lun) # path=/dev/disk/by-path/ip-192.168.3.52:3260-iscsi-iqn.1992- # 04.com.emc:cx.fnm00130200235.a7-lun-203 # target_info_key=iqn.1992-04.com.emc:cx.fnm00130200235-203 return target_info_key def _get_non_ncpu_target_info_map(self): # Group the paths by target_info_key ncpu_target_info_set = self._get_ncpu_emc_target_info_set() device_paths = self._get_emc_device_paths() target_info_map = {} for path in device_paths: target_info_key = self._get_target_info_key(path) if target_info_key in ncpu_target_info_set: continue if target_info_key not in target_info_map: target_info_map[target_info_key] = [] target_info_map[target_info_key].append(path) return target_info_map def _all_related_paths_faulty(self, paths): for path in paths: real_path = os.path.realpath(path) out, err = self._run_multipath(['-ll', real_path], run_as_root=True, check_exit_code=False) if 'active ready' in out: # At least one path is still working return False return True def _delete_all_related_paths(self, paths): for path in paths: real_path = os.path.realpath(path) device_name = os.path.basename(real_path) device_delete = '/sys/block/%s/device/delete' % device_name if os.path.exists(device_delete): # Copy '1' from stdin to the device delete control file utils.execute('cp', '/dev/stdin', device_delete, process_input='1', run_as_root=True) else: print "Unable to delete %s" % real_path def _cleanup_faulty_paths(self): non_ncpu_target_info_map = self._get_non_ncpu_target_info_map() for paths in non_ncpu_target_info_map.itervalues(): if self._all_related_paths_faulty(paths): self._delete_all_related_paths(paths) def _cleanup_faulty_dm_devices(self): out_ll, err_ll = self._run_multipath(['-ll'], run_as_root=True, check_exit_code=False) # Pattern to split the dm device contents as follows # Each section starts with a WWN and ends with a line with # " `-" as the prefix # # 3600601601bd032007c097518e96ae411 dm-2 , # size=1.0G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw # `-+- policy='round-robin 0' prio=0 status=active # `- #:#:#:# - #:# active faulty running # 36006016020d03200bb93e048f733e411 dm-0 DGC,VRAID # size=1.0G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw # |-+- policy='round-robin 0' prio=130 status=active # | |- 3:0:0:2 sdd 8:48 active ready running # | `- 5:0:0:2 sdj 8:144 active ready running # `-+- policy='round-robin 0' prio=10 status=enabled # |- 4:0:0:2 sdg 8:96 active ready running # `- 6:0:0:2 sdm 8:192 active ready running dm_pat = r'([0-9a-fA-F]{30,})[^\n]+,[^\n]*\n[^,]* `-[^\n]*' dm_m = re.compile(dm_pat) path_pat = r'- \d+:\d+:\d+:\d+ ' path_m = re.compile(path_pat) for m in dm_m.finditer(out_ll): if not path_m.search(m.group(0)): # Only #:#:#:# remain in the output, all the paths of the dm # device should have been deleted. No need to keep the device out_f, err_f = self._run_multipath(['-f', m.group(1)], run_as_root=True, check_exit_code=False) def cleanup(self): self._cleanup_faulty_paths() # Make sure the following configuration is in /etc/multipath.conf # Otherwise, there may be "map in use" failure when deleting # dm device # # defaults { # flush_on_last_del yes # } # self._cleanup_faulty_dm_devices() def _get_emc_device_paths(self): # Find all the EMC iSCSI devices under /dev/disk/by-path # except LUNZ and partition reference pattern = '/dev/disk/by-path/ip-*-iscsi-iqn*com.emc*-lun-*' device_paths = [path for path in glob.glob(pattern) if ('lun-0' not in path and '-part' not in path)] return device_paths def _run_multipath(self, multipath_command, **kwargs): check_exit_code = kwargs.pop('check_exit_code', 0) (out, err) = utils.execute('multipath', *multipath_command, run_as_root=True, check_exit_code=check_exit_code) print ("multipath %(command)s: stdout=%(out)s stderr=%(err)s" % {'command': multipath_command, 'out': out, 'err': err}) return out, err if __name__ == "__main__": if len(sys.argv) != 3 or sys.argv[1] != '--config-file': usage() exit(1) out, err = utils.execute('which', 'multipath', check_exit_code=False) if 'multipath' not in out: print('Info: Multipath tools not installed. No cleanup need be done.') exit(0) multipath_flush_on_last_del = False multipath_conf_path = "/etc/multipath.conf" if os.path.exists(multipath_conf_path): flush_on_last_del_yes = re.compile(r'\s*flush_on_last_del.*yes') for line in open(multipath_conf_path, "r"): if flush_on_last_del_yes.match(line): multipath_flush_on_last_del = True break if not multipath_flush_on_last_del: print("Warning: 'flush_on_last_del yes' is not seen in" " /etc/multipath.conf." " 'map in use' failure may show up during cleanup.") CONF(sys.argv[1:]) # connect_volume and disconnect_volume in nova/virt/libvirt/volume.py # need be adjusted to take the same 'external=True' lock for # synchronization #utils.synchronized('connect_volume', external=True) def do_cleanup(): cleaner = FaultyDevicesCleaner() cleaner.cleanup() do_cleanup()
https://wiki.python.org/moin/BeginnersGuide/Programmers http://www.astro.ufl.edu/~warner/prog/python.html looks like this python version 3 so. go for the tutorials of version three. try downloading any IDE. eric5 is good by the way. try executing this file once. learn indentations and dynamic variable declaration do not jump into the ocean first try swimming pool : )
Also Try to learn method declaration. Python is a bit different than java. I will give you a hint looks like system call are also made to execute os commands so try looking at subprocess and how its output is directed to an output stream and error stream.