[#32] Internationalized the core and localized it to french.

This commit is contained in:
Virgil Dupras 2011-01-18 17:33:33 +01:00
parent 04d7880a0c
commit 42cff20710
17 changed files with 153 additions and 37 deletions

View File

@ -0,0 +1,29 @@
"Collecting files to scan" = "Collecting files to scan";
"%s (%d discarded)" = "%s (%d discarded)";
"Scanning for duplicates" = "Scanning for duplicates";
"Loading" = "Loading";
"Moving" = "Moving";
"Copying" = "Copying";
"Sending to Trash" = "Sending to Trash";
"0 matches found" = "0 matches found";
"%d matches found" = "%d matches found";
"Read size of %d/%d files" = "Read size of %d/%d files";
"Grouped %d/%d matches" = "Grouped %d/%d matches";
"%d / %d (%s / %s) duplicates marked." = "%d / %d (%s / %s) duplicates marked.";
" filter: %s" = " filter: %s";
"Read size of %d/%d files" = "Read size of %d/%d files";
"Read metadata of %d/%d files" = "Read metadata of %d/%d files";
"Removing false matches" = "Removing false matches";
"Processed %d/%d matches against the ignore list" = "Processed %d/%d matches against the ignore list";
"Doing group prioritization" = "Doing group prioritization";
"Analyzed %d/%d pictures" = "Analyzed %d/%d pictures";
"Preparing for matching" = "Preparing for matching";
"Matched %d/%d pictures" = "Matched %d/%d pictures";
"Verified %d/%d matches" = "Verified %d/%d matches";
"Removing dead tracks from your iTunes Library" = "Removing dead tracks from your iTunes Library";
"Scanning the iTunes Library" = "Scanning the iTunes Library";
"Probing iPhoto. Don't touch it during the operation!" = "Probing iPhoto. Don't touch it during the operation!";
"Sending dupes to the Trash" = "Sending dupes to the Trash";

View File

@ -0,0 +1,28 @@
"Collecting files to scan" = "Collecte des fichiers à scanner";
"%s (%d discarded)" = "%s (%d hors-groupe)";
"Scanning for duplicates" = "Scan de doublons en cours";
"Loading" = "Chargement en cours";
"Moving" = "Déplacement en cours";
"Copying" = "Copie en cours";
"Sending to Trash" = "Envoi vers corbeille";
"0 matches found" = "0 paires trouvées";
"%d matches found" = "%d paires trouvées";
"Read size of %d/%d files" = "Lu la taille de %d/%d fichiers";
"Grouped %d/%d matches" = "%d/%d paires groupées";
"%d / %d (%s / %s) duplicates marked." = "%d / %d (%s / %s) doublons marqués.";
" filter: %s" = " filtre: %s";
"Read metadata of %d/%d files" = "Lu les métadonnées de %d/%d fichiers";
"Removing false matches" = "Retrait des paires invalides";
"Processed %d/%d matches against the ignore list" = "Vérification de %d/%d paires dans la ignore list";
"Doing group prioritization" = "Prioritization des groupes";
"Analyzed %d/%d pictures" = "Analyzé %d/%d images";
"Preparing for matching" = "Préparation pour la comparaison";
"Matched %d/%d pictures" = "Comparé %d/%d images";
"Verified %d/%d matches" = "Vérifié %d/%d paires";
"Removing dead tracks from your iTunes Library" = "Retrait des tracks mortes de votre librairie iTunes";
"Scanning the iTunes Library" = "Scan de la librairie iTunes en cours";
"Probing iPhoto. Don't touch it during the operation!" = "Communication avec iPhoto en cours. N'y touchez pas!";
"Sending dupes to the Trash" = "Envoi de doublons à la corbeille en cours";

View File

@ -4,6 +4,9 @@
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
from hscommon.trans import install_cocoa_trans
install_cocoa_trans()
from hscommon.cocoa import signature from hscommon.cocoa import signature
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel

View File

@ -45,6 +45,7 @@
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE45274F12E5F62D00005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE45274D12E5F62D00005A15 /* core.strings */; };
CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */; }; CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */; };
CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */; }; CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */; };
CE4B59C91119919700C06C9E /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C61119919700C06C9E /* progress.xib */; }; CE4B59C91119919700C06C9E /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C61119919700C06C9E /* progress.xib */; };
@ -142,6 +143,8 @@
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE45274E12E5F62D00005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE45275012E5F63900005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE49DEF20FDFEB810098617B /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; }; CE49DEF20FDFEB810098617B /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; };
CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; }; CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; };
CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; }; CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; };
@ -270,6 +273,7 @@
CE05330C12E5D3D70029EF25 /* xib */, CE05330C12E5D3D70029EF25 /* xib */,
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
CE05332D12E5D6100029EF25 /* Localizable.strings */, CE05332D12E5D6100029EF25 /* Localizable.strings */,
CE45274D12E5F62D00005A15 /* core.strings */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */, CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */,
); );
@ -503,6 +507,7 @@
CE05331B12E5D3ED0029EF25 /* ResultWindow.xib in Resources */, CE05331B12E5D3ED0029EF25 /* ResultWindow.xib in Resources */,
CE05332312E5D4100029EF25 /* Preferences.xib in Resources */, CE05332312E5D4100029EF25 /* Preferences.xib in Resources */,
CE05332F12E5D6100029EF25 /* Localizable.strings in Resources */, CE05332F12E5D6100029EF25 /* Localizable.strings in Resources */,
CE45274F12E5F62D00005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -612,6 +617,15 @@
name = Localizable.strings; name = Localizable.strings;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CE45274D12E5F62D00005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE45274E12E5F62D00005A15 /* en */,
CE45275012E5F63900005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */ = { CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (

View File

@ -4,6 +4,9 @@
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
from hscommon.trans import install_cocoa_trans
install_cocoa_trans()
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
from core_pe import app_cocoa as app_pe_cocoa from core_pe import app_cocoa as app_pe_cocoa

View File

@ -26,6 +26,7 @@
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE4527AC12E5F6E700005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE4527AA12E5F6E700005A15 /* core.strings */; };
CE60180812DF3EA900236FDC /* HSRecentFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60180712DF3EA900236FDC /* HSRecentFiles.m */; }; CE60180812DF3EA900236FDC /* HSRecentFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60180712DF3EA900236FDC /* HSRecentFiles.m */; };
CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6044EB0FE6796200B71262 /* DetailsPanel.m */; }; CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6044EB0FE6796200B71262 /* DetailsPanel.m */; };
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; }; CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; };
@ -119,6 +120,8 @@
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE4527AB12E5F6E700005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE4527B012E5F72600005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE60180612DF3EA900236FDC /* HSRecentFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSRecentFiles.h; path = ../../cocoalib/HSRecentFiles.h; sourceTree = SOURCE_ROOT; }; CE60180612DF3EA900236FDC /* HSRecentFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSRecentFiles.h; path = ../../cocoalib/HSRecentFiles.h; sourceTree = SOURCE_ROOT; };
CE60180712DF3EA900236FDC /* HSRecentFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSRecentFiles.m; path = ../../cocoalib/HSRecentFiles.m; sourceTree = SOURCE_ROOT; }; CE60180712DF3EA900236FDC /* HSRecentFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSRecentFiles.m; path = ../../cocoalib/HSRecentFiles.m; sourceTree = SOURCE_ROOT; };
CE6044EA0FE6796200B71262 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; }; CE6044EA0FE6796200B71262 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; };
@ -272,6 +275,7 @@
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE0533A912E5DA6A0029EF25 /* Localizable.strings */, CE0533A912E5DA6A0029EF25 /* Localizable.strings */,
CE4527AA12E5F6E700005A15 /* core.strings */,
CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */, CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */,
); );
name = Resources; name = Resources;
@ -507,6 +511,7 @@
CE0533A712E5DA4D0029EF25 /* DetailsPanel.xib in Resources */, CE0533A712E5DA4D0029EF25 /* DetailsPanel.xib in Resources */,
CE0533A812E5DA4D0029EF25 /* Preferences.xib in Resources */, CE0533A812E5DA4D0029EF25 /* Preferences.xib in Resources */,
CE0533AB12E5DA6A0029EF25 /* Localizable.strings in Resources */, CE0533AB12E5DA6A0029EF25 /* Localizable.strings in Resources */,
CE4527AC12E5F6E700005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -629,6 +634,15 @@
path = ../../cocoalib/xib; path = ../../cocoalib/xib;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
CE4527AA12E5F6E700005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE4527AB12E5F6E700005A15 /* en */,
CE4527B012E5F72600005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */

View File

@ -4,6 +4,9 @@
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
from hscommon.trans import install_cocoa_trans
install_cocoa_trans()
from hscommon.cocoa import signature from hscommon.cocoa import signature
from core.scanner import ScanType from core.scanner import ScanType

View File

@ -17,6 +17,7 @@
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE4526F212E5F55F00005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE4526F012E5F55F00005A15 /* core.strings */; };
CE45579B0AE3BC2B005A9546 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; }; CE45579B0AE3BC2B005A9546 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; }; CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; }; CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; };
@ -90,6 +91,8 @@
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE4526F112E5F55F00005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE4526F312E5F57000005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE45579A0AE3BC2B005A9546 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; }; CE45579A0AE3BC2B005A9546 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; };
CE647E541173024A006D28BA /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE647E541173024A006D28BA /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE647E551173024A006D28BA /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; }; CE647E551173024A006D28BA /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; };
@ -249,6 +252,7 @@
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE8113E912E5CE9A00A36C80 /* Localizable.strings */, CE8113E912E5CE9A00A36C80 /* Localizable.strings */,
CE4526F012E5F55F00005A15 /* core.strings */,
CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */, CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */,
); );
name = Resources; name = Resources;
@ -482,6 +486,7 @@
CE81135012E5CE4D00A36C80 /* ResultWindow.xib in Resources */, CE81135012E5CE4D00A36C80 /* ResultWindow.xib in Resources */,
CE81135812E5CE6D00A36C80 /* Preferences.xib in Resources */, CE81135812E5CE6D00A36C80 /* Preferences.xib in Resources */,
CE8113EB12E5CE9A00A36C80 /* Localizable.strings in Resources */, CE8113EB12E5CE9A00A36C80 /* Localizable.strings in Resources */,
CE4526F212E5F55F00005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -527,6 +532,15 @@
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
CE4526F012E5F55F00005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE4526F112E5F55F00005A15 /* en */,
CE4526F312E5F57000005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
CE79638412536C94008D405B /* FairwareReminder.xib */ = { CE79638412536C94008D405B /* FairwareReminder.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (

View File

@ -290,7 +290,7 @@
<reference key="NSControlView" ref="637819333"/> <reference key="NSControlView" ref="637819333"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<object class="NSCustomResource" key="NSNormalImage" id="466498619"> <object class="NSCustomResource" key="NSNormalImage" id="751058253">
<string key="NSClassName">NSImage</string> <string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSSwitch</string> <string key="NSResourceName">NSSwitch</string>
</object> </object>
@ -317,7 +317,7 @@
<reference key="NSControlView" ref="1067721243"/> <reference key="NSControlView" ref="1067721243"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -339,7 +339,7 @@
<reference key="NSControlView" ref="290008886"/> <reference key="NSControlView" ref="290008886"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -361,7 +361,7 @@
<reference key="NSControlView" ref="551239185"/> <reference key="NSControlView" ref="551239185"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -383,7 +383,7 @@
<reference key="NSControlView" ref="208488736"/> <reference key="NSControlView" ref="208488736"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -405,7 +405,7 @@
<reference key="NSControlView" ref="427690895"/> <reference key="NSControlView" ref="427690895"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -621,7 +621,7 @@
<reference key="NSControlView" ref="724127338"/> <reference key="NSControlView" ref="724127338"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@ -643,7 +643,7 @@
<reference key="NSControlView" ref="647216699"/> <reference key="NSControlView" ref="647216699"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="466498619"/> <reference key="NSNormalImage" ref="751058253"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>

View File

@ -19,6 +19,7 @@ from hscommon.notify import Broadcaster
from hscommon.path import Path from hscommon.path import Path
from hscommon.conflict import smart_move, smart_copy from hscommon.conflict import smart_move, smart_copy
from hscommon.util import delete_if_empty, first, escape from hscommon.util import delete_if_empty, first, escape
from hscommon.trans import tr
from . import directories, results, scanner, export, fs from . import directories, results, scanner, export, fs
@ -328,7 +329,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def start_scanning(self): def start_scanning(self):
def do(j): def do(j):
j.set_progress(0, 'Collecting files to scan') j.set_progress(0, tr("Collecting files to scan"))
files = list(self.directories.get_files()) files = list(self.directories.get_files())
if self.options['ignore_hardlink_matches']: if self.options['ignore_hardlink_matches']:
files = self._remove_hardlink_dupes(files) files = self._remove_hardlink_dupes(files)
@ -354,6 +355,6 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def stat_line(self): def stat_line(self):
result = self.results.stat_line result = self.results.stat_line
if self.scanner.discarded_file_count: if self.scanner.discarded_file_count:
result = '%s (%d discarded)' % (result, self.scanner.discarded_file_count) result = tr("%s (%d discarded)") % (result, self.scanner.discarded_file_count)
return result return result

View File

@ -15,15 +15,16 @@ from hscommon.cocoa import install_exception_hook
from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults, from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults,
NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask, NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask,
NSWorkspace) NSWorkspace)
from hscommon.trans import tr
from . import app from . import app
JOBID2TITLE = { JOBID2TITLE = {
app.JOB_SCAN: "Scanning for duplicates", app.JOB_SCAN: tr("Scanning for duplicates"),
app.JOB_LOAD: "Loading", app.JOB_LOAD: tr("Loading"),
app.JOB_MOVE: "Moving", app.JOB_MOVE: tr("Moving"),
app.JOB_COPY: "Copying", app.JOB_COPY: tr("Copying"),
app.JOB_DELETE: "Sending to Trash", app.JOB_DELETE: tr("Sending to Trash"),
} }
class DupeGuru(app.DupeGuru): class DupeGuru(app.DupeGuru):

View File

@ -6,7 +6,6 @@
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
import difflib import difflib
import itertools import itertools
import logging import logging
@ -15,6 +14,7 @@ from collections import defaultdict, namedtuple
from unicodedata import normalize from unicodedata import normalize
from hscommon.util import flatten, multi_replace from hscommon.util import flatten, multi_replace
from hscommon.trans import tr
from jobprogress import job from jobprogress import job
(WEIGHT_WORDS, (WEIGHT_WORDS,
@ -25,6 +25,7 @@ JOB_REFRESH_RATE = 100
def getwords(s): def getwords(s):
if isinstance(s, str): if isinstance(s, str):
# XXX is this really needed?
s = normalize('NFD', s) s = normalize('NFD', s)
s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower() s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower()
s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace) s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace)
@ -175,7 +176,7 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
match_flags.append(MATCH_SIMILAR_WORDS) match_flags.append(MATCH_SIMILAR_WORDS)
if no_field_order: if no_field_order:
match_flags.append(NO_FIELD_ORDER) match_flags.append(NO_FIELD_ORDER)
j.start_job(len(word_dict), '0 matches found') j.start_job(len(word_dict), tr("0 matches found"))
compared = defaultdict(set) compared = defaultdict(set)
result = [] result = []
try: try:
@ -193,7 +194,7 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
result.append(m) result.append(m)
if len(result) >= LIMIT: if len(result) >= LIMIT:
return result return result
j.add_progress(desc='%d matches found' % len(result)) j.add_progress(desc=tr("%d matches found") % len(result))
except MemoryError: except MemoryError:
# This is the place where the memory usage is at its peak during the scan. # This is the place where the memory usage is at its peak during the scan.
# Just continue the process with an incomplete list of matches. # Just continue the process with an incomplete list of matches.
@ -205,14 +206,14 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob): def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob):
j = j.start_subjob([2, 8]) j = j.start_subjob([2, 8])
size2files = defaultdict(set) size2files = defaultdict(set)
for file in j.iter_with_progress(files, 'Read size of %d/%d files'): for file in j.iter_with_progress(files, tr("Read size of %d/%d files")):
filesize = getattr(file, sizeattr) filesize = getattr(file, sizeattr)
if filesize: if filesize:
size2files[filesize].add(file) size2files[filesize].add(file)
possible_matches = [files for files in size2files.values() if len(files) > 1] possible_matches = [files for files in size2files.values() if len(files) > 1]
del size2files del size2files
result = [] result = []
j.start_job(len(possible_matches), '0 matches found') j.start_job(len(possible_matches), tr("0 matches found"))
for group in possible_matches: for group in possible_matches:
for first, second in itertools.combinations(group, 2): for first, second in itertools.combinations(group, 2):
if first.is_ref and second.is_ref: if first.is_ref and second.is_ref:
@ -220,7 +221,7 @@ def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob)
if first.md5partial == second.md5partial: if first.md5partial == second.md5partial:
if partial or first.md5 == second.md5: if partial or first.md5 == second.md5:
result.append(Match(first, second, 100)) result.append(Match(first, second, 100))
j.add_progress(desc='%d matches found' % len(result)) j.add_progress(desc=tr("%d matches found") % len(result))
return result return result
class Group(object): class Group(object):
@ -349,7 +350,7 @@ def get_groups(matches, j=job.nulljob):
dupe2group = {} dupe2group = {}
groups = [] groups = []
try: try:
for match in j.iter_with_progress(matches, 'Grouped %d/%d matches', JOB_REFRESH_RATE): for match in j.iter_with_progress(matches, tr("Grouped %d/%d matches"), JOB_REFRESH_RATE):
first, second, _ = match first, second, _ = match
first_group = dupe2group.get(first) first_group = dupe2group.get(first)
second_group = dupe2group.get(second) second_group = dupe2group.get(second)

View File

@ -14,6 +14,7 @@ from . import engine
from jobprogress.job import nulljob from jobprogress.job import nulljob
from hscommon.markable import Markable from hscommon.markable import Markable
from hscommon.util import flatten, nonone, FileOrPath, format_size from hscommon.util import flatten, nonone, FileOrPath, format_size
from hscommon.trans import tr
class Results(Markable): class Results(Markable):
#---Override #---Override
@ -87,14 +88,14 @@ class Results(Markable):
total_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe)) total_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe))
if self.mark_inverted: if self.mark_inverted:
marked_size = self.__total_size - marked_size marked_size = self.__total_size - marked_size
result = '%d / %d (%s / %s) duplicates marked.' % ( result = tr("%d / %d (%s / %s) duplicates marked.") % (
mark_count, mark_count,
total_count, total_count,
format_size(marked_size, 2), format_size(marked_size, 2),
format_size(total_size, 2), format_size(total_size, 2),
) )
if self.__filters: if self.__filters:
result += ' filter: %s' % ' --> '.join(self.__filters) result += tr(" filter: %s") % ' --> '.join(self.__filters)
return result return result
def __recalculate_stats(self): def __recalculate_stats(self):

View File

@ -12,6 +12,7 @@ import re
from jobprogress import job from jobprogress import job
from hscommon import io from hscommon import io
from hscommon.util import dedupe, rem_file_ext, get_file_ext from hscommon.util import dedupe, rem_file_ext, get_file_ext
from hscommon.trans import tr
from . import engine from . import engine
from .ignore import IgnoreList from .ignore import IgnoreList
@ -44,7 +45,7 @@ class Scanner:
def _getmatches(self, files, j): def _getmatches(self, files, j):
if self.size_threshold: if self.size_threshold:
j = j.start_subjob([2, 8]) j = j.start_subjob([2, 8])
for f in j.iter_with_progress(files, 'Read size of %d/%d files'): for f in j.iter_with_progress(files, tr("Read size of %d/%d files")):
f.size # pre-read, makes a smoother progress if read here (especially for bundles) f.size # pre-read, makes a smoother progress if read here (especially for bundles)
files = [f for f in files if f.size >= self.size_threshold] files = [f for f in files if f.size >= self.size_threshold]
if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio): if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio):
@ -64,7 +65,7 @@ class Scanner:
ScanType.Fields: lambda f: engine.getfields(rem_file_ext(f.name)), ScanType.Fields: lambda f: engine.getfields(rem_file_ext(f.name)),
ScanType.Tag: lambda f: [engine.getwords(str(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags], ScanType.Tag: lambda f: [engine.getwords(str(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags],
}[self.scan_type] }[self.scan_type]
for f in j.iter_with_progress(files, 'Read metadata of %d/%d files'): for f in j.iter_with_progress(files, tr("Read metadata of %d/%d files")):
f.words = func(f) f.words = func(f)
return engine.getmatches(files, j=j, **kw) return engine.getmatches(files, j=j, **kw)
@ -93,13 +94,13 @@ class Scanner:
logging.info('Getting matches') logging.info('Getting matches')
matches = self._getmatches(files, j) matches = self._getmatches(files, j)
logging.info('Found %d matches' % len(matches)) logging.info('Found %d matches' % len(matches))
j.set_progress(100, 'Removing false matches') j.set_progress(100, tr("Removing false matches"))
if not self.mix_file_kind: if not self.mix_file_kind:
matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)] matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)]
matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)] matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)]
if self.ignore_list: if self.ignore_list:
j = j.start_subjob(2) j = j.start_subjob(2)
iter_matches = j.iter_with_progress(matches, 'Processed %d/%d matches against the ignore list') iter_matches = j.iter_with_progress(matches, tr("Processed %d/%d matches against the ignore list"))
matches = [m for m in iter_matches matches = [m for m in iter_matches
if not self.ignore_list.AreIgnored(str(m.first.path), str(m.second.path))] if not self.ignore_list.AreIgnored(str(m.first.path), str(m.second.path))]
logging.info('Grouping matches') logging.info('Grouping matches')
@ -108,7 +109,7 @@ class Scanner:
self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups) self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups)
groups = [g for g in groups if any(not f.is_ref for f in g)] groups = [g for g in groups if any(not f.is_ref for f in g)]
logging.info('Created %d groups' % len(groups)) logging.info('Created %d groups' % len(groups))
j.set_progress(100, 'Doing group prioritization') j.set_progress(100, tr("Doing group prioritization"))
for g in groups: for g in groups:
g.prioritize(self._key_func, self._tie_breaker) g.prioritize(self._key_func, self._tie_breaker)
return groups return groups

View File

@ -11,6 +11,7 @@ from appscript import app, k, CommandError
import time import time
from hscommon.cocoa import as_fetch from hscommon.cocoa import as_fetch
from hscommon.trans import tr
from core.app_cocoa import JOBID2TITLE, DupeGuru as DupeGuruBase from core.app_cocoa import JOBID2TITLE, DupeGuru as DupeGuruBase
@ -20,8 +21,8 @@ JOB_REMOVE_DEAD_TRACKS = 'jobRemoveDeadTracks'
JOB_SCAN_DEAD_TRACKS = 'jobScanDeadTracks' JOB_SCAN_DEAD_TRACKS = 'jobScanDeadTracks'
JOBID2TITLE.update({ JOBID2TITLE.update({
JOB_REMOVE_DEAD_TRACKS: "Removing dead tracks from your iTunes Library", JOB_REMOVE_DEAD_TRACKS: tr("Removing dead tracks from your iTunes Library"),
JOB_SCAN_DEAD_TRACKS: "Scanning the iTunes Library", JOB_SCAN_DEAD_TRACKS: tr("Scanning the iTunes Library"),
}) })
class DupeGuruME(DupeGuruBase): class DupeGuruME(DupeGuruBase):

View File

@ -18,6 +18,7 @@ from hscommon.util import get_file_ext, remove_invalid_xml
from hscommon.path import Path from hscommon.path import Path
from hscommon.cocoa import as_fetch from hscommon.cocoa import as_fetch
from hscommon.cocoa.objcmin import NSUserDefaults, NSURL from hscommon.cocoa.objcmin import NSUserDefaults, NSURL
from hscommon.trans import tr
from core import fs from core import fs
from core import app_cocoa, directories from core import app_cocoa, directories
@ -152,7 +153,7 @@ class DupeGuruPE(app_cocoa.DupeGuru):
marked = [dupe for dupe in self.results.dupes if self.results.is_marked(dupe)] marked = [dupe for dupe in self.results.dupes if self.results.is_marked(dupe)]
self.path2iphoto = {} self.path2iphoto = {}
if any(isinstance(dupe, IPhoto) for dupe in marked): if any(isinstance(dupe, IPhoto) for dupe in marked):
j = j.start_subjob([6, 4], "Probing iPhoto. Don\'t touch it during the operation!") j = j.start_subjob([6, 4], tr("Probing iPhoto. Don't touch it during the operation!"))
try: try:
a = app('iPhoto') a = app('iPhoto')
a.activate(timeout=0) a.activate(timeout=0)
@ -165,7 +166,7 @@ class DupeGuruPE(app_cocoa.DupeGuru):
pass pass
except (CommandError, RuntimeError, ApplicationNotFoundError): except (CommandError, RuntimeError, ApplicationNotFoundError):
pass pass
j.start_job(self.results.mark_count, "Sending dupes to the Trash") j.start_job(self.results.mark_count, tr("Sending dupes to the Trash"))
self.results.perform_on_marked(op, True) self.results.perform_on_marked(op, True)
del self.path2iphoto del self.path2iphoto

View File

@ -10,6 +10,7 @@ import logging
import multiprocessing import multiprocessing
from collections import defaultdict, deque from collections import defaultdict, deque
from hscommon.trans import tr
from jobprogress import job from jobprogress import job
from core.engine import Match from core.engine import Match
@ -32,7 +33,7 @@ def prepare_pictures(pictures, cache_path, j=job.nulljob):
cache = Cache(cache_path) cache = Cache(cache_path)
prepared = [] # only pictures for which there was no error getting blocks prepared = [] # only pictures for which there was no error getting blocks
try: try:
for picture in j.iter_with_progress(pictures, 'Analyzed %d/%d pictures'): for picture in j.iter_with_progress(pictures, tr("Analyzed %d/%d pictures")):
picture.dimensions picture.dimensions
picture.unicode_path = str(picture.path) picture.unicode_path = str(picture.path)
try: try:
@ -76,7 +77,7 @@ def async_compare(ref_id, other_ids, dbname, threshold):
def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nulljob): def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nulljob):
j = j.start_subjob([3, 7]) j = j.start_subjob([3, 7])
pictures = prepare_pictures(pictures, cache_path, j) pictures = prepare_pictures(pictures, cache_path, j)
j = j.start_subjob([9, 1], 'Preparing for matching') j = j.start_subjob([9, 1], tr("Preparing for matching"))
cache = Cache(cache_path) cache = Cache(cache_path)
id2picture = {} id2picture = {}
dimensions2pictures = defaultdict(set) dimensions2pictures = defaultdict(set)
@ -94,7 +95,7 @@ def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nul
async_results = deque() async_results = deque()
matches = [] matches = []
pictures_copy = set(pictures) pictures_copy = set(pictures)
for ref in j.iter_with_progress(pictures, 'Matched %d/%d pictures'): for ref in j.iter_with_progress(pictures, tr("Matched %d/%d pictures")):
others = pictures_copy if match_scaled else dimensions2pictures[ref.dimensions] others = pictures_copy if match_scaled else dimensions2pictures[ref.dimensions]
others.remove(ref) others.remove(ref)
if ref.is_ref: if ref.is_ref:
@ -118,7 +119,7 @@ def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nul
matches.extend(result.get()) matches.extend(result.get())
result = [] result = []
for ref_id, other_id, percentage in j.iter_with_progress(matches, 'Verified %d/%d matches', every=10): for ref_id, other_id, percentage in j.iter_with_progress(matches, tr("Verified %d/%d matches"), every=10):
ref = id2picture[ref_id] ref = id2picture[ref_id]
other = id2picture[other_id] other = id2picture[other_id]
if percentage == 100 and ref.md5 != other.md5: if percentage == 100 and ref.md5 != other.md5: