I could write something myself to accomplish this, but am hoping something already exists. I haven't found anything for it with Google, though.
I have a .RC file which I can compile using Microsoft Windows Resource Compiler. I am wondering if there are any existing programs which will analyze the .RC file and figure out what files within a particular set of folders are currently not referenced by it.
Quick and Dirty python utility, mainly for my own use:
import os
import os.path
location = "C:\PATH\Resources\Stuff.rc"
loca = set([])
used = set([])
for root,dirs,files in os.walk(os.path.dirname(location)):
for item in files:
item = item.lower()
if (item.endswith('.bmp')):
loca.add(os.path.join(root.lower(),item))
with open(location) as rcfile:
for line in rcfile:
for token in line.split('"'):
token = token.lower()
if token.endswith('.bmp'):
used.add(os.path.join(os.path.dirname(location).lower(),token.replace('\\\\','\\')))
print '\n'.join(loca - used)
print len(loca)
print len(used)
print len(loca - used)
Related
A sensor provides a stream of frames containing object coordinates, which are stored in ProtoBuf format in a gzipped file. I would like to read this file in Julia.
Using protoc, I have generated the Protobuf files for both Python and Julia, coordinate_push.py and coordinate_push.jl
My Python code is as follows:
frameList = []
with gzip.open(filePath) as f:
data = f.read()
next_pos, pos = 0, 0
while pos < len(data):
msg = coordinate_push.CoordinatesFrame()
next_pos, pos = _DecodeVarint32(data, pos)
msg.ParseFromString(data[pos:pos + next_pos])
frameList.append(msg)
pos += next_pos
I'd like to rewrite the above in Julia, and don't know where to start. Part of the problem is that I haven't fully understood the Python script (IO is not my strong point).
I understand that I need:
to open the gzip file, presumably using using GZip; file = GZip.open(file_path, "r")
to read in the data, along the lines of using ProtoBuf; data = readproto(iob, CoordinatesFrame())
What I don't understand is:
how to define iob, and especially how to link it to file (in the Julia Protobuf manual, we had iob = PipeBuffer(), but here it's a gzip-file that we'd like to read)
how to replicate the while-loop in Julia, and in particular the mysterious _DecodeVarint32 (I'm on Windows, if it's related to that.)
whether the file coordinate_push.jl has to be in the same directory as my main file, and if not, how I can properly import it (it is currently in a proto subfolder, and in Python I'd import it using from src.proto import coordinate_push)
Insight on any of the three points would be highly appreciated.
You should open an issue on the Gzip GitHub repo and ask this first part of your question there (I am not a Gzip expert unfortunately).
On the second point, I suggest looking here: https://github.com/JuliaIO/FileIO.jl/blob/master/README.md for lots of examples of FileIO loops which seems exactly what you need to replicate that Python loop. For the second part of this question, you best bet for that function is to try and hunt down the definition on GitHub or in the docs somewhere.
For the 3rd questions, coordinate_push.jl does not need to be in the same folder as your "main file" (I am not sure what you mean by this so perhaps it would help to add context on the structure of your files). To import that file all you need to do is add include("path/to/coordinate_push.jl") at the top of the file you want to call/run the code from. It's worth noting that the path can either be the absolute path or the relative project path (in some cases).
I'am trying to make a file searching, Python based program, with GUI.
It's going to be used to search specified directories and subdirectories. For files which filenames have to be inserted in an Entry-box.
while I'am fairly new to python programming, I searched the web and gained some information on the os module.
Then I moved on and tried to write a simple code with os.walk and without the GUI program:
import os
for root, dirs, files in os.walk( 'Path\to\files'):
for file in files:
if file.endswith('.doc'):
print(os.path.join(root, file))
Which worked fine, however... file.endswith() Only looks to the last part of the filename.
The problem is that in the file path are over 1000 files with .doc. And I want the code to be able to search parts of the file name, for example "Caliper" in filename "Hilka_Vernier_Caliper.doc".
So I went on and searched for other methods than file.endswith() and found something about file.index(). So I changed the code to:
import os
for root, dirs, files in os.walk( 'Path\to\files'):
for file in files:
if file.index('Caliper'):
print(os.path.join(root, file))
But that didn't work as planned...
Does someone on here have an idea, how I could make this work?
You may use pathlib instead of the old os: https://docs.python.org/3/library/pathlib.html#pathlib.Path.rglob
BTW, file.index raises an exception if the name is not not found, so you need a try/except clause.
Another way is to use if "Caliper" in str(file):
I use a program which, sadly corrupts some saved files at random times. To be helpful (although I am a novice at this) I am trying to make a Python program to basically backup those file from the AppData/local directory and put them in a folder on C. I need this program to overwrite the previously copied files each time it is run.
I need to generalize the AppData/local because each person who uses this program would, in theory, have a different user directory preceding the AppData folder.
I've tried running some of my own attempts at a solution.
I will post the results.
# Imports
import shutil
import os
import distutils
from distutils import dir_util
# Paths
# os.makedirs("C:/RevSaves-Backup")
path = '%LOCALAPPDATA%/Remnant'
backup_path = "C:/RevSaves-Backup"
# Procedures
print("The Very Basic Remnant Save Backup Utility")
print(" ")
print("Backing up the save source:")
print(path)
print(" ")
print("It is recommended you run this at regular intervals \nto ensure you have the latest saves up to date.")
distutils.dir_util.copy_tree(path, backup_path)
print("Backup completed.")
When I execute this via command prompt or PowerShell, I get the following message:
Traceback (most recent call last):
File "RevSaveBkUp.py", line 28, in
distutils.dir_util.copy_tree(path, backup_path)
File "C:\Users\candr\AppData\Local\Programs\Python\Python37-32\lib\distutils\dir_util.py", line 124, in copy_tree
"cannot copy tree '%s': not a directory" % src)
distutils.errors.DistutilsFileError: cannot copy tree '%LOCALAPPDATA%/Remnant': not a directory
I am having trouble "targeting" the system-specific local AppData folder.
After a lot of reading, I made the following solution if anyone else is trying to do something similar. I do not know if this is the "best" or "right" way of doing things, however.
Here is how I targeted the AppData Local folder regardless of the user logged in:
path = os.path.join(os.path.expanduser('~'), 'AppData', 'Local')
Some explanations for anyone who is new like me:
os.path.join basically connects folders together in the path. For example, using the above code, join would "connect" AppData to Local and the "User Folder" (referenced in the code as '~'). The output would look like this: C:\Users\your_username\AppData\Local
os.path.expanduser defines the user in question. For example, "~" targets the current user logged in. It goes inside the () because this is how you tell "your code" who, to target. If you wanted a specific user (if you had more than one) you could possibly use os.path.expanduser('Jane') I believe.
Keeping the notes above in reference, this method allowed me to define the variables I needed to and use them for the copy above, where I could not normally use the AppData directory as I wanted.
This was done by using the following code as an example:
path = os.path.join(os.path.expanduser('~'), 'AppData', 'Local')
backup_path = "C:/MyBackupFolder"
Finally we executed the copy with this:
distutils.dir_util.copy_tree(path, backup_path)
The above copied The AppData information I needed to the backup folder.
I hope this helps everyone learn as I did, it came in quite handy.
I'm attempting to create a script that looks into a specific directory and then lists all the files of my chosen types in addition to all folders within the original location.
I have managed the first part of listing all the files of the chosen types, however am encountering issues listing the folders.
The code I have is:
import datetime, os
now = datetime.datetime.now()
myFolder = 'F:\\'
textFile = 'myTextFile.txt'
outToFile = open(textFile, mode='w', encoding='utf-8')
filmDir = os.listdir(path=myFolder)
for file in filmDir:
if file.endswith(('avi','mp4','mkv','pdf')):
outToFile.write(os.path.splitext(file)[0] + '\n')
if os.path.isdir(file):
outToFile.write(os.path.splitext(file)[0] + '\n')
outToFile.close()
It is successfully listing all avi/mp4/mkv/pdf files, however isn't ever going into the if os.path.isdir(file): even though there are multiple folders in my F: directory.
Any help would be greatly appreciated. Even if it is suggesting a more effective/efficient method entirely that does the job.
Solution found thanks to Son of a Beach
if os.path.isdir(file):
changed to
if os.path.isdir(os.path.join(myFolder, file)):
os.listdir returns the names of the files, not the fully-qualified paths to the files.
You should use a fully qualified path name in os.path.isdir() (unless you've already told Python where to look).
Eg, instead of using if os.path.isdir(file): you could use:
if os.path.isdir(os.path.join(myFolder, file)):
Is there a way to confirm deleting a file from the tree (left hand side) or remove the option from the context menu?
It is too easy to miss i.e. rename and click delete file instead. Then the file is gone.
I googled and found it should be moved to the trash folder but either that doesn't apply to Win7 or to using network drives. As a result the files are actually deleted or moved somewhere I have failed to track them down so far.
Using Sublime Text (build 3083)
Important: take a look at iron77 answer. It says that if you modify Default.sublime-package (options 1 and 3) this changes might be overriden if sublime text is updated.
Option 1: modify side_bar.py file
You can use sublime API to show an ok/cancel dialog. The code you are looking for is in a file called side_bar.py. This file is located inside the zip file Default.sublime-package. In windows this is usually located in C:\Program Files\Sublime Text 3\Packages\Default.sublime-package and can be explored using programs such as WinRar.
Inside that file locate DeleteFileCommand and add this 3 new lines, so it is changed from this:
class DeleteFileCommand(sublime_plugin.WindowCommand):
def run(self, files):
# Import send2trash on demand, to avoid initialising ctypes for as long as possible
import Default.send2trash as send2trash
To this
class DeleteFileCommand(sublime_plugin.WindowCommand):
def run(self, files):
isSure = sublime.ok_cancel_dialog('Are you sure you want to delete the file?')
if isSure != True:
return
# Import send2trash on demand, to avoid initialising ctypes for as long as possible
import Default.send2trash as send2trash
We are showing a ok/cancel dialog and if the user doesn't press Ok then we return and the file isn't removed.
Notes:
You will have to add the same code in class DeleteFolderCommand in order to confirm also when deleting folders.
Is a good practice to backup your Default.sublime-package file first just in case something goes wrong. EDIT: use a different folder for the backup or the package could be loaded twice causing problems as the OP has said in his comment.
As this is python code indentation is extremly important, don't
replace any spaces for tabs nor add any extra space or it will not
work (you can see it console).
Result:
Option 2: use an existing package
As user leesei said in his answer you can use SideBarEnhancements package to achieve your goal. This package adds many other features to the file context menu as you can see in the following image, but it is a very good choice as you only need to install an exsiting package.
Option 3: remove option from context menu
Edit Side Bar.sublime-menu inside Default.sublime-package (see option 1) and remove this line (and if you want remove also the line reffering to deleting folders):
{ "caption": "Delete File", "command": "delete_file", "args": {"files": []} },
While sergioFC's answers work great, I'm bit worried of modifying Default.sublime-package, as it might someday get overwritten when Sublime is updated, so the fix would need to be manually re-applied after each such update. SideBarEnhancements, on the other hand, might have too many features for someone who only wants the confirmation when deleting a file.
Alternatively, you can add a simple confirmation dialog that should be more resistant to ST updates, by creating a file (plugin). On Linux it should be somewhere around ~/.config/sublime-text-3/Packages/User/confirm_delete.py, and if you're on Windows/Mac or this path does not work for you, you can simply choose from the top menu: Tools -> Developer -> New Plugin and later save as confirm_delete.py - thanks to harrrrrrry for this suggestion. Code to put in:
from Default.side_bar import *
class DeleteFileCommand(sublime_plugin.WindowCommand):
def run(self, files):
if len(files) == 1:
message = "Delete File %s?" % files[0]
else:
message = "Delete %d Files?" % len(files)
if sublime.ok_cancel_dialog(message, "Delete") != True:
return
# Import send2trash on demand, to avoid initialising ctypes for as long as possible
import Default.send2trash as send2trash
for f in files:
v = self.window.find_open_file(f)
if v != None and not v.close():
return
send2trash.send2trash(f)
def is_visible(self, files):
return len(files) > 0
This code is basically a copy of DeleteFileCommand function from Default.sublime-package's side_bar.py combined with confirmation dialogs from DeleteFolderCommand from the same file, as Sublime has such dialog natively for folder removal.
When I choose delete by right clicking on a file in the SideBar, I get a confirmation.
Maybe it's SideBarEnhancements. It is worth a try.
WTF a software that doesn't have a confirm dialog before delete. I can't believe this. Sad but true. Just stupid software!
Unfortunately there is no way to activate a confirmation. Usually the the deleted file is moved to the trash folder but as you mentioned this is only true for local files. Files on a shared network drive are still deleted immediately. This is a Windows 'feature' :(
Locally the Recycle Bin is part of Windows Explorer -- and on the network you are NOT dealing with explorer on the server. Explorer locally isn't going to copy the file to the user's workstation just to put it into the recycle bin.
You CAN implement Microsofts Shadow Copy however, then users can undelete and compare versions. This would be the only way so far for network drives until the sublime developer decides to make an optional confirmation dialog.
According to #iron77's answer, the path for plugin could not exist (in my case). An easier way is:
1) Click Sublime Text topbar menu Tools -> Developer -> New Plugin.
2) Paste the snippet
from Default.side_bar import *
class DeleteFileCommand(sublime_plugin.WindowCommand):
def run(self, files):
if len(files) == 1:
message = "Delete File %s?" % files[0]
else:
message = "Delete %d Files?" % len(files)
if sublime.ok_cancel_dialog(message, "Delete") != True:
return
# Import send2trash on demand, to avoid initialising ctypes for as long as possible
import Default.send2trash as send2trash
for f in files:
v = self.window.find_open_file(f)
if v != None and not v.close():
return
send2trash.send2trash(f)
def is_visible(self, files):
return len(files) > 0
3) Save as confirm_delete.py.