Solved

CD to parent directory of a file path in Python

Posted on 2011-02-28
49
2,330 Views
Last Modified: 2012-05-11
Hey people,

I'm a crappy scripter and brand new to python.

This is the code I need help with
echo Changing Directory to provided episode path... >> $CALL_DATECHANGE_LOG
echo From `pwd` >> $CALL_DATECHANGE_LOG
cd "${PROCESSED_EPISODE_PATH}"
echo To `pwd` >> $CALL_DATECHANGE_LOG
echo Invoking Periscope to original episode name $ORIGINAL_EPISODE_NAME >> $CALL_DATECHANGE_LOG
echo The final command line is: >> $CALL_DATECHANGE_LOG
echo $PERISCOPE_BIN $PERISCOPE_OPTS $PROCESSED_EPISODE_FILE_NAME >> $CALL_DATECHANGE_LOG
echo Invoking it now: >> $CALL_DATECHANGE_LOG

Open in new window


The part "PROCESSED_EPISODE_PATH" will always be "\RandomPath\Shows\ShowName\Seasonxx\episode.mkv"

I need to CD to the show name, it's always going to be two levels up, how do i do it?

Maybe I'm asking the wrong thing, later in the script I need to modify "\RandomPath\Shows\ShowName"

This script is an Extra script that is post processed after another one, the "${PROCESSED_EPISODE_PATH}" is parsed from the previous script, hence the weird request hehe

Cheers.
0
Comment
Question by:chipped
  • 27
  • 17
  • 5
49 Comments
 
LVL 41

Expert Comment

by:HonorGod
ID: 34996757
To begin, the script shown above is not Python.  It is a shell scripting language.

What is the output of?

echo $SHELL

Do you want the Python equivalent of the script shown above?
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 34996813
e.g., if you have a variable containing a path name, like this:

here = r"\RandomPath\Shows\ShowName";

then you can figure out the parent using something simple like:

Example output:

current directory: \RandomPath\Shows\ShowName
parent directory: \RandomPath\Shows
grandparent dir: \RandomPath
import os;

here = r"\RandomPath\Shows\ShowName";

print "current directory:", here;

parent = '\\'.join( here.split( '\\' )[ :-1 ] );

print "parent directory:", parent;

grandpa = '\\'.join( here.split( '\\' )[ :-2 ] );

print "grandparent dir:", grandpa;

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
ID: 34996862
The way it work is that the string type includes a method called split() which takes the string, and uses the split() argument (i.e., a backslash in this case) and returns an array (list) of the substrings delimited by the specified character.  So, the result of:

here.split( '\\' )

will be an array (or list) containing:

['', 'RandomPath', 'Shows', 'ShowName']

The reason the first element is empty is because nothing precedes the initial backslash in the input string.

Given a list, use slicing to make a copy of a portion of the list.

So, given a list, we can specify that we want everything except the last two entries using:

[ :-2 ]

The result of which is, in this case:

['', 'RandomPath']

Given a list, we can combine the elements, and specify the delimiter element, using this notation:

'\\'.join( ... )

Where ... is where the list should be that will be combined into the returned string:

Does that make sense?

0
 
LVL 28

Expert Comment

by:pepr
ID: 34997756
It is probably better to use the os.path.split(yourFullName). You can do it twice, or you can os.path.join() the first head with '..' and then use the os.path.abspath().

See http://docs.python.org/library/os.path.html
http://docs.python.org/library/os.path.html#os.path.split
http://docs.python.org/library/os.path.html#os.path.join
http://docs.python.org/library/os.path.html#os.path.abspath
0
 

Author Comment

by:chipped
ID: 35003243
Doh! This is why I shouldn't script when I'm tired :P

Don't worry about the above script, here is my script so far in Python

import os, time

#path to file
file = '$1'

#Change to Grandparent Folder
fullpath = r"file";

print "current directory:", here;

parent = '\\'.join( fullpath.split( '\\' )[ :-1 ] );

print "parent directory:", parent;

grandpa = '\\'.join( fullpath.split( '\\' )[ :-2 ] );

print "grandparent dir:", grandpa;

#get current file stats
stats = os.stat(file)

#convert time to a more useable format
lastmod_date = time.localtime(stats[8])

#print the last date of modification
print(lastmod_date)

#new value to be stored in "Date Modified" file attribute
modDate = (2009, 2, 4, 20, 20, 12, 6, 39, 0)

#print new value (to compare against modified file
print(modDate)

#convert time to a value the system can handle
SysTime = time.mktime(modDate)

#print the value after conversion
print(SysTime)

#update the file attributes
os.utime('C:\\test\\time.txt', (int(time.time()), SysTime))

Open in new window


So what it does is, modify the Data Modified attribute of the Grandparent folder. I got this code off the net, and I'm not 100% sure how to use Python.

I'm stuck at:

Is Line 4 ok?

How do I use the grandparent directory we figure out on Line 15 in Line 41?

That's it I think :)
0
 
LVL 28

Accepted Solution

by:
pepr earned 500 total points
ID: 35004441
It is possible to do that in many ways.  Yet, I suggest to use the os.path functions whenever possible. Firstly, you reduce the problems with slashes/backslashes (also with appending them sometimes). Secondly, it may look talkative at the beginning but it is actually quite readable after getting used to.  The first part of your code (without the file-time modification part looks like this (see the commented out line how to get the script arguments):

import os
import sys

#path to file from the first argument (no checking)
##fname = sys.argv[1]  # commented out for demonstration

# Notice you can use so called r'raw strings' to avoid doubling backslashes.
# But it is probably better to use normal slashes even in Windows -- it works
# perfectly. 
##fname = r'\RandomPath\Shows\ShowName\Seasonxx\episode.mkv'
fname = '/RandomPath/Shows/ShowName/Seasonxx/episode.mkv'
print fname

# If you still wants to convert them to backslashes, you can
# use the os.path.normpath to convert them for the OS prefered ones.
fname = os.path.normpath(fname)
print fname

# Now split the path to the directory and the bare name (better to say it 
# splits the last element of the path and it does not care whether it is 
# a file name or a subdirectory name.
path, barename = os.path.split(fname)
print path
print barename

print "current directory:", path

parent = os.path.normpath(os.path.join(path, '..'))

print "parent directory:", parent

grandpa = os.path.normpath(os.path.join(parent, '..'))
print "grandparent dir:", grandpa

# or
grandpa = os.path.normpath(os.path.join(path, '..', '..'))
print "grandparent dir:", grandpa

# It is often a good idea (for logs, etc.) to convert the path to the absolute
# one. If you plan to do that, then you need not to do the normpath() as it is
# done during the conversion.
grandpa = os.path.abspath(os.path.join(path, '..', '..'))
print "grandparent dir:", grandpa

Open in new window


And it prints...

C:\tmp\___python\chipped\Q_26852254>python a.py xxx
/RandomPath/Shows/ShowName/Seasonxx/episode.mkv
\RandomPath\Shows\ShowName\Seasonxx\episode.mkv
\RandomPath\Shows\ShowName\Seasonxx
episode.mkv
current directory: \RandomPath\Shows\ShowName\Seasonxx
parent directory: \RandomPath\Shows\ShowName
grandparent dir: \RandomPath\Shows
grandparent dir: \RandomPath\Shows
grandparent dir: C:\RandomPath\Shows

Open in new window

0
 

Author Comment

by:chipped
ID: 35007633
Thanks for that Pepr, but the file path will always be parsed by another python script. I have to use $1 to use it.

So can I make
fname = '/RandomPath/Shows/ShowName/Seasonxx/episode.mkv'

Open in new window

this into
fname = '$1'

Open in new window

Would that work alright?
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 35007666
The $1 is a notation used by shell scripts.

In Python, it is sys.argv[ 1 ]... for example, the output for this script, invoked like this:

python bob.py Hi

Is:

Hi
import sys;
print sys.argv[ 1 ];

Open in new window

0
 

Author Comment

by:chipped
ID: 35007705
Pepr, I see that your code outputs the directory that I need, but I also need to integrate the extra code from this post that changes the date modified attribute of the outputted parent folder. http://www.experts-exchange.com/Programming/Languages/Scripting/Python/Q_26852254.html#a35003243
0
 

Author Comment

by:chipped
ID: 35007713
HonorGod: Oh ok, thanks.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35007964
As HonorGod said.  See also the line 5 in my previous sample that shows exactly the same -- only commented out.

Well, I did not touched the code for modification of the file time.  It is not clear to me, what time should be set to what and what is the overall purpose of that time modification.

A side note: The 'file' identifier should not be used for your variables as it is used form something else.  It may not be that much wrong; however, it may be confusing for those who know what it does name.
0
 

Author Comment

by:chipped
ID: 35008040
Pepr: The reason I want to modify the time of the "ShowName" directory, is so my windows media centre can see the updated show and organise the list accordingly :)
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 35008085
What OS are you using?
0
 

Author Comment

by:chipped
ID: 35008119
Windows, but apparently the date modification code will work on any OS. http://www.dreamincode.net/forums/topic/85465-python-editing-date-modified-file-attribute/
0
 

Author Comment

by:chipped
ID: 35008240
Hmmmmm, os.utime doesn't work on folders. So I'm going to have to create a file under the showname, then delete and recreate each time a episode is added. Then the showname dir will have an updated date modified time and Windows Media Centre will see it.
0
 

Author Comment

by:chipped
ID: 35008284
Pepr: I could use your script and then add a some code to create a file like "\RandomPath\Shows\ShowName\NewEpisodeMarker.txt", and if it exists, delete and recreate.

A little dodgy, but I need Windows Media Centre to be able to see "\RandomPath\Shows\ShowName" as being modified, so it can organize my shows by date.
0
 

Author Comment

by:chipped
ID: 35013581
Ok guys, we are in action, sort of. One minor kink to work out.

Here is the final code:
import os
import sys

#path to file from the first argument (no checking)
fname = sys.argv[1]
#fname = r'E:\\TV Shows\\How I Met Your Mother\\Season 6\\How.I.Met.Your.Mother.S06E18.720p.HDTV.X264-DIMENSION.mkv'

# Now split the path to the directory and the bare name (better to say it 
# splits the last element of the path and it does not care whether it is 
# a file name or a subdirectory name.
path, barename = os.path.split(fname)
print path
print barename

parent = os.path.normpath(os.path.join(path, '..'))

print "parent directory:", parent

# Create file, delete and recreate it if it exists. This will
# change the date modified status of the Show Name folder
# so you can view your show list by date order.
if os.path.isfile(parent + "/" + 'DateMarker.log'):
    os.remove(parent + "/" + 'DateMarker.log')
logfile = open(parent + "/" + 'DateMarker.log', 'w')
logfile.write('Episode ' + fname + ' has been created. This is a marker file, to change the date modified status of the show name.')
logfile.close

Open in new window


And here is the error I get when the script is called by the other python script:
Mar-02 11:44:50 INFO     POSTPROCESSER :: Unable to run extra_script: [Error 193] %1 is not a valid Win32 application
Mar-02 11:44:50 INFO     POSTPROCESSER :: Executing command ['DateM.py', u'E:\\TV Shows\\The Mentalist\\Season 01\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', u'E:\\Complete\\The Mentalist S01E10 720p HDTV x264 CTU\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', '82459', '1', '10', '2008-12-16']

Open in new window


I tried running the script with fname manually point to the parsed file path and it works fine but with "fname = sys.argv[1]" it craps out that error.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35014964
For the line 1 in the error log: The %1 is interpreted by the Windows cmd (batch interpreter) as the value of the first argument.  It is likely that you passed it so that it was not interpreted.

I am not sure if the line 2 is OK. The reason is that the list shows a mixture of both bare, old (Python 2.x) strings and of unicode strings.  It may work if it is anticipated byt the implementation that executes the comman, but I am not sure here.

If the line 6 were used, it should not double backslashes or the r (raw string literal) prefix should be removed. Better to use normal slashes.

I suggest to use os.path functions whenever you work with paths.  You will get used to and you will really appreciate it later (means less errors and problems later) -- see the lines 22 to 24.

There is the principle called DRY in programming.  It means "Don't Repeat Yourself", e.g. "do not write the same thing twice".  The reason is that when modified, you have to modify on more places.  But the main reason is that you want to be lazy as the lazines is the father of progress (the same way as "Repeating is the mother of wisdom" ;) .

The line 26 does not do what you expect.  It literally does nothing as you forgot to add the parentheses -- the method is not called.

After putting the last three together, the lines should look like that (I cannot control the line numbering -- it should be started from 22):

logname = os.path.join(parent, 'DateMarker.log')
if os.path.isfile(logname):
    os.remove(logname)
logfile = open(logname, 'w')
logfile.write('Episode ' + fname + ' has been created. This is a marker file, to change the date modified status of the show name.')
logfile.close()

Open in new window


But there is one more enhancement that makes the code shorter.  When you open the file using the mode 'w', the existing content is overwritten.  This way there is no need to remove the logfile first.

logname = os.path.join(parent, 'DateMarker.log')
logfile = open(logname, 'w')
logfile.write('Episode ' + fname + ' has been created. This is a marker file, to change the date modified status of the show name.')
logfile.close()

Open in new window


As the logname is not repeated now, the os.path.join() could be inserted directly to the open() command.  I prefer the separation as it is more readable and you never know how the code is to be modified later.  But you can combine the 'parent' command from your line 17 as it is probably used only to get the logfile name (probably no need to os.path.normpath()):

logname = os.path.join(path, '..', 'DateMarker.log')

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 35014986
You should also explain how do you want to launch the DateM.py with the arguments.  There are more ways to do that, but the most natural is to define the function in the DateM.py and use the DateM.py as module:

import DateM
...
DateM.myFunction(u'E:\\TV Shows\\The Mentalist\\Season 01\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', 
                 u'E:\\Complete\\The Mentalist S01E10 720p HDTV x264 CTU\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', 
                 '82459', '1', '10', '2008-12-16')

Open in new window

0
 

Author Comment

by:chipped
ID: 35016731
This is the code that runs my script, I think it might might not be running my script properly
    def _run_extra_scripts(self, ep_obj):
        for curScriptName in sickbeard.EXTRA_SCRIPTS:
            script_cmd = shlex.split(curScriptName) + [ep_obj.location, self.file_path, str(ep_obj.show.tvdbid), str(ep_obj.season), str(ep_obj.episode), str(ep_obj.airdate)]
            self._log(u"Executing command "+str(script_cmd))
            self._log(u"Absolute path to script: "+ek.ek(os.path.abspath, script_cmd[0]), logger.DEBUG)
            try:
                p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=sickbeard.PROG_DIR)
                out, err = p.communicate()
                self._log(u"Script result: "+str(out), logger.DEBUG)
            except OSError, e:
                self._log(u"Unable to run extra_script: "+str(e).decode('utf-8'))

Open in new window


I think this is causing the problem, I don't think the subprocess is being run properly.
p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=sickbeard.PROG_DIR)

Open in new window

Any ideas?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35017032
When using the subprocess.Popen(), you prescribe the execution of some executable file.  The .py file is just a text file... unless you work in UNIX-like environmend and chmod the file as executable. In the case, you have to use the #! magical line to define what interpreter will be used to launch it.

Are all of yours called script the Python scripts?  If yes, or you have to call the Python intepretere and pass the DateM.py as the first argument, or you have to mark the DateM.py as executable (UNIX), or you can use the execfile() function (http://docs.python.org/library/functions.html#execfile). BUT...

I still suggest to import the Python module and call the function from inside.  Can you show the fragment of your DateM.py?
0
 

Author Comment

by:chipped
ID: 35021685
I'm running on windows, that code that runs my script, is from another script which is not mine. It just calls my script to do some post processing after it.

All sorts of different scripts from all different Operating Systems are launched from there, some people have shell, batch, python, Windows, Mac, Linux etc

What is a fragment?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35021813
I see. Then you have to have all kind of interpreters on your Windows, like shell, cmd, python.exe... And you have to launch that interpreter and pass it the script as the first argument and the rest of arguments as the other ones.  You have to detect what interpreter should be used for what script. Does it make sense -- just from the abstract point of view? Do I understand it well?
0
 

Author Comment

by:chipped
ID: 35022198
Yep
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:chipped
ID: 35022715
Ok, you are correct. This guy has the exact same problem as me, and he fixed it by implementing what your suggesting.

http://stackoverflow.com/questions/912830/using-subprocess-to-run-python-script-on-windows

I have submitted an issue to the developer of SickBeard << Thats the program based on python, the one that launches my script to post process.
0
 

Author Comment

by:chipped
ID: 35024971
As a temporary solution, I want to run another script like a batch or vbscript to write to passed file name path to a log/text file and then modify the post process script to read the file path from there.

Should I create another thread or can you help me?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35025200
Let's do it here... in steps. The final goal will be to generate a batch file that will call the wanted script. Try the following separate script:

b.py
import shlex
import sys

scriptName = 'test.py'                     
lst = shlex.split(scriptName) + sys.argv[1:]
print lst

Open in new window


And try to call it from the command line:

C:\tmp\___python\chipped\Q_26852254>python "b.py" "a" "b" "c"
['test.py', 'a', 'b', 'c']

Open in new window


Notice I did wrapped the arguments (including the b.py) to double quotes.  This is what the cmd expects when the argument contains say spaces in path or so.  It is just more reliable to us that.

The shlex.split() in simple case just converts the string (no arguments) with the script name to the list containing the same string.  The sys.argv is the list of arguments passed to the Python script -- here only the a, b, c.  The + operator joins the two lists into one.
0
 

Author Comment

by:chipped
ID: 35025405
Oh yeah, that works fine.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35025516
Now try this:

c.py
import os
import shlex
import subprocess
import sys

scriptName = 'test.py'                       # this is the script to be called
lst = shlex.split(scriptName) + sys.argv[1:]

# Detect the kind of script and prepend the interpreter accordingly.
name, ext = os.path.splitext(scriptName)
if ext.lower() == '.py':
    lst.insert(0, 'python.exe')  

# Wrap all elements into double quotes.
lst = ['"' + s + '"' for s in lst]           
print lst

# Generate the aux.bat batch file.
cmd = ' '.join(lst)
print cmd

batchName = 'myBatch.bat'
f = open(batchName, 'w')
f.write('echo The batch started\n')
f.write(cmd)
f.close()

# Call the batch via the subprocess.Popen
p = subprocess.Popen(batchName, 
                     stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                     shell=True)   
out, err = p.communicate()

print 'Output:'
print out
print 'Error:'
print err

Open in new window


It prints on my console:

C:\tmp\___python\chipped\Q_26852254>python "c.py" "a a a" "b b b" "c c c"
['"python.exe"', '"test.py"', '"a a a"', '"b b b"', '"c c c"']
"python.exe" "test.py" "a a a" "b b b" "c c c"
Output:

C:\tmp\___python\chipped\Q_26852254>echo The batch started
The batch started

C:\tmp\___python\chipped\Q_26852254>"python.exe" "test.py" "a a a" "b b b" "c c c"
test ['test.py', 'a a a', 'b b b', 'c c c']

Error:
None

Open in new window

test.py
0
 

Author Comment

by:chipped
ID: 35025620
Ok working fine.
0
 

Author Comment

by:chipped
ID: 35025718
To be honest, I've kinda lost you. I have no idea what "c.py" does and I'm not even sure how/if it relates to "b.py" :S
0
 
LVL 28

Expert Comment

by:pepr
ID: 35025833
c.py, b.py -- they are just names of the samples.  Consider them a different scripts or different versions of the script. The c.py is just the next step of enhancing the b.py.  I use the name mainly because I usually capture the output on console where the name is visible.

The c.py shows the process of how your original subprocess.Popen() arguments can be converted to the string that can be written into the auxiliary batch file.  Then the subprocess.Popen() can launch that auxiliary batch file (fixed name) instead of unsuccessfull launch of the earlier script.

This way you get the intermediate step (the batch file) that solves some things like searching for the executable in the PATH (this is not done via subprocess.Popen() -- you have to explicitly pass the full name of the executable).  Also, there probably will be no problem with launching a batch file.  All the problems can be pre-solved when generating the batch file.  You can also easily test the batch file when running manually.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35025889
In your case, the

lst = shlex.split(scriptName) + sys.argv[1:]

# Detect the kind of script and prepend the interpreter accordingly.
name, ext = os.path.splitext(scriptName)
if ext.lower() == '.py':
    lst.insert(0, 'python.exe')

Open in new window


should be replaced by

script_cmd = shlex.split(curScriptName) + [ep_obj.location, self.file_path, str(ep_obj.show.tvdbid), 
                                           str(ep_obj.season), str(ep_obj.episode), str(ep_obj.airdate)]

# Detect the kind of script and prepend the interpreter accordingly.
name, ext = os.path.splitext(curScriptName)
if ext.lower() == '.py':
    script_cmd.insert(0, 'python.exe')

# Wrap all elements into double quotes.
lst = ['"' + s + '"' for s in script_cmd]           

# Generate the aux.bat batch file.
cmd = ' '.join(lst)

batchName = 'myBatch.bat'
f = open(batchName, 'w')
f.write('echo The batch started\n')
f.write(cmd)
f.close()

Open in new window


and put into your _run_extra_scripts() code... And then the batchName should be launched without other arguments by subprocess.Popen()

Anyway, it is rather complicated. Do not you want to modify the original code?
0
 

Author Comment

by:chipped
ID: 35025911
Wait, I don't want to modify the code that calls my post process script, that's not my code, it's a piece of code from SickBeard (that's the program, the one that calls my script)

I want to work around it, then run it normally when the developer gets around to fixing the bug.
0
 

Author Comment

by:chipped
ID: 35025976
The only code that mine is http://www.experts-exchange.com/M_4593526.html

The code that calls that script is not mine, its part of a program called SickBeard.

Sorry about the confusion.
0
 

Author Comment

by:chipped
ID: 35026166
Do you get me now?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35026242
I see. How the sickbeard.EXTRA_SCRIPTS is defined?  In other words, how do you pass the name of your script to the sickbeard?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35026296
If you somewhere wrote a line like:

DateM.py

Open in new window


then you should modify it to something like:

c:/Python27/python.exe DateM.py

Open in new window


Warning! It must use normal slashes in the path as the shlex.split() removes the backslashes.

Then the line will be split to two elements in the script_cmd, and the SickBeard will subprocess.Popen() the command like

['c:/Python27/python.exe', 'DateM.py', u'E:\\TV Shows\\The Mentalist\\Season 01\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', u'E:\\Complete\\The Mentalist S01E10 720p HDTV x264 CTU\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', '82459', '1', '10', '2008-12-16']

Open in new window


and this should work in your case.
0
 

Author Comment

by:chipped
ID: 35026329
No, I don't want to pass any info to sickbeard.

I just want to use the file name paths that sickbeard passes to the EXTRA_SCRIPTS.

We have made the script for that above.

But SickBeard EXTRA_SCRIPT does not run the python script properly, so our script is doing nothing at the moment.

As a temporary fix, I want to run an SickBeard EXTRA_SCRIPT that will write the file name paths to a log file.

Then our script can read the file name paths from that and do it's thing.

Do you get me now?
0
 
LVL 28

Expert Comment

by:pepr
ID: 35027111
I am confused.  Could you explain how the following arguments get into the SickBeard?

['DateM.py', u'E:\\TV Shows\\The Mentalist\\Season 01\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', u'E:\\Complete\\The Mentalist S01E10 720p HDTV x264 CTU\\the.mentalist.s01e10.720p.hdtv.x264-ctu.mkv', '82459', '1', '10', '2008-12-16']

Open in new window


Is he DateM.py your script?
0
 

Author Comment

by:chipped
ID: 35030596
That line is generates by SicBeard in this script:
    def _run_extra_scripts(self, ep_obj):
        for curScriptName in sickbeard.EXTRA_SCRIPTS:
            script_cmd = shlex.split(curScriptName) + [ep_obj.location, self.file_path, str(ep_obj.show.tvdbid), str(ep_obj.season), str(ep_obj.episode), str(ep_obj.airdate)]
            self._log(u"Executing command "+str(script_cmd))
            self._log(u"Absolute path to script: "+ek.ek(os.path.abspath, script_cmd[0]), logger.DEBUG)
            try:
                p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=sickbeard.PROG_DIR)
                out, err = p.communicate()
                self._log(u"Script result: "+str(out), logger.DEBUG)
            except OSError, e:
                self._log(u"Unable to run extra_script: "+str(e).decode('utf-8'))

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 35031603
OK. What is the sickbeard.EXTRA_SCRIPTS?  Where it gets its values?
0
 

Author Comment

by:chipped
ID: 35032164
SickBeard is a program which actually monitors files that have been downloaded, then moves them into their folders.

It passes the file name path and some other values to the extra script, so the user can do some post processing of their own.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35034161
I think I understand that.  But how you tell the SickBeard to use the extra script?  Is the DateM.py your extra script?  Or is it the standard part of the SickBeard?
0
 

Author Comment

by:chipped
ID: 35034957
Yep, DateM.py is my script.

There is a config.ini where I put the path to my script.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35035138
Can you show the content of that part of the config.ini?
0
 

Author Comment

by:chipped
ID: 35035660
extra_scripts = DateM.py

Open in new window

0
 

Author Comment

by:chipped
ID: 35035807
Ok solved, hell yeah!

Used a batch script to call my python script properly, and pass the info.
c:\Python27\python.exe c:\SickBeard\DateM.py %1 %2 %3 %4 %5

Open in new window


And this is the code I used to place marker file in the TV Show folder, so that windows sees the TV Show as modified.
import os
import sys

#path to file from the first argument (no checking)
fname = sys.argv[1]
#fname = r'E:\\TV Shows\\How I Met Your Mother\\Season 6\\How.I.Met.Your.Mother.S06E18.720p.HDTV.X264-DIMENSION.mkv'
print fname

# Now split the path to the directory and the bare name (better to say it 
# splits the last element of the path and it does not care whether it is 
# a file name or a subdirectory name.
path, barename = os.path.split(fname)
print path
print barename

parent = os.path.normpath(os.path.join(path, '..'))
print "parent directory:", parent

# Create file, delete and recreate it if it exists. This will
# change the date modified status of the Show Name folder
# so you can view your show list by date order.
logname = os.path.join(parent, 'DateMarker.log')
if os.path.isfile(logname):
    os.remove(logname)
logfile = open(logname, 'w')
logfile.write('Episode ' + fname + ' has been created. This is a marker file, to change the date modified status of the show name.')
logfile.close()

Open in new window

0
 

Author Closing Comment

by:chipped
ID: 35035818
Thank you so much guys, especially Pepr.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Less strange, but still introduction This introduction was added (1st August, 2011) to reflect some reactions.  Firstly, the term basics in the title of the article...  As any other word, it is a symbol with meaning attached to the word by some a…
Dictionaries contain key:value pairs. Which means a collection of tuples with an attribute name and an assigned value to it. The semicolon present in between each key and values and attribute with values are delimited with a comma.  In python we can…
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now