From 2fe818872cec6e5016c2e5db73cbacda4dcb3198 Mon Sep 17 00:00:00 2001 From: Davide Romanini Date: Mon, 16 Feb 2015 13:25:35 +0100 Subject: [PATCH] removed splitted comicapi --- comicapi/UnRAR2/UnRARDLL/license.txt | 18 - comicapi/UnRAR2/UnRARDLL/unrar.dll | Bin 165376 -> 0 bytes comicapi/UnRAR2/UnRARDLL/unrar.h | 140 --- comicapi/UnRAR2/UnRARDLL/unrar.lib | Bin 4114 -> 0 bytes comicapi/UnRAR2/UnRARDLL/unrardll.txt | 606 ------------ comicapi/UnRAR2/UnRARDLL/whatsnew.txt | 80 -- comicapi/UnRAR2/UnRARDLL/x64/readme.txt | 1 - comicapi/UnRAR2/UnRARDLL/x64/unrar64.dll | Bin 191488 -> 0 bytes comicapi/UnRAR2/UnRARDLL/x64/unrar64.lib | Bin 3972 -> 0 bytes comicapi/UnRAR2/__init__.py | 177 ---- comicapi/UnRAR2/rar_exceptions.py | 30 - comicapi/UnRAR2/test_UnRAR2.py | 138 --- comicapi/UnRAR2/unix.py | 218 ----- comicapi/UnRAR2/windows.py | 309 ------ comicapi/__init__.py | 1 - comicapi/comet.py | 260 ------ comicapi/comicarchive.py | 1088 ---------------------- comicapi/comicbookinfo.py | 152 --- comicapi/comicinfoxml.py | 293 ------ comicapi/filenameparser.py | 277 ------ comicapi/genericmetadata.py | 316 ------- comicapi/issuestring.py | 140 --- comicapi/utils.py | 597 ------------ 23 files changed, 4841 deletions(-) delete mode 100644 comicapi/UnRAR2/UnRARDLL/license.txt delete mode 100644 comicapi/UnRAR2/UnRARDLL/unrar.dll delete mode 100644 comicapi/UnRAR2/UnRARDLL/unrar.h delete mode 100644 comicapi/UnRAR2/UnRARDLL/unrar.lib delete mode 100644 comicapi/UnRAR2/UnRARDLL/unrardll.txt delete mode 100644 comicapi/UnRAR2/UnRARDLL/whatsnew.txt delete mode 100644 comicapi/UnRAR2/UnRARDLL/x64/readme.txt delete mode 100644 comicapi/UnRAR2/UnRARDLL/x64/unrar64.dll delete mode 100644 comicapi/UnRAR2/UnRARDLL/x64/unrar64.lib delete mode 100644 comicapi/UnRAR2/__init__.py delete mode 100644 comicapi/UnRAR2/rar_exceptions.py delete mode 100644 comicapi/UnRAR2/test_UnRAR2.py delete mode 100644 comicapi/UnRAR2/unix.py delete mode 100644 comicapi/UnRAR2/windows.py delete mode 100644 comicapi/__init__.py delete mode 100644 comicapi/comet.py delete mode 100644 comicapi/comicarchive.py delete mode 100644 comicapi/comicbookinfo.py delete mode 100644 comicapi/comicinfoxml.py delete mode 100644 comicapi/filenameparser.py delete mode 100644 comicapi/genericmetadata.py delete mode 100644 comicapi/issuestring.py delete mode 100644 comicapi/utils.py diff --git a/comicapi/UnRAR2/UnRARDLL/license.txt b/comicapi/UnRAR2/UnRARDLL/license.txt deleted file mode 100644 index 0c1540e..0000000 --- a/comicapi/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/comicapi/UnRAR2/UnRARDLL/unrar.dll b/comicapi/UnRAR2/UnRARDLL/unrar.dll deleted file mode 100644 index 9757bf3d692d8668ce892c4bee814eb5394adf37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165376 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 Zpd|w>8EDBsO9omp(2{|c4E$3W_-_?5`fC6H diff --git a/comicapi/UnRAR2/UnRARDLL/unrar.h b/comicapi/UnRAR2/UnRARDLL/unrar.h deleted file mode 100644 index 7643fa7..0000000 --- a/comicapi/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/comicapi/UnRAR2/UnRARDLL/unrar.lib b/comicapi/UnRAR2/UnRARDLL/unrar.lib deleted file mode 100644 index 0f6b3146b8ec5bd83698122653a75bcb1f2caf70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4114 zcmcInOK%fN5dLhFhn=T@+wLMGkQOc`amG%NR?FnI5XB_X#DU{5*aNW`;>Zr*8-HML zd*Q%x;YaK>;<|@D?B2N`{sm&IW_o&h+GA%dLQ6H>T~*y*cXd^F&DCF=PUG;`!mVPw zES9S))g_~PdnwLe5Z&davS>Xj0QdnIUjrtaK>iId^&z0?62MgW9MDV;@aYrPMAL5r znxQ$EW-URdR1?j;6I7;}XsXU++gtbdcCEU-vAMr)ZSB=}E&Ih$$LYYfcMfW`elcGA z@<3X@cd)Z-i=VOy)#?y-BcN;YV{bWMY1Xgxo+6Zmn>&E6p0KtkH%w4+SmTCs;v|hq5Q}k6xBIHyY3eY03ZFFZ zx+fc+_rUFRTkRurLD_;X896SDC@$tGFxJL_<|ObY4}6#cO4Gn+^7P&e@QLUx^$S#6 zv%o3QI~r6bs*^4S6~-}#3m8Kl1x#QPQ<%mqW{^R4pe*P6b%LAen@j2DWH4cH=}d8! z^o%ndHaMl2_XySiKZu_jIZVRQ_s9EL*FhBJx|L-3_t{EHQd}6?^`Ki%PNfL6xQkm- z4v5&=1)ztX9FY`bs!)xL7(ci^ln5Mfhx#{bsp)wlRL*)ijFpOfIck|4Hvju`dm=+` z2YEY{OsVNUe)07Be$WN(P~-QoBWe@#Yo%6`ZinmiDg@;+ReuwG6#X34CKgVGURAIu zj({&jp&s*16i>5M&r_Un$;(asj7#$q#NpYvusq+pc)!)?w7cymC&e4q&0=k9XWN%* zABt^%AWr}aV^9ds(|62oNeq~c_VZ&}XTJ9bzJ3kCSf2|oEQ@fvCfyUvISe`e#&~(T zkYlh8F(REx#9{sw{)obJ0n4JtRTew+J--3gkftw+ zK8lAdg>=Obk^Q|ACe<1m zhiOKj>CaIFCtE3_O9q#Q_9LNX1zP-xlL(Nllvu-dmg~pzpG}D|GMX{u)Gi1#<;CSh zHv&7?Qyc3?^WXOfPPS57(pXOR$RI}yJTgiSDE*ZHqx<79J5Gq5MOc0!@}1Bo1)7%K zd;?lV{?EoE`zm>VUP05+(QiN;7H@?JQOUz1Fxg7!C6zF>(qj7>?T-H(IN?vsp(PLs F{{t7Z#m)c# diff --git a/comicapi/UnRAR2/UnRARDLL/unrardll.txt b/comicapi/UnRAR2/UnRARDLL/unrardll.txt deleted file mode 100644 index 291c871..0000000 --- a/comicapi/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/comicapi/UnRAR2/UnRARDLL/whatsnew.txt b/comicapi/UnRAR2/UnRARDLL/whatsnew.txt deleted file mode 100644 index 84ad72c..0000000 --- a/comicapi/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/comicapi/UnRAR2/UnRARDLL/x64/readme.txt b/comicapi/UnRAR2/UnRARDLL/x64/readme.txt deleted file mode 100644 index 8f3b4e1..0000000 --- a/comicapi/UnRAR2/UnRARDLL/x64/readme.txt +++ /dev/null @@ -1 +0,0 @@ -This is x64 version of unrar.dll. diff --git a/comicapi/UnRAR2/UnRARDLL/x64/unrar64.dll b/comicapi/UnRAR2/UnRARDLL/x64/unrar64.dll deleted file mode 100644 index e17a19e59113c2bd17d1db85f594a1f7c8d4707f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191488 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 diff --git a/comicapi/UnRAR2/UnRARDLL/x64/unrar64.lib b/comicapi/UnRAR2/UnRARDLL/x64/unrar64.lib deleted file mode 100644 index fd037919ee10c91665fa5f30e9ec6f37ac9e03c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3972 zcmcImJ5L)y5FTt^e(;c!Dj|{+Ath-DG3N`GqR0l5VDYldtHT_=3$}9D$TkUGIz*8! zb;?lEr=v!Sl){l{Qsh6-lUeWH-K@_T8+R=JFX0GJG)aPil0o?14WT1u~E*0RaD)!9rcy|$9c9u&)3SydpLU0z>YbQ{2D zVZq1O=GT`OvdP3+0y2rr%Dz!dU>FJ?4V<8`x1ViL%H6rcrdFs%yIHeTFtp!L@t7EYzHkb;~448R}+APB=S1U=xncFgNykIP$BP^!vZHz9Cb1ex(;lg;n&NAB^TZ`y9008Qv_ zur8+{+2dPer=4|DqS#t_cWpHdMl&VN91;nKHAG2Lg9OQ*)zQ&OX~1k#rj&Alj@ZGI zlno)g_N)?T*o1DHb&B6~N-MD``;^v?ypXDWTL|<3GLn}G-Pk$U9bXk)NMPfO)e&_Z zMrS4pI;QY=#2UJfjh`rgg~E$<9460%9iHC2V2Z#Mie<;NaR{Gzunu8%uo56nJ%xLt zn0D~1K7w}%*1p5gQXy9^RZ8!x;b)oW;l@3K>vR4ml53`RbY<7T{=&{NJ z8T{VurRFE@w#Af4)VkTX{rZuo&XgbZ#jzyD7qIBL_XE5H6A0N>>1QEQQ3Q7cd^KUsd!5{I~zUy7w?cE7ETsF~fJN4MR` z-rdP%UC3efzGO+NAFDqoRO#VZ@&!b}I?go3eo@Pw zv3G-qqtSb&xN%qfe|O$=y&Y@eo8QK> Y-(qC?Tll6l_w5P#7I3f{o_G}UA258WCIA2c diff --git a/comicapi/UnRAR2/__init__.py b/comicapi/UnRAR2/__init__.py deleted file mode 100644 index a913fcb..0000000 --- a/comicapi/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.3' - -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/comicapi/UnRAR2/rar_exceptions.py b/comicapi/UnRAR2/rar_exceptions.py deleted file mode 100644 index d90d1c8..0000000 --- a/comicapi/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/comicapi/UnRAR2/test_UnRAR2.py b/comicapi/UnRAR2/test_UnRAR2.py deleted file mode 100644 index e86ba2c..0000000 --- a/comicapi/UnRAR2/test_UnRAR2.py +++ /dev/null @@ -1,138 +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)) - - -# basic test -cleanup() -rarc = UnRAR2.RarFile('test.rar') -rarc.infolist() -assert rarc.comment == "This is a test." -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() -rarc = UnRAR2.RarFile('test_protected_files.rar', password="protected") -rarc.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/comicapi/UnRAR2/unix.py b/comicapi/UnRAR2/unix.py deleted file mode 100644 index bd9ee85..0000000 --- a/comicapi/UnRAR2/unix.py +++ /dev/null @@ -1,218 +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 -rar_executable_version = 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): - global rar_executable_version - 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('UNRAR')): - line = source.next() - signature = line - # The code below is mighty flaky - # and will probably crash on localized versions of RAR - # but I see no safe way to rewrite it using a CLI tool - if signature.startswith("UNRAR 4"): - rar_executable_version = 4 - 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:] # strip out "Comment:" part - self.comment = '\n'.join(accum[:-1]) - else: - self.comment = None - elif signature.startswith("UNRAR 5"): - rar_executable_version = 5 - line = source.next() - while not line.startswith('Archive:'): - if line.strip().endswith('is not RAR archive'): - raise InvalidRARArchive - accum.append(line.rstrip('\n')) - line = source.next() - if len(accum): - self.comment = '\n'.join(accum[:-1]).strip() - else: - self.comment = None - else: - raise UnpackerNotInstalled("Unsupported RAR version, expected 4.x or 5.x, found: " - + signature.split(" ")[1]) - - - 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): - - command = "v" if rar_executable_version == 4 else "l" - stdoutdata, stderrdata = self.call(command, ['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.startswith("CRC failed") or line.startswith("Checksum error"): - raise IncorrectRARPassword - line = source.next() - line = source.next() - i = 0 - re_spaces = re.compile(r"\s+") - if rar_executable_version == 4: - while not line.startswith('-----------'): - accum.append(line) - if len(accum)==2: - data = {} - data['index'] = i - # asterisks mark password-encrypted files - data['filename'] = accum[0].strip().lstrip("*") # asterisks marks password-encrypted files - fields = re_spaces.split(accum[1].strip()) - data['size'] = int(fields[0]) - attr = fields[5] - data['isdir'] = 'd' in attr.lower() - data['datetime'] = time.strptime(fields[3]+" "+fields[4], '%d-%m-%y %H:%M') - data['comment'] = None - yield data - accum = [] - i += 1 - line = source.next() - elif rar_executable_version == 5: - while not line.startswith('-----------'): - fields = line.strip().lstrip("*").split() - data = {} - data['index'] = i - data['filename'] = " ".join(fields[4:]) - data['size'] = int(fields[1]) - attr = fields[0] - data['isdir'] = 'd' in attr.lower() - data['datetime'] = time.strptime(fields[2]+" "+fields[3], '%d-%m-%y %H:%M') - data['comment'] = None - yield data - 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 or stderrdata.find("Checksum error")>=0: - raise IncorrectRARPassword - return res - - def destruct(self): - pass - - diff --git a/comicapi/UnRAR2/windows.py b/comicapi/UnRAR2/windows.py deleted file mode 100644 index bb92481..0000000 --- a/comicapi/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 - - diff --git a/comicapi/__init__.py b/comicapi/__init__.py deleted file mode 100644 index 0d9bd7c..0000000 --- a/comicapi/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'dromanin' diff --git a/comicapi/comet.py b/comicapi/comet.py deleted file mode 100644 index 1a06977..0000000 --- a/comicapi/comet.py +++ /dev/null @@ -1,260 +0,0 @@ -""" -A python class to encapsulate CoMet data -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from datetime import datetime -import zipfile -from pprint import pprint -import xml.etree.ElementTree as ET -from genericmetadata import GenericMetadata -import utils - -class CoMet: - - writer_synonyms = ['writer', 'plotter', 'scripter'] - penciller_synonyms = [ 'artist', 'penciller', 'penciler', 'breakdowns' ] - inker_synonyms = [ 'inker', 'artist', 'finishes' ] - colorist_synonyms = [ 'colorist', 'colourist', 'colorer', 'colourer' ] - letterer_synonyms = [ 'letterer'] - cover_synonyms = [ 'cover', 'covers', 'coverartist', 'cover artist' ] - editor_synonyms = [ 'editor'] - - def metadataFromString( self, string ): - - tree = ET.ElementTree(ET.fromstring( string )) - return self.convertXMLToMetadata( tree ) - - def stringFromMetadata( self, metadata ): - - header = '\n' - - tree = self.convertMetadataToXML( self, metadata ) - return header + ET.tostring(tree.getroot()) - - def indent( self, elem, level=0 ): - # for making the XML output readable - i = "\n" + level*" " - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + " " - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for elem in elem: - self.indent( elem, level+1 ) - if not elem.tail or not elem.tail.strip(): - elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i - - def convertMetadataToXML( self, filename, metadata ): - - #shorthand for the metadata - md = metadata - - # build a tree structure - root = ET.Element("comet") - root.attrib['xmlns:comet'] = "http://www.denvog.com/comet/" - root.attrib['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance" - root.attrib['xsi:schemaLocation'] = "http://www.denvog.com http://www.denvog.com/comet/comet.xsd" - - #helper func - def assign( comet_entry, md_entry): - if md_entry is not None: - ET.SubElement(root, comet_entry).text = u"{0}".format(md_entry) - - # title is manditory - if md.title is None: - md.title = "" - assign( 'title', md.title ) - assign( 'series', md.series ) - assign( 'issue', md.issue ) #must be int?? - assign( 'volume', md.volume ) - assign( 'description', md.comments ) - assign( 'publisher', md.publisher ) - assign( 'pages', md.pageCount ) - assign( 'format', md.format ) - assign( 'language', md.language ) - assign( 'rating', md.maturityRating ) - assign( 'price', md.price ) - assign( 'isVersionOf', md.isVersionOf ) - assign( 'rights', md.rights ) - assign( 'identifier', md.identifier ) - assign( 'lastMark', md.lastMark ) - assign( 'genre', md.genre ) # TODO repeatable - - if md.characters is not None: - char_list = [ c.strip() for c in md.characters.split(',') ] - for c in char_list: - assign( 'character', c ) - - if md.manga is not None and md.manga == "YesAndRightToLeft": - assign( 'readingDirection', "rtl") - - date_str = "" - if md.year is not None: - date_str = str(md.year).zfill(4) - if md.month is not None: - date_str += "-" + str(md.month).zfill(2) - assign( 'date', date_str ) - - assign( 'coverImage', md.coverImage ) - - # need to specially process the credits, since they are structured differently than CIX - credit_writer_list = list() - credit_penciller_list = list() - credit_inker_list = list() - credit_colorist_list = list() - credit_letterer_list = list() - credit_cover_list = list() - credit_editor_list = list() - - # loop thru credits, and build a list for each role that CoMet supports - for credit in metadata.credits: - - if credit['role'].lower() in set( self.writer_synonyms ): - ET.SubElement(root, 'writer').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.penciller_synonyms ): - ET.SubElement(root, 'penciller').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.inker_synonyms ): - ET.SubElement(root, 'inker').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.colorist_synonyms ): - ET.SubElement(root, 'colorist').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.letterer_synonyms ): - ET.SubElement(root, 'letterer').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.cover_synonyms ): - ET.SubElement(root, 'coverDesigner').text = u"{0}".format(credit['person']) - - if credit['role'].lower() in set( self.editor_synonyms ): - ET.SubElement(root, 'editor').text = u"{0}".format(credit['person']) - - - # self pretty-print - self.indent(root) - - # wrap it in an ElementTree instance, and save as XML - tree = ET.ElementTree(root) - return tree - - - def convertXMLToMetadata( self, tree ): - - root = tree.getroot() - - if root.tag != 'comet': - raise 1 - return None - - metadata = GenericMetadata() - md = metadata - - # Helper function - def xlate( tag ): - node = root.find( tag ) - if node is not None: - return node.text - else: - return None - - md.series = xlate( 'series' ) - md.title = xlate( 'title' ) - md.issue = xlate( 'issue' ) - md.volume = xlate( 'volume' ) - md.comments = xlate( 'description' ) - md.publisher = xlate( 'publisher' ) - md.language = xlate( 'language' ) - md.format = xlate( 'format' ) - md.pageCount = xlate( 'pages' ) - md.maturityRating = xlate( 'rating' ) - md.price = xlate( 'price' ) - md.isVersionOf = xlate( 'isVersionOf' ) - md.rights = xlate( 'rights' ) - md.identifier = xlate( 'identifier' ) - md.lastMark = xlate( 'lastMark' ) - md.genre = xlate( 'genre' ) # TODO - repeatable field - - date = xlate( 'date' ) - if date is not None: - parts = date.split('-') - if len( parts) > 0: - md.year = parts[0] - if len( parts) > 1: - md.month = parts[1] - - md.coverImage = xlate( 'coverImage' ) - - readingDirection = xlate( 'readingDirection' ) - if readingDirection is not None and readingDirection == "rtl": - md.manga = "YesAndRightToLeft" - - # loop for character tags - char_list = [] - for n in root: - if n.tag == 'character': - char_list.append(n.text.strip()) - md.characters = utils.listToString( char_list ) - - # Now extract the credit info - for n in root: - if ( n.tag == 'writer' or - n.tag == 'penciller' or - n.tag == 'inker' or - n.tag == 'colorist' or - n.tag == 'letterer' or - n.tag == 'editor' - ): - metadata.addCredit( n.text.strip(), n.tag.title() ) - - if n.tag == 'coverDesigner': - metadata.addCredit( n.text.strip(), "Cover" ) - - - metadata.isEmpty = False - - return metadata - - #verify that the string actually contains CoMet data in XML format - def validateString( self, string ): - try: - tree = ET.ElementTree(ET.fromstring( string )) - root = tree.getroot() - if root.tag != 'comet': - raise Exception - except: - return False - - return True - - - def writeToExternalFile( self, filename, metadata ): - - tree = self.convertMetadataToXML( self, metadata ) - #ET.dump(tree) - tree.write(filename, encoding='utf-8') - - def readFromExternalFile( self, filename ): - - tree = ET.parse( filename ) - return self.convertXMLToMetadata( tree ) - diff --git a/comicapi/comicarchive.py b/comicapi/comicarchive.py deleted file mode 100644 index 381dc68..0000000 --- a/comicapi/comicarchive.py +++ /dev/null @@ -1,1088 +0,0 @@ -""" -A python class to represent a single comic, be it file or folder of images -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import zipfile -import os -import struct -import sys -import tempfile -import subprocess -import platform -import locale -from natsort import natsorted - -if platform.system() == "Windows": - import _subprocess -import time - -import StringIO -try: - import Image - pil_available = True -except ImportError: - pil_available = False - -sys.path.insert(0, os.path.abspath(".") ) -import UnRAR2 -from UnRAR2.rar_exceptions import * - -#from settings import ComicTaggerSettings -from comicinfoxml import ComicInfoXml -from comicbookinfo import ComicBookInfo -from comet import CoMet -from genericmetadata import GenericMetadata, PageType -from filenameparser import FileNameParser -from PyPDF2 import PdfFileReader - -class MetaDataStyle: - CBI = 0 - CIX = 1 - COMET = 2 - name = [ 'ComicBookLover', 'ComicRack', 'CoMet' ] - -class ZipArchiver: - - def __init__( self, path ): - self.path = path - - def getArchiveComment( self ): - zf = zipfile.ZipFile( self.path, 'r' ) - comment = zf.comment - zf.close() - return comment - - def setArchiveComment( self, comment ): - return self.writeZipComment( self.path, comment ) - - def readArchiveFile( self, archive_file ): - data = "" - zf = zipfile.ZipFile( self.path, 'r' ) - - try: - data = zf.read( archive_file ) - except zipfile.BadZipfile as e: - print >> sys.stderr, u"bad zipfile [{0}]: {1} :: {2}".format(e, self.path, archive_file) - zf.close() - raise IOError - except Exception as e: - zf.close() - print >> sys.stderr, u"bad zipfile [{0}]: {1} :: {2}".format(e, self.path, archive_file) - raise IOError - finally: - zf.close() - return data - - def removeArchiveFile( self, archive_file ): - try: - self.rebuildZipFile( [ archive_file ] ) - except: - return False - else: - return True - - def writeArchiveFile( self, archive_file, data ): - # At the moment, no other option but to rebuild the whole - # zip archive w/o the indicated file. Very sucky, but maybe - # another solution can be found - try: - self.rebuildZipFile( [ archive_file ] ) - - #now just add the archive file as a new one - zf = zipfile.ZipFile(self.path, mode='a', compression=zipfile.ZIP_DEFLATED ) - zf.writestr( archive_file, data ) - zf.close() - return True - except: - return False - - def getArchiveFilenameList( self ): - try: - zf = zipfile.ZipFile( self.path, 'r' ) - namelist = zf.namelist() - zf.close() - return namelist - except Exception as e: - print >> sys.stderr, u"Unable to get zipfile list [{0}]: {1}".format(e, self.path) - return [] - - # zip helper func - def rebuildZipFile( self, exclude_list ): - - # this recompresses the zip archive, without the files in the exclude_list - #print ">> sys.stderr, Rebuilding zip {0} without {1}".format( self.path, exclude_list ) - - # generate temp file - tmp_fd, tmp_name = tempfile.mkstemp( dir=os.path.dirname(self.path) ) - os.close( tmp_fd ) - - zin = zipfile.ZipFile (self.path, 'r') - zout = zipfile.ZipFile (tmp_name, 'w') - for item in zin.infolist(): - buffer = zin.read(item.filename) - if ( item.filename not in exclude_list ): - zout.writestr(item, buffer) - - #preserve the old comment - zout.comment = zin.comment - - zout.close() - zin.close() - - # replace with the new file - os.remove( self.path ) - os.rename( tmp_name, self.path ) - - - def writeZipComment( self, filename, comment ): - """ - This is a custom function for writing a comment to a zip file, - since the built-in one doesn't seem to work on Windows and Mac OS/X - - Fortunately, the zip comment is at the end of the file, and it's - easy to manipulate. See this website for more info: - see: http://en.wikipedia.org/wiki/Zip_(file_format)#Structure - """ - - #get file size - statinfo = os.stat(filename) - file_length = statinfo.st_size - - try: - fo = open(filename, "r+b") - - #the starting position, relative to EOF - pos = -4 - - found = False - value = bytearray() - - # walk backwards to find the "End of Central Directory" record - while ( not found ) and ( -pos != file_length ): - # seek, relative to EOF - fo.seek( pos, 2) - - value = fo.read( 4 ) - - #look for the end of central directory signature - if bytearray(value) == bytearray([ 0x50, 0x4b, 0x05, 0x06 ]): - found = True - else: - # not found, step back another byte - pos = pos - 1 - #print pos,"{1} int: {0:x}".format(bytearray(value)[0], value) - - if found: - - # now skip forward 20 bytes to the comment length word - pos += 20 - fo.seek( pos, 2) - - # Pack the length of the comment string - format = "H" # one 2-byte integer - comment_length = struct.pack(format, len(comment)) # pack integer in a binary string - - # write out the length - fo.write( comment_length ) - fo.seek( pos+2, 2) - - # write out the comment itself - fo.write( comment ) - fo.truncate() - fo.close() - else: - raise Exception('Failed to write comment to zip file!') - except: - return False - else: - return True - - def copyFromArchive( self, otherArchive ): - # Replace the current zip with one copied from another archive - try: - zout = zipfile.ZipFile (self.path, 'w') - for fname in otherArchive.getArchiveFilenameList(): - data = otherArchive.readArchiveFile( fname ) - if data is not None: - zout.writestr( fname, data ) - zout.close() - - #preserve the old comment - comment = otherArchive.getArchiveComment() - if comment is not None: - if not self.writeZipComment( self.path, comment ): - return False - except Exception as e: - print >> sys.stderr, u"Error while copying to {0}: {1}".format(self.path, e) - return False - else: - return True - - -#------------------------------------------ -# RAR implementation - -class RarArchiver: - - devnull = None - def __init__( self, path, rar_exe_path ): - self.path = path - self.rar_exe_path = rar_exe_path - - if RarArchiver.devnull is None: - RarArchiver.devnull = open(os.devnull, "w") - - # windows only, keeps the cmd.exe from popping up - if platform.system() == "Windows": - self.startupinfo = subprocess.STARTUPINFO() - self.startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW - else: - self.startupinfo = None - - def __del__(self): - #RarArchiver.devnull.close() - pass - - def getArchiveComment( self ): - - rarc = self.getRARObj() - return rarc.comment - - def setArchiveComment( self, comment ): - - if self.rar_exe_path is not None: - try: - # write comment to temp file - tmp_fd, tmp_name = tempfile.mkstemp() - f = os.fdopen(tmp_fd, 'w+b') - f.write( comment ) - f.close() - - working_dir = os.path.dirname( os.path.abspath( self.path ) ) - - # use external program to write comment to Rar archive - subprocess.call([self.rar_exe_path, 'c', '-w' + working_dir , '-c-', '-z' + tmp_name, self.path], - startupinfo=self.startupinfo, - stdout=RarArchiver.devnull) - - if platform.system() == "Darwin": - time.sleep(1) - - os.remove( tmp_name) - except: - return False - else: - return True - else: - return False - - def readArchiveFile( self, archive_file ): - - # Make sure to escape brackets, since some funky stuff is going on - # underneath with "fnmatch" - archive_file = archive_file.replace("[", '[[]') - entries = [] - - rarc = self.getRARObj() - - tries = 0 - while tries < 7: - try: - tries = tries+1 - entries = rarc.read_files( archive_file ) - - if entries[0][0].size != len(entries[0][1]): - print >> sys.stderr, u"readArchiveFile(): [file is not expected size: {0} vs {1}] {2}:{3} [attempt # {4}]".format( - entries[0][0].size,len(entries[0][1]), self.path, archive_file, tries) - continue - - except (OSError, IOError) as e: - print >> sys.stderr, u"readArchiveFile(): [{0}] {1}:{2} attempt#{3}".format(str(e), self.path, archive_file, tries) - time.sleep(1) - except Exception as e: - print >> sys.stderr, u"Unexpected exception in readArchiveFile(): [{0}] for {1}:{2} attempt#{3}".format(str(e), self.path, archive_file, tries) - break - - else: - #Success" - #entries is a list of of tuples: ( rarinfo, filedata) - if tries > 1: - print >> sys.stderr, u"Attempted read_files() {0} times".format(tries) - if (len(entries) == 1): - return entries[0][1] - else: - raise IOError - - raise IOError - - - - def writeArchiveFile( self, archive_file, data ): - - if self.rar_exe_path is not None: - try: - tmp_folder = tempfile.mkdtemp() - - tmp_file = os.path.join( tmp_folder, archive_file ) - - working_dir = os.path.dirname( os.path.abspath( self.path ) ) - - # TODO: will this break if 'archive_file' is in a subfolder. i.e. "foo/bar.txt" - # will need to create the subfolder above, I guess... - f = open(tmp_file, 'w') - f.write( data ) - f.close() - - # use external program to write file to Rar archive - subprocess.call([self.rar_exe_path, 'a', '-w' + working_dir ,'-c-', '-ep', self.path, tmp_file], - startupinfo=self.startupinfo, - stdout=RarArchiver.devnull) - - if platform.system() == "Darwin": - time.sleep(1) - os.remove( tmp_file) - os.rmdir( tmp_folder) - except: - return False - else: - return True - else: - return False - - def removeArchiveFile( self, archive_file ): - if self.rar_exe_path is not None: - try: - # use external program to remove file from Rar archive - subprocess.call([self.rar_exe_path, 'd','-c-', self.path, archive_file], - startupinfo=self.startupinfo, - stdout=RarArchiver.devnull) - - if platform.system() == "Darwin": - time.sleep(1) - except: - return False - else: - return True - else: - return False - - def getArchiveFilenameList( self ): - - rarc = self.getRARObj() - #namelist = [ item.filename for item in rarc.infolist() ] - #return namelist - - tries = 0 - while tries < 7: - try: - tries = tries+1 - #namelist = [ item.filename for item in rarc.infolist() ] - namelist = [] - for item in rarc.infolist(): - if item.size != 0: - namelist.append( item.filename ) - - except (OSError, IOError) as e: - print >> sys.stderr, u"getArchiveFilenameList(): [{0}] {1} attempt#{2}".format(str(e), self.path, tries) - time.sleep(1) - - else: - #Success" - return namelist - - raise e - - - def getRARObj( self ): - tries = 0 - while tries < 7: - try: - tries = tries+1 - rarc = UnRAR2.RarFile( self.path ) - - except (OSError, IOError) as e: - print >> sys.stderr, u"getRARObj(): [{0}] {1} attempt#{2}".format(str(e), self.path, tries) - time.sleep(1) - - else: - #Success" - return rarc - - raise e - -#------------------------------------------ -# Folder implementation -class FolderArchiver: - - def __init__( self, path ): - self.path = path - self.comment_file_name = "ComicTaggerFolderComment.txt" - - def getArchiveComment( self ): - return self.readArchiveFile( self.comment_file_name ) - - def setArchiveComment( self, comment ): - return self.writeArchiveFile( self.comment_file_name, comment ) - - def readArchiveFile( self, archive_file ): - - data = "" - fname = os.path.join( self.path, archive_file ) - try: - with open( fname, 'rb' ) as f: - data = f.read() - f.close() - except IOError as e: - pass - - return data - - def writeArchiveFile( self, archive_file, data ): - - fname = os.path.join( self.path, archive_file ) - try: - with open(fname, 'w+') as f: - f.write( data ) - f.close() - except: - return False - else: - return True - - def removeArchiveFile( self, archive_file ): - - fname = os.path.join( self.path, archive_file ) - try: - os.remove( fname ) - except: - return False - else: - return True - - def getArchiveFilenameList( self ): - return self.listFiles( self.path ) - - def listFiles( self, folder ): - - itemlist = list() - - for item in os.listdir( folder ): - itemlist.append( item ) - if os.path.isdir( item ): - itemlist.extend( self.listFiles( os.path.join( folder, item ) )) - - return itemlist - -#------------------------------------------ -# Unknown implementation -class UnknownArchiver: - - def __init__( self, path ): - self.path = path - - def getArchiveComment( self ): - return "" - def setArchiveComment( self, comment ): - return False - def readArchiveFile( self ): - return "" - def writeArchiveFile( self, archive_file, data ): - return False - def removeArchiveFile( self, archive_file ): - return False - def getArchiveFilenameList( self ): - return [] - -class PdfArchiver: - def __init__( self, path ): - self.path = path - - def getArchiveComment( self ): - return "" - def setArchiveComment( self, comment ): - return False - def readArchiveFile( self, page_num ): - return subprocess.check_output(['mudraw', '-o','-', self.path, str(int(os.path.basename(page_num)[:-4]))]) - def writeArchiveFile( self, archive_file, data ): - return False - def removeArchiveFile( self, archive_file ): - return False - def getArchiveFilenameList( self ): - out = [] - pdf = PdfFileReader(open(self.path, 'rb')) - for page in range(1, pdf.getNumPages() + 1): - out.append("/%04d.jpg" % (page)) - return out - -#------------------------------------------------------------------ -class ComicArchive: - - logo_data = None - - class ArchiveType: - Zip, Rar, Folder, Pdf, Unknown = range(5) - - def __init__( self, path, rar_exe_path=None, default_image_path=None ): - self.path = path - - self.rar_exe_path = rar_exe_path - self.ci_xml_filename = 'ComicInfo.xml' - self.comet_default_filename = 'CoMet.xml' - self.resetCache() - self.default_image_path = default_image_path - - # Use file extension to decide which archive test we do first - ext = os.path.splitext(path)[1].lower() - - self.archive_type = self.ArchiveType.Unknown - self.archiver = UnknownArchiver( self.path ) - - if ext == ".cbr" or ext == ".rar": - if self.rarTest(): - self.archive_type = self.ArchiveType.Rar - self.archiver = RarArchiver( self.path, rar_exe_path=self.rar_exe_path ) - - elif self.zipTest(): - self.archive_type = self.ArchiveType.Zip - self.archiver = ZipArchiver( self.path ) - else: - if self.zipTest(): - self.archive_type = self.ArchiveType.Zip - self.archiver = ZipArchiver( self.path ) - - elif self.rarTest(): - self.archive_type = self.ArchiveType.Rar - self.archiver = RarArchiver( self.path, rar_exe_path=self.rar_exe_path ) - elif os.path.basename(self.path)[-3:] == 'pdf': - self.archive_type = self.ArchiveType.Pdf - self.archiver = PdfArchiver(self.path) - - if ComicArchive.logo_data is None: - #fname = ComicTaggerSettings.getGraphic('nocover.png') - fname = self.default_image_path - with open(fname, 'rb') as fd: - ComicArchive.logo_data = fd.read() - - # Clears the cached data - def resetCache( self ): - self.has_cix = None - self.has_cbi = None - self.has_comet = None - self.comet_filename = None - self.page_count = None - self.page_list = None - self.cix_md = None - self.cbi_md = None - self.comet_md = None - - def loadCache( self, style_list ): - for style in style_list: - self.readMetadata(style) - - def rename( self, path ): - self.path = path - self.archiver.path = path - - def zipTest( self ): - return zipfile.is_zipfile( self.path ) - - def rarTest( self ): - try: - rarc = UnRAR2.RarFile( self.path ) - except: # InvalidRARArchive: - return False - else: - return True - - - def isZip( self ): - return self.archive_type == self.ArchiveType.Zip - - def isRar( self ): - return self.archive_type == self.ArchiveType.Rar - def isPdf(self): - return self.archive_type == self.ArchiveType.Pdf - def isFolder( self ): - return self.archive_type == self.ArchiveType.Folder - - def isWritable( self, check_rar_status=True ): - if self.archive_type == self.ArchiveType.Unknown : - return False - - elif check_rar_status and self.isRar() and self.rar_exe_path is None: - return False - - elif not os.access(self.path, os.W_OK): - return False - - elif ((self.archive_type != self.ArchiveType.Folder) and - (not os.access( os.path.dirname( os.path.abspath(self.path)), os.W_OK ))): - return False - - return True - - def isWritableForStyle( self, data_style ): - - if self.isRar() and data_style == MetaDataStyle.CBI: - return False - - return self.isWritable() - - def seemsToBeAComicArchive( self ): - - # Do we even care about extensions?? - ext = os.path.splitext(self.path)[1].lower() - - if ( - ( self.isZip() or self.isRar() or self.isPdf()) #or self.isFolder() ) - and - ( self.getNumberOfPages() > 0) - - ): - return True - else: - return False - - def readMetadata( self, style ): - - if style == MetaDataStyle.CIX: - return self.readCIX() - elif style == MetaDataStyle.CBI: - return self.readCBI() - elif style == MetaDataStyle.COMET: - return self.readCoMet() - else: - return GenericMetadata() - - def writeMetadata( self, metadata, style ): - - retcode = None - if style == MetaDataStyle.CIX: - retcode = self.writeCIX( metadata ) - elif style == MetaDataStyle.CBI: - retcode = self.writeCBI( metadata ) - elif style == MetaDataStyle.COMET: - retcode = self.writeCoMet( metadata ) - return retcode - - - def hasMetadata( self, style ): - - if style == MetaDataStyle.CIX: - return self.hasCIX() - elif style == MetaDataStyle.CBI: - return self.hasCBI() - elif style == MetaDataStyle.COMET: - return self.hasCoMet() - else: - return False - - def removeMetadata( self, style ): - retcode = True - if style == MetaDataStyle.CIX: - retcode = self.removeCIX() - elif style == MetaDataStyle.CBI: - retcode = self.removeCBI() - elif style == MetaDataStyle.COMET: - retcode = self.removeCoMet() - return retcode - - def getPage( self, index ): - - image_data = None - - filename = self.getPageName( index ) - - if filename is not None: - try: - image_data = self.archiver.readArchiveFile( filename ) - except IOError: - print >> sys.stderr, u"Error reading in page. Substituting logo page." - image_data = ComicArchive.logo_data - - return image_data - - def getPageName( self, index ): - - if index is None: - return None - - page_list = self.getPageNameList() - - num_pages = len( page_list ) - if num_pages == 0 or index >= num_pages: - return None - - return page_list[index] - - def getScannerPageIndex( self ): - - scanner_page_index = None - - #make a guess at the scanner page - name_list = self.getPageNameList() - count = self.getNumberOfPages() - - #too few pages to really know - if count < 5: - return None - - # count the length of every filename, and count occurences - length_buckets = dict() - for name in name_list: - fname = os.path.split(name)[1] - length = len(fname) - if length_buckets.has_key( length ): - length_buckets[ length ] += 1 - else: - length_buckets[ length ] = 1 - - # sort by most common - sorted_buckets = sorted(length_buckets.iteritems(), key=lambda (k,v): (v,k), reverse=True) - - # statistical mode occurence is first - mode_length = sorted_buckets[0][0] - - # we are only going to consider the final image file: - final_name = os.path.split(name_list[count-1])[1] - - common_length_list = list() - for name in name_list: - if len(os.path.split(name)[1]) == mode_length: - common_length_list.append( os.path.split(name)[1] ) - - prefix = os.path.commonprefix(common_length_list) - - if mode_length <= 7 and prefix == "": - #probably all numbers - if len(final_name) > mode_length: - scanner_page_index = count-1 - - # see if the last page doesn't start with the same prefix as most others - elif not final_name.startswith(prefix): - scanner_page_index = count-1 - - return scanner_page_index - - - def getPageNameList( self , sort_list=True): - - if self.page_list is None: - # get the list file names in the archive, and sort - files = self.archiver.getArchiveFilenameList() - - # seems like some archive creators are on Windows, and don't know about case-sensitivity! - if sort_list: - def keyfunc(k): - #hack to account for some weird scanner ID pages - #basename=os.path.split(k)[1] - #if basename < '0': - # k = os.path.join(os.path.split(k)[0], "z" + basename) - return k.lower() - - files = natsorted(files, key=keyfunc,signed=False) - - # make a sub-list of image files - self.page_list = [] - for name in files: - if ( name[-4:].lower() in [ ".jpg", "jpeg", ".png", ".gif", "webp" ] and os.path.basename(name)[0] != "." ): - self.page_list.append(name) - - return self.page_list - - def getNumberOfPages( self ): - - if self.page_count is None: - self.page_count = len( self.getPageNameList( ) ) - return self.page_count - - def readCBI( self ): - if self.cbi_md is None: - raw_cbi = self.readRawCBI() - if raw_cbi is None: - self.cbi_md = GenericMetadata() - else: - self.cbi_md = ComicBookInfo().metadataFromString( raw_cbi ) - - self.cbi_md.setDefaultPageList( self.getNumberOfPages() ) - - return self.cbi_md - - def readRawCBI( self ): - if ( not self.hasCBI() ): - return None - - return self.archiver.getArchiveComment() - - def hasCBI(self): - if self.has_cbi is None: - - #if ( not ( self.isZip() or self.isRar()) or not self.seemsToBeAComicArchive() ): - if not self.seemsToBeAComicArchive(): - self.has_cbi = False - else: - comment = self.archiver.getArchiveComment() - self.has_cbi = ComicBookInfo().validateString( comment ) - - return self.has_cbi - - def writeCBI( self, metadata ): - if metadata is not None: - self.applyArchiveInfoToMetadata( metadata ) - cbi_string = ComicBookInfo().stringFromMetadata( metadata ) - write_success = self.archiver.setArchiveComment( cbi_string ) - if write_success: - self.has_cbi = True - self.cbi_md = metadata - self.resetCache() - return write_success - else: - return False - - def removeCBI( self ): - if self.hasCBI(): - write_success = self.archiver.setArchiveComment( "" ) - if write_success: - self.has_cbi = False - self.cbi_md = None - self.resetCache() - return write_success - return True - - def readCIX( self ): - if self.cix_md is None: - raw_cix = self.readRawCIX() - if raw_cix is None or raw_cix == "": - self.cix_md = GenericMetadata() - else: - self.cix_md = ComicInfoXml().metadataFromString( raw_cix ) - - #validate the existing page list (make sure count is correct) - if len ( self.cix_md.pages ) != 0 : - if len ( self.cix_md.pages ) != self.getNumberOfPages(): - # pages array doesn't match the actual number of images we're seeing - # in the archive, so discard the data - self.cix_md.pages = [] - - if len( self.cix_md.pages ) == 0: - self.cix_md.setDefaultPageList( self.getNumberOfPages() ) - - return self.cix_md - - def readRawCIX( self ): - if not self.hasCIX(): - return None - try: - raw_cix = self.archiver.readArchiveFile( self.ci_xml_filename ) - except IOError: - print "Error reading in raw CIX!" - raw_cix = "" - return raw_cix - - def writeCIX(self, metadata): - - if metadata is not None: - self.applyArchiveInfoToMetadata( metadata, calc_page_sizes=True ) - cix_string = ComicInfoXml().stringFromMetadata( metadata ) - write_success = self.archiver.writeArchiveFile( self.ci_xml_filename, cix_string ) - if write_success: - self.has_cix = True - self.cix_md = metadata - self.resetCache() - return write_success - else: - return False - - def removeCIX( self ): - if self.hasCIX(): - write_success = self.archiver.removeArchiveFile( self.ci_xml_filename ) - if write_success: - self.has_cix = False - self.cix_md = None - self.resetCache() - return write_success - return True - - - def hasCIX(self): - if self.has_cix is None: - - if not self.seemsToBeAComicArchive(): - self.has_cix = False - elif self.ci_xml_filename in self.archiver.getArchiveFilenameList(): - self.has_cix = True - else: - self.has_cix = False - return self.has_cix - - - def readCoMet( self ): - if self.comet_md is None: - raw_comet = self.readRawCoMet() - if raw_comet is None or raw_comet == "": - self.comet_md = GenericMetadata() - else: - self.comet_md = CoMet().metadataFromString( raw_comet ) - - self.comet_md.setDefaultPageList( self.getNumberOfPages() ) - #use the coverImage value from the comet_data to mark the cover in this struct - # walk through list of images in file, and find the matching one for md.coverImage - # need to remove the existing one in the default - if self.comet_md.coverImage is not None: - cover_idx = 0 - for idx,f in enumerate(self.getPageNameList()): - if self.comet_md.coverImage == f: - cover_idx = idx - break - if cover_idx != 0: - del (self.comet_md.pages[0]['Type'] ) - self.comet_md.pages[ cover_idx ]['Type'] = PageType.FrontCover - - return self.comet_md - - def readRawCoMet( self ): - if not self.hasCoMet(): - print >> sys.stderr, self.path, "doesn't have CoMet data!" - return None - - try: - raw_comet = self.archiver.readArchiveFile( self.comet_filename ) - except IOError: - print >> sys.stderr, u"Error reading in raw CoMet!" - raw_comet = "" - return raw_comet - - def writeCoMet(self, metadata): - - if metadata is not None: - if not self.hasCoMet(): - self.comet_filename = self.comet_default_filename - - self.applyArchiveInfoToMetadata( metadata ) - # Set the coverImage value, if it's not the first page - cover_idx = int(metadata.getCoverPageIndexList()[0]) - if cover_idx != 0: - metadata.coverImage = self.getPageName( cover_idx ) - - comet_string = CoMet().stringFromMetadata( metadata ) - write_success = self.archiver.writeArchiveFile( self.comet_filename, comet_string ) - if write_success: - self.has_comet = True - self.comet_md = metadata - self.resetCache() - return write_success - else: - return False - - def removeCoMet( self ): - if self.hasCoMet(): - write_success = self.archiver.removeArchiveFile( self.comet_filename ) - if write_success: - self.has_comet = False - self.comet_md = None - self.resetCache() - return write_success - return True - - def hasCoMet(self): - if self.has_comet is None: - self.has_comet = False - if not self.seemsToBeAComicArchive(): - return self.has_comet - - #look at all xml files in root, and search for CoMet data, get first - for n in self.archiver.getArchiveFilenameList(): - if ( os.path.dirname(n) == "" and - os.path.splitext(n)[1].lower() == '.xml'): - # read in XML file, and validate it - try: - data = self.archiver.readArchiveFile( n ) - except: - data = "" - print >> sys.stderr, u"Error reading in Comet XML for validation!" - if CoMet().validateString( data ): - # since we found it, save it! - self.comet_filename = n - self.has_comet = True - break - - return self.has_comet - - - - def applyArchiveInfoToMetadata( self, md, calc_page_sizes=False): - md.pageCount = self.getNumberOfPages() - - if calc_page_sizes: - for p in md.pages: - idx = int( p['Image'] ) - if pil_available: - if 'ImageSize' not in p or 'ImageHeight' not in p or 'ImageWidth' not in p: - data = self.getPage( idx ) - if data is not None: - try: - im = Image.open(StringIO.StringIO(data)) - w,h = im.size - - p['ImageSize'] = str(len(data)) - p['ImageHeight'] = str(h) - p['ImageWidth'] = str(w) - except IOError: - p['ImageSize'] = str(len(data)) - - else: - if 'ImageSize' not in p: - data = self.getPage( idx ) - p['ImageSize'] = str(len(data)) - - - - def metadataFromFilename( self , parse_scan_info=True): - - metadata = GenericMetadata() - - fnp = FileNameParser() - fnp.parseFilename( self.path ) - - if fnp.issue != "": - metadata.issue = fnp.issue - if fnp.series != "": - metadata.series = fnp.series - if fnp.volume != "": - metadata.volume = fnp.volume - if fnp.year != "": - metadata.year = fnp.year - if fnp.issue_count != "": - metadata.issueCount = fnp.issue_count - if parse_scan_info: - if fnp.remainder != "": - metadata.scanInfo = fnp.remainder - - metadata.isEmpty = False - - return metadata - - def exportAsZip( self, zipfilename ): - if self.archive_type == self.ArchiveType.Zip: - # nothing to do, we're already a zip - return True - - zip_archiver = ZipArchiver( zipfilename ) - return zip_archiver.copyFromArchive( self.archiver ) - diff --git a/comicapi/comicbookinfo.py b/comicapi/comicbookinfo.py deleted file mode 100644 index a0bbaf0..0000000 --- a/comicapi/comicbookinfo.py +++ /dev/null @@ -1,152 +0,0 @@ -""" -A python class to encapsulate the ComicBookInfo data -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - - -import json -from datetime import datetime -import zipfile - -from genericmetadata import GenericMetadata -import utils -#import ctversion - -class ComicBookInfo: - - - def metadataFromString( self, string ): - - cbi_container = json.loads( unicode(string, 'utf-8') ) - - metadata = GenericMetadata() - - cbi = cbi_container[ 'ComicBookInfo/1.0' ] - - #helper func - # If item is not in CBI, return None - def xlate( cbi_entry): - if cbi_entry in cbi: - return cbi[cbi_entry] - else: - return None - - metadata.series = xlate( 'series' ) - metadata.title = xlate( 'title' ) - metadata.issue = xlate( 'issue' ) - metadata.publisher = xlate( 'publisher' ) - metadata.month = xlate( 'publicationMonth' ) - metadata.year = xlate( 'publicationYear' ) - metadata.issueCount = xlate( 'numberOfIssues' ) - metadata.comments = xlate( 'comments' ) - metadata.credits = xlate( 'credits' ) - metadata.genre = xlate( 'genre' ) - metadata.volume = xlate( 'volume' ) - metadata.volumeCount = xlate( 'numberOfVolumes' ) - metadata.language = xlate( 'language' ) - metadata.country = xlate( 'country' ) - metadata.criticalRating = xlate( 'rating' ) - metadata.tags = xlate( 'tags' ) - - # make sure credits and tags are at least empty lists and not None - if metadata.credits is None: - metadata.credits = [] - if metadata.tags is None: - metadata.tags = [] - - #need to massage the language string to be ISO - if metadata.language is not None: - # reverse look-up - pattern = metadata.language - metadata.language = None - for key in utils.getLanguageDict(): - if utils.getLanguageDict()[ key ] == pattern.encode('utf-8'): - metadata.language = key - break - - metadata.isEmpty = False - - return metadata - - def stringFromMetadata( self, metadata ): - - cbi_container = self.createJSONDictionary( metadata ) - return json.dumps( cbi_container ) - - #verify that the string actually contains CBI data in JSON format - def validateString( self, string ): - - try: - cbi_container = json.loads( string ) - except: - return False - - return ( 'ComicBookInfo/1.0' in cbi_container ) - - - def createJSONDictionary( self, metadata ): - - # Create the dictionary that we will convert to JSON text - cbi = dict() - cbi_container = {'appID' : 'ComicTagger/' + '1.0.0', #ctversion.version, - 'lastModified' : str(datetime.now()), - 'ComicBookInfo/1.0' : cbi } - - #helper func - def assign( cbi_entry, md_entry): - if md_entry is not None: - cbi[cbi_entry] = md_entry - - #helper func - def toInt(s): - i = None - if type(s) in [ str, unicode, int ]: - try: - i = int(s) - except ValueError: - pass - return i - - assign( 'series', metadata.series ) - assign( 'title', metadata.title ) - assign( 'issue', metadata.issue ) - assign( 'publisher', metadata.publisher ) - assign( 'publicationMonth', toInt(metadata.month) ) - assign( 'publicationYear', toInt(metadata.year) ) - assign( 'numberOfIssues', toInt(metadata.issueCount) ) - assign( 'comments', metadata.comments ) - assign( 'genre', metadata.genre ) - assign( 'volume', toInt(metadata.volume) ) - assign( 'numberOfVolumes', toInt(metadata.volumeCount) ) - assign( 'language', utils.getLanguageFromISO(metadata.language) ) - assign( 'country', metadata.country ) - assign( 'rating', metadata.criticalRating ) - assign( 'credits', metadata.credits ) - assign( 'tags', metadata.tags ) - - return cbi_container - - - def writeToExternalFile( self, filename, metadata ): - - cbi_container = self.createJSONDictionary(metadata) - - f = open(filename, 'w') - f.write(json.dumps(cbi_container, indent=4)) - f.close - diff --git a/comicapi/comicinfoxml.py b/comicapi/comicinfoxml.py deleted file mode 100644 index 9e9df07..0000000 --- a/comicapi/comicinfoxml.py +++ /dev/null @@ -1,293 +0,0 @@ -""" -A python class to encapsulate ComicRack's ComicInfo.xml data -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from datetime import datetime -import zipfile -from pprint import pprint -import xml.etree.ElementTree as ET -from genericmetadata import GenericMetadata -import utils - -class ComicInfoXml: - - writer_synonyms = ['writer', 'plotter', 'scripter'] - penciller_synonyms = [ 'artist', 'penciller', 'penciler', 'breakdowns' ] - inker_synonyms = [ 'inker', 'artist', 'finishes' ] - colorist_synonyms = [ 'colorist', 'colourist', 'colorer', 'colourer' ] - letterer_synonyms = [ 'letterer'] - cover_synonyms = [ 'cover', 'covers', 'coverartist', 'cover artist' ] - editor_synonyms = [ 'editor'] - - - def getParseableCredits( self ): - parsable_credits = [] - parsable_credits.extend( self.writer_synonyms ) - parsable_credits.extend( self.penciller_synonyms ) - parsable_credits.extend( self.inker_synonyms ) - parsable_credits.extend( self.colorist_synonyms ) - parsable_credits.extend( self.letterer_synonyms ) - parsable_credits.extend( self.cover_synonyms ) - parsable_credits.extend( self.editor_synonyms ) - return parsable_credits - - def metadataFromString( self, string ): - - tree = ET.ElementTree(ET.fromstring( string )) - return self.convertXMLToMetadata( tree ) - - def stringFromMetadata( self, metadata ): - - header = '\n' - - tree = self.convertMetadataToXML( self, metadata ) - return header + ET.tostring(tree.getroot()) - - def indent( self, elem, level=0 ): - # for making the XML output readable - i = "\n" + level*" " - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + " " - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for elem in elem: - self.indent( elem, level+1 ) - if not elem.tail or not elem.tail.strip(): - elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i - - def convertMetadataToXML( self, filename, metadata ): - - #shorthand for the metadata - md = metadata - - # build a tree structure - root = ET.Element("ComicInfo") - root.attrib['xmlns:xsi']="http://www.w3.org/2001/XMLSchema-instance" - root.attrib['xmlns:xsd']="http://www.w3.org/2001/XMLSchema" - #helper func - def assign( cix_entry, md_entry): - if md_entry is not None: - ET.SubElement(root, cix_entry).text = u"{0}".format(md_entry) - - assign( 'Title', md.title ) - assign( 'Series', md.series ) - assign( 'Number', md.issue ) - assign( 'Count', md.issueCount ) - assign( 'Volume', md.volume ) - assign( 'AlternateSeries', md.alternateSeries ) - assign( 'AlternateNumber', md.alternateNumber ) - assign( 'StoryArc', md.storyArc ) - assign( 'SeriesGroup', md.seriesGroup ) - assign( 'AlternateCount', md.alternateCount ) - assign( 'Summary', md.comments ) - assign( 'Notes', md.notes ) - assign( 'Year', md.year ) - assign( 'Month', md.month ) - assign( 'Day', md.day ) - - # need to specially process the credits, since they are structured differently than CIX - credit_writer_list = list() - credit_penciller_list = list() - credit_inker_list = list() - credit_colorist_list = list() - credit_letterer_list = list() - credit_cover_list = list() - credit_editor_list = list() - - # first, loop thru credits, and build a list for each role that CIX supports - for credit in metadata.credits: - - if credit['role'].lower() in set( self.writer_synonyms ): - credit_writer_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.penciller_synonyms ): - credit_penciller_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.inker_synonyms ): - credit_inker_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.colorist_synonyms ): - credit_colorist_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.letterer_synonyms ): - credit_letterer_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.cover_synonyms ): - credit_cover_list.append(credit['person'].replace(",","")) - - if credit['role'].lower() in set( self.editor_synonyms ): - credit_editor_list.append(credit['person'].replace(",","")) - - # second, convert each list to string, and add to XML struct - if len( credit_writer_list ) > 0: - node = ET.SubElement(root, 'Writer') - node.text = utils.listToString( credit_writer_list ) - - if len( credit_penciller_list ) > 0: - node = ET.SubElement(root, 'Penciller') - node.text = utils.listToString( credit_penciller_list ) - - if len( credit_inker_list ) > 0: - node = ET.SubElement(root, 'Inker') - node.text = utils.listToString( credit_inker_list ) - - if len( credit_colorist_list ) > 0: - node = ET.SubElement(root, 'Colorist') - node.text = utils.listToString( credit_colorist_list ) - - if len( credit_letterer_list ) > 0: - node = ET.SubElement(root, 'Letterer') - node.text = utils.listToString( credit_letterer_list ) - - if len( credit_cover_list ) > 0: - node = ET.SubElement(root, 'CoverArtist') - node.text = utils.listToString( credit_cover_list ) - - if len( credit_editor_list ) > 0: - node = ET.SubElement(root, 'Editor') - node.text = utils.listToString( credit_editor_list ) - - assign( 'Publisher', md.publisher ) - assign( 'Imprint', md.imprint ) - assign( 'Genre', md.genre ) - assign( 'Web', md.webLink ) - assign( 'PageCount', md.pageCount ) - assign( 'LanguageISO', md.language ) - assign( 'Format', md.format ) - assign( 'AgeRating', md.maturityRating ) - if md.blackAndWhite is not None and md.blackAndWhite: - ET.SubElement(root, 'BlackAndWhite').text = "Yes" - assign( 'Manga', md.manga ) - assign( 'Characters', md.characters ) - assign( 'Teams', md.teams ) - assign( 'Locations', md.locations ) - assign( 'ScanInformation', md.scanInfo ) - - # loop and add the page entries under pages node - if len( md.pages ) > 0: - pages_node = ET.SubElement(root, 'Pages') - for page_dict in md.pages: - page_node = ET.SubElement(pages_node, 'Page') - page_node.attrib = page_dict - - # self pretty-print - self.indent(root) - - # wrap it in an ElementTree instance, and save as XML - tree = ET.ElementTree(root) - return tree - - - def convertXMLToMetadata( self, tree ): - - root = tree.getroot() - - if root.tag != 'ComicInfo': - raise 1 - return None - - metadata = GenericMetadata() - md = metadata - - - # Helper function - def xlate( tag ): - node = root.find( tag ) - if node is not None: - return node.text - else: - return None - - md.series = xlate( 'Series' ) - md.title = xlate( 'Title' ) - md.issue = xlate( 'Number' ) - md.issueCount = xlate( 'Count' ) - md.volume = xlate( 'Volume' ) - md.alternateSeries = xlate( 'AlternateSeries' ) - md.alternateNumber = xlate( 'AlternateNumber' ) - md.alternateCount = xlate( 'AlternateCount' ) - md.comments = xlate( 'Summary' ) - md.notes = xlate( 'Notes' ) - md.year = xlate( 'Year' ) - md.month = xlate( 'Month' ) - md.day = xlate( 'Day' ) - md.publisher = xlate( 'Publisher' ) - md.imprint = xlate( 'Imprint' ) - md.genre = xlate( 'Genre' ) - md.webLink = xlate( 'Web' ) - md.language = xlate( 'LanguageISO' ) - md.format = xlate( 'Format' ) - md.manga = xlate( 'Manga' ) - md.characters = xlate( 'Characters' ) - md.teams = xlate( 'Teams' ) - md.locations = xlate( 'Locations' ) - md.pageCount = xlate( 'PageCount' ) - md.scanInfo = xlate( 'ScanInformation' ) - md.storyArc = xlate( 'StoryArc' ) - md.seriesGroup = xlate( 'SeriesGroup' ) - md.maturityRating = xlate( 'AgeRating' ) - - tmp = xlate( 'BlackAndWhite' ) - md.blackAndWhite = False - if tmp is not None and tmp.lower() in [ "yes", "true", "1" ]: - md.blackAndWhite = True - # Now extract the credit info - for n in root: - if ( n.tag == 'Writer' or - n.tag == 'Penciller' or - n.tag == 'Inker' or - n.tag == 'Colorist' or - n.tag == 'Letterer' or - n.tag == 'Editor' - ): - if n.text is not None: - for name in n.text.split(','): - metadata.addCredit( name.strip(), n.tag ) - - if n.tag == 'CoverArtist': - if n.text is not None: - for name in n.text.split(','): - metadata.addCredit( name.strip(), "Cover" ) - - # parse page data now - pages_node = root.find( "Pages" ) - if pages_node is not None: - for page in pages_node: - metadata.pages.append( page.attrib ) - #print page.attrib - - metadata.isEmpty = False - - return metadata - - def writeToExternalFile( self, filename, metadata ): - - tree = self.convertMetadataToXML( self, metadata ) - #ET.dump(tree) - tree.write(filename, encoding='utf-8') - - def readFromExternalFile( self, filename ): - - tree = ET.parse( filename ) - return self.convertXMLToMetadata( tree ) - diff --git a/comicapi/filenameparser.py b/comicapi/filenameparser.py deleted file mode 100644 index 6f3aa05..0000000 --- a/comicapi/filenameparser.py +++ /dev/null @@ -1,277 +0,0 @@ -""" -Functions for parsing comic info from filename - -This should probably be re-written, but, well, it mostly works! - -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - - -# Some portions of this code were modified from pyComicMetaThis project -# http://code.google.com/p/pycomicmetathis/ - -import re -import os -from urllib import unquote - -class FileNameParser: - - def repl(self, m): - return ' ' * len(m.group()) - - def fixSpaces( self, string, remove_dashes=True ): - if remove_dashes: - placeholders = ['[-_]',' +'] - else: - placeholders = ['[_]',' +'] - for ph in placeholders: - string = re.sub(ph, self.repl, string ) - return string #.strip() - - - def getIssueCount( self,filename, issue_end ): - - count = "" - filename = filename[issue_end:] - - # replace any name seperators with spaces - tmpstr = self.fixSpaces(filename) - found = False - - match = re.search('(?<=\sof\s)\d+(?=\s)', tmpstr, re.IGNORECASE) - if match: - count = match.group() - found = True - - if not found: - match = re.search('(?<=\(of\s)\d+(?=\))', tmpstr, re.IGNORECASE) - if match: - count = match.group() - found = True - - - count = count.lstrip("0") - - return count - - def getIssueNumber( self, filename ): - - # Returns a tuple of issue number string, and start and end indexs in the filename - # (The indexes will be used to split the string up for further parsing) - - found = False - issue = '' - start = 0 - end = 0 - - # first, look for multiple "--", this means it's formatted differently from most: - if "--" in filename: - # the pattern seems to be that anything to left of the first "--" is the series name followed by issue - filename = re.sub("--.*", self.repl, filename) - - elif "__" in filename: - # the pattern seems to be that anything to left of the first "__" is the series name followed by issue - filename = re.sub("__.*", self.repl, filename) - - filename = filename.replace("+", " ") - - # replace parenthetical phrases with spaces - filename = re.sub( "\(.*?\)", self.repl, filename) - filename = re.sub( "\[.*?\]", self.repl, filename) - - # replace any name seperators with spaces - filename = self.fixSpaces(filename) - - # remove any "of NN" phrase with spaces (problem: this could break on some titles) - filename = re.sub( "of [\d]+", self.repl, filename) - - #print u"[{0}]".format(filename) - - # we should now have a cleaned up filename version with all the words in - # the same positions as original filename - - # make a list of each word and its position - word_list = list() - for m in re.finditer("\S+", filename): - word_list.append( (m.group(0), m.start(), m.end()) ) - - # remove the first word, since it can't be the issue number - if len(word_list) > 1: - word_list = word_list[1:] - else: - #only one word?? just bail. - return issue, start, end - - # Now try to search for the likely issue number word in the list - - # first look for a word with "#" followed by digits with optional sufix - # this is almost certainly the issue number - for w in reversed(word_list): - if re.match("#[-]?(([0-9]*\.[0-9]+|[0-9]+)(\w*))", w[0]): - found = True - break - - # same as above but w/o a '#', and only look at the last word in the list - if not found: - w = word_list[-1] - if re.match("[-]?(([0-9]*\.[0-9]+|[0-9]+)(\w*))", w[0]): - found = True - - # now try to look for a # followed by any characters - if not found: - for w in reversed(word_list): - if re.match("#\S+", w[0]): - found = True - break - - if found: - issue = w[0] - start = w[1] - end = w[2] - if issue[0] == '#': - issue = issue[1:] - - return issue, start, end - - def getSeriesName(self, filename, issue_start ): - - # use the issue number string index to split the filename string - - if issue_start != 0: - filename = filename[:issue_start] - - # in case there is no issue number, remove some obvious stuff - if "--" in filename: - # the pattern seems to be that anything to left of the first "--" is the series name followed by issue - filename = re.sub("--.*", self.repl, filename) - - elif "__" in filename: - # the pattern seems to be that anything to left of the first "__" is the series name followed by issue - filename = re.sub("__.*", self.repl, filename) - - filename = filename.replace("+", " ") - tmpstr = self.fixSpaces(filename, remove_dashes=False) - - series = tmpstr - volume = "" - - #save the last word - try: - last_word = series.split()[-1] - except: - last_word = "" - - # remove any parenthetical phrases - series = re.sub( "\(.*?\)", "", series) - - # search for volume number - match = re.search('(.+)([vV]|[Vv][oO][Ll]\.?\s?)(\d+)\s*$', series) - if match: - series = match.group(1) - volume = match.group(3) - - # if a volume wasn't found, see if the last word is a year in parentheses - # since that's a common way to designate the volume - if volume == "": - #match either (YEAR), (YEAR-), or (YEAR-YEAR2) - match = re.search("(\()(\d{4})(-(\d{4}|)|)(\))", last_word) - if match: - volume = match.group(2) - - series = series.strip() - - # if we don't have an issue number (issue_start==0), look - # for hints i.e. "TPB", "one-shot", "OS", "OGN", etc that might - # be removed to help search online - if issue_start == 0: - one_shot_words = [ "tpb", "os", "one-shot", "ogn", "gn" ] - try: - last_word = series.split()[-1] - if last_word.lower() in one_shot_words: - series = series.rsplit(' ', 1)[0] - except: - pass - - return series, volume.strip() - - def getYear( self,filename, issue_end): - - filename = filename[issue_end:] - - year = "" - # look for four digit number with "(" ")" or "--" around it - match = re.search('(\(\d\d\d\d\))|(--\d\d\d\d--)', filename) - if match: - year = match.group() - # remove non-numerics - year = re.sub("[^0-9]", "", year) - return year - - def getRemainder( self, filename, year, count, issue_end ): - - #make a guess at where the the non-interesting stuff begins - remainder = "" - - if "--" in filename: - remainder = filename.split("--",1)[1] - elif "__" in filename: - remainder = filename.split("__",1)[1] - elif issue_end != 0: - remainder = filename[issue_end:] - - remainder = self.fixSpaces(remainder, remove_dashes=False) - if year != "": - remainder = remainder.replace(year,"",1) - if count != "": - remainder = remainder.replace("of "+count,"",1) - - remainder = remainder.replace("()","") - - return remainder.strip() - - def parseFilename( self, filename ): - - # remove the path - filename = os.path.basename(filename) - - # remove the extension - filename = os.path.splitext(filename)[0] - - #url decode, just in case - filename = unquote(filename) - - # sometimes archives get messed up names from too many decodings - # often url encodings will break and leave "_28" and "_29" in place - # of "(" and ")" see if there are a number of these, and replace them - if filename.count("_28") > 1 and filename.count("_29") > 1: - filename = filename.replace("_28", "(") - filename = filename.replace("_29", ")") - - self.issue, issue_start, issue_end = self.getIssueNumber(filename) - self.series, self.volume = self.getSeriesName(filename, issue_start) - self.year = self.getYear(filename, issue_end) - self.issue_count = self.getIssueCount(filename, issue_end) - self.remainder = self.getRemainder( filename, self.year, self.issue_count, issue_end ) - - if self.issue != "": - # strip off leading zeros - self.issue = self.issue.lstrip("0") - if self.issue == "": - self.issue = "0" - if self.issue[0] == ".": - self.issue = "0" + self.issue diff --git a/comicapi/genericmetadata.py b/comicapi/genericmetadata.py deleted file mode 100644 index 8e7aeaf..0000000 --- a/comicapi/genericmetadata.py +++ /dev/null @@ -1,316 +0,0 @@ -""" - A python class for internal metadata storage - - The goal of this class is to handle ALL the data that might come from various - tagging schemes and databases, such as ComicVine or GCD. This makes conversion - possible, however lossy it might be - -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import utils - -# These page info classes are exactly the same as the CIX scheme, since it's unique -class PageType: - FrontCover = "FrontCover" - InnerCover = "InnerCover" - Roundup = "Roundup" - Story = "Story" - Advertisement = "Advertisement" - Editorial = "Editorial" - Letters = "Letters" - Preview = "Preview" - BackCover = "BackCover" - Other = "Other" - Deleted = "Deleted" - -""" -class PageInfo: - Image = 0 - Type = PageType.Story - DoublePage = False - ImageSize = 0 - Key = "" - ImageWidth = 0 - ImageHeight = 0 -""" - -class GenericMetadata: - - def __init__(self): - - self.isEmpty = True - self.tagOrigin = None - - self.series = None - self.issue = None - self.title = None - self.publisher = None - self.month = None - self.year = None - self.day = None - self.issueCount = None - self.volume = None - self.genre = None - self.language = None # 2 letter iso code - self.comments = None # use same way as Summary in CIX - - self.volumeCount = None - self.criticalRating = None - self.country = None - - self.alternateSeries = None - self.alternateNumber = None - self.alternateCount = None - self.imprint = None - self.notes = None - self.webLink = None - self.format = None - self.manga = None - self.blackAndWhite = None - self.pageCount = None - self.maturityRating = None - - self.storyArc = None - self.seriesGroup = None - self.scanInfo = None - - self.characters = None - self.teams = None - self.locations = None - - self.credits = list() - self.tags = list() - self.pages = list() - - # Some CoMet-only items - self.price = None - self.isVersionOf = None - self.rights = None - self.identifier = None - self.lastMark = None - self.coverImage = None - - def overlay( self, new_md ): - # Overlay a metadata object on this one - # that is, when the new object has non-None - # values, over-write them to this one - - def assign( cur, new ): - if new is not None: - if type(new) == str and len(new) == 0: - setattr(self, cur, None) - else: - setattr(self, cur, new) - - if not new_md.isEmpty: - self.isEmpty = False - - assign( 'series', new_md.series ) - assign( "issue", new_md.issue ) - assign( "issueCount", new_md.issueCount ) - assign( "title", new_md.title ) - assign( "publisher", new_md.publisher ) - assign( "day", new_md.day ) - assign( "month", new_md.month ) - assign( "year", new_md.year ) - assign( "volume", new_md.volume ) - assign( "volumeCount", new_md.volumeCount ) - assign( "genre", new_md.genre ) - assign( "language", new_md.language ) - assign( "country", new_md.country ) - assign( "criticalRating", new_md.criticalRating ) - assign( "alternateSeries", new_md.alternateSeries ) - assign( "alternateNumber", new_md.alternateNumber ) - assign( "alternateCount", new_md.alternateCount ) - assign( "imprint", new_md.imprint ) - assign( "webLink", new_md.webLink ) - assign( "format", new_md.format ) - assign( "manga", new_md.manga ) - assign( "blackAndWhite", new_md.blackAndWhite ) - assign( "maturityRating", new_md.maturityRating ) - assign( "storyArc", new_md.storyArc ) - assign( "seriesGroup", new_md.seriesGroup ) - assign( "scanInfo", new_md.scanInfo ) - assign( "characters", new_md.characters ) - assign( "teams", new_md.teams ) - assign( "locations", new_md.locations ) - assign( "comments", new_md.comments ) - assign( "notes", new_md.notes ) - - assign( "price", new_md.price ) - assign( "isVersionOf", new_md.isVersionOf ) - assign( "rights", new_md.rights ) - assign( "identifier", new_md.identifier ) - assign( "lastMark", new_md.lastMark ) - - self.overlayCredits( new_md.credits ) - # TODO - - # not sure if the tags and pages should broken down, or treated - # as whole lists.... - - # For now, go the easy route, where any overlay - # value wipes out the whole list - if len(new_md.tags) > 0: - assign( "tags", new_md.tags ) - - if len(new_md.pages) > 0: - assign( "pages", new_md.pages ) - - - def overlayCredits( self, new_credits ): - for c in new_credits: - if c.has_key('primary') and c['primary']: - primary = True - else: - primary = False - - # Remove credit role if person is blank - if c['person'] == "": - for r in reversed(self.credits): - if r['role'].lower() == c['role'].lower(): - self.credits.remove(r) - # otherwise, add it! - else: - self.addCredit( c['person'], c['role'], primary ) - - def setDefaultPageList( self, count ): - # generate a default page list, with the first page marked as the cover - for i in range(count): - page_dict = dict() - page_dict['Image'] = str(i) - if i == 0: - page_dict['Type'] = PageType.FrontCover - self.pages.append( page_dict ) - - def getArchivePageIndex( self, pagenum ): - # convert the displayed page number to the page index of the file in the archive - if pagenum < len( self.pages ): - return int( self.pages[pagenum]['Image'] ) - else: - return 0 - - def getCoverPageIndexList( self ): - # return a list of archive page indices of cover pages - coverlist = [] - for p in self.pages: - if 'Type' in p and p['Type'] == PageType.FrontCover: - coverlist.append( int(p['Image'])) - - if len(coverlist) == 0: - coverlist.append( 0 ) - - return coverlist - - def addCredit( self, person, role, primary = False ): - - credit = dict() - credit['person'] = person - credit['role'] = role - if primary: - credit['primary'] = primary - - # look to see if it's not already there... - found = False - for c in self.credits: - if ( c['person'].lower() == person.lower() and - c['role'].lower() == role.lower() ): - # no need to add it. just adjust the "primary" flag as needed - c['primary'] = primary - found = True - break - - if not found: - self.credits.append(credit) - - - def __str__( self ): - vals = [] - if self.isEmpty: - return "No metadata" - - def add_string( tag, val ): - if val is not None and u"{0}".format(val) != "": - vals.append( (tag, val) ) - - def add_attr_string( tag ): - val = getattr(self,tag) - add_string( tag, getattr(self,tag) ) - - add_attr_string( "series" ) - add_attr_string( "issue" ) - add_attr_string( "issueCount" ) - add_attr_string( "title" ) - add_attr_string( "publisher" ) - add_attr_string( "year" ) - add_attr_string( "month" ) - add_attr_string( "day" ) - add_attr_string( "volume" ) - add_attr_string( "volumeCount" ) - add_attr_string( "genre" ) - add_attr_string( "language" ) - add_attr_string( "country" ) - add_attr_string( "criticalRating" ) - add_attr_string( "alternateSeries" ) - add_attr_string( "alternateNumber" ) - add_attr_string( "alternateCount" ) - add_attr_string( "imprint" ) - add_attr_string( "webLink" ) - add_attr_string( "format" ) - add_attr_string( "manga" ) - - add_attr_string( "price" ) - add_attr_string( "isVersionOf" ) - add_attr_string( "rights" ) - add_attr_string( "identifier" ) - add_attr_string( "lastMark" ) - - if self.blackAndWhite: - add_attr_string( "blackAndWhite" ) - add_attr_string( "maturityRating" ) - add_attr_string( "storyArc" ) - add_attr_string( "seriesGroup" ) - add_attr_string( "scanInfo" ) - add_attr_string( "characters" ) - add_attr_string( "teams" ) - add_attr_string( "locations" ) - add_attr_string( "comments" ) - add_attr_string( "notes" ) - - add_string( "tags", utils.listToString( self.tags ) ) - - for c in self.credits: - primary = "" - if c.has_key('primary') and c['primary']: - primary = " [P]" - add_string( "credit", c['role']+": "+c['person'] + primary) - - # find the longest field name - flen = 0 - for i in vals: - flen = max( flen, len(i[0]) ) - flen += 1 - - #format the data nicely - outstr = "" - fmt_str = u"{0: <" + str(flen) + "} {1}\n" - for i in vals: - outstr += fmt_str.format( i[0]+":", i[1] ) - - return outstr diff --git a/comicapi/issuestring.py b/comicapi/issuestring.py deleted file mode 100644 index 751aa8c..0000000 --- a/comicapi/issuestring.py +++ /dev/null @@ -1,140 +0,0 @@ -# coding=utf-8 -""" -Class for handling the odd permutations of an 'issue number' that the comics industry throws at us - -e.g.: - -"12" -"12.1" -"0" -"-1" -"5AU" -"100-2" - -""" - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import utils -import math -import re - -class IssueString: - def __init__(self, text): - - # break up the issue number string into 2 parts: the numeric and suffix string. - # ( assumes that the numeric portion is always first ) - - self.num = None - self.suffix = "" - - if text is None: - return - - if type(text) == int: - text = str(text) - - if len(text) == 0: - return - - text = unicode(text) - - #skip the minus sign if it's first - if text[0] == '-': - start = 1 - else: - start = 0 - - # if it's still not numeric at start skip it - if text[start].isdigit() or text[start] == ".": - # walk through the string, look for split point (the first non-numeric) - decimal_count = 0 - for idx in range( start, len(text) ): - if text[idx] not in "0123456789.": - break - # special case: also split on second "." - if text[idx] == ".": - decimal_count += 1 - if decimal_count > 1: - break - else: - idx = len(text) - - # move trailing numeric decimal to suffix - # (only if there is other junk after ) - if text[idx-1] == "." and len(text) != idx: - idx = idx -1 - - # if there is no numeric after the minus, make the minus part of the suffix - if idx == 1 and start == 1: - idx = 0 - - part1 = text[0:idx] - part2 = text[idx:len(text)] - - if part1 != "": - self.num = float( part1 ) - self.suffix = part2 - else: - self.suffix = text - - #print "num: {0} suf: {1}".format(self.num, self.suffix) - - def asString( self, pad = 0 ): - #return the float, left side zero-padded, with suffix attached - if self.num is None: - return self.suffix - - negative = self.num < 0 - - num_f = abs(self.num) - - num_int = int( num_f ) - num_s = str( num_int ) - if float( num_int ) != num_f: - num_s = str( num_f ) - - num_s += self.suffix - - # create padding - padding = "" - l = len( str(num_int)) - if l < pad : - padding = "0" * (pad - l) - - num_s = padding + num_s - if negative: - num_s = "-" + num_s - - return num_s - - def asFloat( self ): - #return the float, with no suffix - if self.suffix == u"½": - if self.num is not None: - return self.num + .5 - else: - return .5 - return self.num - - def asInt( self ): - #return the int version of the float - if self.num is None: - return None - return int( self.num ) - - diff --git a/comicapi/utils.py b/comicapi/utils.py deleted file mode 100644 index e315cd7..0000000 --- a/comicapi/utils.py +++ /dev/null @@ -1,597 +0,0 @@ -# coding=utf-8 - -""" -Some generic utilities -""" - - -""" -Copyright 2012-2014 Anthony Beville - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import sys -import os -import re -import platform -import locale -import codecs - - -class UtilsVars: - already_fixed_encoding = False - -def get_actual_preferred_encoding(): - preferred_encoding = locale.getpreferredencoding() - if platform.system() == "Darwin": - preferred_encoding = "utf-8" - return preferred_encoding - -def fix_output_encoding( ): - if not UtilsVars.already_fixed_encoding: - # this reads the environment and inits the right locale - locale.setlocale(locale.LC_ALL, "") - - # try to make stdout/stderr encodings happy for unicode printing - preferred_encoding = get_actual_preferred_encoding() - sys.stdout = codecs.getwriter(preferred_encoding)(sys.stdout) - sys.stderr = codecs.getwriter(preferred_encoding)(sys.stderr) - UtilsVars.already_fixed_encoding = True - -def get_recursive_filelist( pathlist ): - """ - Get a recursive list of of all files under all path items in the list - """ - filename_encoding = sys.getfilesystemencoding() - filelist = [] - for p in pathlist: - # if path is a folder, walk it recursivly, and all files underneath - if type(p) == str: - #make sure string is unicode - p = p.decode(filename_encoding) #, 'replace') - elif type(p) != unicode: - #it's probably a QString - p = unicode(p) - - if os.path.isdir( p ): - for root,dirs,files in os.walk( p ): - for f in files: - if type(f) == str: - #make sure string is unicode - f = f.decode(filename_encoding, 'replace') - elif type(f) != unicode: - #it's probably a QString - f = unicode(f) - filelist.append(os.path.join(root,f)) - else: - filelist.append(p) - - return filelist - -def listToString( l ): - string = "" - if l is not None: - for item in l: - if len(string) > 0: - string += ", " - string += item - return string - -def addtopath( dirname ): - if dirname is not None and dirname != "": - - # verify that path doesn't already contain the given dirname - tmpdirname = re.escape(dirname) - pattern = r"{sep}{dir}$|^{dir}{sep}|{sep}{dir}{sep}|^{dir}$".format( dir=tmpdirname, sep=os.pathsep) - - match = re.search(pattern, os.environ['PATH']) - if not match: - os.environ['PATH'] = dirname + os.pathsep + os.environ['PATH'] - -# returns executable path, if it exists -def which(program): - - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file - - return None - -def removearticles( text ): - text = text.lower() - articles = ['and', 'the', 'a', '&', 'issue' ] - newText = '' - for word in text.split(' '): - if word not in articles: - newText += word+' ' - - newText = newText[:-1] - - # now get rid of some other junk - newText = newText.replace(":", "") - newText = newText.replace(",", "") - newText = newText.replace("-", " ") - - # since the CV api changed, searches for series names with periods - # now explicity require the period to be in the search key, - # so the line below is removed (for now) - #newText = newText.replace(".", "") - - return newText - - -def unique_file(file_name): - counter = 1 - file_name_parts = os.path.splitext(file_name) # returns ('/path/file', '.ext') - while 1: - if not os.path.lexists( file_name): - return file_name - file_name = file_name_parts[0] + ' (' + str(counter) + ')' + file_name_parts[1] - counter += 1 - - -# -o- coding: utf-8 -o- -# ISO639 python dict -# oficial list in http://www.loc.gov/standards/iso639-2/php/code_list.php - -lang_dict = { - 'ab': 'Abkhaz', - 'aa': 'Afar', - 'af': 'Afrikaans', - 'ak': 'Akan', - 'sq': 'Albanian', - 'am': 'Amharic', - 'ar': 'Arabic', - 'an': 'Aragonese', - 'hy': 'Armenian', - 'as': 'Assamese', - 'av': 'Avaric', - 'ae': 'Avestan', - 'ay': 'Aymara', - 'az': 'Azerbaijani', - 'bm': 'Bambara', - 'ba': 'Bashkir', - 'eu': 'Basque', - 'be': 'Belarusian', - 'bn': 'Bengali', - 'bh': 'Bihari', - 'bi': 'Bislama', - 'bs': 'Bosnian', - 'br': 'Breton', - 'bg': 'Bulgarian', - 'my': 'Burmese', - 'ca': 'Catalan; Valencian', - 'ch': 'Chamorro', - 'ce': 'Chechen', - 'ny': 'Chichewa; Chewa; Nyanja', - 'zh': 'Chinese', - 'cv': 'Chuvash', - 'kw': 'Cornish', - 'co': 'Corsican', - 'cr': 'Cree', - 'hr': 'Croatian', - 'cs': 'Czech', - 'da': 'Danish', - 'dv': 'Divehi; Maldivian;', - 'nl': 'Dutch', - 'dz': 'Dzongkha', - 'en': 'English', - 'eo': 'Esperanto', - 'et': 'Estonian', - 'ee': 'Ewe', - 'fo': 'Faroese', - 'fj': 'Fijian', - 'fi': 'Finnish', - 'fr': 'French', - 'ff': 'Fula', - 'gl': 'Galician', - 'ka': 'Georgian', - 'de': 'German', - 'el': 'Greek, Modern', - 'gn': 'Guaraní', - 'gu': 'Gujarati', - 'ht': 'Haitian', - 'ha': 'Hausa', - 'he': 'Hebrew (modern)', - 'hz': 'Herero', - 'hi': 'Hindi', - 'ho': 'Hiri Motu', - 'hu': 'Hungarian', - 'ia': 'Interlingua', - 'id': 'Indonesian', - 'ie': 'Interlingue', - 'ga': 'Irish', - 'ig': 'Igbo', - 'ik': 'Inupiaq', - 'io': 'Ido', - 'is': 'Icelandic', - 'it': 'Italian', - 'iu': 'Inuktitut', - 'ja': 'Japanese', - 'jv': 'Javanese', - 'kl': 'Kalaallisut', - 'kn': 'Kannada', - 'kr': 'Kanuri', - 'ks': 'Kashmiri', - 'kk': 'Kazakh', - 'km': 'Khmer', - 'ki': 'Kikuyu, Gikuyu', - 'rw': 'Kinyarwanda', - 'ky': 'Kirghiz, Kyrgyz', - 'kv': 'Komi', - 'kg': 'Kongo', - 'ko': 'Korean', - 'ku': 'Kurdish', - 'kj': 'Kwanyama, Kuanyama', - 'la': 'Latin', - 'lb': 'Luxembourgish', - 'lg': 'Luganda', - 'li': 'Limburgish', - 'ln': 'Lingala', - 'lo': 'Lao', - 'lt': 'Lithuanian', - 'lu': 'Luba-Katanga', - 'lv': 'Latvian', - 'gv': 'Manx', - 'mk': 'Macedonian', - 'mg': 'Malagasy', - 'ms': 'Malay', - 'ml': 'Malayalam', - 'mt': 'Maltese', - 'mi': 'Māori', - 'mr': 'Marathi (Marāṭhī)', - 'mh': 'Marshallese', - 'mn': 'Mongolian', - 'na': 'Nauru', - 'nv': 'Navajo, Navaho', - 'nb': 'Norwegian Bokmål', - 'nd': 'North Ndebele', - 'ne': 'Nepali', - 'ng': 'Ndonga', - 'nn': 'Norwegian Nynorsk', - 'no': 'Norwegian', - 'ii': 'Nuosu', - 'nr': 'South Ndebele', - 'oc': 'Occitan', - 'oj': 'Ojibwe, Ojibwa', - 'cu': 'Old Church Slavonic', - 'om': 'Oromo', - 'or': 'Oriya', - 'os': 'Ossetian, Ossetic', - 'pa': 'Panjabi, Punjabi', - 'pi': 'Pāli', - 'fa': 'Persian', - 'pl': 'Polish', - 'ps': 'Pashto, Pushto', - 'pt': 'Portuguese', - 'qu': 'Quechua', - 'rm': 'Romansh', - 'rn': 'Kirundi', - 'ro': 'Romanian, Moldavan', - 'ru': 'Russian', - 'sa': 'Sanskrit (Saṁskṛta)', - 'sc': 'Sardinian', - 'sd': 'Sindhi', - 'se': 'Northern Sami', - 'sm': 'Samoan', - 'sg': 'Sango', - 'sr': 'Serbian', - 'gd': 'Scottish Gaelic', - 'sn': 'Shona', - 'si': 'Sinhala, Sinhalese', - 'sk': 'Slovak', - 'sl': 'Slovene', - 'so': 'Somali', - 'st': 'Southern Sotho', - 'es': 'Spanish; Castilian', - 'su': 'Sundanese', - 'sw': 'Swahili', - 'ss': 'Swati', - 'sv': 'Swedish', - 'ta': 'Tamil', - 'te': 'Telugu', - 'tg': 'Tajik', - 'th': 'Thai', - 'ti': 'Tigrinya', - 'bo': 'Tibetan', - 'tk': 'Turkmen', - 'tl': 'Tagalog', - 'tn': 'Tswana', - 'to': 'Tonga', - 'tr': 'Turkish', - 'ts': 'Tsonga', - 'tt': 'Tatar', - 'tw': 'Twi', - 'ty': 'Tahitian', - 'ug': 'Uighur, Uyghur', - 'uk': 'Ukrainian', - 'ur': 'Urdu', - 'uz': 'Uzbek', - 've': 'Venda', - 'vi': 'Vietnamese', - 'vo': 'Volapük', - 'wa': 'Walloon', - 'cy': 'Welsh', - 'wo': 'Wolof', - 'fy': 'Western Frisian', - 'xh': 'Xhosa', - 'yi': 'Yiddish', - 'yo': 'Yoruba', - 'za': 'Zhuang, Chuang', - 'zu': 'Zulu', -} - - -countries = [ - ('AF', 'Afghanistan'), - ('AL', 'Albania'), - ('DZ', 'Algeria'), - ('AS', 'American Samoa'), - ('AD', 'Andorra'), - ('AO', 'Angola'), - ('AI', 'Anguilla'), - ('AQ', 'Antarctica'), - ('AG', 'Antigua And Barbuda'), - ('AR', 'Argentina'), - ('AM', 'Armenia'), - ('AW', 'Aruba'), - ('AU', 'Australia'), - ('AT', 'Austria'), - ('AZ', 'Azerbaijan'), - ('BS', 'Bahamas'), - ('BH', 'Bahrain'), - ('BD', 'Bangladesh'), - ('BB', 'Barbados'), - ('BY', 'Belarus'), - ('BE', 'Belgium'), - ('BZ', 'Belize'), - ('BJ', 'Benin'), - ('BM', 'Bermuda'), - ('BT', 'Bhutan'), - ('BO', 'Bolivia'), - ('BA', 'Bosnia And Herzegowina'), - ('BW', 'Botswana'), - ('BV', 'Bouvet Island'), - ('BR', 'Brazil'), - ('BN', 'Brunei Darussalam'), - ('BG', 'Bulgaria'), - ('BF', 'Burkina Faso'), - ('BI', 'Burundi'), - ('KH', 'Cambodia'), - ('CM', 'Cameroon'), - ('CA', 'Canada'), - ('CV', 'Cape Verde'), - ('KY', 'Cayman Islands'), - ('CF', 'Central African Rep'), - ('TD', 'Chad'), - ('CL', 'Chile'), - ('CN', 'China'), - ('CX', 'Christmas Island'), - ('CC', 'Cocos Islands'), - ('CO', 'Colombia'), - ('KM', 'Comoros'), - ('CG', 'Congo'), - ('CK', 'Cook Islands'), - ('CR', 'Costa Rica'), - ('CI', 'Cote D`ivoire'), - ('HR', 'Croatia'), - ('CU', 'Cuba'), - ('CY', 'Cyprus'), - ('CZ', 'Czech Republic'), - ('DK', 'Denmark'), - ('DJ', 'Djibouti'), - ('DM', 'Dominica'), - ('DO', 'Dominican Republic'), - ('TP', 'East Timor'), - ('EC', 'Ecuador'), - ('EG', 'Egypt'), - ('SV', 'El Salvador'), - ('GQ', 'Equatorial Guinea'), - ('ER', 'Eritrea'), - ('EE', 'Estonia'), - ('ET', 'Ethiopia'), - ('FK', 'Falkland Islands (Malvinas)'), - ('FO', 'Faroe Islands'), - ('FJ', 'Fiji'), - ('FI', 'Finland'), - ('FR', 'France'), - ('GF', 'French Guiana'), - ('PF', 'French Polynesia'), - ('TF', 'French S. Territories'), - ('GA', 'Gabon'), - ('GM', 'Gambia'), - ('GE', 'Georgia'), - ('DE', 'Germany'), - ('GH', 'Ghana'), - ('GI', 'Gibraltar'), - ('GR', 'Greece'), - ('GL', 'Greenland'), - ('GD', 'Grenada'), - ('GP', 'Guadeloupe'), - ('GU', 'Guam'), - ('GT', 'Guatemala'), - ('GN', 'Guinea'), - ('GW', 'Guinea-bissau'), - ('GY', 'Guyana'), - ('HT', 'Haiti'), - ('HN', 'Honduras'), - ('HK', 'Hong Kong'), - ('HU', 'Hungary'), - ('IS', 'Iceland'), - ('IN', 'India'), - ('ID', 'Indonesia'), - ('IR', 'Iran'), - ('IQ', 'Iraq'), - ('IE', 'Ireland'), - ('IL', 'Israel'), - ('IT', 'Italy'), - ('JM', 'Jamaica'), - ('JP', 'Japan'), - ('JO', 'Jordan'), - ('KZ', 'Kazakhstan'), - ('KE', 'Kenya'), - ('KI', 'Kiribati'), - ('KP', 'Korea (North)'), - ('KR', 'Korea (South)'), - ('KW', 'Kuwait'), - ('KG', 'Kyrgyzstan'), - ('LA', 'Laos'), - ('LV', 'Latvia'), - ('LB', 'Lebanon'), - ('LS', 'Lesotho'), - ('LR', 'Liberia'), - ('LY', 'Libya'), - ('LI', 'Liechtenstein'), - ('LT', 'Lithuania'), - ('LU', 'Luxembourg'), - ('MO', 'Macau'), - ('MK', 'Macedonia'), - ('MG', 'Madagascar'), - ('MW', 'Malawi'), - ('MY', 'Malaysia'), - ('MV', 'Maldives'), - ('ML', 'Mali'), - ('MT', 'Malta'), - ('MH', 'Marshall Islands'), - ('MQ', 'Martinique'), - ('MR', 'Mauritania'), - ('MU', 'Mauritius'), - ('YT', 'Mayotte'), - ('MX', 'Mexico'), - ('FM', 'Micronesia'), - ('MD', 'Moldova'), - ('MC', 'Monaco'), - ('MN', 'Mongolia'), - ('MS', 'Montserrat'), - ('MA', 'Morocco'), - ('MZ', 'Mozambique'), - ('MM', 'Myanmar'), - ('NA', 'Namibia'), - ('NR', 'Nauru'), - ('NP', 'Nepal'), - ('NL', 'Netherlands'), - ('AN', 'Netherlands Antilles'), - ('NC', 'New Caledonia'), - ('NZ', 'New Zealand'), - ('NI', 'Nicaragua'), - ('NE', 'Niger'), - ('NG', 'Nigeria'), - ('NU', 'Niue'), - ('NF', 'Norfolk Island'), - ('MP', 'Northern Mariana Islands'), - ('NO', 'Norway'), - ('OM', 'Oman'), - ('PK', 'Pakistan'), - ('PW', 'Palau'), - ('PA', 'Panama'), - ('PG', 'Papua New Guinea'), - ('PY', 'Paraguay'), - ('PE', 'Peru'), - ('PH', 'Philippines'), - ('PN', 'Pitcairn'), - ('PL', 'Poland'), - ('PT', 'Portugal'), - ('PR', 'Puerto Rico'), - ('QA', 'Qatar'), - ('RE', 'Reunion'), - ('RO', 'Romania'), - ('RU', 'Russian Federation'), - ('RW', 'Rwanda'), - ('KN', 'Saint Kitts And Nevis'), - ('LC', 'Saint Lucia'), - ('VC', 'St Vincent/Grenadines'), - ('WS', 'Samoa'), - ('SM', 'San Marino'), - ('ST', 'Sao Tome'), - ('SA', 'Saudi Arabia'), - ('SN', 'Senegal'), - ('SC', 'Seychelles'), - ('SL', 'Sierra Leone'), - ('SG', 'Singapore'), - ('SK', 'Slovakia'), - ('SI', 'Slovenia'), - ('SB', 'Solomon Islands'), - ('SO', 'Somalia'), - ('ZA', 'South Africa'), - ('ES', 'Spain'), - ('LK', 'Sri Lanka'), - ('SH', 'St. Helena'), - ('PM', 'St.Pierre'), - ('SD', 'Sudan'), - ('SR', 'Suriname'), - ('SZ', 'Swaziland'), - ('SE', 'Sweden'), - ('CH', 'Switzerland'), - ('SY', 'Syrian Arab Republic'), - ('TW', 'Taiwan'), - ('TJ', 'Tajikistan'), - ('TZ', 'Tanzania'), - ('TH', 'Thailand'), - ('TG', 'Togo'), - ('TK', 'Tokelau'), - ('TO', 'Tonga'), - ('TT', 'Trinidad And Tobago'), - ('TN', 'Tunisia'), - ('TR', 'Turkey'), - ('TM', 'Turkmenistan'), - ('TV', 'Tuvalu'), - ('UG', 'Uganda'), - ('UA', 'Ukraine'), - ('AE', 'United Arab Emirates'), - ('UK', 'United Kingdom'), - ('US', 'United States'), - ('UY', 'Uruguay'), - ('UZ', 'Uzbekistan'), - ('VU', 'Vanuatu'), - ('VA', 'Vatican City State'), - ('VE', 'Venezuela'), - ('VN', 'Viet Nam'), - ('VG', 'Virgin Islands (British)'), - ('VI', 'Virgin Islands (U.S.)'), - ('EH', 'Western Sahara'), - ('YE', 'Yemen'), - ('YU', 'Yugoslavia'), - ('ZR', 'Zaire'), - ('ZM', 'Zambia'), - ('ZW', 'Zimbabwe') -] - - - -def getLanguageDict(): - return lang_dict - -def getLanguageFromISO( iso ): - if iso == None: - return None - else: - return lang_dict[ iso ] - - - - - - - - - -