How to write lists as a file attribute using PyGTK - python

A comment by the Linux Mint founder stated that file emblems in newer versions of Nemo can be programatically accessed, as seen in the following example using Python and PyGTK:
import gio
file = gio.File("/home/guest/Documents/Todo")
emblems = file.query_info("metadata::emblems")
print emblems.get_attribute_as_string("metadata::emblems")
Which outputs something in the format
[emblem-important, emblem-urgent]
The object stored as metadata::emblems, as you can see, is a list (I guess of strings). However, in the PyGTK documentation on Gio.FileInfo, I can't find a method to access (read or write) attributes of array types.
Is there any method to do this (i.e. reading single emblems or setting new emblems programatically)? If yes, how can I accomplish this?

It's strange that there's no convenience method to do this, but you can call File.set_attribute directly, using STRINGV as the type.
f.set_attribute('metadata::emblems', gio.FILE_ATTRIBUTE_TYPE_STRINGV, ['emblem-important', 'emblem-urgent'])

Related

Saving NLTK Alignments

I am using NLTK 3.2 and I was wondering how you save NLTK alignments. I have found this link: How to save Python NLTK alignment models for later use?, but it seems that there is no align() method. Also, I figured out that nltk.align has been renamed to nltk.translate, but I still cannot access the align() method. Thanks!
Yeah, you are right. The method align became private in the current version. So, if you want to use that method, you have to modify the source code.
To modify the source code, you have to get to the directory of the file. You can find that directory by:
Open your terminal
Type these commands:
>>> python
>>> import nltk
>>> nltk.translate.ibm1.__file__
Here is a screen-shot of what it should look like:
Now, you have to go to that directory and find the file 'ibm1.py'. Open the file and modify the method __align to align.
It's the last method in the file.
CAUTION:
The align method returns Alignment class instead of AlignedSent in earlier versions.

How to set win32clipboard data on CF_HDROP format?

I am confronted to the loss of alpha channel when I try to send image to clipboard, none of the solutions described here worked with the software I am working with but when I copy paste png files into this software, the alpha channel seems to be preserved.
Under this consideration, I want to simulate the Ctrl+C on files allowed by Windows Explorer. Using Clipview I found that the field 15 : CF_HDROP is relevant to my goal. tried to set this field using win32clipboard
import win32clipboard
win32clipboard.OpenClipboard(0)
file1="C:\\Users\\User\\Desktop\\test.png"
win32clipboard.SetClipboardData(15, file1)
win32clipboard.CloseClipboard()
I don't get any error doing this, but it does not work when I try to use this new clipboard content, because as described there tuple of unicode filenames must be stored in the CF_HDROP field.
I have no clue how to proceed. I also tried with
file1= (unicode('C:\\Users\\User\\Desktop\\CANEVAS\\test.png'),)
but I got this error:
TypeError: expected a readable buffer object.
The documentation for CF_HDROP says
The data consists of an STGMEDIUM structure that contains a global memory object. The structure's hGlobal member points to a DROPFILES structure as its hGlobal member.
win32clipboard.GetClipboardData has built-in support for CF_HDROP. It decodes the STGMEDIUM and DROPFILES structures to produce a tuple of file names.
The documentation does not state that SetClipboardData has the corresponding code to construct the STGMEDIUM and DROPFILES structures from a tuple of file names.
I don't know enough about Python or its FFI to know how straightforward it is to construct the structures and pass them to the SetClipboardData function. Or if there is an existing library that will do this for you.

copy netcdf file using python

I would like to make a copy of netcdf file using Python.
There are very nice examples of how to read or write netcdf-file, but perhaps there is also a good way how to make the input and then output of the variables to another file.
A good-simple method would be nice, in order to get the dimensions and dimension variables to the output file with the lowest cost.
I found the answer to this question at python netcdf: making a copy of all variables and attributes but one, but I needed to change it to work with my version of python/netCDF4 (Python 2.7.6/1.0.4). If you needed to add or subtract elements, you would make the appropriate modifications.
import netCDF4 as nc
def create_file_from_source(src_file, trg_file):
src = nc.Dataset(src_file)
trg = nc.Dataset(trg_file, mode='w')
# Create the dimensions of the file
for name, dim in src.dimensions.items():
trg.createDimension(name, len(dim) if not dim.isunlimited() else None)
# Copy the global attributes
trg.setncatts({a:src.getncattr(a) for a in src.ncattrs()})
# Create the variables in the file
for name, var in src.variables.items():
trg.createVariable(name, var.dtype, var.dimensions)
# Copy the variable attributes
trg.variables[name].setncatts({a:var.getncattr(a) for a in var.ncattrs()})
# Copy the variables values (as 'f4' eventually)
trg.variables[name][:] = src.variables[name][:]
# Save the file
trg.close()
create_file_from_source('in.nc', 'out.nc')
This snippet has been tested.
If you want to only use the netCDF-4 API to copy any netCDF-4 file, even those with variables that use arbitrary user-defined types, that's a difficult problem. The netCDF4 module at netcdf4-python.googlecode.com currently lacks support for compound types that have variable-length members or variable-length types of a compound base type, for example.
The nccopy utility that is available with the netCDF-4 C distribution shows it is possible to copy an arbitrary netCDF-4 file using only the C netCDF-4 API, but that's because the C API fully supports the netCDF-4 data model. If you limit your goal to copying netCDF-4 files that only use flat types supported by the googlecode module, the algorithm used in nccopy.c should work fine and should be well-suited to a more elegant implementation in Python.
A less ambitious project that would be even easier is a Python program that would copy any netCDF "classic format" file, because the classic model supported by netCDF-3 has no user-defined types or recursive types. This program would even work for netCDF-4 classic model files that also use performance features such as compression and chunking.
Since I discovered xarray, this has been my go-to tool for everything python+netCDF related
You can easily copy a netcdf file, for example:
import xarray as xr
input = xr.open_dataset('ncfile.nc')
input.to_netcdf('copy_of_ncfile.nc')
If you are on Linux or macOS, this can be achived easily with nctoolkit (https://nctoolkit.readthedocs.io/en/latest/installing.html).
import nctoolkit as nc
data = nc.open_data("infile.nc")
data.to_nc("outfile.nc")
see How do I copy a file in python?: a netcdf file is not different from any other file so it should fit your needs

Storing a file in the clipboard in python

Is there a way to use the win32clipboard module to store a reference to a file in the windows clipboard in python. My goal is to paste an image in a way that allows transparency. If I drag and drop a 'png' file into OneNote or I copy the file and then paste it into OneNote, this seems to preserve transparency. As far as I can tell, the clipboard can't store transparent images which is why it has to be a reference to a file.
My research suggests that it might involve the win32clipboard.CF_HDrop attribute but I'm not sure.
So, just to summarize, my goal is to have a bit of python code which I can click and which uses a specific file on my Desktop named 'img.png' for instance. The result is that 'img.png' gets stored in the clipboard and can be pasted into other programs. Essentially, the same behavior as if I selected the file on the Desktop myself, right-clicked and selected 'Copy'.
EDIT:
This page seems to suggest there is a way using win32clipboard.CF_HDrop somehow:
http://timgolden.me.uk/pywin32-docs/win32clipboard__GetClipboardData_meth.html
It says "CF_HDROP" is associated with "a tuple of Unicode filenames"
from PythonMagick import Image
Image("img.png").write("clipboard:")
Grab the windows binaries for PythonMagick
I write this as an answer, although it's just a step that might help you, because comments don't have a lot of formatting options.
I wrote this sample script:
import win32clipboard as clp, win32api
clp.OpenClipboard(None)
rc= clp.EnumClipboardFormats(0)
while rc:
try: format_name= clp.GetClipboardFormatName(rc)
except win32api.error: format_name= "?"
print "format", rc, format_name
rc= clp.EnumClipboardFormats(rc)
clp.CloseClipboard()
Then I selected an image file in explorer and copied it; then, the script reports the following available clipboard formats:
format 49161 DataObject
format 49268 Shell IDList Array
format 15 ?
format 49519 DataObjectAttributes
format 49292 Preferred DropEffect
format 49329 Shell Object Offsets
format 49158 FileName
format 49159 FileNameW
format 49171 Ole Private Data
This “Preferred DropEffect” seems suspicious, although I'm far from a Windows expert. I would try first with FileNameW, though, since this might do the job for you (I don't have OneNote installed, sorry). It seems it expects as data only the full pathname encoded as 'utf-16-le' with a null character (i.e encoded as '\0\0') at the end.

python: edit ISO file directly

Is it possible to take an ISO file and edit a file in it directly, i.e. not by unpacking it, changing the file, and repacking it?
It is possible to do 1. from Python? How would I do it?
You can use for listing and extracting, I tested the first.
https://github.com/barneygale/iso9660/blob/master/iso9660.py
import iso9660
cd = iso9660.ISO9660("/Users/murat/Downloads/VisualStudio6Enterprise.ISO")
for path in cd.tree():
print path
https://github.com/barneygale/isoparser
import isoparser
iso = isoparser.parse("http://www.microsoft.com/linux.iso")
print iso.record("boot", "grub").children
print iso.record("boot", "grub", "grub.cfg").content
Have you seen Hachoir, a Python library to "view and edit a binary stream field by field"? I haven't had a need to try it myself, but ISO 9660 is listed as a supported parser format.
PyCdlib can read and edit ISO-9660 files, as well as Joliet, Rock Ridge, UDF, and El Torito extensions. It has a bunch of detailed examples in its documentation, including one showing how to edit a file in-place. At the time of writing, it cannot add or remove files, or edit directories. However, it is still actively maintained, in contrast to the libraries linked in older answers.
Of course, as with any file.
It can be done with open/read/write/seek/tell/close operations on a file. Pack/unpack the data with struct/ctypes. It would require serious knowledge of the contents of ISO, but I presume you already know what to do. If you're lucky you can try using mmap - the interface to file contents string-like.

Categories

Resources