how to open multiple files in default program with python - python

We have the function os.startfile() where I can pass the path to file so it would be opened in the default program if any one declared.
Now I need to open multiple files at once , using a simple for loop would open each one in a new instance or would close the previous files .
So is there a functions to which I can pass a list of paths to be opened at once?
For declaration : I need to emulate clicking on a file then pressing control then clicking on other file and finally pressing enter or using the open "open with" in file explorer.
edit: here is a photo of what i need to emulate from file explorer
edit: trying a simple for loop like this
import os
my_list = [ "D:\Music\Videoder\Abyusif I أبيوسف\ِAbyusif - Kol 7aga Bteb2a Gham2a l أبيوسف - كل حاجة بتبقى غامقة.mp3",
"D:\Music\Videoder\Abyusif I أبيوسف\Abyusif- 3ala maydoub eltalg (Prod by NGM) l أبيوسف- على ما يدوب التلج.mp3"]
for song in my_list:
os.startfile(song)
this would open the last element in the list , as after opening each file the previous is closed

If I understood your question correctly, you could use a simple for loop.
Code:
import os
file_paths = ["<file path here>", "<file path here>"]
for file in file_paths:
os.startfile(file)

Well, if you only want to execute music files, a quick and dirty way can be achieved like so:
import os
import time
from win32com.client import Dispatch
my_song_list = [
r'path\to\my\awesome\music\1.mp3',
r'path\to\my\awesome\music\2.mp3',
r'path\to\my\awesome\music\3.mp3'
]
wmp = Dispatch('WMPlayer.OCX')
for i, path in enumerate(my_song_list):
song = wmp.newMedia(path)
os.startfile(path)
if i < len(my_song_list) - 1:
time.sleep(song.duration)
Using the Windows Media Player to get the song's duration, then, running the audio file (openig with default player), and waiting exactly the duration to run the next.

Related

shutil.move() not working after reading object with pywin32

I've got a script that is intended to sort my photo/video collection (Windows). The photos work fine as they are sortable by EXIF which is easily accessed.
Videos are harder because I have to get the file's "Media Creation Date" which is readable by only pywin32, to my understanding. However, once I've accessed the media creation date, shutil.move() does not work. It throws no error, it just runs indefinitely without progress until I manually kill the script:
Here's the snippet in question:
from datetime import datetime
import exifread
import os
from pathlib import Path
import shutil
from win32com.propsys import propsys, pscon
# get the file list, do stuff with photos, etc
# f is the file
# cr is the path root to which it will be moved
elif str(f).lower().endswith(("mp4", "mov")):
props = propsys.SHGetPropertyStoreFromParsingName(f)
dt = props.GetValue(pscon.PKEY_Media_DateEncoded).GetValue()
year, month = str(dt.year), str(dt.month).zfill(2)
new_fn = dt.strftime("%Y-%m-%d_%H%M%S")
new_fn = f"{new_fn}{os.path.splitext(f)[1]}"
move_path = os.path.join(cr, year, month, new_fn)
print(f"SRC: {f}")
print(f"DESTINATION: {move_path}")
print("----------------------------------")
shutil.move(f, move_path)
It prints the source correctly, and the destination correctly, but does not move the file. I have also tried os.rename() and os.replace() with the same result, which suggests that perhaps the propsys method still has a lock on the file? How do I free up this file for moving?
Yes, propsys is blocking the file (you can check in Process Explorer), try just deleting it:
fpath = r'c:\temp\user\t\test.mp4'
move_path = r'c:\temp\user\t\test moved.mp4'
props = propsys.SHGetPropertyStoreFromParsingName(fpath)
print( props.GetValue(pscon.PKEY_Media_DateEncoded).GetValue() )
del props
shutil.move(fpath , move_path)

Script can't save data to file

Based on *.blend file I have to write a script that gets informations about objects and saves them to json. This script can be opened in Blender, or running. The launch should save the json file with the data in the current directory.
So I created this:
import bpy
import json
objects = bpy.context.scene.objects
data = {}
for ob in objects:
item = {}
item['location'] = ob.location
if ob.name == 'Cube':
item['material_name'] = ob.active_material.name
data[ob.name] = item
elif ob.name == 'Camera':
item['camera_type'] = ob.data.type
data[ob.name] = item
elif ob.name == 'Lamp':
item['lamp_type'] = ob.data.type
data[ob.name] = item
with open('scene_objects.json', 'w') as json_file:
json.dump(data, json_file)
However, when I run the script in Blender, I received the following error:
PermissionError: [Errno 13] Permission denied: 'scene_objects.json'
I'm a beginner in using Blender so maybe it's impossible to write to file from Blender? However, if I can do it, I am asking for advice on how?
Your issue isn't with blender, the OS is preventing the creation (or writability) of the file based on file system permissions.
The line -
with open('scene_objects.json', 'w') as json_file:
will create a new file (or open existing) in the current working directory. When running blender that could be one of several options, depending on which OS you are using. It is also possible that starting blender from a GUI can leave you without a valid CWD, or a temporary dir that a user does not have permission to write to.
You can use os.chdir() to change the CWD to one that you know exists and that you can write to. You can also specify a full path instead of just a filename.

Python Uploading on webbrowser

I am writing an script that will upload file from my local machine to an webpage. This is the url: https://tutorshelping.com/bulkask and there is a upload option. but i am trouble not getting how to upload it.
my current script:
import webbrowser, os
def fileUploader(dirname):
mydir = os.getcwd() + dirname
filelist = os.listdir(mydir)
for file in filelist:
filepath = mydir + file #This is the file absolte file path
print(filepath)
url = "https://tutorshelping.com/bulkask"
webbrowser.open_new(url) # open in default browser
webbrowser.get('firefox').open_new_tab(url)
if __name__ == '__main__':
dirname = '/testdir'
fileUploader(dirname)
A quick solution would be to use something like AppRobotic personal macro software to either interact with the Windows pop-ups and apps directly, or just use X,Y coordinates to move the mouse, click on buttons, and then to send keyboard keys to type or tab through your files.
Something like this would work when tweaked, so that it runs at the point when you're ready to click the upload button and browse for your file:
import win32com.client
x = win32com.client.Dispatch("AppRobotic.API")
import webbrowser
# specify URL
url = "https://www.google.com"
# open with default browser
webbrowser.open_new(url)
# wait a bit for page to open
x.Wait(3000)
# use UI Item Explorer to find the X,Y coordinates of Search box
x.MoveCursor(438, 435)
# click inside Search box
x.MouseLeftClick
x.Type("AppRobotic")
x.Type("{ENTER}")
I don't think the Python webbrowser package can do anything else than open a browser / tab with a specific url.
If I understand your question well, you want to open the page, set the file to upload and then simulate a button click. You can try pyppeteer for this.
Disclaimer: I have never used the Python version, only the JS version (puppeteer).

Tkinter FileDialog.askopenfilename failing on already open files

I can not find a way using the the Tkinter tkFileDialog.askopenfilename / Open() method to get a file name of an already opened file. At least on Windows 7 anyway.
Simply need to return the filename selected, but when I select an 'opened' file I get the "This file is in use" popup. Any searches for getting filenames seems to always point back to using FileDialog.
There seems to be the same question but using c# here:
Open File Which is already open in window explorer
Are there any ways not listed that can be used to arrive at this? A file selection popup that doesn't fail on already opened files on Windows 7?
Python 2.7.11
Windows 7_64
Selection dialog:
opts = {}
opts['title'] = 'Select file.'
filename = tkFileDialog.Open(**opts).show()
or
filename = tkFileDialog.askopenfilename(**opts)
Which are the same as askopenfilename calls Open().show() which in turn is calling command = "tk_getOpenFile".
Searching tk_getOpenFile shows nothing to override this behavior.
Any pointers here would be much appreciated.
Update:
So as to not reiterate everything that's been gone over here's the break down of the Tkinter 8.5 FileDialog.
def askopenfile(mode = "r", **options):
"Ask for a filename to open, and returned the opened file"
filename = Open(**options).show()
if filename:
return open(filename, mode)
return None
def askopenfilename(**options):
"Ask for a filename to open"
return Open(**options).show()
Both call the Open class but askopenfile follows up with an open(file), here:
class Open(_Dialog):
"Ask for a filename to open"
command = "tk_getOpenFile"
def _fixresult(self, widget, result):
if isinstance(result, tuple):
# multiple results:
result = tuple([getattr(r, "string", r) for r in result])
if result:
import os
path, file = os.path.split(result[0])
self.options["initialdir"] = path
# don't set initialfile or filename, as we have multiple of these
return result
if not widget.tk.wantobjects() and "multiple" in self.options:
# Need to split result explicitly
return self._fixresult(widget, widget.tk.splitlist(result))
return _Dialog._fixresult(self, widget, result)
UPDATE2(answerish):
Seems the windows trc/tk tk_getOpenFile ultimately calls
OPENFILENAME ofn;
which apparently can not, at times, return a filename if the file is in use.
Yet to find the reason why but regardless.
In my case, needing to reference a running QuickBooks file, it will not work using askopenfilename().
Again the link above references someone having the same issue but using c# .

Passing an open file from one function to another

I'm a python beginner so bear with me. I have written some code on a GUI that allows users to select a file using one button (browse_inputfile), it then displays the file path and then the user can click another button to run a conversion on that file (run_conversion).
However to do this I've had to define a global variable to enable the open file to be passed from one function to another. Is there a better way to do this? I tried passing the path and actually opening it in the second function but this produced "file not found" errors I think due to the "\" used in the string path.
This is the code I have:
def browse_inputfile(self):
global inputfile
inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`
Then there's some code to display the path using "inputfile.name".
The second function is like this:
def run_conversion(self):
global inputfile
if inputfile: # if user didn't pick a file don't continue
#do stuff
inputfile.close()
I know using global variables is not good practise, so how can I pass the open file from one function to another and have it so that the user clicks the second button before the "stuff" is run on the file?
I want them to be able to check it's the right file before doing the "stuff" on it.
Thanks
Use inputfile as field of the class, in this way there is no need to pass the file as a parameter or to use a global.
class MyClass:
def browse_inputfile(self):
self.inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`
# you code for display the path
def run_conversion(self):
if self.inputfile: # if user didn't pick a file don't continue
#do stuff
self.inputfile.close()
Your current method risks inputfile not being closed on exit. I would do something like this:
file_path = None
def browse_inputfile(self):
return QtGui.QFileDialog.getOpenFileName(self, 'Openfile', '/home')
def run_conversion(self, path):
if path: # if user didn't pick a file don't continue
with open(path) as f:
#do stuff
If you want to manipulate file names robustly, use the functions in the os.path module https://docs.python.org/2/library/os.path.html.

Categories

Resources