How to change multiple files creation date using python script? - python

When i was importing my photos from my ipad to my hard disk i mistakenly imported them with the creation date of that day.
So now the true date for each photo is the modified date of it. I basically use this command to Setfile -d "$(GetFileInfo -m _FILE_PATH_)" _FILE_PATH_ to set the creation date of my photo to its modified date. But i was wondering if there is a way to put this command line in a python script where i can batch select multiple photos to preform this action.
Also, since if I open any photo the system will change its modified date, the only way that i can guess which date some photos belong to is by sorting them by name to see which date the photos before and after it belong to.
Any ideas on how I can write a script that deduces the real date of photos which have dates larger than a specific date based on the photos before and after it?
For example, you see in the screenshot that there is a photo from May 8 between two photos from October 5, so clearly it should be taken on October 5 as well.
But unfortunately sometimes the modified date of the photos before and after a photo are also wrong so I think the program has to look for the smallest date before and after the photo to deduce the real date.
UPDATE
I wrote this code on the python and it works fine for single files when I drag and drop them into the terminal to give the program the path. Im wondering if there is a way to do this with multiple files.
from subprocess import call
import os
path = input("enter filepath: ")
info = '"$(GetFileInfo -m '+ path + ')" '
command = 'Setfile -d ' + info + path
print('Setfile -d ' + info + path)
call(command, shell=True)

Not requiring interactive input is probably a crucial improvement so that you can run this on a large number of files at the same time. The way to do that in Python is with sys.argv.
Also, rather than subprocess.call, use subprocess.check_call (or subprocess.check_output to get the output) so that you can avoid invoking a shell, and check that the subprocess completed successfully. (There will be a traceback if not; if you want something more user-friendly, wrap it in try/except. Probably look for existing questions before posting another question asking for help with that.)
from subprocess import check_output, check_call
from sys import argv
for path in argv[1:]:
date = check_output(['GetFileInfo', '-m', path])
check_call(['Setfile', '-d', date, path])
Use it like
python3 script.py file1.png /path/to/file2.png ../elsewhere/file3.png ...
(Relative paths are resolved starting from your current working directory; no path resolves to the current directory.)

Related

On linux , using a bash script how do I rename an Excel file to include the row count at the end of the existing filename

First post so be gentle please.
I have a bash script running on a Linux server which does a daily sftp download of an Excel file. The file is moved to a Windows share.
An additional requirement has arisen in that i'd like to add the number of rows to the filename which is also timestamped so different each day. Ideally at the end before the xlsx extension.
After doing some research it would seem I may be able to do it all in the same script if I use Python and one of the Excel modules. I'm a complete noob in Python but i have done some experimenting and have some working code using the Pandas module.
Here's what i have working in a test spreadsheet with a worksheet named mysheet and counting a column named code.
>>> excel_file = pd.ExcelFile('B:\PythonTest.xlsx')
>>> df = excel_file.parse('mysheet')
>>> df[['code']].count()
code 10
dtype: int64
>>> mycount = df[['code']].count()
>>> print(mycount)
code 10
dtype: int64
>>>
I have 2 questions please.
First how do I pass todays filename into the python script to then do the count on and how do i return this to bash. Also how do i just return the count value e.g 10 in the above example. i dont want column name or dtype passed back.
Thanks in advance.
Assuming we put your python into a separate script file, something like:
# count_script.py
import sys
import pandas as pd
excel_file = pd.ExcelFile(sys.argv[1])
df = excel_file.parse('mysheet')
print(df[['code']].count().at(0))
We could then easily call that script from within the bash script that invoked it in the first place (the one that downloads the file).
TODAYS_FILE="PythonTest.xlsx"
# ...
# Download the file
# ...
# Pass the file into your python script (manipulate the file name to include
# the correct path first, if necessary).
# By printing the output in the python script, the bash subshell (invoking a
# command inside the $(...) will slurp up the output and store it in the COUNT variable.
COUNT=$(python count_script.py "${TODAYS_FILE}")
# this performs a find/replace on $TODAYS_FILE, replacing the ending ".xlsx" with an
# underscore, then the count obtained via pandas, then tacks on a ".xlsx" again at the end.
NEW_FILENAME="${TODAYS_FILE/\.xlsx/_$COUNT}.xlsx"
# Then rename it
mv "${TODAYS_FILE}" "${NEW_FILENAME}"
You can pass command-line arguments to python programs, by invoking them as such:
python3 script.py argument1 argument2 ... argumentn
They can then be accessed within the script using sys.argv. You must import sys before using it. sys.argv[0] is the name of the python script, and the rest are the additional command-line arguments.
Alternatively you may pass it in stdin, which can be read in Python using normal standard input functions like input(). To pass input in stdin, in bash do this:
echo $data_to_pass | python3 script.py
To give output you can write to stdout using print(). Then redirect output in bash, to say, a file:
echo $data_to_pass | python3 script.py > output.txt
To get the count value within Python, you simply need to add .at(0) at the end to get the first value; that is:
df[["code"]].count().at(0)
You can then print() it to send it to bash.

How to list both files and folders based on time of creation on python?

I am a newbie to python and linux. I want a solution for listing the files and folders based on the timestamp. I know this is already asked. But I cannot get an insight in what I am doing. I want the code to return the latest created file or folder. I have a script that identifies the type of content(file or folder). I need it to get the latest created content. The content identifier goes like this.
import os
dirlist=[]
dirlist2=[]
for filename in os.listdir('/var/www/html/secure_downloads'):
if (os.path.isdir(os.path.join('/var/www/html/secure_downloads',filename))):
dirlist.append(filename)
else:
dirlist2.append(filename)
print "For Folders",dirlist
print "For Files",dirlist2
Option 1: Use glob
I found this great article here: https://janakiev.com/blog/python-filesystem-analysis/
Option 2: Pipe the output of ls -l to python
The way I initially thought about solving this issue is doing the following...
You can list all the directories and their timestamps with ls -l.
Then you can pipe that output using subprocess like this:
import subprocess
proc=subprocess.Popen('echo "to stdout"', shell=True, stdout=subprocess.PIPE, )
output=proc.communicate()[0]
print(output)

Shell Script to Delete Selected Directory based on Changing date

My requirement is to delete the previous day directory and create a new directory in the format like as given in the below screen.
We generally make a directory in a below format taking into account the day and the date.
For example:
TP1_<TODAY_DAY>_<TODAY_DATE> TP1_TUE_19JUN2018.
How can this be achieved?
to get it into a variable on linux shell you can use the following:
export mydate=$(date +%a_%d%b%Y|tr [a-z] [A-Z])
then you can use the variable as part of cd, mkdir or any other command, i.e.
echo TP1__ TP1_$mydate
will give as result, please note that I used it on a Italian Cent OS Linux,
TP1__ TP1_MAR_19GIU2018

Python: Create a directory with data and time

By using subprocess module , how can we create a directory with today's date and time as directory name ?
I can follow one process , like assigning todays date to a variable in the the python and use that variable as reference to create a directory.
And I am using windows as my target machine.
but is there any other best ways I could follow ?
Thanks
If you think that you can rely upon your system's timezone setting, you may use built in date command (on Unix-like systems) in a way like this:
os.system("mkdir `date +%Y-%m-%d_%H:%M:%S`")
Though, there are other solutions, like to use os.mkdir().
Try it out.
The following will create a folder with the current date as its name. See the 'man date' to adjust the output to your liking.
import subprocess
p = subprocess.Popen('mkdir "$(date)"', shell=True)

Get full path of currently open files

I'm trying to code a simple application that must read all currently open files within a certain directory.
More specificly, I want to get a list of files open anywhere inside my Documents folder,
but I don't want only the processes' IDs or process name, I want the full path of the open file.
The thing is I haven't quite found anything to do that.
I couldn't do it neither in linux shell (using ps and lsof commands) nor using python's psutil library. None of these is giving me the information I need, which is only the path of currently open files in a dir.
Any advice?
P.S: I'm tagging this as python question (besides os related tags) because it would be a plus if it could be done using some python library.
This seems to work (on Linux):
import subprocess
import shlex
cmd = shlex.split('lsof -F n +d .')
try:
output = subprocess.check_output(cmd).splitlines()
except subprocess.CalledProcessError as err:
output = err.output.splitlines()
output = [line[3:] for line in output if line.startswith('n./')]
# Out[3]: ['file.tmp']
it reads open files from current directory, non-recursively.
For recursive search, use +D option. Keep in mind, that it is vulnerable to race condition - when you get your ouput, situation might have changed already. It is always best to try to do something (open file), and check for failure, e.g. open file and catch exception or check for null FILE value in C.

Categories

Resources