Files
pyfa/gui/utils/exportHtml.py
TimmeeY eb8e5c5135 Added an option for HTML Export, to produce a minimal html version
Added an Opton in the HTMLExport menu to set the HTML export to produce
a minimal HTML version, without any styles or Javscript dependencies.
This can be useful if you are not javascript capable, or if you just
want to copy'n'pase the exported HTML into some web-editor (wordpress).
2016-05-08 23:50:41 +02:00

287 lines
11 KiB
Python

import threading
import time
import service
import wx
class exportHtml():
_instance = None
@classmethod
def getInstance(cls):
if cls._instance is None:
cls._instance = exportHtml()
return cls._instance
def __init__(self):
self.thread = exportHtmlThread()
def refreshFittingHtml(self, force=False, callback=False):
settings = service.settings.HTMLExportSettings.getInstance()
if force or settings.getEnabled():
self.thread.stop()
self.thread = exportHtmlThread(callback)
self.thread.start()
class exportHtmlThread(threading.Thread):
def __init__(self, callback=False):
threading.Thread.__init__(self)
self.callback = callback
self.stopRunning = False
def stop(self):
self.stopRunning = True
def run(self):
# wait 1 second just in case a lot of modifications get made
time.sleep(1)
if self.stopRunning:
return
sMkt = service.Market.getInstance()
sFit = service.Fit.getInstance()
settings = service.settings.HTMLExportSettings.getInstance()
timestamp = time.localtime(time.time())
localDate = "%d/%02d/%02d %02d:%02d" % (timestamp[0], timestamp[1], timestamp[2], timestamp[3], timestamp[4])
minimal = settings.getMinimalEnabled();
website = settings.getWebsite()
if website == "o.smium.org":
dnaUrl = "https://o.smium.org/loadout/dna/"
elif website == "null-sec.com":
dnaUrl = "https://null-sec.com/hangar/?dna="
if minimal:
HTML = self.generateMinimalHTML(sMkt,sFit, dnaUrl)
else:
HTML = self.generateFullHTML(sMkt,sFit, dnaUrl)
try:
FILE = open(settings.getPath(), "w")
FILE.write(HTML.encode('utf-8'))
FILE.close()
except IOError:
print "Failed to write to " + settings.getPath()
pass
if self.callback:
wx.CallAfter(self.callback, -1)
def generateFullHTML(self,sMkt,sFit,dnaUrl):
""" Generate the complete HTML with styling and javascript """
timestamp = time.localtime(time.time())
localDate = "%d/%02d/%02d %02d:%02d" % (timestamp[0], timestamp[1], timestamp[2], timestamp[3], timestamp[4])
HTML = """
<!DOCTYPE html>
<html>
<head>
<title>Pyfa Fittings</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
// http://stackoverflow.com/questions/32453806/uncaught-securityerror-failed-to-execute-replacestate-on-history-cannot-be
$(document).bind('mobileinit',function(){
$.mobile.changePage.defaults.changeHash = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
});
</script>
<script src="https://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
<style>
/* Basic settings */
.ui-li-static.ui-collapsible {
padding: 0;
}
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview,
.ui-li-static.ui-collapsible > .ui-collapsible-heading {
margin: 0;
}
.ui-li-static.ui-collapsible > .ui-collapsible-content {
padding-top: 0;
padding-bottom: 0;
padding-right: 0;
border-bottom-width: 0;
}
/* collapse vertical borders */
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview > li.ui-last-child,
.ui-li-static.ui-collapsible.ui-collapsible-collapsed > .ui-collapsible-heading > a.ui-btn {
border-bottom-width: 0;
}
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview > li.ui-first-child,
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview > li.ui-first-child > a.ui-btn,
.ui-li-static.ui-collapsible > .ui-collapsible-heading > a.ui-btn {
border-top-width: 0;
}
/* Remove right borders */
.ui-li-static.ui-collapsible > .ui-collapsible-heading > a.ui-btn,
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview > .ui-li-static,
.ui-li-static.ui-collapsible > .ui-collapsible-content > .ui-listview > li > a.ui-btn,
.ui-li-static.ui-collapsible > .ui-collapsible-content {
border-right-width: 0;
}
/* Remove left borders */
/* Here, we need class ui-listview-outer to identify the outermost listview */
.ui-listview-outer > .ui-li-static.ui-collapsible .ui-li-static.ui-collapsible.ui-collapsible,
.ui-listview-outer > .ui-li-static.ui-collapsible > .ui-collapsible-heading > a.ui-btn,
.ui-li-static.ui-collapsible > .ui-collapsible-content {
border-left-width: 0;
}
.ui-content { max-width: 800px !important; margin: 0 auto !important; }
.ui-listview > .ui-li-static.ui-li-has-count { padding-right: 0px }
</style>
<script>
$(document).ready(function() {
var start = new Date(%d * 1000);
setInterval(function() {
var diff = (new Date - start) / 1000;
var days = Math.floor((diff %% 31536000) / 86400);
var hours = Math.floor(((diff %% 31536000) %% 86400) / 3600);
var minutes = Math.floor((((diff %% 31536000) %% 86400) %% 3600) / 60);
var seconds = Math.floor(((diff %% 31536000) %% 86400) %% 3600) %% 60;
$('.timer').text(days+":"+hours+":"+minutes+":"+seconds+" ago");
}, 1000);
$('a[data-dna]').each(function( index ) {
var dna = $(this).data('dna');
if (typeof CCPEVE !== 'undefined') { // inside IGB
$(this).attr('href', 'javascript:CCPEVE.showFitting("'+dna+'");');}
else { // outside IGB
$(this).attr('href', '%s'+dna); }
});
});
</script>
</head>
<body>
<div id="canvas" data-role="page">
<div data-role="header">
<h1>Pyfa fits</h1>
</div>
<div data-role="content">
<div style="text-align: center;"><strong>Last updated:</strong> %s <small>(<span class="timer"></span>)</small></div>
""" % (time.time(), dnaUrl, localDate)
HTML += ' <ul data-role="listview" class="ui-listview-outer" data-inset="true" data-filter="true">\n'
categoryList = list(sMkt.getShipRoot())
categoryList.sort(key=lambda ship: ship.name)
count = 0
for group in categoryList:
# init market group string to give ships something to attach to
HTMLgroup = ''
ships = list(sMkt.getShipList(group.ID))
ships.sort(key=lambda ship: ship.name)
# Keep track of how many ships per group
groupFits = 0
for ship in ships:
fits = sFit.getFitsWithShip(ship.ID)
if len(fits) > 0:
groupFits += len(fits)
if len(fits) == 1:
if self.stopRunning:
return
fit = fits[0]
try:
dnaFit = sFit.exportDna(fit[0])
HTMLgroup += (
' <li><a data-dna="' + dnaFit + '" target="_blank">' + ship.name + ": " + fit[1] + '</a></li>\n')
except:
pass
finally:
if self.callback:
wx.CallAfter(self.callback, count)
count += 1
else:
# Ship group header
HTMLship = (
' <li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">\n'
' <h2>' + ship.name + ' <span class="ui-li-count">'+str(len(fits))+'</span></h2>\n'
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n')
for fit in fits:
if self.stopRunning:
return
try:
dnaFit = sFit.exportDna(fit[0])
HTMLship += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + fit[1] + '</a></li>\n'
except:
continue
finally:
if self.callback:
wx.CallAfter(self.callback, count)
count += 1
HTMLgroup += HTMLship + (' </ul>\n'
' </li>\n')
if groupFits > 0:
# Market group header
HTML += (
' <li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">\n'
' <h2>' + group.groupName + ' <span class="ui-li-count">'+str(groupFits)+'</span></h2>\n'
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n'
+ HTMLgroup +
' </ul>\n'
' </li>')
HTML += """
</ul>
</div>
</div>
</body>
</html>"""
return HTML
def generateMinimalHTML(self,sMkt,sFit,dnaUrl):
""" Generate a minimal HTML version of the fittings, without any javascript or styling"""
categoryList = list(sMkt.getShipRoot())
categoryList.sort(key=lambda ship: ship.name)
count = 0
HTML = ''
for group in categoryList:
# init market group string to give ships something to attach to
ships = list(sMkt.getShipList(group.ID))
ships.sort(key=lambda ship: ship.name)
ships.sort(key=lambda ship: ship.name)
for ship in ships:
fits = sFit.getFitsWithShip(ship.ID)
for fit in fits:
if self.stopRunning:
return
try:
dnaFit = sFit.exportDna(fit[0])
HTML += ' <a class="inGameBrowserLink" target="_blank" href=javascript:CCPEVE.showFitting("'+dnaFit+'");>IGB</a>' +\
' / <a class="outOfGameBrowserLink" target="_blank" href="' + dnaUrl + dnaFit + '">OOGB</a> '+ fit[1]+ '<br>'
except:
continue
finally:
if self.callback:
wx.CallAfter(self.callback, count)
count += 1
return HTML;