1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2025-03-11 22:24:35 +00:00

[#14 state:port] Changed the results export method to a pure python (and simpler) one.

--HG--
extra : convert_revision : svn%3Ac306627e-7827-47d3-bdf0-9a457c9553a1/trunk%40106
This commit is contained in:
hsoft 2009-09-01 14:05:00 +00:00
parent 7112c57b92
commit 4eebc7bb2c
15 changed files with 186 additions and 393 deletions

View File

@ -20,7 +20,7 @@ http://www.hardcoded.net/licenses/hs_license
- (void)saveIgnoreList; - (void)saveIgnoreList;
- (void)clearIgnoreList; - (void)clearIgnoreList;
- (void)purgeIgnoreList; - (void)purgeIgnoreList;
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds xslt:(NSString *)xsltPath css:(NSString *)cssPath; - (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds;
- (NSNumber *)doScan; - (NSNumber *)doScan;

View File

@ -36,6 +36,8 @@ http://www.hardcoded.net/licenses/hs_license
- (NSString *)logoImageName; - (NSString *)logoImageName;
/* Helpers */ /* Helpers */
- (NSArray *)getColumnsOrder;
- (NSDictionary *)getColumnsWidth;
- (NSArray *)getSelected:(BOOL)aDupesOnly; - (NSArray *)getSelected:(BOOL)aDupesOnly;
- (NSArray *)getSelectedPaths:(BOOL)aDupesOnly; - (NSArray *)getSelectedPaths:(BOOL)aDupesOnly;
- (void)updatePySelection; - (void)updatePySelection;
@ -48,6 +50,7 @@ http://www.hardcoded.net/licenses/hs_license
- (IBAction)copyMarked:(id)sender; - (IBAction)copyMarked:(id)sender;
- (IBAction)deleteMarked:(id)sender; - (IBAction)deleteMarked:(id)sender;
- (IBAction)expandAll:(id)sender; - (IBAction)expandAll:(id)sender;
- (IBAction)exportToXHTML:(id)sender;
- (IBAction)moveMarked:(id)sender; - (IBAction)moveMarked:(id)sender;
- (IBAction)switchSelected:(id)sender; - (IBAction)switchSelected:(id)sender;
- (IBAction)togglePowerMarker:(id)sender; - (IBAction)togglePowerMarker:(id)sender;

View File

@ -75,6 +75,37 @@ http://www.hardcoded.net/licenses/hs_license
} }
/* Helpers */ /* Helpers */
//Returns an array of identifiers, in order.
- (NSArray *)getColumnsOrder
{
NSTableColumn *col;
NSString *colId;
NSMutableArray *result = [NSMutableArray array];
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
while (col = [e nextObject])
{
colId = [col identifier];
[result addObject:colId];
}
return result;
}
- (NSDictionary *)getColumnsWidth
{
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSTableColumn *col;
NSString *colId;
NSNumber *width;
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
while (col = [e nextObject])
{
colId = [col identifier];
width = [NSNumber numberWithFloat:[col width]];
[result setObject:width forKey:colId];
}
return result;
}
- (NSArray *)getSelected:(BOOL)aDupesOnly - (NSArray *)getSelected:(BOOL)aDupesOnly
{ {
if (_powerMode) if (_powerMode)
@ -185,6 +216,12 @@ http://www.hardcoded.net/licenses/hs_license
[matches expandItem:[matches itemAtRow:i]]; [matches expandItem:[matches itemAtRow:i]];
} }
- (IBAction)exportToXHTML:(id)sender
{
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder]];
[[NSWorkspace sharedWorkspace] openFile:exported];
}
- (IBAction)moveMarked:(id)sender - (IBAction)moveMarked:(id)sender
{ {
int mark_count = [[py getMarkCount] intValue]; int mark_count = [[py getMarkCount] intValue];

View File

@ -19,7 +19,7 @@ from hsutil.reg import RegistrableApplication, RegistrationRequired
from hsutil.misc import flatten, first from hsutil.misc import flatten, first
from hsutil.str import escape from hsutil.str import escape
from . import directories, results, scanner from . import directories, results, scanner, export
JOB_SCAN = 'job_scan' JOB_SCAN = 'job_scan'
JOB_LOAD = 'job_load' JOB_LOAD = 'job_load'
@ -177,6 +177,20 @@ class DupeGuru(RegistrableApplication):
self._demo_check() self._demo_check()
self._start_job(JOB_DELETE, self._do_delete) self._start_job(JOB_DELETE, self._do_delete)
def export_to_xhtml(self, column_ids):
column_ids = [colid for colid in column_ids if colid.isdigit()]
column_ids = map(int, column_ids)
column_ids.sort()
colnames = [col['display'] for i, col in enumerate(self.data.COLUMNS) if i in column_ids]
rows = []
for group in self.results.groups:
for dupe in group:
data = self.data.GetDisplayInfo(dupe, group)
row = [data[colid] for colid in column_ids]
row.insert(0, dupe is not group.ref)
rows.append(row)
return export.export_to_xhtml(colnames, rows)
def load(self): def load(self):
self._start_job(JOB_LOAD, self._do_load) self._start_job(JOB_LOAD, self._do_load)
self.load_ignore_list() self.load_ignore_list()

View File

@ -17,7 +17,7 @@ from hsutil.cocoa import install_exception_hook
from hsutil.misc import stripnone from hsutil.misc import stripnone
from hsutil.reg import RegistrationRequired from hsutil.reg import RegistrationRequired
import export, app, data import app, data
JOBID2TITLE = { JOBID2TITLE = {
app.JOB_SCAN: "Scanning for duplicates", app.JOB_SCAN: "Scanning for duplicates",
@ -116,16 +116,6 @@ class DupeGuru(app.DupeGuru):
copy_or_move_marked = demo_method(app.DupeGuru.copy_or_move_marked) copy_or_move_marked = demo_method(app.DupeGuru.copy_or_move_marked)
delete_marked = demo_method(app.DupeGuru.delete_marked) delete_marked = demo_method(app.DupeGuru.delete_marked)
def ExportToXHTML(self,column_ids,xslt_path,css_path):
columns = []
for index,column in enumerate(self.data.COLUMNS):
display = column['display']
enabled = str(index) in column_ids
columns.append((display,enabled))
xml_path = op.join(self.appdata,'results_export.xml')
self.results.save_to_xml(xml_path,self.data.GetDisplayInfo)
return export.export_to_xhtml(xml_path,xslt_path,css_path,columns)
def MakeSelectedReference(self): def MakeSelectedReference(self):
self.make_reference(self.selected_dupes) self.make_reference(self.selected_dupes)

View File

@ -7,60 +7,132 @@
# 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/hs_license # http://www.hardcoded.net/licenses/hs_license
from xml.dom import minidom
import tempfile import tempfile
import os.path as op import os.path as op
import os from tempfile import mkdtemp
from StringIO import StringIO
from hsutil.files import FileOrPath # Yes, this is a very low-tech solution, but at least it doesn't have all these annoying dependency
# and resource problems.
def output_column_xml(outfile, columns): MAIN_TEMPLATE = u"""
"""Creates a xml file outfile with the supplied columns. <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<title>dupeGuru Results</title>
<style type="text/css">
BODY
{
background-color:white;
}
outfile can be a filename or a file object. BODY,A,P,UL,TABLE,TR,TD
columns is a list of 2 sized tuples (display,enabled) {
""" font-family:Tahoma,Arial,sans-serif;
doc = minidom.Document() font-size:10pt;
root = doc.appendChild(doc.createElement('columns')) color: #4477AA;
for display,enabled in columns: }
col_node = root.appendChild(doc.createElement('column'))
col_node.setAttribute('display', display)
col_node.setAttribute('enabled', {True:'y',False:'n'}[enabled])
with FileOrPath(outfile, 'wb') as fp:
doc.writexml(fp, '\t','\t','\n', encoding='utf-8')
def merge_css_into_xhtml(xhtml, css): TABLE
with FileOrPath(xhtml, 'r+') as xhtml: {
with FileOrPath(css) as css: background-color: #225588;
try: margin-left: auto;
doc = minidom.parse(xhtml) margin-right: auto;
except Exception: width: 90%;
return False }
head = doc.getElementsByTagName('head')[0]
links = head.getElementsByTagName('link')
for link in links:
if link.getAttribute('rel') == 'stylesheet':
head.removeChild(link)
style = head.appendChild(doc.createElement('style'))
style.setAttribute('type','text/css')
style.appendChild(doc.createTextNode(css.read()))
xhtml.truncate(0)
doc.writexml(xhtml, '\t','\t','\n', encoding='utf-8')
xhtml.seek(0)
return True
def export_to_xhtml(xml, xslt, css, columns, cmd='xsltproc --path "%(folder)s" "%(xslt)s" "%(xml)s"'): TR
folder = op.split(xml)[0] {
output_column_xml(op.join(folder,'columns.xml'),columns) background-color: white;
html = StringIO() }
cmd = cmd % {'folder': folder, 'xslt': xslt, 'xml': xml}
html.write(os.popen(cmd).read()) TH
html.seek(0) {
merge_css_into_xhtml(html,css) font-weight: bold;
html.seek(0) color: black;
html_path = op.join(folder,'export.htm') background-color: #C8D6E5;
html_file = open(html_path,'w') }
html_file.write(html.read().encode('utf-8'))
html_file.close() TH TD
return html_path {
color:black;
}
TD
{
padding-left: 2pt;
}
TD.rightelem
{
text-align:right;
/*padding-left:0pt;*/
padding-right: 2pt;
width: 17%;
}
TD.indented
{
padding-left: 12pt;
}
H1
{
font-family:&quot;Courier New&quot;,monospace;
color:#6699CC;
font-size:18pt;
color:#6da500;
border-color: #70A0CF;
border-width: 1pt;
border-style: solid;
margin-top: 16pt;
margin-left: 5%;
margin-right: 5%;
padding-top: 2pt;
padding-bottom:2pt;
text-align: center;
}
</style>
</head>
<body>
<h1>dupeGuru Results</h1>
<table>
<tr>$colheaders</tr>
$rows
</table>
</body>
</html>
"""
COLHEADERS_TEMPLATE = u"<th>{name}</th>"
ROW_TEMPLATE = u"""
<tr>
<td class="{indented}">{filename}</td>{cells}
</tr>
"""
CELL_TEMPLATE = u"""<td>{value}</td>"""
def export_to_xhtml(colnames, rows):
# a row is a list of values with the first value being a flag indicating if the row should be indented
if rows:
assert len(rows[0]) == len(colnames) + 1 # + 1 is for the "indented" flag
colheaders = u''.join(COLHEADERS_TEMPLATE.format(name=name) for name in colnames)
rendered_rows = []
for row in rows:
# [2:] is to remove the indented flag + filename
indented = u'indented' if row[0] else u''
filename = row[1]
cells = u''.join(CELL_TEMPLATE.format(value=value) for value in row[2:])
rendered_rows.append(ROW_TEMPLATE.format(indented=indented, filename=filename, cells=cells))
rendered_rows = u''.join(rendered_rows)
# The main template can't use format because the css code uses {}
content = MAIN_TEMPLATE.replace('$colheaders', colheaders).replace('$rows', rendered_rows)
folder = mkdtemp()
destpath = op.join(folder, u'export.htm')
fp = open(destpath, 'w')
fp.write(content.encode('utf-8'))
fp.close()
return destpath

View File

@ -252,7 +252,7 @@ class Results(Markable):
group.clean_matches() group.clean_matches()
self.__dupes = None self.__dupes = None
def save_to_xml(self, outfile, with_data=False): def save_to_xml(self, outfile):
self.apply_filter(None) self.apply_filter(None)
outfile, must_close = open_if_filename(outfile, 'wb') outfile, must_close = open_if_filename(outfile, 'wb')
writer = XMLGenerator(outfile, 'utf-8') writer = XMLGenerator(outfile, 'utf-8')
@ -275,14 +275,6 @@ class Results(Markable):
'marked': cond(self.is_marked(d), 'y', 'n') 'marked': cond(self.is_marked(d), 'y', 'n')
}) })
writer.startElement('file', attrs) writer.startElement('file', attrs)
if with_data:
data_list = self.data.GetDisplayInfo(d, g)
for data in data_list:
attrs = AttributesImpl({
'value': data,
})
writer.startElement('data', attrs)
writer.endElement('data')
writer.endElement('file') writer.endElement('file')
for match in g.matches: for match in g.matches:
attrs = AttributesImpl({ attrs = AttributesImpl({

View File

@ -1,86 +0,0 @@
# Created By: Virgil Dupras
# Created On: 2006/09/16
# $Id$
# Copyright 2009 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "HS" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/hs_license
from xml.dom import minidom
from StringIO import StringIO
from hsutil.testcase import TestCase
from .. import export
from ..export import *
class TCoutput_columns_xml(TestCase):
def test_empty_columns(self):
f = StringIO()
output_column_xml(f,[])
f.seek(0)
doc = minidom.parse(f)
root = doc.documentElement
self.assertEqual('columns',root.nodeName)
self.assertEqual(0,len(root.childNodes))
def test_some_columns(self):
f = StringIO()
output_column_xml(f,[('foo',True),('bar',False),('baz',True)])
f.seek(0)
doc = minidom.parse(f)
columns = doc.getElementsByTagName('column')
self.assertEqual(3,len(columns))
c1,c2,c3 = columns
self.assertEqual('foo',c1.getAttribute('display'))
self.assertEqual('bar',c2.getAttribute('display'))
self.assertEqual('baz',c3.getAttribute('display'))
self.assertEqual('y',c1.getAttribute('enabled'))
self.assertEqual('n',c2.getAttribute('enabled'))
self.assertEqual('y',c3.getAttribute('enabled'))
class TCmerge_css_into_xhtml(TestCase):
def test_main(self):
css = StringIO()
css.write('foobar')
css.seek(0)
xhtml = StringIO()
xhtml.write("""<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dupeGuru - Duplicate file scanner</title>
<link rel="SHORTCUT ICON" href="/favicon.ico" />
<link rel="stylesheet" href="../hardcoded.css" type="text/css" />
</head>
<body>
</body>
</html>""")
xhtml.seek(0)
self.assert_(merge_css_into_xhtml(xhtml,css))
xhtml.seek(0)
doc = minidom.parse(xhtml)
head = doc.getElementsByTagName('head')[0]
#A style node should have been added in head.
styles = head.getElementsByTagName('style')
self.assertEqual(1,len(styles))
style = styles[0]
self.assertEqual('text/css',style.getAttribute('type'))
self.assertEqual('foobar',style.firstChild.nodeValue.strip())
#all <link rel="stylesheet"> should be removed
self.assertEqual(1,len(head.getElementsByTagName('link')))
def test_empty(self):
self.assert_(not merge_css_into_xhtml(StringIO(),StringIO()))
def test_malformed(self):
xhtml = StringIO()
xhtml.write("""<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">""")
xhtml.seek(0)
self.assert_(not merge_css_into_xhtml(xhtml,StringIO()))

View File

@ -395,30 +395,6 @@ class TCResultsXML(TestCase):
self.assertEqual('ibabtu',d1.getAttributeNode('words').nodeValue) self.assertEqual('ibabtu',d1.getAttributeNode('words').nodeValue)
self.assertEqual('ibabtu',d2.getAttributeNode('words').nodeValue) self.assertEqual('ibabtu',d2.getAttributeNode('words').nodeValue)
def test_save_to_xml_with_columns(self):
class FakeDataModule:
def GetDisplayInfo(self,dupe,group):
return [str(dupe.size),dupe.foo.upper()]
for i,object in enumerate(self.objects):
object.size = i
object.foo = u'bar\u00e9'
f = StringIO.StringIO()
self.results.data = FakeDataModule()
self.results.save_to_xml(f,True)
f.seek(0)
doc = xml.dom.minidom.parse(f)
root = doc.documentElement
g1,g2 = root.getElementsByTagName('group')
d1,d2,d3 = g1.getElementsByTagName('file')
d4,d5 = g2.getElementsByTagName('file')
self.assertEqual('0',d1.getElementsByTagName('data')[0].getAttribute('value'))
self.assertEqual(u'BAR\u00c9',d1.getElementsByTagName('data')[1].getAttribute('value')) #\u00c9 is upper of \u00e9
self.assertEqual('1',d2.getElementsByTagName('data')[0].getAttribute('value'))
self.assertEqual('2',d3.getElementsByTagName('data')[0].getAttribute('value'))
self.assertEqual('3',d4.getElementsByTagName('data')[0].getAttribute('value'))
self.assertEqual('4',d5.getElementsByTagName('data')[0].getAttribute('value'))
def test_LoadXML(self): def test_LoadXML(self):
def get_file(path): def get_file(path):
return [f for f in self.objects if str(f.path) == path][0] return [f for f in self.objects if str(f.path) == path][0]

View File

@ -25,7 +25,6 @@ http://www.hardcoded.net/licenses/hs_license
NSMutableIndexSet *_deltaColumns; NSMutableIndexSet *_deltaColumns;
} }
- (IBAction)clearIgnoreList:(id)sender; - (IBAction)clearIgnoreList:(id)sender;
- (IBAction)exportToXHTML:(id)sender;
- (IBAction)filter:(id)sender; - (IBAction)filter:(id)sender;
- (IBAction)ignoreSelected:(id)sender; - (IBAction)ignoreSelected:(id)sender;
- (IBAction)markAll:(id)sender; - (IBAction)markAll:(id)sender;
@ -47,8 +46,6 @@ http://www.hardcoded.net/licenses/hs_license
- (IBAction)toggleDetailsPanel:(id)sender; - (IBAction)toggleDetailsPanel:(id)sender;
- (NSTableColumn *)getColumnForIdentifier:(int)aIdentifier title:(NSString *)aTitle width:(int)aWidth refCol:(NSTableColumn *)aColumn; - (NSTableColumn *)getColumnForIdentifier:(int)aIdentifier title:(NSString *)aTitle width:(int)aWidth refCol:(NSTableColumn *)aColumn;
- (NSArray *)getColumnsOrder;
- (NSDictionary *)getColumnsWidth;
- (void)initResultColumns; - (void)initResultColumns;
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth; - (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth;
@end @end

View File

@ -58,14 +58,6 @@ http://www.hardcoded.net/licenses/hs_license
[py clearIgnoreList]; [py clearIgnoreList];
} }
- (IBAction)exportToXHTML:(id)sender
{
NSString *xsltPath = [[NSBundle mainBundle] pathForResource:@"dg" ofType:@"xsl"];
NSString *cssPath = [[NSBundle mainBundle] pathForResource:@"hardcoded" ofType:@"css"];
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder] xslt:xsltPath css:cssPath];
[[NSWorkspace sharedWorkspace] openFile:exported];
}
- (IBAction)filter:(id)sender - (IBAction)filter:(id)sender
{ {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@ -272,37 +264,6 @@ http://www.hardcoded.net/licenses/hs_license
return col; return col;
} }
//Returns an array of identifiers, in order.
- (NSArray *)getColumnsOrder
{
NSTableColumn *col;
NSString *colId;
NSMutableArray *result = [NSMutableArray array];
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
while (col = [e nextObject])
{
colId = [col identifier];
[result addObject:colId];
}
return result;
}
- (NSDictionary *)getColumnsWidth
{
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSTableColumn *col;
NSString *colId;
NSNumber *width;
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
while (col = [e nextObject])
{
colId = [col identifier];
width = [NSNumber numberWithFloat:[col width]];
[result setObject:width forKey:colId];
}
return result;
}
- (void)initResultColumns - (void)initResultColumns
{ {
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"]; NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];

View File

@ -12,8 +12,6 @@
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
CE073F6309CAE1A3005C1D2F /* dupeguru_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_help */; }; CE073F6309CAE1A3005C1D2F /* dupeguru_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_help */; };
CE0D67640ABC2D3E00E2FFD9 /* dg.xsl in Resources */ = {isa = PBXBuildFile; fileRef = CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */; };
CE0D67650ABC2D3E00E2FFD9 /* hardcoded.css in Resources */ = {isa = PBXBuildFile; fileRef = CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */; };
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 */; };
@ -77,8 +75,6 @@
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
8D1107320486CEB800E47090 /* dupeGuru.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dupeGuru.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107320486CEB800E47090 /* dupeGuru.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dupeGuru.app; sourceTree = BUILT_PRODUCTS_DIR; };
CE073F5409CAE1A3005C1D2F /* dupeguru_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_help; path = help/dupeguru_help; sourceTree = "<group>"; }; CE073F5409CAE1A3005C1D2F /* dupeguru_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_help; path = help/dupeguru_help; sourceTree = "<group>"; };
CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; name = dg.xsl; path = w3/dg.xsl; sourceTree = SOURCE_ROOT; };
CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = hardcoded.css; path = w3/hardcoded.css; sourceTree = SOURCE_ROOT; };
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
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; };
@ -215,7 +211,6 @@
CE073F5409CAE1A3005C1D2F /* dupeguru_help */, CE073F5409CAE1A3005C1D2F /* dupeguru_help */,
CE381CF509915304003581CE /* dg_cocoa.plugin */, CE381CF509915304003581CE /* dg_cocoa.plugin */,
CEFC294309C89E0000D9F998 /* images */, CEFC294309C89E0000D9F998 /* images */,
CE0D67610ABC2D3E00E2FFD9 /* w3 */,
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
@ -235,15 +230,6 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CE0D67610ABC2D3E00E2FFD9 /* w3 */ = {
isa = PBXGroup;
children = (
CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */,
CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */,
);
path = w3;
sourceTree = "<group>";
};
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */ = { CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -375,8 +361,6 @@
CEF7823809C8AA0200EF38FF /* gear.png in Resources */, CEF7823809C8AA0200EF38FF /* gear.png in Resources */,
CECA899909DB12CA00A3D774 /* Details.nib in Resources */, CECA899909DB12CA00A3D774 /* Details.nib in Resources */,
CE3AA46709DB207900DB3A21 /* Directories.nib in Resources */, CE3AA46709DB207900DB3A21 /* Directories.nib in Resources */,
CE0D67640ABC2D3E00E2FFD9 /* dg.xsl in Resources */,
CE0D67650ABC2D3E00E2FFD9 /* hardcoded.css in Resources */,
CEFC7FAD0FC9518A00CD5728 /* ErrorReportWindow.xib in Resources */, CEFC7FAD0FC9518A00CD5728 /* ErrorReportWindow.xib in Resources */,
CEFC7FAE0FC9518A00CD5728 /* progress.nib in Resources */, CEFC7FAE0FC9518A00CD5728 /* progress.nib in Resources */,
CEFC7FAF0FC9518A00CD5728 /* registration.nib in Resources */, CEFC7FAF0FC9518A00CD5728 /* registration.nib in Resources */,
@ -534,12 +518,11 @@
C01FCF5008A954540054247B /* Release */ = { C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = ( ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
ppc, ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
i386,
);
FRAMEWORK_SEARCH_PATHS = "@executable_path/../Frameworks"; FRAMEWORK_SEARCH_PATHS = "@executable_path/../Frameworks";
GCC_C_LANGUAGE_STANDARD = c99; GCC_C_LANGUAGE_STANDARD = c99;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.4; MACOSX_DEPLOYMENT_TARGET = 10.4;

View File

@ -41,8 +41,8 @@ class PyDupeGuru(PyApp):
def doScan(self): def doScan(self):
return self.app.start_scanning() return self.app.start_scanning()
def exportToXHTMLwithColumns_xslt_css_(self,column_ids,xslt_path,css_path): def exportToXHTMLwithColumns_(self, column_ids):
return self.app.ExportToXHTML(column_ids,xslt_path,css_path) return self.app.export_to_xhtml(column_ids)
def loadIgnoreList(self): def loadIgnoreList(self):
self.app.load_ignore_list() self.app.load_ignore_list()

View File

@ -1,75 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="xml"
encoding="utf-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
indent="yes"/>
<xsl:template match="column">
<xsl:if test="@enabled = 'y'">
<th>
<xsl:value-of select="@display"/>
</th>
</xsl:if>
</xsl:template>
<xsl:template match="file">
<tr>
<xsl:variable name="td_class">
<xsl:if test="position() > 1">
<xsl:text>indented</xsl:text>
</xsl:if>
</xsl:variable>
<xsl:variable name="file_node" select="."/>
<xsl:for-each select="data">
<xsl:variable name="data_pos" select="position()"/>
<xsl:if test="document('columns.xml')/columns/column[$data_pos]/@enabled = 'y'">
<td>
<xsl:if test="position() = 1">
<xsl:attribute name="class">
<xsl:value-of select="$td_class"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="@value"/>
</td>
</xsl:if>
</xsl:for-each>
<!-- <xsl:for-each select="//results/column">
<td>
<xsl:variable name="attr_name">
<xsl:text>attr_</xsl:text>
<xsl:value-of select="@name"/>
</xsl:variable>
<xsl:value-of select="$file_node/@*[local-name(.) = $attr_name]"/>
</td>
</xsl:for-each> -->
</tr>
</xsl:template>
<xsl:template match="group">
<xsl:apply-templates select="file"/>
</xsl:template>
<xsl:template match="results">
<html>
<head>
<title>dupeGuru Results</title>
<link rel="stylesheet" href="hardcoded.css" type="text/css"/>
</head>
<body>
<h1>dupeGuru Results</h1>
<table>
<tr>
<xsl:apply-templates select="document('columns.xml')/columns/column"/>
</tr>
<xsl:apply-templates select="group"/>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,71 +0,0 @@
BODY
{
background-color:white;
}
BODY,A,P,UL,TABLE,TR,TD
{
font-family:Tahoma,Arial,sans-serif;
font-size:10pt;
color: #4477AA;
}
TABLE
{
background-color: #225588;
margin-left: auto;
margin-right: auto;
width: 90%;
}
TR
{
background-color: white;
}
TH
{
font-weight: bold;
color: black;
background-color: #C8D6E5;
}
TH TD
{
color:black;
}
TD
{
padding-left: 2pt;
}
TD.rightelem
{
text-align:right;
/*padding-left:0pt;*/
padding-right: 2pt;
width: 17%;
}
TD.indented
{
padding-left: 12pt;
}
H1
{
font-family:"Courier New",monospace;
color:#6699CC;
font-size:18pt;
color:#6da500;
border-color: #70A0CF;
border-width: 1pt;
border-style: solid;
margin-top: 16pt;
margin-left: 5%;
margin-right: 5%;
padding-top: 2pt;
padding-bottom:2pt;
text-align: center;
}