19 changed files with 1925 additions and 9 deletions
@ -0,0 +1,27 @@ |
|||
Metadata-Version: 1.0 |
|||
Name: pyUnRAR2 |
|||
Version: 0.99.2 |
|||
Summary: Improved Python wrapper around the free UnRAR.dll |
|||
Home-page: http://code.google.com/py-unrar2 |
|||
Author: Konstantin Yegupov |
|||
Author-email: yk4ever@gmail.com |
|||
License: MIT |
|||
Description: 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. |
|||
Platform: Windows |
|||
Classifier: Development Status :: 4 - Beta |
|||
Classifier: Environment :: Win32 (MS Windows) |
|||
Classifier: License :: OSI Approved :: MIT License |
|||
Classifier: Natural Language :: English |
|||
Classifier: Operating System :: Microsoft :: Windows |
|||
Classifier: Programming Language :: Python |
|||
Classifier: Topic :: Software Development :: Libraries :: Python Modules |
|||
Classifier: Topic :: System :: Archiving :: Compression |
@ -0,0 +1,191 @@ |
|||
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
|||
<html><head><title>Python: package UnRAR2</title> |
|||
</head><body bgcolor="#f0f0f8"> |
|||
|
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> |
|||
<tr bgcolor="#7799ee"> |
|||
<td valign=bottom> <br> |
|||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>UnRAR2</strong></big></big> (version 0.99.1)</font></td |
|||
><td align=right valign=bottom |
|||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:///C|/python26/lib/site-packages/unrar2/__init__.py">c:\python26\lib\site-packages\unrar2\__init__.py</a></font></td></tr></table> |
|||
<p><tt>pyUnRAR2 is a ctypes based wrapper around the free UnRAR.dll. <br> |
|||
<br> |
|||
It is an modified version of Jimmy Retzlaff's pyUnRAR - more simple,<br> |
|||
stable and foolproof.<br> |
|||
Notice that it has INCOMPATIBLE interface.<br> |
|||
<br> |
|||
It enables reading and unpacking of archives created with the<br> |
|||
RAR/WinRAR archivers. There is a low-level interface which is very<br> |
|||
similar to the C interface provided by UnRAR. There is also a<br> |
|||
higher level interface which makes some common operations easier.</tt></p> |
|||
<p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#aa55cc"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr> |
|||
|
|||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> |
|||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="UnRAR2.rar_exceptions.html">rar_exceptions</a><br> |
|||
<a href="UnRAR2.setup.html">setup</a><br> |
|||
</td><td width="25%" valign=top><a href="UnRAR2.test_UnRAR2.html">test_UnRAR2</a><br> |
|||
<a href="UnRAR2.unix.html">unix</a><br> |
|||
</td><td width="25%" valign=top><a href="UnRAR2.windows.html">windows</a><br> |
|||
</td><td width="25%" valign=top></td></tr></table></td></tr></table><p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#ee77aa"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> |
|||
|
|||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> |
|||
<td width="100%"><dl> |
|||
<dt><font face="helvetica, arial"><a href="UnRAR2.windows.html#RarFileImplementation">UnRAR2.windows.RarFileImplementation</a>(<a href="__builtin__.html#object">__builtin__.object</a>) |
|||
</font></dt><dd> |
|||
<dl> |
|||
<dt><font face="helvetica, arial"><a href="UnRAR2.html#RarFile">RarFile</a> |
|||
</font></dt></dl> |
|||
</dd> |
|||
<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a> |
|||
</font></dt><dd> |
|||
<dl> |
|||
<dt><font face="helvetica, arial"><a href="UnRAR2.html#RarInfo">RarInfo</a> |
|||
</font></dt></dl> |
|||
</dd> |
|||
</dl> |
|||
<p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#ffc8d8"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#000000" face="helvetica, arial"><a name="RarFile">class <strong>RarFile</strong></a>(<a href="UnRAR2.windows.html#RarFileImplementation">UnRAR2.windows.RarFileImplementation</a>)</font></td></tr> |
|||
|
|||
<tr><td bgcolor="#ffc8d8"><tt> </tt></td><td> </td> |
|||
<td width="100%"><dl><dt>Method resolution order:</dt> |
|||
<dd><a href="UnRAR2.html#RarFile">RarFile</a></dd> |
|||
<dd><a href="UnRAR2.windows.html#RarFileImplementation">UnRAR2.windows.RarFileImplementation</a></dd> |
|||
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd> |
|||
</dl> |
|||
<hr> |
|||
Methods defined here:<br> |
|||
<dl><dt><a name="RarFile-__del__"><strong>__del__</strong></a>(self)</dt></dl> |
|||
|
|||
<dl><dt><a name="RarFile-__init__"><strong>__init__</strong></a>(self, archiveName, password<font color="#909090">=None</font>)</dt><dd><tt>Instantiate the archive.<br> |
|||
<br> |
|||
archiveName is the name of the RAR file.<br> |
|||
password is used to decrypt the files in the archive.<br> |
|||
<br> |
|||
Properties:<br> |
|||
comment - comment associated with the archive<br> |
|||
<br> |
|||
>>> print <a href="#RarFile">RarFile</a>('test.rar').comment<br> |
|||
This is a test.</tt></dd></dl> |
|||
|
|||
<dl><dt><a name="RarFile-extract"><strong>extract</strong></a>(self, condition<font color="#909090">='*'</font>, path<font color="#909090">='.'</font>, withSubpath<font color="#909090">=True</font>, overwrite<font color="#909090">=True</font>)</dt><dd><tt>Extract specific files from archive to disk.<br> |
|||
<br> |
|||
If "condition" is a list of numbers, then extract files which have those positions in infolist.<br> |
|||
If "condition" is a string, then it is treated as a wildcard for names of files to extract.<br> |
|||
If "condition" is a function, it is treated as a callback function, which accepts a <a href="#RarInfo">RarInfo</a> <a href="__builtin__.html#object">object</a><br> |
|||
and returns either boolean True (extract) or boolean False (skip).<br> |
|||
DEPRECATED: If "condition" callback returns string (only supported for Windows) - <br> |
|||
that string will be used as a new name to save the file under.<br> |
|||
If "condition" is omitted, all files are extracted.<br> |
|||
<br> |
|||
"path" is a directory to extract to<br> |
|||
"withSubpath" flag denotes whether files are extracted with their full path in the archive.<br> |
|||
"overwrite" flag denotes whether extracted files will overwrite old ones. Defaults to true.<br> |
|||
<br> |
|||
Returns list of RarInfos for extracted files.</tt></dd></dl> |
|||
|
|||
<dl><dt><a name="RarFile-infoiter"><strong>infoiter</strong></a>(self)</dt><dd><tt>Iterate over all the files in the archive, generating RarInfos.<br> |
|||
<br> |
|||
>>> import os<br> |
|||
>>> for fileInArchive in <a href="#RarFile">RarFile</a>('test.rar').<a href="#RarFile-infoiter">infoiter</a>():<br> |
|||
... print os.path.split(fileInArchive.filename)[-1],<br> |
|||
... print fileInArchive.isdir,<br> |
|||
... print fileInArchive.size,<br> |
|||
... print fileInArchive.comment,<br> |
|||
... print tuple(fileInArchive.datetime)[0:5],<br> |
|||
... print time.strftime('%a, %d %b %Y %H:%M', fileInArchive.datetime)<br> |
|||
test True 0 None (2003, 6, 30, 1, 59) Mon, 30 Jun 2003 01:59<br> |
|||
test.txt False 20 None (2003, 6, 30, 2, 1) Mon, 30 Jun 2003 02:01<br> |
|||
this.py False 1030 None (2002, 2, 8, 16, 47) Fri, 08 Feb 2002 16:47</tt></dd></dl> |
|||
|
|||
<dl><dt><a name="RarFile-infolist"><strong>infolist</strong></a>(self)</dt><dd><tt>Return a list of RarInfos, descripting the contents of the archive.</tt></dd></dl> |
|||
|
|||
<dl><dt><a name="RarFile-read_files"><strong>read_files</strong></a>(self, condition<font color="#909090">='*'</font>)</dt><dd><tt>Read specific files from archive into memory.<br> |
|||
If "condition" is a list of numbers, then return files which have those positions in infolist.<br> |
|||
If "condition" is a string, then it is treated as a wildcard for names of files to extract.<br> |
|||
If "condition" is a function, it is treated as a callback function, which accepts a <a href="#RarInfo">RarInfo</a> <a href="__builtin__.html#object">object</a> <br> |
|||
and returns boolean True (extract) or False (skip).<br> |
|||
If "condition" is omitted, all files are returned.<br> |
|||
<br> |
|||
Returns list of tuples (<a href="#RarInfo">RarInfo</a> info, str contents)</tt></dd></dl> |
|||
|
|||
<hr> |
|||
Methods inherited from <a href="UnRAR2.windows.html#RarFileImplementation">UnRAR2.windows.RarFileImplementation</a>:<br> |
|||
<dl><dt><a name="RarFile-destruct"><strong>destruct</strong></a>(self)</dt></dl> |
|||
|
|||
<dl><dt><a name="RarFile-init"><strong>init</strong></a>(self, password<font color="#909090">=None</font>)</dt></dl> |
|||
|
|||
<dl><dt><a name="RarFile-make_sure_ready"><strong>make_sure_ready</strong></a>(self)</dt></dl> |
|||
|
|||
<hr> |
|||
Data descriptors inherited from <a href="UnRAR2.windows.html#RarFileImplementation">UnRAR2.windows.RarFileImplementation</a>:<br> |
|||
<dl><dt><strong>__dict__</strong></dt> |
|||
<dd><tt>dictionary for instance variables (if defined)</tt></dd> |
|||
</dl> |
|||
<dl><dt><strong>__weakref__</strong></dt> |
|||
<dd><tt>list of weak references to the object (if defined)</tt></dd> |
|||
</dl> |
|||
</td></tr></table> <p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#ffc8d8"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#000000" face="helvetica, arial"><a name="RarInfo">class <strong>RarInfo</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr> |
|||
|
|||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> |
|||
<td colspan=2><tt>Represents a file header in an archive. Don't instantiate directly.<br> |
|||
Use only to obtain information about file.<br> |
|||
YOU CANNOT EXTRACT FILE CONTENTS USING THIS OBJECT.<br> |
|||
USE METHODS OF <a href="#RarFile">RarFile</a> CLASS INSTEAD.<br> |
|||
<br> |
|||
Properties:<br> |
|||
index - index of file within the archive<br> |
|||
filename - name of the file in the archive including path (if any)<br> |
|||
datetime - file date/time as a struct_time suitable for time.strftime<br> |
|||
isdir - True if the file is a directory<br> |
|||
size - size in bytes of the uncompressed file<br> |
|||
comment - comment associated with the file<br> |
|||
<br> |
|||
Note - this is not currently intended to be a Python file-like <a href="__builtin__.html#object">object</a>.<br> </tt></td></tr> |
|||
<tr><td> </td> |
|||
<td width="100%">Methods defined here:<br> |
|||
<dl><dt><a name="RarInfo-__init__"><strong>__init__</strong></a>(self, rarfile, data)</dt></dl> |
|||
|
|||
<dl><dt><a name="RarInfo-__str__"><strong>__str__</strong></a>(self)</dt></dl> |
|||
|
|||
<hr> |
|||
Data descriptors defined here:<br> |
|||
<dl><dt><strong>__dict__</strong></dt> |
|||
<dd><tt>dictionary for instance variables (if defined)</tt></dd> |
|||
</dl> |
|||
<dl><dt><strong>__weakref__</strong></dt> |
|||
<dd><tt>list of weak references to the object (if defined)</tt></dd> |
|||
</dl> |
|||
</td></tr></table></td></tr></table><p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#eeaa77"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr> |
|||
|
|||
<tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td> |
|||
<td width="100%"><dl><dt><a name="-condition2checker"><strong>condition2checker</strong></a>(condition)</dt><dd><tt>Converts different condition types to callback</tt></dd></dl> |
|||
</td></tr></table><p> |
|||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> |
|||
<tr bgcolor="#55aa55"> |
|||
<td colspan=3 valign=bottom> <br> |
|||
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr> |
|||
|
|||
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td> |
|||
<td width="100%"><strong>__version__</strong> = '0.99.1'<br> |
|||
<strong>in_windows</strong> = True</td></tr></table> |
|||
</body></html> |
@ -0,0 +1,18 @@ |
|||
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 |
Binary file not shown.
@ -0,0 +1,140 @@ |
|||
#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 |
Binary file not shown.
@ -0,0 +1,606 @@ |
|||
|
|||
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. |
|||
|
@ -0,0 +1,80 @@ |
|||
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. |
@ -0,0 +1 @@ |
|||
This is x64 version of unrar.dll. |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,177 @@ |
|||
# 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 '<RarInfo "%s" in "%s">' % (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 |
|||
|
|||
|
@ -0,0 +1,21 @@ |
|||
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. |
@ -0,0 +1,30 @@ |
|||
# 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 |
@ -0,0 +1,175 @@ |
|||
# 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 |
|||
|
|||
|
@ -0,0 +1,309 @@ |
|||
# 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 |
|||
|
|||
|
Loading…
Reference in new issue