diff --git a/brainstorm.py b/brainstorm.py
index d79ed1a..19fe4ba 100644
--- a/brainstorm.py
+++ b/brainstorm.py
@@ -20,7 +20,11 @@ from logs.logresolver import LogFileResolver as LogFile
from logs import combat
# for windows its kinda this:
-settings = {'logfiles': os.path.join(os.path.expanduser('~'),
+settings = {'root_path': os.path.join(os.path.expanduser('~'),
+ 'Documents',
+ 'My Games',
+ 'StarConflict',),
+ 'logfiles': os.path.join(os.path.expanduser('~'),
'Documents',
'My Games',
'StarConflict',
diff --git a/config/common.py b/config/common.py
new file mode 100644
index 0000000..10f6bdf
--- /dev/null
+++ b/config/common.py
@@ -0,0 +1,5 @@
+"""
+
+
+
+"""
\ No newline at end of file
diff --git a/config/display_config.py b/config/display_config.py
index 619ef9b..b26c4b4 100644
--- a/config/display_config.py
+++ b/config/display_config.py
@@ -2,6 +2,7 @@
Simple brainstorm to display a config file.
"""
import os, logging
+from settings import settings
logging.basicConfig(level=logging.INFO)
# import ET:
try:
@@ -24,13 +25,80 @@ finally:
raise NotImplementedError, "XML Parser not found in your Python."
##################################################################################################
-
-CONFIG_FILE = os.path.join(os.path.expanduser('~'),
- 'Documents',
- 'My Games',
- 'StarConflict',
- 'user_config.xml')
-
+class ConfigFile(object):
+ def __init__(self, config_file=None):
+ self.cvars = []
+ if config_file:
+ self.config_file = config_file
+ elif settings:
+ # settings based loading.
+ self.config_file = os.path.join(settings.get_path(), 'user_config.xml')
+
+ def open(self, filename = None):
+ # reads a config file.
+ filename = filename or self.config_file
+ self.tree = ET.parse(filename)
+ doc = self.tree.getroot()
+ if doc.tag == 'UserConfig' \
+ and len(doc) == 1\
+ and doc[0].tag == 'CVars'\
+ and doc[0].attrib['version'] == '4':
+ logging.info( "Found valid config file." )
+ # save my cvars
+ self.cvars = doc[0]
+ else:
+ logging.info( "Config File not supported." )
+ return self
+
+ def pprint(self):
+ # print out my cvars
+ for child in self.cvars:
+ print '%s = %s' % (child.tag, child.attrib['val'])
+
+ def write(self, filename):
+ output = '\n'
+ doc = self.tree.getroot()
+ # we manually serialize it to keep it exactly the same
+ # like original SC to avoid problems with their software.
+ def append_node(node, depth=0):
+ # xml serializing helper function...
+ s = ['%s<%s' % (' '*depth*2, node.tag),]
+ for key, val in node.attrib.items():
+ s.append(' %s="%s"' % (key, val))
+ if len(node):
+ s.append('>\n')
+ # append children
+ for child in node:
+ s.extend(append_node(child, depth+1))
+ s.append('%s%s>\n' % (' '*depth*2, node.tag))
+ else:
+ s.append(' />\n')
+ return s
+ l = append_node(doc)
+ output = output + ''.join( l )
+ if filename is None:
+ # dev.
+ assert output[-1], '\n'
+ else:
+ try:
+ f = open(filename, 'w')
+ f.write(output)
+ finally:
+ f.close()
+ return output
+
+ def debug_serializing(self):
+ # detects if output would result in the same data as input
+ input, output = None, None
+ try:
+ f = open(self.config_file, 'r')
+ input = f.read()
+ finally:
+ f.close()
+ output = self.write(None)
+ return output == input
+
+
def read_config(config_file):
tree = ET.parse(config_file)
# doc = tree.getroot()
@@ -38,15 +106,14 @@ def read_config(config_file):
if __name__ == '__main__':
# Read the config
- tree = read_config(CONFIG_FILE)
- doc = tree.getroot()
- if doc.tag == 'UserConfig' \
- and len(doc) == 1\
- and doc[0].tag == 'CVars'\
- and doc[0].attrib['version'] == '4':
- print "Found valid config file."
- cvars = doc[0]
- for child in cvars:
- print '%s = %s' % (child.tag, child.attrib['val'])
- else:
- print "Not found valid config file."
\ No newline at end of file
+ settings.autodetect()
+ c = ConfigFile().open()
+ print '#' * 80
+ print "Output File would be:"
+ print c.write(None)
+ print '#' * 80
+ print "Detected Settings:"
+ c.pprint()
+ print '#' * 80
+ print 'Serializing Test successful: %s' % c.debug_serializing()
+
\ No newline at end of file
diff --git a/config/readme.txt b/config/readme.txt
new file mode 100644
index 0000000..c04afa6
--- /dev/null
+++ b/config/readme.txt
@@ -0,0 +1,11 @@
+This Package deals with config files, but also deals with configuration itself.
+
+This includes:
+ - The config files for SCON itself (config_user.xml)
+ - The config files for the applications in the scon package itself
+ - basic config throughout the apps in this app, including...
+
+ * loading/importing XML Libraries
+ * OS detection
+ * logging setup
+ etc.
\ No newline at end of file
diff --git a/config/settings.py b/config/settings.py
new file mode 100644
index 0000000..62984b2
--- /dev/null
+++ b/config/settings.py
@@ -0,0 +1,31 @@
+import os
+import platform
+
+class Settings(dict):
+ def autodetect(self, path=None):
+ # autodetect settings.
+ d = path
+ system = platform.system()
+ if system == 'Windows' or system.startswith('CYGWIN_NT'):
+ # try to find user folder:
+ d = d or os.path.join(os.path.expanduser('~'),
+ 'Documents',
+ 'My Games',
+ 'StarConflict',)
+ elif system == 'Linux':
+ raise NotImplementedError, "Implement Linux!"
+ elif system == 'Darwin':
+ raise NotImplementedError, "Implement Mac!"
+ else:
+ raise NotImplementedError, "Unknown System! %s" % platform.system()
+ if not os.path.exists(d) or not os.path.isdir(d):
+ raise Exception, "Configuration Autodetection failed. "
+ self['root_path'] = d
+
+ def get_path(self):
+ return self.get('root_path', None)
+
+ def get_logs_path(self):
+ return os.path.join(self.get_path, 'logs')
+
+settings = Settings()
diff --git a/dejaqt/__init__.py b/dejaqt/__init__.py
new file mode 100644
index 0000000..f2a3fcb
--- /dev/null
+++ b/dejaqt/__init__.py
@@ -0,0 +1,3 @@
+"""
+
+"""
\ No newline at end of file
diff --git a/dejaqt/qweb.py b/dejaqt/qweb.py
new file mode 100644
index 0000000..f6c0bb2
--- /dev/null
+++ b/dejaqt/qweb.py
@@ -0,0 +1,152 @@
+"""
+ Qt WebKit Browser for local access to internal Django Views.
+"""
+import os, logging
+from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork
+from django.test import Client
+
+class DebugPage(QtWebKit.QWebPage):
+ def sayMyName(self):
+ return 'DebugPage'
+
+class DejaWebView(QtWebKit.QWebView):
+ '''
+ BaseDir. Get rid of it?
+ '''
+ def __init__(self, *args, **kwargs):
+ basedir = kwargs.pop('basedir', None)
+ QtWebKit.QWebView.__init__(self, *args, **kwargs)
+ oldManager = self.page().networkAccessManager()
+ self.setPage(DebugPage())
+ self.page().setNetworkAccessManager(DejaNetworkAccessManager(self, basedir))
+
+ def set_basedir(self, basedir):
+ self.page().setNetworkAccessManager(DejaNetworkAccessManager(self, basedir))
+
+class DejaNetworkAccessManager(QtNetwork.QNetworkAccessManager):
+ '''
+ The Deja Network Access Manager provides access to two new protocols:
+ - page:/// tries to resolve a page internally via a django test client.
+ - res:/// access to a resource.
+
+ Note, if page does not find the page, a res:/// attempt is made automatically.
+ This has to be expanded!
+
+ '''
+ USE_NETWORK = False
+ def __init__(self, parent=None, basedir=None):
+ QtNetwork.QNetworkAccessManager.__init__(self, parent=None)
+ if not basedir:
+ # take current dir as basedir.
+ self.basedir = os.path.dirname(os.path.abspath(__file__))
+ else:
+ self.basedir = basedir
+
+ def createRequest(self, operation, request, data):
+ scheme = request.url().scheme()
+ if scheme != 'page' and scheme != 'res':
+ if self.USE_NETWORK:
+ return QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data)
+ elif scheme == 'page':
+ if operation == self.GetOperation:
+ # Handle page:// URLs separately by creating custom
+ # QNetworkReply objects.
+ reply = PageReply(self, request.url(), self.GetOperation)
+ #print('here')
+ #print reply
+ return reply
+ elif operation == self.PostOperation:
+ #print data.readAll()
+ #print request
+ reply = PageReply(self, request.url(), self.PostOperation)
+ return reply
+ elif scheme == 'res':
+ if operation == self.GetOperation:
+ return ImageReply(self, request.url(), self.GetOperation, self.basedir)
+ else:
+ if self.USE_NETWORK:
+ return QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data)
+ return NoNetworkReply(self, request.url(), self.GetOperation)
+
+class BasePageReply(QtNetwork.QNetworkReply):
+ content_type = 'text/html; charset=utf-8'
+ def __init__(self, parent, url, operation):
+ QtNetwork.QNetworkReply.__init__(self, parent)
+ self.content = self.initialize_content(url, operation)
+ self.offset = 0
+ self.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, self.get_content_type())
+ self.setHeader(QtNetwork.QNetworkRequest.ContentLengthHeader, len(self.content))
+ QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL('readyRead()'))
+ QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL('finished()'))
+ self.open(self.ReadOnly | self.Unbuffered)
+ self.setUrl(url)
+
+ def get_content_type(self):
+ return self.content_type
+
+ def initialize_content(self, url, operation):
+ return '''
+
+
Empty Page
+ This is an empty page. If you see this, you need to subclass BasePageReply.
+
+ '''
+
+ def abort(self):
+ pass
+
+ def bytesAvailable(self):
+ return len(self.content) - self.offset + QtNetwork.QNetworkReply.bytesAvailable(self)
+
+ def isSequential(self):
+ return True
+
+ def readData(self, maxSize):
+ if self.offset < len(self.content):
+ end = min(self.offset + maxSize, len(self.content))
+ data = self.content[self.offset:end]
+ self.offset = end
+ return data
+
+class PageReply(BasePageReply):
+ def initialize_content(self, url, operation):
+ c = Client()
+ print "Response for %s, method %s" % (url.path(), operation)
+ if operation == LocalNetworkAccessManager.GetOperation:
+ response = c.get(unicode(url.path()), )
+ elif operation == LocalNetworkAccessManager.PostOperation:
+ response = c.post(unicode(url.path()))
+ # response code
+ print "Response Status: %s" % response.status_code
+ # note: on a 404, we might need to trigger file response.
+ return response.content
+
+class NoNetworkReply(BasePageReply):
+ def initialize_content(self, url, operation):
+ return '''
+
+ No Network Access.
+
+ Internal access to the network has been disabled.
+
+
+ '''
+
+class ImageReply(BasePageReply):
+ content_type = 'image/png'
+ def __init__(self, parent, url, operation, basedir):
+ self.basedir = basedir
+ BasePageReply.__init__(self, parent, url, operation)
+
+ def initialize_content(self, url, operation):
+ path = os.path.join(self.basedir, unicode(url.path()).lstrip('/'))
+ if not os.path.exists(path):
+ logging.error('Image does not exist: %s' % path)
+ return ''
+ h = url.host()
+ try:
+ f = open(path, 'rb')
+ return f.read()
+ finally:
+ f.close()
+
\ No newline at end of file
diff --git a/dj/__init__.py b/dj/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/dj/scon/__init__.py b/dj/scon/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/dj/scon/admin.py b/dj/scon/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/dj/scon/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/dj/scon/forms.py b/dj/scon/forms.py
new file mode 100644
index 0000000..5e8242e
--- /dev/null
+++ b/dj/scon/forms.py
@@ -0,0 +1,10 @@
+'''
+Created on 27.05.2014
+
+@author: g4b
+'''
+from django import forms
+
+class ConfigForm(forms.Form):
+ def __init__(self, *args, **kwargs):
+
\ No newline at end of file
diff --git a/dj/scon/logic.py b/dj/scon/logic.py
new file mode 100644
index 0000000..8fc8823
--- /dev/null
+++ b/dj/scon/logic.py
@@ -0,0 +1,10 @@
+'''
+'''
+
+def config(condict):
+ # modify condict.
+ return condict
+
+def overview(condict):
+ return condict
+
diff --git a/dj/scon/media/scon/conflict-logo.png b/dj/scon/media/scon/conflict-logo.png
new file mode 100644
index 0000000..22f1eb6
Binary files /dev/null and b/dj/scon/media/scon/conflict-logo.png differ
diff --git a/dj/scon/models.py b/dj/scon/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/dj/scon/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/dj/scon/templates/404.html b/dj/scon/templates/404.html
new file mode 100644
index 0000000..b5266ad
--- /dev/null
+++ b/dj/scon/templates/404.html
@@ -0,0 +1 @@
+Site Not Found.
\ No newline at end of file
diff --git a/dj/scon/templates/500.html b/dj/scon/templates/500.html
new file mode 100644
index 0000000..55b8a08
--- /dev/null
+++ b/dj/scon/templates/500.html
@@ -0,0 +1 @@
+Internal Server Error.
\ No newline at end of file
diff --git a/dj/scon/templates/base.html b/dj/scon/templates/base.html
new file mode 100644
index 0000000..7bc913d
--- /dev/null
+++ b/dj/scon/templates/base.html
@@ -0,0 +1,12 @@
+
+
+
+
+ {{ title }}
+ {% block extrahead %}{% endblock extrahead%}
+ {% block css %}{% endblock css %}
+ {% block js %}{% endblock js %}
+
+{% block context %}
+{% endblock context %}
+
\ No newline at end of file
diff --git a/dj/scon/templates/scon/base.html b/dj/scon/templates/scon/base.html
new file mode 100644
index 0000000..730d1e5
--- /dev/null
+++ b/dj/scon/templates/scon/base.html
@@ -0,0 +1 @@
+{% extends "base.html" %}
diff --git a/dj/scon/templates/scon/config.html b/dj/scon/templates/scon/config.html
new file mode 100644
index 0000000..4771f7e
--- /dev/null
+++ b/dj/scon/templates/scon/config.html
@@ -0,0 +1,11 @@
+{% extends "scon/base.html" %}
+{% load i18n %}
+
+{% block context %}
+{% blocktrans %}{% endblocktrans %}
+
+{% endblock context %}
\ No newline at end of file
diff --git a/dj/scon/tests.py b/dj/scon/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/dj/scon/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/dj/scon/views.py b/dj/scon/views.py
new file mode 100644
index 0000000..3e86048
--- /dev/null
+++ b/dj/scon/views.py
@@ -0,0 +1,10 @@
+
+from django.shortcuts import render
+from django.http import HttpResponse
+from django.template import RequestContext, loader
+import logic
+
+def config(request):
+ t = loader.get_template('scon/config.html')
+ c = RequestContext(request, logic.config({'title': 'Configure your Client'}))
+ return HttpResponse(t.render(c))
diff --git a/dj/settings.py b/dj/settings.py
new file mode 100644
index 0000000..13e99e7
--- /dev/null
+++ b/dj/settings.py
@@ -0,0 +1,82 @@
+"""
+Django settings for dj project.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.6/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.6/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+BASE_DIR = os.path.dirname(os.path.dirname(__file__))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'xp$g5ho)(=013v9#qb@sncz%ye7#oy34&1=ltj1315d)j+lwm)'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+TEMPLATE_DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = (
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+)
+
+ROOT_URLCONF = 'scon.dj.urls'
+
+WSGI_APPLICATION = 'dj.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.6/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.6/howto/static-files/
+
+STATIC_URL = '/static/'
diff --git a/dj/urls.py b/dj/urls.py
new file mode 100644
index 0000000..fd424c2
--- /dev/null
+++ b/dj/urls.py
@@ -0,0 +1,12 @@
+from django.conf.urls import patterns, include, url
+
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+ # Examples:
+ # url(r'^$', 'dj.views.home', name='home'),
+ # url(r'^blog/', include('blog.urls')),
+ url(r'^admin/', include(admin.site.urls)),
+ #url(r'^scon/', include('scon.urls')),
+)
diff --git a/dj/wsgi.py b/dj/wsgi.py
new file mode 100644
index 0000000..cb6ef28
--- /dev/null
+++ b/dj/wsgi.py
@@ -0,0 +1,14 @@
+"""
+WSGI config for dj project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
+"""
+
+import os
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dj.settings")
+
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
diff --git a/game/pieces.py b/game/pieces.py
new file mode 100644
index 0000000..22d47b9
--- /dev/null
+++ b/game/pieces.py
@@ -0,0 +1,100 @@
+
+def res_to_red(res):
+ ''' calculates reduction % of damage from base resistance
+ incoming damage is assumed to be 100.0 to get percentages.
+ '''
+ if res >= 0:
+ fd = 100 / (1.0+res/100.0)
+ else:
+ fd = 100 / (1.0-res/100.0)
+ return 100.0 - fd
+
+def dam_res(dam, res):
+ ''' calculates damage modified by resistance.
+ '''
+ if res >= 0:
+ fd = dam / (1.0+res/100.0)
+ else:
+ fd = dam / (1.0-res/100.0)
+ return fd
+
+class ShipInstance(object):
+ # just testin something.
+ def __init__(self,
+ shields=None,
+ hulls=None,
+ shield_resis=None,
+ hull_resis=None ):
+ self.shield_max = shields or 5000
+ self.hull_max = hulls or 5000
+ shield_resis = shield_resis or (100,100,100)
+ hull_resis = hull_resis or (100,100,100)
+ self.set_shield_res(*shield_resis)
+ self.set_hull_res(*hull_resis)
+
+
+ def set_shield_res(self, kn, em, th):
+ self.shield_res_kn = kn
+ self.shield_res_em = em
+ self.shield_res_th = th
+
+ def set_hull_res(self, kn, em, th):
+ self.hull_res_kn = kn
+ self.hull_res_em = em
+ self.hull_res_th = th
+
+ def survivability(self):
+ # i have no clue how they calc this.
+ # multiple attempts shows, they are using base pts as measure, but how exactly the calc is?
+ krs = (self.shield_max/100.0 * self.shield_res_kn)
+ ers = (self.shield_max/100.0 * self.shield_res_em)
+ trs = (self.shield_max/100.0 * self.shield_res_th)
+ print "Shield.", krs, ers, trs
+
+ krh = (self.hull_max/100.0 * self.hull_res_kn)
+ erh = (self.hull_max/100.0 * self.hull_res_em)
+ trh = (self.hull_max/100.0 * self.hull_res_th)
+ print "Hull.", krh, erh, trh
+
+ #print "?1", ((krs+ers+trs+krh+erh+trh)/6.0)+self.shield_max + self.hull_max
+ print "?2", ((krs+ers+trs+3*self.shield_max)/3.0)+((krh+erh+trh+3*self.hull_max)/3.0)
+
+
+ # another try:
+ """
+ lets assume survivability is really measured through applying 1000 dps for 10 secs.
+
+ """
+ print "Assuming dps..."
+ shield = self.shield_max
+ hull = self.hull_max
+ r1s = shield / (1.0*dam_res(1000, self.shield_res_kn))
+ r2s = shield / (1.0*dam_res(1000, self.shield_res_em))
+ r3s = shield / (1.0*dam_res(1000, self.shield_res_th))
+ print r1s, r2s, r3s
+ rXs = (r1s+r2s+r3s) / 3.0
+ print "Shield survival time at 1kdps", rXs
+
+ r1h = hull / (1.0*dam_res(1000, self.hull_res_kn))
+ r2h = hull / (1.0*dam_res(1000, self.hull_res_em))
+ r3h = hull / (1.0*dam_res(1000, self.hull_res_th))
+ print r1h, r2h, r3h
+ rXh = (r1h+r2h+r3h) / 3.0
+ print "Hull survival time at 1kdps", rXh
+
+ print "Total survival time ", rXs + rXh, " sec"
+ print "Surv should be ", int(round((rXs+rXh) * 1000))
+
+
+
+ return ((krs+ers+trs)/3.0)+self.shield_max + self.hull_max + ((krh+erh+trh)/3.0)
+
+
+
+ship = ShipInstance()
+print ship.survivability()
+
+print "#" * 80
+mykatanas=ShipInstance(7664, 4296, (70,61,100), (20,80,50))
+print "We know its 19736... but own calcs say..."
+print mykatanas.survivability()
\ No newline at end of file
diff --git a/gui/localbrowser.py b/gui/localbrowser.py
new file mode 100644
index 0000000..31a995b
--- /dev/null
+++ b/gui/localbrowser.py
@@ -0,0 +1,142 @@
+import os, logging
+from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork
+from treeview import TreeViewModel, Node
+from django.test import Client
+
+class DebugPage(QtWebKit.QWebPage):
+ def sayMyName(self):
+ return 'DebugPage'
+
+class LocalWebView(QtWebKit.QWebView):
+ def __init__(self, *args, **kwargs):
+ basedir = kwargs.pop('basedir', None)
+ QtWebKit.QWebView.__init__(self, *args, **kwargs)
+ oldManager = self.page().networkAccessManager()
+ self.setPage(DebugPage())
+ self.page().setNetworkAccessManager(LocalNetworkAccessManager(self, basedir))
+
+ def set_basedir(self, basedir):
+ self.page().setNetworkAccessManager(LocalNetworkAccessManager(self, basedir))
+
+class LocalNetworkAccessManager(QtNetwork.QNetworkAccessManager):
+ USE_NETWORK = False
+ def __init__(self, parent=None, basedir=None):
+ QtNetwork.QNetworkAccessManager.__init__(self, parent=None)
+ if not basedir:
+ # take current dir as basedir.
+ self.basedir = os.path.dirname(os.path.abspath(__file__))
+ else:
+ self.basedir = basedir
+
+ def createRequest(self, operation, request, data):
+ scheme = request.url().scheme()
+ if scheme != 'page' and scheme != 'image':
+ if self.USE_NETWORK:
+ return QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data)
+ elif scheme == 'page':
+ if operation == self.GetOperation:
+ # Handle page:// URLs separately by creating custom
+ # QNetworkReply objects.
+ reply = PageReply(self, request.url(), self.GetOperation)
+ #print('here')
+ #print reply
+ return reply
+ elif operation == self.PostOperation:
+ #print data.readAll()
+ #print request
+ reply = PageReply(self, request.url(), self.PostOperation)
+ return reply
+ elif scheme == 'image':
+ if operation == self.GetOperation:
+ return ImageReply(self, request.url(), self.GetOperation, self.basedir)
+ else:
+ if self.USE_NETWORK:
+ return QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data)
+ return NoNetworkReply(self, request.url(), self.GetOperation)
+
+class BasePageReply(QtNetwork.QNetworkReply):
+ content_type = 'text/html; charset=utf-8'
+ def __init__(self, parent, url, operation):
+ QtNetwork.QNetworkReply.__init__(self, parent)
+ self.content = self.initialize_content(url, operation)
+ self.offset = 0
+ self.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, self.get_content_type())
+ self.setHeader(QtNetwork.QNetworkRequest.ContentLengthHeader, len(self.content))
+ QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL('readyRead()'))
+ QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL('finished()'))
+ self.open(self.ReadOnly | self.Unbuffered)
+ self.setUrl(url)
+
+ def get_content_type(self):
+ return self.content_type
+
+ def initialize_content(self, url, operation):
+ return '''
+
+ Test
+
+
+ '''
+
+ def abort(self):
+ pass
+
+ def bytesAvailable(self):
+ return len(self.content) - self.offset + QtNetwork.QNetworkReply.bytesAvailable(self)
+
+ def isSequential(self):
+ return True
+
+ def readData(self, maxSize):
+ if self.offset < len(self.content):
+ end = min(self.offset + maxSize, len(self.content))
+ data = self.content[self.offset:end]
+ self.offset = end
+ return data
+
+class PageReply(BasePageReply):
+ def initialize_content(self, url, operation):
+ c = Client()
+ print "Response for %s, method %s" % (url.path(), operation)
+ if operation == LocalNetworkAccessManager.GetOperation:
+ response = c.get(unicode(url.path()), )
+ elif operation == LocalNetworkAccessManager.PostOperation:
+ response = c.post(unicode(url.path()))
+ # response code
+ print "Response Status: %s" % response.status_code
+ # note: on a 404, we might need to trigger file response.
+ return response.content
+
+class NoNetworkReply(BasePageReply):
+ def initialize_content(self, url, operation):
+ return '''
+
+ No Network Access.
+
+ Internal access to the network has been disabled.
+
+
+ '''
+
+class ImageReply(BasePageReply):
+ content_type = 'image/png'
+ def __init__(self, parent, url, operation, basedir):
+ self.basedir = basedir
+ BasePageReply.__init__(self, parent, url, operation)
+
+ def initialize_content(self, url, operation):
+ path = os.path.join(self.basedir, unicode(url.path()).lstrip('/'))
+ if not os.path.exists(path):
+ logging.error('Image does not exist: %s' % path)
+ return ''
+ h = url.host()
+ try:
+ f = open(path, 'rb')
+ return f.read()
+ finally:
+ f.close()
+
\ No newline at end of file
diff --git a/gui/viewer.py b/gui/viewer.py
index 49ded97..7b7e302 100644
--- a/gui/viewer.py
+++ b/gui/viewer.py
@@ -4,10 +4,15 @@
Viewer - starts a webbrowser which is coupled to a local renderer
"""
-
+import os
+os.environ['DJANGO_SETTINGS_MODULE'] = 'scon.dj.settings'
+#from django.core.management import setup_environ
+#from scon.dj import settings
+#setup_environ(settings)
import sys
-from PyQt4 import QtCore, QtGui, QtWebKit
+from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork
from treeview import TreeViewModel, Node
+from localbrowser import LocalWebView
class MenuTree(QtGui.QTreeView):
def __init__(self, *args, **kwargs):
@@ -58,9 +63,9 @@ class Browser(QtGui.QMainWindow):
self.horizontalMainLayout = QtGui.QHBoxLayout()
self.gridLayout.addLayout(self.horizontalMainLayout)
#
- self.menu = MenuTree()
- self.html = QtWebKit.QWebView()
- self.horizontalMainLayout.addWidget(self.menu)
+ #self.menu = MenuTree()
+ self.html = LocalWebView(basedir='D:/work/workspace/scon/src/scon/dj/scon/media/')
+ #self.horizontalMainLayout.addWidget(self.menu)
self.horizontalMainLayout.addWidget(self.html)
self.mainLayout.addWidget(self.frame)
self.setCentralWidget(self.centralwidget)
@@ -70,6 +75,7 @@ class Browser(QtGui.QMainWindow):
self.connect(self.bt_ahead, QtCore.SIGNAL("clicked()"), self.html.forward)
self.tb_url.setText('Search...')
+
self.browse()
def browse(self):
@@ -80,14 +86,15 @@ class Browser(QtGui.QMainWindow):
#url = self.tb_url.text() if self.tb_url.text() else self.default_url
#self.html.load(QtCore.QUrl(url))
- self.html.setHtml(self.serve())
+ #self.html.setHtml(self.serve())
+ self.html.load(QtCore.QUrl('page:///admin/'))
self.html.show()
def serve(self, what=None):
return "It works!
"
if __name__ == "__main__":
-
+
app = QtGui.QApplication(sys.argv)
main = Browser()
main.show()
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..e6b047b
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dj.settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)