diff --git a/TorrentToMedia.py b/TorrentToMedia.py index c89bf89f..3a1268fd 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -11,8 +11,6 @@ from subprocess import call # Custom imports import linktastic.linktastic as linktastic -import UnRAR2 -from UnRAR2.rar_exceptions import * import autoProcessMovie import autoProcessTV from nzbToMediaEnv import * @@ -25,14 +23,6 @@ fileHandler.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(messa fileHandler.level = logging.DEBUG Logger.addHandler(fileHandler) - -def cleanup(outputDestination): - for path, dirs, files in os.walk(outputDestination): - for fn in files: - os.remove(os.path.join(path, fn)) - for dir in dirs: - os.removedirs(os.path.join(path, dir)) - def category_search(inputDirectory, inputCategory, root): categorySearch = os.path.split(os.path.normpath(inputDirectory)) # Test for blackhole sub-directory if categorySearch[1] == inputName: @@ -83,7 +73,7 @@ def copy_link(source, target, useLink, outputDestination): # Create destination folder if not os.path.exists(outputDestination): try: - Logger.debug("COPYLINK: Creating destination folder: %s", outputDestination) + Logger.info("COPYLINK: Creating destination folder: %s", outputDestination) os.makedirs(outputDestination) except Exception, e: Logger.error("COPYLINK: Not possible to create destination folder: %s", e) @@ -91,7 +81,7 @@ def copy_link(source, target, useLink, outputDestination): if useLink: try: - Logger.debug("COPYLINK: Linking %s to %s", source, target) + Logger.info("COPYLINK: Linking %s to %s", source, target) linktastic.link(source, target) except: if os.path.isfile(target): @@ -105,30 +95,80 @@ def copy_link(source, target, useLink, outputDestination): shutil.copy(source, target) return True -def unpack(dirpath, file, outputDestination): -# Create destination folder - if not os.path.exists(outputDestination): +def unpack(dirpath, file, destination): + # Using Windows + if os.name == 'nt': + Logger.info("EXTRACTOR: We are using Windows") + cmd_7zip = [extractionTool, 'x -y'] + ext_7zip = [".rar",".zip",".tar.gz","tgz",".tar.bz2",".tbz",".tar.lzma",".tlz",".7z",".xz"] + EXTRACT_COMMANDS = dict.fromkeys(ext_7zip, cmd_7zip) + + # Using linux + elif os.name == 'posix': + Logger.info("EXTRACTOR: We are using *nix") + required_cmds=["unrar", "unzip", "tar", "unxz", "unlzma", "7zr"] + EXTRACT_COMMANDS = {".rar": ["unrar", "x -o+ -y"], ".zip": ["unzip", ""], ".tar.gz": ["tar", "xzf"], ".tgz": ["tar", "xzf"], ".tar.bz2": ["tar", "xjf"], ".tbz": ["tar", "xjf"], ".tar.lzma": ["tar", "--lzma xf"], ".tlz": ["tar", "--lzma xf"], ".txz": ["tar", "--xz xf"], ".7z": ["7zr", "x"],} + + # Need to add a check for which commands that can be utilized in *nix systems.. + else: + Logger.error("EXTRACTOR: Unknown OS, exiting") + + ext = os.path.splitext(file) + fp = os.path.join(dirpath, file) + if ext[1] in (".gz", ".bz2", ".lzma"): + # Check if this is a tar + if os.path.splitext(ext[0])[1] == ".tar": + cmd = EXTRACT_COMMANDS[".tar" + ext[1]] + else: + if ext[1] in EXTRACT_COMMANDS: + cmd = EXTRACT_COMMANDS[ext[1]] + else: + Logger.debug("EXTRACTOR: Unknown file type: %s", ext[1]) + return False + + # Create destination folder + if not os.path.exists(destination): try: - Logger.debug("EXTRACTOR: Creating destination folder: %s", outputDestination) - os.makedirs(outputDestination) + Logger.debug("EXTRACTOR: Creating destination folder: %s", destination) + os.makedirs(destination) except Exception, e: Logger.error("EXTRACTOR: Not possible to create destination folder: %s", e) return False - path = os.path.join(dirpath, file) - try: - archive = UnRAR2.RarFile(path) - for rarinfo in archive.infoiter(): - name = rarinfo.filename - archive.extract(name, outputDestination) - Logger.error("EXTRACTOR: Files extracted from %s to %s", path, outputDestination) - except Exception, e: - Logger.error("EXTRACTOR: Extraction process failed: %s", e) - sys.exit(-1) + + Logger.info("Extracting %s to %s", fp, destination) + + # Running + Logger.debug("Extracting %s %s %s %s", cmd[0], cmd[1], fp, destination) + pwd = os.getcwd() # Get our Present Working Directory + os.chdir(destination) # Not all unpack commands accept full paths, so just extract into this directory + if os.name == 'nt': # Windows needs quotes around directory structure + try: + run = "\"" + cmd[0] + "\" " + cmd[1] + " \"" + fp + "\"" # Windows needs quotes around directories + res = call(run) + if res == 0: + Logger.info("EXTRACTOR: Extraction was successful for %s to %s", fp, destination) + else: + Logger.info("EXTRACTOR: Extraction failed for %s. 7zip result was %s", fp, res) + except: + Logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s %s", fp, run) + else: + try: + if cmd[1] == "": # If calling unzip, we dont want to pass the "" + res = call([cmd[0], fp]) + else: + res = call([cmd[0], cmd[1], fp]) + if res == 0: + Logger.info("EXTRACTOR: Extraction was successful for %s to %s", fp, destination) + else: + Logger.error("EXTRACTOR: Extraction failed for %s. 7zip result was %s", fp, res) + except: + Logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s %s %s %s", fp, cmd[0], cmd[1], fp) + os.chdir(pwd) # Go back to our Original Working Directory return True def flatten(outputDestination): Logger.info("FLATTEN: Flattening directory: %s", outputDestination) - for dirpath, dirnames, filenames in os.walk(outputDestination): #flatten out the directory to make postprocessing easier + for dirpath, dirnames, filenames in os.walk(outputDestination): # Flatten out the directory to make postprocessing easier if dirpath == outputDestination: continue # No need to try and move files in the root destination directory for filename in filenames: @@ -220,7 +260,7 @@ else: Logger.debug("MAIN: Looking for %s in filename", inputName) if (inputName in file) or (os.path.splitext(file)[0] in inputName): pass # This file does match the Torrent name - logger.debug("Found file %s that matches Torrent Name %s", file, inputName) + Logger.debug("Found file %s that matches Torrent Name %s", file, inputName) else: continue # This file does not match the Torrent name, skip it filePath = os.path.join(dirpath, file) @@ -233,7 +273,7 @@ else: video = video + 1 source = filePath target = os.path.join(outputDestination, file) - Logger.info("MAIN: Found video file %s in %", fileExtention, filePath) + Logger.info("MAIN: Found video file %s in %s", fileExtention, filePath) state = copy_link(source, target, useLink, outputDestination) if state == False: Logger.info("MAIN: Failed to link file %s", file) @@ -262,9 +302,9 @@ else: filePath = os.path.join(dirpath, file) fileExtention = os.path.splitext(file)[1] if fileExtention in mediaContainer: # If the file is a video file - if is_sample(file_path, Name): - Logger.info("file %s is a sample file. Removing", file_path) - os.unlink(file_path) #remove samples + if is_sample(filePath, inputName): + Logger.info("file %s is a sample file. Removing", filePath) + os.unlink(filePath) #remove samples else: video2 = video2 + 1 if video2 >= video and video2 > 0: # Check that all video files were moved @@ -273,8 +313,8 @@ else: if status == 0: Logger.info("MAIN: Successful run") # Now we pass off to CouchPotato or Sick-Beard - ## log this output. - old_stdout = sys.stdout ## Still crude, but we wat to capture this for now. + # Log this output + old_stdout = sys.stdout # Still crude, but we wat to capture this for now log_file = open(logFile,"a+") sys.stdout = log_file if inputCategory == movieCategory: diff --git a/UnRAR2/UnRARDLL/license.txt b/UnRAR2/UnRARDLL/license.txt deleted file mode 100644 index 0c1540e5..00000000 --- a/UnRAR2/UnRARDLL/license.txt +++ /dev/null @@ -1,18 +0,0 @@ - The unrar.dll library is freeware. This means: - - 1. All copyrights to RAR and the unrar.dll are exclusively - owned by the author - Alexander Roshal. - - 2. The unrar.dll library may be used in any software to handle RAR - archives without limitations free of charge. - - 3. THE RAR ARCHIVER AND THE UNRAR.DLL LIBRARY ARE DISTRIBUTED "AS IS". - NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT - YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, - DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING - OR MISUSING THIS SOFTWARE. - - Thank you for your interest in RAR and unrar.dll. - - - Alexander L. Roshal \ No newline at end of file diff --git a/UnRAR2/UnRARDLL/unrar.dll b/UnRAR2/UnRARDLL/unrar.dll deleted file mode 100644 index 9757bf3d..00000000 Binary files a/UnRAR2/UnRARDLL/unrar.dll and /dev/null differ diff --git a/UnRAR2/UnRARDLL/unrar.h b/UnRAR2/UnRARDLL/unrar.h deleted file mode 100644 index 4582f2c6..00000000 --- a/UnRAR2/UnRARDLL/unrar.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef _UNRAR_DLL_ -#define _UNRAR_DLL_ - -#define ERAR_END_ARCHIVE 10 -#define ERAR_NO_MEMORY 11 -#define ERAR_BAD_DATA 12 -#define ERAR_BAD_ARCHIVE 13 -#define ERAR_UNKNOWN_FORMAT 14 -#define ERAR_EOPEN 15 -#define ERAR_ECREATE 16 -#define ERAR_ECLOSE 17 -#define ERAR_EREAD 18 -#define ERAR_EWRITE 19 -#define ERAR_SMALL_BUF 20 -#define ERAR_UNKNOWN 21 -#define ERAR_MISSING_PASSWORD 22 - -#define RAR_OM_LIST 0 -#define RAR_OM_EXTRACT 1 -#define RAR_OM_LIST_INCSPLIT 2 - -#define RAR_SKIP 0 -#define RAR_TEST 1 -#define RAR_EXTRACT 2 - -#define RAR_VOL_ASK 0 -#define RAR_VOL_NOTIFY 1 - -#define RAR_DLL_VERSION 4 - -#ifdef _UNIX -#define CALLBACK -#define PASCAL -#define LONG long -#define HANDLE void * -#define LPARAM long -#define UINT unsigned int -#endif - -struct RARHeaderData -{ - char ArcName[260]; - char FileName[260]; - unsigned int Flags; - unsigned int PackSize; - unsigned int UnpSize; - unsigned int HostOS; - unsigned int FileCRC; - unsigned int FileTime; - unsigned int UnpVer; - unsigned int Method; - unsigned int FileAttr; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; -}; - - -struct RARHeaderDataEx -{ - char ArcName[1024]; - wchar_t ArcNameW[1024]; - char FileName[1024]; - wchar_t FileNameW[1024]; - unsigned int Flags; - unsigned int PackSize; - unsigned int PackSizeHigh; - unsigned int UnpSize; - unsigned int UnpSizeHigh; - unsigned int HostOS; - unsigned int FileCRC; - unsigned int FileTime; - unsigned int UnpVer; - unsigned int Method; - unsigned int FileAttr; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Reserved[1024]; -}; - - -struct RAROpenArchiveData -{ - char *ArcName; - unsigned int OpenMode; - unsigned int OpenResult; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; -}; - -struct RAROpenArchiveDataEx -{ - char *ArcName; - wchar_t *ArcNameW; - unsigned int OpenMode; - unsigned int OpenResult; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Flags; - unsigned int Reserved[32]; -}; - -enum UNRARCALLBACK_MESSAGES { - UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD -}; - -typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2); - -typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode); -typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size); - -#ifdef __cplusplus -extern "C" { -#endif - -HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData); -HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData); -int PASCAL RARCloseArchive(HANDLE hArcData); -int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData); -int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData); -int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName); -int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName); -void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData); -void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc); -void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc); -void PASCAL RARSetPassword(HANDLE hArcData,char *Password); -int PASCAL RARGetDllVersion(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/UnRAR2/UnRARDLL/unrar.lib b/UnRAR2/UnRARDLL/unrar.lib deleted file mode 100644 index 0f6b3146..00000000 Binary files a/UnRAR2/UnRARDLL/unrar.lib and /dev/null differ diff --git a/UnRAR2/UnRARDLL/unrardll.txt b/UnRAR2/UnRARDLL/unrardll.txt deleted file mode 100644 index c49dd5b4..00000000 --- a/UnRAR2/UnRARDLL/unrardll.txt +++ /dev/null @@ -1,606 +0,0 @@ - - UnRAR.dll Manual - ~~~~~~~~~~~~~~~~ - - UnRAR.dll is a 32-bit Windows dynamic-link library which provides - file extraction from RAR archives. - - - Exported functions - -==================================================================== -HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData) -==================================================================== - -Description -~~~~~~~~~~~ - Open RAR archive and allocate memory structures - -Parameters -~~~~~~~~~~ -ArchiveData Points to RAROpenArchiveData structure - -struct RAROpenArchiveData -{ - char *ArcName; - UINT OpenMode; - UINT OpenResult; - char *CmtBuf; - UINT CmtBufSize; - UINT CmtSize; - UINT CmtState; -}; - -Structure fields: - -ArcName - Input parameter which should point to zero terminated string - containing the archive name. - -OpenMode - Input parameter. - - Possible values - - RAR_OM_LIST - Open archive for reading file headers only. - - RAR_OM_EXTRACT - Open archive for testing and extracting files. - - RAR_OM_LIST_INCSPLIT - Open archive for reading file headers only. If you open an archive - in such mode, RARReadHeader[Ex] will return all file headers, - including those with "file continued from previous volume" flag. - In case of RAR_OM_LIST such headers are automatically skipped. - So if you process RAR volumes in RAR_OM_LIST_INCSPLIT mode, you will - get several file header records for same file if file is split between - volumes. For such files only the last file header record will contain - the correct file CRC and if you wish to get the correct packed size, - you need to sum up packed sizes of all parts. - -OpenResult - Output parameter. - - Possible values - - 0 Success - ERAR_NO_MEMORY Not enough memory to initialize data structures - ERAR_BAD_DATA Archive header broken - ERAR_BAD_ARCHIVE File is not valid RAR archive - ERAR_UNKNOWN_FORMAT Unknown encryption used for archive headers - ERAR_EOPEN File open error - -CmtBuf - Input parameter which should point to the buffer for archive - comments. Maximum comment size is limited to 64Kb. Comment text is - zero terminated. If the comment text is larger than the buffer - size, the comment text will be truncated. If CmtBuf is set to - NULL, comments will not be read. - -CmtBufSize - Input parameter which should contain size of buffer for archive - comments. - -CmtSize - Output parameter containing size of comments actually read into the - buffer, cannot exceed CmtBufSize. - -CmtState - Output parameter. - - Possible values - - 0 comments not present - 1 Comments read completely - ERAR_NO_MEMORY Not enough memory to extract comments - ERAR_BAD_DATA Broken comment - ERAR_UNKNOWN_FORMAT Unknown comment format - ERAR_SMALL_BUF Buffer too small, comments not completely read - -Return values -~~~~~~~~~~~~~ - Archive handle or NULL in case of error - - -======================================================================== -HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData) -======================================================================== - -Description -~~~~~~~~~~~ - Similar to RAROpenArchive, but uses RAROpenArchiveDataEx structure - allowing to specify Unicode archive name and returning information - about archive flags. - -Parameters -~~~~~~~~~~ -ArchiveData Points to RAROpenArchiveDataEx structure - -struct RAROpenArchiveDataEx -{ - char *ArcName; - wchar_t *ArcNameW; - unsigned int OpenMode; - unsigned int OpenResult; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Flags; - unsigned int Reserved[32]; -}; - -Structure fields: - -ArcNameW - Input parameter which should point to zero terminated Unicode string - containing the archive name or NULL if Unicode name is not specified. - -Flags - Output parameter. Combination of bit flags. - - Possible values - - 0x0001 - Volume attribute (archive volume) - 0x0002 - Archive comment present - 0x0004 - Archive lock attribute - 0x0008 - Solid attribute (solid archive) - 0x0010 - New volume naming scheme ('volname.partN.rar') - 0x0020 - Authenticity information present - 0x0040 - Recovery record present - 0x0080 - Block headers are encrypted - 0x0100 - First volume (set only by RAR 3.0 and later) - -Reserved[32] - Reserved for future use. Must be zero. - -Information on other structure fields and function return values -is available above, in RAROpenArchive function description. - - -==================================================================== -int PASCAL RARCloseArchive(HANDLE hArcData) -==================================================================== - -Description -~~~~~~~~~~~ - Close RAR archive and release allocated memory. It must be called when - archive processing is finished, even if the archive processing was stopped - due to an error. - -Parameters -~~~~~~~~~~ -hArcData - This parameter should contain the archive handle obtained from the - RAROpenArchive function call. - -Return values -~~~~~~~~~~~~~ - 0 Success - ERAR_ECLOSE Archive close error - - -==================================================================== -int PASCAL RARReadHeader(HANDLE hArcData, - struct RARHeaderData *HeaderData) -==================================================================== - -Description -~~~~~~~~~~~ - Read header of file in archive. - -Parameters -~~~~~~~~~~ -hArcData - This parameter should contain the archive handle obtained from the - RAROpenArchive function call. - -HeaderData - It should point to RARHeaderData structure: - -struct RARHeaderData -{ - char ArcName[260]; - char FileName[260]; - UINT Flags; - UINT PackSize; - UINT UnpSize; - UINT HostOS; - UINT FileCRC; - UINT FileTime; - UINT UnpVer; - UINT Method; - UINT FileAttr; - char *CmtBuf; - UINT CmtBufSize; - UINT CmtSize; - UINT CmtState; -}; - -Structure fields: - -ArcName - Output parameter which contains a zero terminated string of the - current archive name. May be used to determine the current volume - name. - -FileName - Output parameter which contains a zero terminated string of the - file name in OEM (DOS) encoding. - -Flags - Output parameter which contains file flags: - - 0x01 - file continued from previous volume - 0x02 - file continued on next volume - 0x04 - file encrypted with password - 0x08 - file comment present - 0x10 - compression of previous files is used (solid flag) - - bits 7 6 5 - - 0 0 0 - dictionary size 64 Kb - 0 0 1 - dictionary size 128 Kb - 0 1 0 - dictionary size 256 Kb - 0 1 1 - dictionary size 512 Kb - 1 0 0 - dictionary size 1024 Kb - 1 0 1 - dictionary size 2048 KB - 1 1 0 - dictionary size 4096 KB - 1 1 1 - file is directory - - Other bits are reserved. - -PackSize - Output parameter means packed file size or size of the - file part if file was split between volumes. - -UnpSize - Output parameter - unpacked file size. - -HostOS - Output parameter - operating system used for archiving: - - 0 - MS DOS; - 1 - OS/2. - 2 - Win32 - 3 - Unix - -FileCRC - Output parameter which contains unpacked file CRC. In case of file parts - split between volumes only the last part contains the correct CRC - and it is accessible only in RAR_OM_LIST_INCSPLIT listing mode. - -FileTime - Output parameter - contains date and time in standard MS DOS format. - -UnpVer - Output parameter - RAR version needed to extract file. - It is encoded as 10 * Major version + minor version. - -Method - Output parameter - packing method. - -FileAttr - Output parameter - file attributes. - -CmtBuf - File comments support is not implemented in the new DLL version yet. - Now CmtState is always 0. - -/* - * Input parameter which should point to the buffer for file - * comments. Maximum comment size is limited to 64Kb. Comment text is - * a zero terminated string in OEM encoding. If the comment text is - * larger than the buffer size, the comment text will be truncated. - * If CmtBuf is set to NULL, comments will not be read. - */ - -CmtBufSize - Input parameter which should contain size of buffer for archive - comments. - -CmtSize - Output parameter containing size of comments actually read into the - buffer, should not exceed CmtBufSize. - -CmtState - Output parameter. - - Possible values - - 0 Absent comments - 1 Comments read completely - ERAR_NO_MEMORY Not enough memory to extract comments - ERAR_BAD_DATA Broken comment - ERAR_UNKNOWN_FORMAT Unknown comment format - ERAR_SMALL_BUF Buffer too small, comments not completely read - -Return values -~~~~~~~~~~~~~ - - 0 Success - ERAR_END_ARCHIVE End of archive - ERAR_BAD_DATA File header broken - - -==================================================================== -int PASCAL RARReadHeaderEx(HANDLE hArcData, - struct RARHeaderDataEx *HeaderData) -==================================================================== - -Description -~~~~~~~~~~~ - Similar to RARReadHeader, but uses RARHeaderDataEx structure, -containing information about Unicode file names and 64 bit file sizes. - -struct RARHeaderDataEx -{ - char ArcName[1024]; - wchar_t ArcNameW[1024]; - char FileName[1024]; - wchar_t FileNameW[1024]; - unsigned int Flags; - unsigned int PackSize; - unsigned int PackSizeHigh; - unsigned int UnpSize; - unsigned int UnpSizeHigh; - unsigned int HostOS; - unsigned int FileCRC; - unsigned int FileTime; - unsigned int UnpVer; - unsigned int Method; - unsigned int FileAttr; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Reserved[1024]; -}; - - -==================================================================== -int PASCAL RARProcessFile(HANDLE hArcData, - int Operation, - char *DestPath, - char *DestName) -==================================================================== - -Description -~~~~~~~~~~~ - Performs action and moves the current position in the archive to - the next file. Extract or test the current file from the archive - opened in RAR_OM_EXTRACT mode. If the mode RAR_OM_LIST is set, - then a call to this function will simply skip the archive position - to the next file. - -Parameters -~~~~~~~~~~ -hArcData - This parameter should contain the archive handle obtained from the - RAROpenArchive function call. - -Operation - File operation. - - Possible values - - RAR_SKIP Move to the next file in the archive. If the - archive is solid and RAR_OM_EXTRACT mode was set - when the archive was opened, the current file will - be processed - the operation will be performed - slower than a simple seek. - - RAR_TEST Test the current file and move to the next file in - the archive. If the archive was opened with - RAR_OM_LIST mode, the operation is equal to - RAR_SKIP. - - RAR_EXTRACT Extract the current file and move to the next file. - If the archive was opened with RAR_OM_LIST mode, - the operation is equal to RAR_SKIP. - - -DestPath - This parameter should point to a zero terminated string containing the - destination directory to which to extract files to. If DestPath is equal - to NULL, it means extract to the current directory. This parameter has - meaning only if DestName is NULL. - -DestName - This parameter should point to a string containing the full path and name - to assign to extracted file or it can be NULL to use the default name. - If DestName is defined (not NULL), it overrides both the original file - name saved in the archive and path specigied in DestPath setting. - - Both DestPath and DestName must be in OEM encoding. If necessary, - use CharToOem to convert text to OEM before passing to this function. - -Return values -~~~~~~~~~~~~~ - 0 Success - ERAR_BAD_DATA File CRC error - ERAR_BAD_ARCHIVE Volume is not valid RAR archive - ERAR_UNKNOWN_FORMAT Unknown archive format - ERAR_EOPEN Volume open error - ERAR_ECREATE File create error - ERAR_ECLOSE File close error - ERAR_EREAD Read error - ERAR_EWRITE Write error - - -Note: if you wish to cancel extraction, return -1 when processing - UCM_PROCESSDATA callback message. - - -==================================================================== -int PASCAL RARProcessFileW(HANDLE hArcData, - int Operation, - wchar_t *DestPath, - wchar_t *DestName) -==================================================================== - -Description -~~~~~~~~~~~ - Unicode version of RARProcessFile. It uses Unicode DestPath - and DestName parameters, other parameters and return values - are the same as in RARProcessFile. - - -==================================================================== -void PASCAL RARSetCallback(HANDLE hArcData, - int PASCAL (*CallbackProc)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2), - LPARAM UserData); -==================================================================== - -Description -~~~~~~~~~~~ - Set a user-defined callback function to process Unrar events. - -Parameters -~~~~~~~~~~ -hArcData - This parameter should contain the archive handle obtained from the - RAROpenArchive function call. - -CallbackProc - It should point to a user-defined callback function. - - The function will be passed four parameters: - - - msg Type of event. Described below. - - UserData User defined value passed to RARSetCallback. - - P1 and P2 Event dependent parameters. Described below. - - - Possible events - - UCM_CHANGEVOLUME Process volume change. - - P1 Points to the zero terminated name - of the next volume. - - P2 The function call mode: - - RAR_VOL_ASK Required volume is absent. The function should - prompt user and return a positive value - to retry or return -1 value to terminate - operation. The function may also specify a new - volume name, placing it to the address specified - by P1 parameter. - - RAR_VOL_NOTIFY Required volume is successfully opened. - This is a notification call and volume name - modification is not allowed. The function should - return a positive value to continue or -1 - to terminate operation. - - UCM_PROCESSDATA Process unpacked data. It may be used to read - a file while it is being extracted or tested - without actual extracting file to disk. - Return a positive value to continue process - or -1 to cancel the archive operation - - P1 Address pointing to the unpacked data. - Function may refer to the data but must not - change it. - - P2 Size of the unpacked data. It is guaranteed - only that the size will not exceed the maximum - dictionary size (4 Mb in RAR 3.0). - - UCM_NEEDPASSWORD DLL needs a password to process archive. - This message must be processed if you wish - to be able to handle archives with encrypted - file names. It can be also used as replacement - of RARSetPassword function even for usual - encrypted files with non-encrypted names. - - P1 Address pointing to the buffer for a password. - You need to copy a password here. - - P2 Size of the password buffer. - - -UserData - User data passed to callback function. - - Other functions of UnRAR.dll should not be called from the callback - function. - -Return values -~~~~~~~~~~~~~ - None - - - -==================================================================== -void PASCAL RARSetChangeVolProc(HANDLE hArcData, - int PASCAL (*ChangeVolProc)(char *ArcName,int Mode)); -==================================================================== - -Obsoleted, use RARSetCallback instead. - - - -==================================================================== -void PASCAL RARSetProcessDataProc(HANDLE hArcData, - int PASCAL (*ProcessDataProc)(unsigned char *Addr,int Size)) -==================================================================== - -Obsoleted, use RARSetCallback instead. - - -==================================================================== -void PASCAL RARSetPassword(HANDLE hArcData, - char *Password); -==================================================================== - -Description -~~~~~~~~~~~ - Set a password to decrypt files. - -Parameters -~~~~~~~~~~ -hArcData - This parameter should contain the archive handle obtained from the - RAROpenArchive function call. - -Password - It should point to a string containing a zero terminated password. - -Return values -~~~~~~~~~~~~~ - None - - -==================================================================== -void PASCAL RARGetDllVersion(); -==================================================================== - -Description -~~~~~~~~~~~ - Returns API version. - -Parameters -~~~~~~~~~~ - None. - -Return values -~~~~~~~~~~~~~ - Returns an integer value denoting UnRAR.dll API version, which is also -defined in unrar.h as RAR_DLL_VERSION. API version number is incremented -only in case of noticeable changes in UnRAR.dll API. Do not confuse it -with version of UnRAR.dll stored in DLL resources, which is incremented -with every DLL rebuild. - - If RARGetDllVersion() returns a value lower than UnRAR.dll which your -application was designed for, it may indicate that DLL version is too old -and it will fail to provide all necessary functions to your application. - - This function is absent in old versions of UnRAR.dll, so it is safer -to use LoadLibrary and GetProcAddress to access this function. - diff --git a/UnRAR2/UnRARDLL/whatsnew.txt b/UnRAR2/UnRARDLL/whatsnew.txt deleted file mode 100644 index 874d19b1..00000000 --- a/UnRAR2/UnRARDLL/whatsnew.txt +++ /dev/null @@ -1,80 +0,0 @@ -List of unrar.dll API changes. We do not include performance and reliability -improvements into this list, but this library and RAR/UnRAR tools share -the same source code. So the latest version of unrar.dll usually contains -same decompression algorithm changes as the latest UnRAR version. -============================================================================ - --- 18 January 2008 - -all LONG parameters of CallbackProc function were changed -to LPARAM type for 64 bit mode compatibility. - - --- 12 December 2007 - -Added new RAR_OM_LIST_INCSPLIT open mode for function RAROpenArchive. - - --- 14 August 2007 - -Added NoCrypt\unrar_nocrypt.dll without decryption code for those -applications where presence of encryption or decryption code is not -allowed because of legal restrictions. - - --- 14 December 2006 - -Added ERAR_MISSING_PASSWORD error type. This error is returned -if empty password is specified for encrypted file. - - --- 12 June 2003 - -Added RARProcessFileW function, Unicode version of RARProcessFile - - --- 9 August 2002 - -Added RAROpenArchiveEx function allowing to specify Unicode archive -name and get archive flags. - - --- 24 January 2002 - -Added RARReadHeaderEx function allowing to read Unicode file names -and 64 bit file sizes. - - --- 23 January 2002 - -Added ERAR_UNKNOWN error type (it is used for all errors which -do not have special ERAR code yet) and UCM_NEEDPASSWORD callback -message. - -Unrar.dll automatically opens all next volumes not only when extracting, -but also in RAR_OM_LIST mode. - - --- 27 November 2001 - -RARSetChangeVolProc and RARSetProcessDataProc are replaced by -the single callback function installed with RARSetCallback. -Unlike old style callbacks, the new function accepts the user defined -parameter. Unrar.dll still supports RARSetChangeVolProc and -RARSetProcessDataProc for compatibility purposes, but if you write -a new application, better use RARSetCallback. - -File comments support is not implemented in the new DLL version yet. -Now CmtState is always 0. - - --- 13 August 2001 - -Added RARGetDllVersion function, so you may distinguish old unrar.dll, -which used C style callback functions and the new one with PASCAL callbacks. - - --- 10 May 2001 - -Callback functions in RARSetChangeVolProc and RARSetProcessDataProc -use PASCAL style call convention now. diff --git a/UnRAR2/UnRARDLL/x64/readme.txt b/UnRAR2/UnRARDLL/x64/readme.txt deleted file mode 100644 index bbfb340d..00000000 --- a/UnRAR2/UnRARDLL/x64/readme.txt +++ /dev/null @@ -1 +0,0 @@ -This is x64 version of unrar.dll. diff --git a/UnRAR2/UnRARDLL/x64/unrar64.dll b/UnRAR2/UnRARDLL/x64/unrar64.dll deleted file mode 100644 index e17a19e5..00000000 Binary files a/UnRAR2/UnRARDLL/x64/unrar64.dll and /dev/null differ diff --git a/UnRAR2/UnRARDLL/x64/unrar64.lib b/UnRAR2/UnRARDLL/x64/unrar64.lib deleted file mode 100644 index fd037919..00000000 Binary files a/UnRAR2/UnRARDLL/x64/unrar64.lib and /dev/null differ diff --git a/UnRAR2/__init__.py b/UnRAR2/__init__.py deleted file mode 100644 index b5c9a4d3..00000000 --- a/UnRAR2/__init__.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright (c) 2003-2005 Jimmy Retzlaff, 2008 Konstantin Yegupov -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -pyUnRAR2 is a ctypes based wrapper around the free UnRAR.dll. - -It is an modified version of Jimmy Retzlaff's pyUnRAR - more simple, -stable and foolproof. -Notice that it has INCOMPATIBLE interface. - -It enables reading and unpacking of archives created with the -RAR/WinRAR archivers. There is a low-level interface which is very -similar to the C interface provided by UnRAR. There is also a -higher level interface which makes some common operations easier. -""" - -__version__ = '0.99.2' - -try: - WindowsError - in_windows = True -except NameError: - in_windows = False - -if in_windows: - from windows import RarFileImplementation -else: - from unix import RarFileImplementation - - -import fnmatch, time, weakref - -class RarInfo(object): - """Represents a file header in an archive. Don't instantiate directly. - Use only to obtain information about file. - YOU CANNOT EXTRACT FILE CONTENTS USING THIS OBJECT. - USE METHODS OF RarFile CLASS INSTEAD. - - Properties: - index - index of file within the archive - filename - name of the file in the archive including path (if any) - datetime - file date/time as a struct_time suitable for time.strftime - isdir - True if the file is a directory - size - size in bytes of the uncompressed file - comment - comment associated with the file - - Note - this is not currently intended to be a Python file-like object. - """ - - def __init__(self, rarfile, data): - self.rarfile = weakref.proxy(rarfile) - self.index = data['index'] - self.filename = data['filename'] - self.isdir = data['isdir'] - self.size = data['size'] - self.datetime = data['datetime'] - self.comment = data['comment'] - - - - def __str__(self): - try : - arcName = self.rarfile.archiveName - except ReferenceError: - arcName = "[ARCHIVE_NO_LONGER_LOADED]" - return '' % (self.filename, arcName) - -class RarFile(RarFileImplementation): - - def __init__(self, archiveName, password=None): - """Instantiate the archive. - - archiveName is the name of the RAR file. - password is used to decrypt the files in the archive. - - Properties: - comment - comment associated with the archive - - >>> print RarFile('test.rar').comment - This is a test. - """ - self.archiveName = archiveName - RarFileImplementation.init(self, password) - - def __del__(self): - self.destruct() - - def infoiter(self): - """Iterate over all the files in the archive, generating RarInfos. - - >>> import os - >>> for fileInArchive in RarFile('test.rar').infoiter(): - ... print os.path.split(fileInArchive.filename)[-1], - ... print fileInArchive.isdir, - ... print fileInArchive.size, - ... print fileInArchive.comment, - ... print tuple(fileInArchive.datetime)[0:5], - ... print time.strftime('%a, %d %b %Y %H:%M', fileInArchive.datetime) - test True 0 None (2003, 6, 30, 1, 59) Mon, 30 Jun 2003 01:59 - test.txt False 20 None (2003, 6, 30, 2, 1) Mon, 30 Jun 2003 02:01 - this.py False 1030 None (2002, 2, 8, 16, 47) Fri, 08 Feb 2002 16:47 - """ - for params in RarFileImplementation.infoiter(self): - yield RarInfo(self, params) - - def infolist(self): - """Return a list of RarInfos, descripting the contents of the archive.""" - return list(self.infoiter()) - - def read_files(self, condition='*'): - """Read specific files from archive into memory. - If "condition" is a list of numbers, then return files which have those positions in infolist. - If "condition" is a string, then it is treated as a wildcard for names of files to extract. - If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object - and returns boolean True (extract) or False (skip). - If "condition" is omitted, all files are returned. - - Returns list of tuples (RarInfo info, str contents) - """ - checker = condition2checker(condition) - return RarFileImplementation.read_files(self, checker) - - - def extract(self, condition='*', path='.', withSubpath=True, overwrite=True): - """Extract specific files from archive to disk. - - If "condition" is a list of numbers, then extract files which have those positions in infolist. - If "condition" is a string, then it is treated as a wildcard for names of files to extract. - If "condition" is a function, it is treated as a callback function, which accepts a RarInfo object - and returns either boolean True (extract) or boolean False (skip). - DEPRECATED: If "condition" callback returns string (only supported for Windows) - - that string will be used as a new name to save the file under. - If "condition" is omitted, all files are extracted. - - "path" is a directory to extract to - "withSubpath" flag denotes whether files are extracted with their full path in the archive. - "overwrite" flag denotes whether extracted files will overwrite old ones. Defaults to true. - - Returns list of RarInfos for extracted files.""" - checker = condition2checker(condition) - return RarFileImplementation.extract(self, checker, path, withSubpath, overwrite) - -def condition2checker(condition): - """Converts different condition types to callback""" - if type(condition) in [str, unicode]: - def smatcher(info): - return fnmatch.fnmatch(info.filename, condition) - return smatcher - elif type(condition) in [list, tuple] and type(condition[0]) in [int, long]: - def imatcher(info): - return info.index in condition - return imatcher - elif callable(condition): - return condition - else: - raise TypeError - - diff --git a/UnRAR2/license.txt b/UnRAR2/license.txt deleted file mode 100644 index a395801b..00000000 --- a/UnRAR2/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2003-2005 Jimmy Retzlaff, 2008 Konstantin Yegupov - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/UnRAR2/rar_exceptions.py b/UnRAR2/rar_exceptions.py deleted file mode 100644 index d90d1c8d..00000000 --- a/UnRAR2/rar_exceptions.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2003-2005 Jimmy Retzlaff, 2008 Konstantin Yegupov -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# Low level interface - see UnRARDLL\UNRARDLL.TXT - - -class ArchiveHeaderBroken(Exception): pass -class InvalidRARArchive(Exception): pass -class FileOpenError(Exception): pass -class IncorrectRARPassword(Exception): pass -class InvalidRARArchiveUsage(Exception): pass diff --git a/UnRAR2/setup.py b/UnRAR2/setup.py deleted file mode 100644 index 7fab60fe..00000000 --- a/UnRAR2/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -# setup.py, config file for distutils - -import __init__ - -from distutils.core import setup -from distutils.command.install_data import install_data -import os - - -class smart_install_data(install_data): - def run(self): - #need to change self.install_dir to the actual library dir - install_cmd = self.get_finalized_command('install') - self.install_dir = getattr(install_cmd, 'install_lib') - return install_data.run(self) - - -data_files = [] -for dirpath, dirnames, filenames in os.walk(r'.'): - for dirname in ['.svn','build', 'dist', '_sgbak', '.hg']: - try: - dirnames.remove(dirname) - except ValueError: - pass - for filename in [fn for fn in filenames if os.path.splitext(fn)[-1].lower() in ('.pyc', '.pyo', '.scc')]: - filenames.remove(filename) - parts = ['UnRAR2']+dirpath.split(os.sep)[1:] - - data_files.append((os.path.join(*parts), [os.path.join(dirpath, fn) for fn in filenames])) - -setup(name='pyUnRAR2', - version=__init__.__version__, - description='Improved Python wrapper around the free UnRAR.dll', - long_description=__init__.__doc__.strip(), - author='Konstantin Yegupov', - author_email='yk4ever@gmail.com', - url='http://code.google.com/py-unrar2', - license='MIT', - platforms='Windows', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Win32 (MS Windows)', - 'License :: OSI Approved :: MIT License', - 'Natural Language :: English', - 'Operating System :: Microsoft :: Windows', - 'Programming Language :: Python', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: System :: Archiving :: Compression', - ], - packages=['UnRAR2'], - package_dir={'UnRAR2' : ''}, - data_files=data_files, - cmdclass = {'install_data': smart_install_data}, - ) diff --git a/UnRAR2/test_UnRAR2.py b/UnRAR2/test_UnRAR2.py deleted file mode 100644 index 49fc6e01..00000000 --- a/UnRAR2/test_UnRAR2.py +++ /dev/null @@ -1,139 +0,0 @@ -import os, sys - -import UnRAR2 -from UnRAR2.rar_exceptions import * - - -def cleanup(dir='test'): - for path, dirs, files in os.walk(dir): - for fn in files: - os.remove(os.path.join(path, fn)) - for dir in dirs: - os.removedirs(os.path.join(path, dir)) - - - - - -# reuse RarArchive object, en -cleanup() -rarc = UnRAR2.RarFile('test.rar') -rarc.infolist() -for info in rarc.infoiter(): - saveinfo = info - assert (str(info)=="""""") - break -rarc.extract() -assert os.path.exists('test'+os.sep+'test.txt') -assert os.path.exists('test'+os.sep+'this.py') -del rarc -assert (str(saveinfo)=="""""") -cleanup() - -# extract all the files in test.rar -cleanup() -UnRAR2.RarFile('test.rar').extract() -assert os.path.exists('test'+os.sep+'test.txt') -assert os.path.exists('test'+os.sep+'this.py') -cleanup() - -# extract all the files in test.rar matching the wildcard *.txt -cleanup() -UnRAR2.RarFile('test.rar').extract('*.txt') -assert os.path.exists('test'+os.sep+'test.txt') -assert not os.path.exists('test'+os.sep+'this.py') -cleanup() - - -# check the name and size of each file, extracting small ones -cleanup() -archive = UnRAR2.RarFile('test.rar') -assert archive.comment == 'This is a test.' -archive.extract(lambda rarinfo: rarinfo.size <= 1024) -for rarinfo in archive.infoiter(): - if rarinfo.size <= 1024 and not rarinfo.isdir: - assert rarinfo.size == os.stat(rarinfo.filename).st_size -assert file('test'+os.sep+'test.txt', 'rt').read() == 'This is only a test.' -assert not os.path.exists('test'+os.sep+'this.py') -cleanup() - - -# extract this.py, overriding it's destination -cleanup('test2') -archive = UnRAR2.RarFile('test.rar') -archive.extract('*.py', 'test2', False) -assert os.path.exists('test2'+os.sep+'this.py') -cleanup('test2') - - -# extract test.txt to memory -cleanup() -archive = UnRAR2.RarFile('test.rar') -entries = UnRAR2.RarFile('test.rar').read_files('*test.txt') -assert len(entries)==1 -assert entries[0][0].filename.endswith('test.txt') -assert entries[0][1]=='This is only a test.' - - -# extract all the files in test.rar with overwriting -cleanup() -fo = open('test'+os.sep+'test.txt',"wt") -fo.write("blah") -fo.close() -UnRAR2.RarFile('test.rar').extract('*.txt') -assert open('test'+os.sep+'test.txt',"rt").read()!="blah" -cleanup() - -# extract all the files in test.rar without overwriting -cleanup() -fo = open('test'+os.sep+'test.txt',"wt") -fo.write("blahblah") -fo.close() -UnRAR2.RarFile('test.rar').extract('*.txt', overwrite = False) -assert open('test'+os.sep+'test.txt',"rt").read()=="blahblah" -cleanup() - -# list big file in an archive -list(UnRAR2.RarFile('test_nulls.rar').infoiter()) - -# extract files from an archive with protected files -cleanup() -UnRAR2.RarFile('test_protected_files.rar', password="protected").extract() -assert os.path.exists('test'+os.sep+'top_secret_xxx_file.txt') -cleanup() -errored = False -try: - UnRAR2.RarFile('test_protected_files.rar', password="proteqted").extract() -except IncorrectRARPassword: - errored = True -assert not os.path.exists('test'+os.sep+'top_secret_xxx_file.txt') -assert errored -cleanup() - -# extract files from an archive with protected headers -cleanup() -UnRAR2.RarFile('test_protected_headers.rar', password="secret").extract() -assert os.path.exists('test'+os.sep+'top_secret_xxx_file.txt') -cleanup() -errored = False -try: - UnRAR2.RarFile('test_protected_headers.rar', password="seqret").extract() -except IncorrectRARPassword: - errored = True -assert not os.path.exists('test'+os.sep+'top_secret_xxx_file.txt') -assert errored -cleanup() - -# make sure docstring examples are working -import doctest -doctest.testmod(UnRAR2) - -# update documentation -import pydoc -pydoc.writedoc(UnRAR2) - -# cleanup -try: - os.remove('__init__.pyc') -except: - pass diff --git a/UnRAR2/unix.py b/UnRAR2/unix.py deleted file mode 100644 index 9d87b18c..00000000 --- a/UnRAR2/unix.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright (c) 2003-2005 Jimmy Retzlaff, 2008 Konstantin Yegupov -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# Unix version uses unrar command line executable - -import subprocess -import gc - -import os, os.path -import time, re - -from rar_exceptions import * - -class UnpackerNotInstalled(Exception): pass - -rar_executable_cached = None - -def call_unrar(params): - "Calls rar/unrar command line executable, returns stdout pipe" - global rar_executable_cached - if rar_executable_cached is None: - for command in ('unrar', 'rar'): - try: - subprocess.Popen([command], stdout=subprocess.PIPE) - rar_executable_cached = command - break - except OSError: - pass - if rar_executable_cached is None: - raise UnpackerNotInstalled("No suitable RAR unpacker installed") - - assert type(params) == list, "params must be list" - args = [rar_executable_cached] + params - try: - gc.disable() # See http://bugs.python.org/issue1336 - return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - finally: - gc.enable() - -class RarFileImplementation(object): - - def init(self, password=None): - self.password = password - - - - stdoutdata, stderrdata = self.call('v', []).communicate() - - for line in stderrdata.splitlines(): - if line.strip().startswith("Cannot open"): - raise FileOpenError - if line.find("CRC failed")>=0: - raise IncorrectRARPassword - accum = [] - source = iter(stdoutdata.splitlines()) - line = '' - while not (line.startswith('Comment:') or line.startswith('Pathname/Comment')): - if line.strip().endswith('is not RAR archive'): - raise InvalidRARArchive - line = source.next() - while not line.startswith('Pathname/Comment'): - accum.append(line.rstrip('\n')) - line = source.next() - if len(accum): - accum[0] = accum[0][9:] - self.comment = '\n'.join(accum[:-1]) - else: - self.comment = None - - def escaped_password(self): - return '-' if self.password == None else self.password - - - def call(self, cmd, options=[], files=[]): - options2 = options + ['p'+self.escaped_password()] - soptions = ['-'+x for x in options2] - return call_unrar([cmd]+soptions+['--',self.archiveName]+files) - - def infoiter(self): - - stdoutdata, stderrdata = self.call('v', ['c-']).communicate() - - for line in stderrdata.splitlines(): - if line.strip().startswith("Cannot open"): - raise FileOpenError - - accum = [] - source = iter(stdoutdata.splitlines()) - line = '' - while not line.startswith('--------------'): - if line.strip().endswith('is not RAR archive'): - raise InvalidRARArchive - if line.find("CRC failed")>=0: - raise IncorrectRARPassword - line = source.next() - line = source.next() - i = 0 - re_spaces = re.compile(r"\s+") - while not line.startswith('--------------'): - accum.append(line) - if len(accum)==2: - data = {} - data['index'] = i - data['filename'] = accum[0].strip() - info = re_spaces.split(accum[1].strip()) - data['size'] = int(info[0]) - attr = info[5] - data['isdir'] = 'd' in attr.lower() - data['datetime'] = time.strptime(info[3]+" "+info[4], '%d-%m-%y %H:%M') - data['comment'] = None - yield data - accum = [] - i += 1 - line = source.next() - - def read_files(self, checker): - res = [] - for info in self.infoiter(): - checkres = checker(info) - if checkres==True and not info.isdir: - pipe = self.call('p', ['inul'], [info.filename]).stdout - res.append((info, pipe.read())) - return res - - - def extract(self, checker, path, withSubpath, overwrite): - res = [] - command = 'x' - if not withSubpath: - command = 'e' - options = [] - if overwrite: - options.append('o+') - else: - options.append('o-') - if not path.endswith(os.sep): - path += os.sep - names = [] - for info in self.infoiter(): - checkres = checker(info) - if type(checkres) in [str, unicode]: - raise NotImplementedError("Condition callbacks returning strings are deprecated and only supported in Windows") - if checkres==True and not info.isdir: - names.append(info.filename) - res.append(info) - names.append(path) - proc = self.call(command, options, names) - stdoutdata, stderrdata = proc.communicate() - if stderrdata.find("CRC failed")>=0: - raise IncorrectRARPassword - return res - - def destruct(self): - pass - - diff --git a/UnRAR2/windows.py b/UnRAR2/windows.py deleted file mode 100644 index bb92481b..00000000 --- a/UnRAR2/windows.py +++ /dev/null @@ -1,309 +0,0 @@ -# Copyright (c) 2003-2005 Jimmy Retzlaff, 2008 Konstantin Yegupov -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# Low level interface - see UnRARDLL\UNRARDLL.TXT - -from __future__ import generators - -import ctypes, ctypes.wintypes -import os, os.path, sys -import Queue -import time - -from rar_exceptions import * - -ERAR_END_ARCHIVE = 10 -ERAR_NO_MEMORY = 11 -ERAR_BAD_DATA = 12 -ERAR_BAD_ARCHIVE = 13 -ERAR_UNKNOWN_FORMAT = 14 -ERAR_EOPEN = 15 -ERAR_ECREATE = 16 -ERAR_ECLOSE = 17 -ERAR_EREAD = 18 -ERAR_EWRITE = 19 -ERAR_SMALL_BUF = 20 -ERAR_UNKNOWN = 21 - -RAR_OM_LIST = 0 -RAR_OM_EXTRACT = 1 - -RAR_SKIP = 0 -RAR_TEST = 1 -RAR_EXTRACT = 2 - -RAR_VOL_ASK = 0 -RAR_VOL_NOTIFY = 1 - -RAR_DLL_VERSION = 3 - -# enum UNRARCALLBACK_MESSAGES -UCM_CHANGEVOLUME = 0 -UCM_PROCESSDATA = 1 -UCM_NEEDPASSWORD = 2 - -architecture_bits = ctypes.sizeof(ctypes.c_voidp)*8 -dll_name = "unrar.dll" -if architecture_bits == 64: - dll_name = "x64\\unrar64.dll" - - -try: - unrar = ctypes.WinDLL(os.path.join(os.path.split(__file__)[0], 'UnRARDLL', dll_name)) -except WindowsError: - unrar = ctypes.WinDLL(dll_name) - - -class RAROpenArchiveDataEx(ctypes.Structure): - def __init__(self, ArcName=None, ArcNameW=u'', OpenMode=RAR_OM_LIST): - self.CmtBuf = ctypes.c_buffer(64*1024) - ctypes.Structure.__init__(self, ArcName=ArcName, ArcNameW=ArcNameW, OpenMode=OpenMode, _CmtBuf=ctypes.addressof(self.CmtBuf), CmtBufSize=ctypes.sizeof(self.CmtBuf)) - - _fields_ = [ - ('ArcName', ctypes.c_char_p), - ('ArcNameW', ctypes.c_wchar_p), - ('OpenMode', ctypes.c_uint), - ('OpenResult', ctypes.c_uint), - ('_CmtBuf', ctypes.c_voidp), - ('CmtBufSize', ctypes.c_uint), - ('CmtSize', ctypes.c_uint), - ('CmtState', ctypes.c_uint), - ('Flags', ctypes.c_uint), - ('Reserved', ctypes.c_uint*32), - ] - -class RARHeaderDataEx(ctypes.Structure): - def __init__(self): - self.CmtBuf = ctypes.c_buffer(64*1024) - ctypes.Structure.__init__(self, _CmtBuf=ctypes.addressof(self.CmtBuf), CmtBufSize=ctypes.sizeof(self.CmtBuf)) - - _fields_ = [ - ('ArcName', ctypes.c_char*1024), - ('ArcNameW', ctypes.c_wchar*1024), - ('FileName', ctypes.c_char*1024), - ('FileNameW', ctypes.c_wchar*1024), - ('Flags', ctypes.c_uint), - ('PackSize', ctypes.c_uint), - ('PackSizeHigh', ctypes.c_uint), - ('UnpSize', ctypes.c_uint), - ('UnpSizeHigh', ctypes.c_uint), - ('HostOS', ctypes.c_uint), - ('FileCRC', ctypes.c_uint), - ('FileTime', ctypes.c_uint), - ('UnpVer', ctypes.c_uint), - ('Method', ctypes.c_uint), - ('FileAttr', ctypes.c_uint), - ('_CmtBuf', ctypes.c_voidp), - ('CmtBufSize', ctypes.c_uint), - ('CmtSize', ctypes.c_uint), - ('CmtState', ctypes.c_uint), - ('Reserved', ctypes.c_uint*1024), - ] - -def DosDateTimeToTimeTuple(dosDateTime): - """Convert an MS-DOS format date time to a Python time tuple. - """ - dosDate = dosDateTime >> 16 - dosTime = dosDateTime & 0xffff - day = dosDate & 0x1f - month = (dosDate >> 5) & 0xf - year = 1980 + (dosDate >> 9) - second = 2*(dosTime & 0x1f) - minute = (dosTime >> 5) & 0x3f - hour = dosTime >> 11 - return time.localtime(time.mktime((year, month, day, hour, minute, second, 0, 1, -1))) - -def _wrap(restype, function, argtypes): - result = function - result.argtypes = argtypes - result.restype = restype - return result - -RARGetDllVersion = _wrap(ctypes.c_int, unrar.RARGetDllVersion, []) - -RAROpenArchiveEx = _wrap(ctypes.wintypes.HANDLE, unrar.RAROpenArchiveEx, [ctypes.POINTER(RAROpenArchiveDataEx)]) - -RARReadHeaderEx = _wrap(ctypes.c_int, unrar.RARReadHeaderEx, [ctypes.wintypes.HANDLE, ctypes.POINTER(RARHeaderDataEx)]) - -_RARSetPassword = _wrap(ctypes.c_int, unrar.RARSetPassword, [ctypes.wintypes.HANDLE, ctypes.c_char_p]) -def RARSetPassword(*args, **kwargs): - _RARSetPassword(*args, **kwargs) - -RARProcessFile = _wrap(ctypes.c_int, unrar.RARProcessFile, [ctypes.wintypes.HANDLE, ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p]) - -RARCloseArchive = _wrap(ctypes.c_int, unrar.RARCloseArchive, [ctypes.wintypes.HANDLE]) - -UNRARCALLBACK = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint, ctypes.c_long, ctypes.c_long, ctypes.c_long) -RARSetCallback = _wrap(ctypes.c_int, unrar.RARSetCallback, [ctypes.wintypes.HANDLE, UNRARCALLBACK, ctypes.c_long]) - - - -RARExceptions = { - ERAR_NO_MEMORY : MemoryError, - ERAR_BAD_DATA : ArchiveHeaderBroken, - ERAR_BAD_ARCHIVE : InvalidRARArchive, - ERAR_EOPEN : FileOpenError, - } - -class PassiveReader: - """Used for reading files to memory""" - def __init__(self, usercallback = None): - self.buf = [] - self.ucb = usercallback - - def _callback(self, msg, UserData, P1, P2): - if msg == UCM_PROCESSDATA: - data = (ctypes.c_char*P2).from_address(P1).raw - if self.ucb!=None: - self.ucb(data) - else: - self.buf.append(data) - return 1 - - def get_result(self): - return ''.join(self.buf) - -class RarInfoIterator(object): - def __init__(self, arc): - self.arc = arc - self.index = 0 - self.headerData = RARHeaderDataEx() - self.res = RARReadHeaderEx(self.arc._handle, ctypes.byref(self.headerData)) - if self.res==ERAR_BAD_DATA: - raise IncorrectRARPassword - self.arc.lockStatus = "locked" - self.arc.needskip = False - - def __iter__(self): - return self - - def next(self): - if self.index>0: - if self.arc.needskip: - RARProcessFile(self.arc._handle, RAR_SKIP, None, None) - self.res = RARReadHeaderEx(self.arc._handle, ctypes.byref(self.headerData)) - - if self.res: - raise StopIteration - self.arc.needskip = True - - data = {} - data['index'] = self.index - data['filename'] = self.headerData.FileName - data['datetime'] = DosDateTimeToTimeTuple(self.headerData.FileTime) - data['isdir'] = ((self.headerData.Flags & 0xE0) == 0xE0) - data['size'] = self.headerData.UnpSize + (self.headerData.UnpSizeHigh << 32) - if self.headerData.CmtState == 1: - data['comment'] = self.headerData.CmtBuf.value - else: - data['comment'] = None - self.index += 1 - return data - - - def __del__(self): - self.arc.lockStatus = "finished" - -def generate_password_provider(password): - def password_provider_callback(msg, UserData, P1, P2): - if msg == UCM_NEEDPASSWORD and password!=None: - (ctypes.c_char*P2).from_address(P1).value = password - return 1 - return password_provider_callback - -class RarFileImplementation(object): - - def init(self, password=None): - self.password = password - archiveData = RAROpenArchiveDataEx(ArcNameW=self.archiveName, OpenMode=RAR_OM_EXTRACT) - self._handle = RAROpenArchiveEx(ctypes.byref(archiveData)) - self.c_callback = UNRARCALLBACK(generate_password_provider(self.password)) - RARSetCallback(self._handle, self.c_callback, 1) - - if archiveData.OpenResult != 0: - raise RARExceptions[archiveData.OpenResult] - - if archiveData.CmtState == 1: - self.comment = archiveData.CmtBuf.value - else: - self.comment = None - - if password: - RARSetPassword(self._handle, password) - - self.lockStatus = "ready" - - - - def destruct(self): - if self._handle and RARCloseArchive: - RARCloseArchive(self._handle) - - def make_sure_ready(self): - if self.lockStatus == "locked": - raise InvalidRARArchiveUsage("cannot execute infoiter() without finishing previous one") - if self.lockStatus == "finished": - self.destruct() - self.init(self.password) - - def infoiter(self): - self.make_sure_ready() - return RarInfoIterator(self) - - def read_files(self, checker): - res = [] - for info in self.infoiter(): - if checker(info) and not info.isdir: - reader = PassiveReader() - c_callback = UNRARCALLBACK(reader._callback) - RARSetCallback(self._handle, c_callback, 1) - tmpres = RARProcessFile(self._handle, RAR_TEST, None, None) - if tmpres==ERAR_BAD_DATA: - raise IncorrectRARPassword - self.needskip = False - res.append((info, reader.get_result())) - return res - - - def extract(self, checker, path, withSubpath, overwrite): - res = [] - for info in self.infoiter(): - checkres = checker(info) - if checkres!=False and not info.isdir: - if checkres==True: - fn = info.filename - if not withSubpath: - fn = os.path.split(fn)[-1] - target = os.path.join(path, fn) - else: - raise DeprecationWarning, "Condition callbacks returning strings are deprecated and only supported in Windows" - target = checkres - if overwrite or (not os.path.exists(target)): - tmpres = RARProcessFile(self._handle, RAR_EXTRACT, None, target) - if tmpres==ERAR_BAD_DATA: - raise IncorrectRARPassword - - self.needskip = False - res.append(info) - return res - -