From 68595ee09d8c82703b0bd1a27ba33d9da1617e2e Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Tue, 15 Apr 2014 17:42:16 +0200 Subject: [PATCH] Import rar archives --- beets/importer.py | 11 +++++++++++ setup.py | 1 + test/rsrc/archive.rar | Bin 0 -> 2357 bytes test/test_importer.py | 13 +++++++++++++ tox.ini | 1 + 5 files changed, 26 insertions(+) create mode 100644 test/rsrc/archive.rar diff --git a/beets/importer.py b/beets/importer.py index d31fd1a11..61ff1294a 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -548,6 +548,10 @@ class ImportTask(object): class ArchiveImportTask(ImportTask): + """Additional methods for handling archives. + + Use when `toppath` points to a `zip`, `tar`, or `rar` archive. + """ def __init__(self, toppath): super(ArchiveImportTask, self).__init__(toppath) @@ -582,6 +586,13 @@ class ArchiveImportTask(ImportTask): cls._handlers.append((is_zipfile, ZipFile)) from tarfile import is_tarfile, TarFile cls._handlers.append((is_tarfile, TarFile)) + try: + from rarfile import is_rarfile, RarFile + except ImportError: + pass + else: + cls._handlers.append((is_rarfile, RarFile)) + return cls._handlers def cleanup(self): diff --git a/setup.py b/setup.py index e2c917121..c602d275f 100755 --- a/setup.py +++ b/setup.py @@ -99,6 +99,7 @@ setup( 'echonest_tempo': ['pyechonest'], 'lastgenre': ['pylast'], 'web': ['flask'], + 'import': ['rarfile'], }, # Non-Python/non-PyPI plugin dependencies: # replaygain: mp3gain || aacgain diff --git a/test/rsrc/archive.rar b/test/rsrc/archive.rar new file mode 100644 index 0000000000000000000000000000000000000000..e51051155c56a793e6659603e3dcb9126f948f62 GIT binary patch literal 2357 zcmV-53Ci|TVR9iF2LR8Ia{vGh000000002_Y;+)yDgf{Z004yx000B}p?Ia}Sd2s+ zGY9~rfdBwzb!==dZE#}%zz`jkSjde$m;w9jkdi2YChof&1SGRI+UlbO`9jqQYYMqt zs$Ei-H)zWbf&$1Ak^;1r&s46{HdWW*b4|+P$#kmYH)=N#6GaIHuG4jOV4CA~5g=IL zHTWMCQbrTogoK3oci1x*cQ=27>7MlGdCv2l=Xu{e?`QK|_s)EM?>y&w=6?PAp7WF6 zb0_eg#MX$XrUC4)+yigNzFAM;1ic}e=7x#t^bhQAFTl`Yh=q@4L#Z!|)YCboynQT| zn4>gH)XQC*$@A?&hC>Qi@j~|HFwl28x1?2w^oOflLk0`g0U#YC4(Qp5O<@xbK97I_ zNx6GLY5=G%bKmKcN{zW|4CKSDo2y#rAPkF^?qFj>1ChNilgD}?kxtpqMN(9<>OYF zoAIcd`l*%nF=W0eAMHujJTxjM87x9z${uR6~p==0NY^r6i z43~RYc#_cOqA-JZ9VQ!!t&?>|5eWSuyYAiOxTOv)Qv5>iohSkjBp}BgJ+i28ekOzC z0jZGk5Ed*k^UOAY1{5Gxo*ljXI9yBMX2(r4E%?T<7K?^x(Ym_8CuG89hYX0R!?wB3 zD|+9!Xj;OeztRzip#h|=UJ{lq^dYV6=UBGn~#n?W^8HX;mH~O1L-u>zXWYla-Cl;c`>-)n01Vc)~1@Qn4s78 zDp^=;?yPROi0-T|szMfA&R!(#i?fpqDSH9M+0Z}ekbVu93AG~J07mh6fgf~Zt8_zi zd{){9d@5_3w9gS_BJ0$HsIqLN$v2X1|HIgZ^yXMxv2yR~)j7p0SmHi?ikYM2kBcZN zFvC0fOiJ+AwQ+bv&k^#QtO``s(Rpz=o!{+;T^E4p-R_cDJIk}&`;NQZh=*is!?V>F zT1nQ#?=qI_j{MH&VoeyzAHXu)v|!zMADg2r_p~gvo{ouR{LI{z>(^PE-z?{QaT`0^18?OOBP?66~loT=q z!_KiejX%1AfMiv7$9QoA6)Ht4)27&01VLqq>5P4kM4^r0$jj?!TXsPj^Y0!L#Wv;v z^S%Eg3Y@r)Ho_D+r-d|t{ZTM&!rl?IFN>xz7=58iHPJ`8`*Lgbq5{ZjzBsNWXBiCo zbqAKZ2Y%lsM%70*f^gwo88%+|>%<>Z`t%@Ar_wLzev!=)&Dk~`q@fbRofXl&!U#Hs z2WfCXpd`vb!Wv?7Yoa`FkRC?G6a7(q_SIk$v$Vooov(uHi_|kzOTUa!dI@16FT9k> zrPMRF?&@>9zc*cGFz*bRJuRwgP_rcBGC(#8(x7s%ABhig?v(~~xGYhOQ{9SuD9{U~ zS2RH1-?P(EWNDRTe@9jAOsJh6z9>8EnuEarmm$aluo6>7QS`|Q2fZ$lXk~PERnbu} z>hD533Oz8ex1mr|BwUbCq#&Uf^&|1$B>-@ze)llxE+YHneia{T;0HfE{Yv7)_WH9_a{F2wmq+>X{wrU;H|MYZq+x{_Tr2?#ZyL~MrUWlqa&#Ex z&@_Beg5;Ut>DeG8eFdsv7p+f*`vZo-g?UsSa#!9TLTv8om=unM!i;4^Rm_ zepC+~dV~AguSM<-onj`h7PPHlvqTMu%PmqLUf76vhC-wH+dx6 zlT)Fe*}C!sn{L{L<3S%C9i@VzfeLCC-*xnfkvkoYLL^>%LTY5lQ9W7`4q?0q=<|`% z5OXjy@cG2Q^{;auBs}-Hs7|?^nse7FMyO56BO@)N}Dnk;~>NIl@rLF zX9Yi+8=P&rhux!mR%68eVrhKlX(^KVUT6HcAhe>Vrl^0dEfajo@66v()Fphp^Zy-} zzJdh@q@V%W$_ZoAX6k_Tj^ zV_r23j!`Kq9UDC=>&D3;m3hZ^L$Q;OI^+KWh6W8OKe3LXc*+Lko6I*T5YS}0)G@L0 b5>G>ukvl5sq5t646b-lVK*T+J06+%-6)>9n literal 0 HcmV?d00001 diff --git a/test/test_importer.py b/test/test_importer.py index 854b21d4b..d6b211c2d 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -342,6 +342,19 @@ class ImportTarTest(ImportZipTest): return path +class ImportRarTest(ImportZipTest): + + def create_archive(self): + return os.path.join(_common.RSRC, 'archive.rar') + + +@unittest.skip('Implment me!') +class ImportPasswordRarTest(ImportZipTest): + + def create_archive(self): + return os.path.join(_common.RSRC, 'password.rar') + + class ImportSingletonTest(_common.TestCase, ImportHelper): """Test ``APPLY`` and ``ASIS`` choices for an import session with singletons config set to True. diff --git a/tox.ini b/tox.ini index 5e50071c6..e84f536ac 100644 --- a/tox.ini +++ b/tox.ini @@ -14,6 +14,7 @@ deps = flask responses pyechonest + rarfile commands = nosetests {posargs}