Author Topic: [Python] Multi Dir Unrar  (Read 1155 times)

0 Members and 1 Guest are viewing this topic.

Offline techb

  • Soy Sauce Feeler
  • Global Moderator
  • King
  • *
  • Posts: 2350
  • Cookies: 345
  • Aliens do in fact wear hats.
    • View Profile
    • github
[Python] Multi Dir Unrar
« on: August 09, 2014, 07:48:35 am »
Since joining IPT some of the downloads come packed in rar. Where this is an issue is tv shows. Sometimes, like the DBZ I just downloaded come in a seasons folder, in the seasons folder is episodes folder, and in the episodes folders is a multipart rar file.

Example on season 1 episode 1:
/home/me/exthdd/DBZ/DBZ_SE1/DBZ_SE01_EP01/multipart.rar

Each seasons episode is in it own file in a multipart rar.

Unraring it by hand for each season->episode would take ages for 9 seasons of video files.

So, I wrote a little python script to grab all the file paths and unrar them all in succession with the "unrar" command.

On Arch, Kernel 3.15.8-1.
Depends: unrar
Code: (bash) [Select]
pacman -S unrarPython 3 [should be installed]

Code: (python) [Select]
# unrarpy
# By: TechB 8/8/14

import os, sys, subprocess

def unrar(fl):
rars = fl[0]
total = fl[1]
progress = 0
for r in rars:
p1, p2 = os.path.split(r)
os.chdir(p1)
                #print("Progress in percent: %d" % int((progress/total)*100))
                # -inul is supposed to suppress unrar output, not tested yet
#subprocess.call(["unrar", "-inul", "e", os.path.join(p1,p2)])
                subprocess.call(["unrar", "e", os.path.join(p1,p2)])
progress += 1
print("All done")

def getFiles(rootdir):
rars = []
for root, dirs, files in os.walk(rootdir):
for f in files:
if ".RAR" in f.upper() and "SAMPLE.RAR" not in f.upper():
x = os.path.join(root, f)
rars.append(x)

return (rars, len(rars))



try:
rootdir = sys.argv[1]
except:
rootdir = os.getcwd()

filelist = getFiles(rootdir)
print("Total ammount to unrar:  %d" % filelist[1])

ans = input("Proceed? y/n:  ")
if ans == "n":
print("exiting...")
sys.exit()
elif ans == "y" or ans == "":
unrar(filelist)
print("exiting...")
else:
print("invalid answer, exiting...")
sys.exit()

Like all the code I post, very quick and dirty and does exactly what I need it to do on my own system and for a task I delegate. I wanted it to be better, like with a folder dialog and input checks and other things, but I don't really need it and was only written to extract the DBZ I downloaded. Please update it and make it more user friendly if you want. Even with quick simple mods could be used almost as is for your own personal needs.

There it is, first thing I've coded in a while and thought someone else might use it if there are in a similar situation.
« Last Edit: August 09, 2014, 11:40:39 am by techb »
>>>import this
-----------------------------

Offline Fur

  • Knight
  • **
  • Posts: 216
  • Cookies: 34
    • View Profile
Re: [Python] Multi Dir Unrar
« Reply #1 on: August 09, 2014, 09:51:37 am »
Cleaned your code a bit:
Code: (Python) [Select]
# unrarpy
# By: TechB 8/8/14

# Note that this modification DOES unrar sample.rar

import os, sys, subprocess

# Unrars a list of files into their respective directory.
def unrar(file_list):
    for rar in file_list:
        p1, p2 = os.path.split(rar)
        os.chdir(p1)
        subprocess.call(["unrar", "e", os.path.join(p1, p2)]) # Extract to current directory.
       
# Gets .rar files in a directory and all of its subdirectories.
def get_rar_files(rootdir):
    rars = []
    for root, dirs, files in os.walk(rootdir):
        for f in files:
            if ".RAR" in f.upper():
                rars.append(os.path.join(root, f))
    return rars # Why were you returning len(rars)? Why not just calculate the length when we need it?
   
def main():
    # Only use exceptions when you have to, and even then you should avoid generic catching; what if a MemoryError was raised?
    if len(sys.argv) > 1:
        root_dir = sys.argv[1]
    else:
        print("Usage: script.py dir")
        return 1
       
    rar_files = get_rar_files(root_dir)
    print("Total ammount to unrar:  %d" % len(rar_files))

    ans = input("Proceed? y/n:  ")
    if ans.upper() == "Y":
        unrar(rar_files)
        return 0
    else:
        return 1
 
main()

Rewrote in bash:
Code: (Bash) [Select]
#!/bin/sh
# Unrars all .rar files from the specified directory to the same directory, where the specified directory is the first argument to the program
for file in `find $1 -iname "*.rar*" ! -iname "*sample.rar*"`
do
    unrar e -inul $file $1
done
Edit to bash script: now extracts to input dir  instead of the current dir and suppresses messages from unrar.
« Last Edit: August 09, 2014, 11:17:54 am by Fur »

Offline techb

  • Soy Sauce Feeler
  • Global Moderator
  • King
  • *
  • Posts: 2350
  • Cookies: 345
  • Aliens do in fact wear hats.
    • View Profile
    • github
Re: [Python] Multi Dir Unrar
« Reply #2 on: August 09, 2014, 10:34:11 am »
Don't know bash so I can't comment on that.

As for python.

1) len(rars) was there because I thought about a progression bar or something to tell you about the current progression. Which was implemented in the actual code I used that worked. BUT no mater what I used stdout was still printed to shell when run. Popen, system, call, didn't matter "unrar" would still spit and spew it's progress info out to the the shell no matter what I tried to do with the pipes.

2) exceptions where and only put there because I thought I would extend it. I even wanted to do a gui to pick a dir like in tk or something dialog or something. I was going to do error checking and what not with the current script, but I only liked the idea of extending it. I'm not going to do anything with this than what I did, which is why I posted for improvements.

Thank you for going through it and making it better, this is exactly why I put it on the internet.
>>>import this
-----------------------------

Offline Fur

  • Knight
  • **
  • Posts: 216
  • Cookies: 34
    • View Profile
Re: [Python] Multi Dir Unrar
« Reply #3 on: August 09, 2014, 11:10:12 am »
Popen, system, call, didn't matter "unrar" would still spit and spew it's progress info out to the the shell no matter what I tried to do with the pipes.
The man page says the "inul" switch disables messages. I tested it and nothing was printed.

Offline techb

  • Soy Sauce Feeler
  • Global Moderator
  • King
  • *
  • Posts: 2350
  • Cookies: 345
  • Aliens do in fact wear hats.
    • View Profile
    • github
Re: [Python] Multi Dir Unrar
« Reply #4 on: August 09, 2014, 11:18:18 am »
The man page says the "inul" switch disables messages. I tested it and nothing was printed.

switch with what? I haven't seen in the python docs about anything with inul. Link it so I can read more about it. Cause what I did with subprocess.call wasn't supposed to spew to the shell either.
>>>import this
-----------------------------

Offline Fur

  • Knight
  • **
  • Posts: 216
  • Cookies: 34
    • View Profile
Re: [Python] Multi Dir Unrar
« Reply #5 on: August 09, 2014, 11:24:23 am »
switch with what? I haven't seen in the python docs about anything with inul.
Unrar.
Quote from: man unrar
       -inul  Disable all messages.

Offline techb

  • Soy Sauce Feeler
  • Global Moderator
  • King
  • *
  • Posts: 2350
  • Cookies: 345
  • Aliens do in fact wear hats.
    • View Profile
    • github
Re: [Python] Multi Dir Unrar
« Reply #6 on: August 09, 2014, 11:32:22 am »
Unrar.

I did do a unrar --help, but never noticed it. I can't really test it just this minute, but if it works then that means my own custom progress bar can be used. I have unrared what I needed for now, but I'm going to update my op with it and try it out next time I have a show downloaded. Might extend further and throw some gui into the mix. Cause picking a dir is better than having to check for one in code and all. Hell, could wrap this with tarpy even.
>>>import this
-----------------------------