3

This is driving me nuts, I've looked at & tried a number of the answers here for solving this problem but nothing is working out so far.

The basic problem is that I have some 1300+ rar files that I'd like to extract and keep somewhat organized, and to make things more fun a number of the rar files contain more rar files (which is why I'm disinclined to just do this by hand).

My first attempt, I just figured I'd do a simple python script that would just call unrar directly:

import os
import glob
import string
import subprocess

fileCount=0
files = glob.glob('Archives/*.rar')

for file in files:
  print file

  callstring = ["/usr/local/bin/unrar","e",file]
  output = subprocess.check_output(callstring)
  print output

This code returns the following:

Traceback (most recent call last):
  File "/Users/Overlord/Documents/python/Unpacker.py", line 25, in <module>
    output = subprocess.check_output(callstring)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command '['/usr/local/bin/unrar', 'e', 'testFile.rar']' returned non-zero exit status 10

(anyone know what error code 10 means?) Using unrar from the command line works without any problem.

Secondly I tried using libarchive, but despite a lack of build errors, I couldn't get the library to import.

Next I went with pyunpack:

from pyunpack import Archive

files = glob.glob('Archives/*.rar')

for file in files:
  print file
  Archive(file).extractall(".")

This threw a "no such file or directory" error.

EasyProcessError: start error <EasyProcess cmd_param=['patool', 'extract', Path(u'/Users/Overlord/Documents/python/testFile.rar'), Path(u'--outdir=/Users/Overlord/Documents/python')] cmd=['patool', 'extract', Path(u'/Users/Overlord/Documents/python/testFile.rar'), Path(u'--outdir=/Users/Overlord/Documents/python')] oserror=[Errno 2] No such file or directory returncode=None stdout="None" stderr="None" timeout=False>

Then I tried patoolib:

import patoolib

files = glob.glob('Archives/*.rar')

for file in files:
  print file
  patoolib.extract_archive(file,outdir=".")

This one threw the following:

PatoolError: could not find an executable program to extract format rar; candidates are (rar,unrar,7z)

Despite this message when I run patool directly from the command line the file is unrar'd with no problems.

So I went back to the original subprocess solution and tried using patool instead of unrar

import subprocess

fileCount=0
files = glob.glob('Archives/*.rar')

for file in files:
  print file

  callstring = ["/Library/Frameworks/Python.framework/Versions/2.7/bin/patool","extract",file]
  output = subprocess.check_output(callstring)
  print output

And got back the following:

CalledProcessError: Command '['/Library/Frameworks/Python.framework/Versions/2.7/bin/patool', 'extract', 'testFile.rar']' returned non-zero exit status 1

Any thoughts or suggestions while I still have a few hairs I haven't pulled out of my head?

PixelThis
  • 31
  • 1
  • 2
  • Are you showing us the correct code? The filename that gives an error is `testFile.rar`. But your glob is `Archives/*.rar`. So the filename *should be* `Archives/testFile.rar`. So my guess is that you're either cutting off the directory or using a non-existent filename. – Roland Smith May 31 '15 at 00:11
  • Sorry, apparently I copied and pasted from the wrong sample code. The errors remained the same, however. The code that gave the error actually changed directories into the archive directory before calling unrar. – PixelThis Jun 01 '15 at 04:43

1 Answers1

1

You can use the rarfile library here:

Install:

$ pip install rarfile

Example:

from rarfile import RarFile

with RarFile("myarchive.rar") as rf:
    for f in rf.infolist():
        with open(f.filename, "wb") as of:
            of.write(rf.read(f))

Update: Alternatively you can just "extract all" in one step by doing:

from rarfile import RarFile


with RarFile("myarchive.rar") as rf:
    rf.extractall()
USERNAME GOES HERE
  • 692
  • 1
  • 15
  • 29
James Mills
  • 18,669
  • 3
  • 49
  • 62
  • No problems! Seems like a nice little library/wrapper :) Please accept this if you find it acceptable and working! – James Mills May 28 '15 at 09:08
  • 1
    Playing around with it, I think I found a slightly simpler construction: `from rarfile import RarFile with RarFile("myarchive.rar") as rf: rf.extracall()` – PixelThis May 30 '15 at 18:12
  • I guess it depends if you want to do any processing on each file before writing them out or perhaps renaming them or what not :) – James Mills May 30 '15 at 22:01