Last active
July 20, 2017 00:23
-
-
Save MaxMorais/54513362fd7698a9841b2079a31070a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"_type": "div", | |
"_class": "installation-process-step", | |
"#text": "Installation Progress: Step 2 of 5" | |
}, | |
{ | |
"_type": "div", | |
"_class": "clear" | |
}, | |
{ | |
"_type": "div", | |
"_class": "text-center", | |
"#text": "Database Configuration" | |
}, | |
{ | |
"_type": "div", | |
"_class": "clear" | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-medium dump-down-most", | |
"#text": "Books will automatically configure your database. Before proceeding, create your database and database user.<br>If you need assistance, check the README.md file for step by step database and database user creation instructions." | |
}, | |
{ | |
"_type": "form", | |
"method": "POST", | |
"children": [ | |
{ | |
"_type": "hidden", | |
"type": "type", | |
"name": "install-step", | |
"value": "2" | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation form text-medium bump-down-most", | |
"children": [ | |
{ | |
"_type": "div", | |
"_class": "text-medium", | |
"#text": "Please enter your MySQL database details." | |
}, | |
{ | |
"_type": "div", | |
"_class": "left-right-row dump-down-more", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "left", | |
"#text": "Database Type" | |
}, | |
{ | |
"_type": "span", | |
"_class": "right", | |
"children": [ | |
{ | |
"_type": "select", | |
"name": "type" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "left-right-row bump-down-more", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "left", | |
"#text": "Hostname" | |
}, | |
{ | |
"_type": "span", | |
"_class": "right", | |
"children": [ | |
{ | |
"_type": "input", | |
"type": "text", | |
"name": "database_hostname", | |
"placeholder": "i.e. localhost or 192.168.0.1:1337" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "left-right-row bump-down-more", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "left", | |
"#text": "Database Name" | |
}, | |
{ | |
"_type": "span", | |
"_class": "right", | |
"children": [ | |
{ | |
"_type": "input", | |
"type": "text", | |
"name": "database_database", | |
"placeholder": "i.e. beans" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "left-right-row bump-down-more", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "left", | |
"#text": "Username" | |
}, | |
{ | |
"_type": "span", | |
"_class": "right", | |
"children": [ | |
{ | |
"_type": "input", | |
"type": "text", | |
"name": "database_username" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "left-right-row bump-down-more", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "left", | |
"#text": "Password" | |
}, | |
{ | |
"_type": "span", | |
"_class": "right", | |
"children": [ | |
{ | |
"_type": "input", | |
"type": "password", | |
"name": "database_password" | |
} | |
] | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-small bump-down-most", | |
"children": [ | |
{ | |
"_type": "span", | |
"_class": "text-bold", | |
"#text": "Database Creation:" | |
} | |
], | |
"#text": "The README.md file has a section titled "MySQL"e; that provides instructions on how to create a database and user account for Books." | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-center dump-down-most", | |
"children": [ | |
{ | |
"_type": "a", | |
"href": "#", | |
"class": "button process-step", | |
"onclick": "callback_process_step_clicked", | |
"#text": "Verify Database Information" | |
} | |
] | |
} | |
] | |
} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"_type": "div", | |
"_class": "intallation-process-step", | |
"#text": "Installation Progress: Getting Started" | |
}, | |
{ | |
"_type": "div", | |
"_class": "clear" | |
}, | |
{ | |
"_type": "h3", | |
"_class": "text-center", | |
"#text": "Thanks for choosing Books!" | |
}, | |
{ | |
"_type": "div", | |
"_class": "clear" | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-medium bump-down-most" | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-medium bump-down-most", | |
"children": [ | |
{ | |
"_type": "div", | |
"_class": "text-center text-bold", | |
"#text": "Important!" | |
}, | |
{ | |
"_type": "div", | |
"_class": "text-center", | |
"#text": "Have the following information available before starting the installation." | |
}, | |
{ | |
"_type": "br" | |
}, | |
{ | |
"_type": "ul", | |
"children": [ | |
{ | |
"_type": "li", | |
"#text": "Empty MySQL database user credentials" | |
}, | |
{ | |
"_type": "li", | |
"#text": "SMTP (email) connection information" | |
}, | |
{ | |
"_type": "li", | |
"#text": "File Access to the directory that Books will be located." | |
} | |
] | |
} | |
] | |
}, | |
{ | |
"_type": "div", | |
"_class": "explanation text-medium bump-down-most", | |
"children": [ | |
{ | |
"_type": "div", | |
"_class": "text-large text-center", | |
"#text": "Ready to go?" | |
}, | |
{ | |
"_type": "div", | |
"_class": "text-center", | |
"children": [ | |
{ | |
"_type": "a", | |
"_class": "button", | |
"href": "/install/check", | |
"#text": "Start Installation", | |
"onclick": "callback_button_click" | |
} | |
] | |
} | |
] | |
} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-*- coding: utf-8 -*- | |
from __future__ import unicode_literals | |
from remi import gui | |
class JSONView(gui.Widget): | |
def __init__(self, *args, **kwargs): | |
super(JSONView, self).__init__(*args, **kwargs) | |
self.build_element(self.layout, self) | |
@property | |
def layout(self): | |
path = os.path.join( | |
os.path.dirname(__file__), | |
self.__class__.__name__ + '.json' | |
) | |
if os.path.exists(path): | |
with open(path, 'rb') as f: | |
content = json.load(f) | |
return content | |
return [{ | |
"_type": "div", | |
"#text": "No layout file found at {0}".format(path) | |
}] | |
def build_element(self, element, parent): | |
for d in element: | |
# Verify if the element is an String, if yes check for the implementation handler | |
if isinstance(d, basestring): | |
if d.startswith('fn:'): | |
if hasattr(self, d[3:]): | |
fn = getattr(self, d[3:]) | |
if callable(fn): | |
fn(d) | |
continue | |
# Verify if the element type have they own implementation handler | |
if "_type" in d: | |
fn = "_build_{0}_element".format(d["_type"]) | |
if hasattr(self, fn): | |
fn = getattr(self, fn) | |
if callable(fn): | |
fn(d, parent) | |
continue | |
children = d.pop("children", []) # extract the children | |
class_names = d.pop("_class", "").split(" ") # extract the css classes | |
style = d.pop("style", {}) # extract the element style | |
events = [ | |
(k, d.pop(k)) | |
for k in d.keys() if k.startswith('on') | |
] | |
text = d.pop("#text", False) # extract the element text | |
# Build the widget constructor args | |
kwargs = { | |
k: d.pop(k).strip() | |
for k in ["_type", "id"] if k in d | |
} | |
# If the element has a class, append the first class as default class | |
if class_names: | |
kwargs['_class'] = class_names.pop(0) | |
# Build the widget | |
el = gui.Widget(**kwargs) | |
# Append any aditional class to the element | |
for class_name in class_names: | |
el.add_class(class_name) | |
# After the extraction of the common elements in the object | |
# any remaining value will be threat as an attribute | |
for k, v in d.items(): | |
el.attributes[k] = v | |
# Append the element style | |
for s, v in style.items(): | |
el.style[s] = v | |
# Append the element children | |
if children: | |
self.build_element(children, el) | |
# Append the text to the element at the last position | |
if text: | |
el.add_child("text", text) | |
# assign any input with a name | |
if kwargs.get("_type") == "input" and "name" in el.attributes: | |
attr = self._build_attribute_name(el.attributes['name']) | |
setattr(self, attr, el) | |
elif hasattr(self, 'as_attribute'): | |
if "_class" in kwargs and "." + kwargs["_class"] in self.as_attribute: | |
attr = self._build_attribute_name(kwargs["_class"]) | |
setattr(self, attr, el) | |
elif "id" in kwargs and "#" + kwargs["id"] in self.as_attribute: | |
attr = self._build_attribute_name(kwargs["id"]) | |
setattr(self, attr, el) | |
parent.append(el) | |
# attach any event listener | |
for event, callback in events: | |
setattr(self, event, self._build_event_handler(event)) | |
setattr(self, 'set_{0}_listener'.format(event), | |
self._build_event_listener); | |
if hasattr(self, callback): | |
callback = getattr(self, listener) | |
else: | |
callback = self._build_event_callback(callback, event) | |
listener = getattr(self, 'set_{0}_listener'.format(event)) | |
listener(callback) | |
def _build_attribute_name(self, s): | |
attr = str(s).lower().replace(" ", "_").replace("-", "") | |
if attr[0].isdigit(): | |
attr = "_" + attr | |
if hasattr(self, attr): | |
count = 1 | |
while hasattr(self, "{0}_{1}".format(attr, count)): | |
count += 1 | |
attr = "{0}_{1}".format(attr, count) | |
return attr | |
@staticmethod | |
def _build_event_handler(event_name): | |
def handler(self, event): | |
print type(event) | |
print event | |
self.eventManager.propagate(event_name, (event,)) | |
return handler | |
@staticmethod | |
def _build_event_callback(event_name, callback): | |
def callback(self, event): | |
fn = getattr(self, callback, None) | |
if callable(fn): | |
fn(event) | |
else: | |
print("""You must implement a callback in the class for the event `{event_name}` as: | |
def {callback}(self, event): ... | |
""".format( | |
event_name=event_name, | |
callback=callback | |
) | |
@staticmethod | |
def _build_event_listener(event_name): | |
def listener(self, callback, *userdata): | |
js = """ | |
function pathSelector = function(node){ | |
if (!node || !node.outerHTML) { return null; } | |
var path, name, parent, domSiblings, sibling, i, j; | |
while (node.parentElement){ | |
name = node.localName; | |
if (!name) { break; } | |
name = name.toLowerCase(); | |
parent = node.parentElement; | |
domSiblings = []; | |
if (parent.children && parent.children.length > 0){ | |
j = parent.children.length; | |
for (; i < j; i++){ | |
sibling = parent.children[i]; | |
if (sibling.localName && sibling.localName.toLowerCase){ | |
if (sibling.localName.toLowerCase() === name){ | |
domSiblings.push(sibling); | |
} | |
} | |
} | |
} | |
if (domSiblings.length > 1){ | |
name += ':eq(' + domSiblinds.indexOf(node) + ')'; | |
} | |
path = name + (path ? '>' + path : ''); | |
node = parent; | |
} | |
return path; | |
} | |
var params = { | |
'event': { | |
'eventName': e.toString(), | |
'altKey': e.altKey, | |
'bubbles': e.bubbles, | |
'button': e.button, | |
'buttons': e.buttons, | |
'cancelBubble': e.cancelBubble, | |
'cancelable': e.cancelable, | |
'clientY': e.clientY, | |
'clientX': e.clientX, | |
'composed': e.composed, | |
'ctrlKey': e.ctrlKey, | |
'currentTarget': e.currentTarget ? '#' + e.currentTarget.id : null, | |
'defaultPrevented': e.defaultPrevented, | |
'detail': e.detail, | |
'eventPhase': e.eventPhase, | |
'fromElement': e.fromElement ? '#' + e.fromElement.id : null, | |
'isTrusted': e.isTrusted, | |
'layerX': e.layerX, | |
'layerY': e.layerY, | |
'metaKey': e.metaKey, | |
'movementX': e.movementX, | |
'movementY': e.movementY, | |
'offsetX': e.offsetX, | |
'offsetY': e.offsetY, | |
'pageX': e.pageX, | |
'pageY': e.pageY, | |
'path': pathToSelector(e.path && e.path.length ? e.path[0] : null), | |
'relatedTarget': e.relatedTarget ? '#' + e.relatedTarget.id : null, | |
'returnValue': e.returnValue, | |
'screenX': e.screenX, | |
'screenY': e.screenY, | |
'shiftKey': e.shiftKey, | |
'sourceCapabilities: e.sourceCapabilities ? e.sourceCapabilities() : null, | |
'target': e.target ? '#' + e.target.id : null, | |
'timeStamp': e.timeStamp, | |
'toElement': e.toElement ? '#' + e.toElement.id : null, | |
'type': e.type, | |
'view': e.view ? e.view.toString() : null, | |
'which': e.which, | |
'x': e.x, | |
'y': e.y | |
} | |
}; | |
sendCallbackParam('{id}', '{event}', param); | |
event.stopPropagation(); | |
event.preventDefault(); | |
return false; | |
""".format( | |
id=self.identifier, | |
event_name | |
) | |
self.attributes[event_name] = ''.join([l.strip() for l in js.splitlines()]) | |
self.eventManager.register_listener(event_name, callback, *userdata) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-*- coding: utf-8 -*- | |
from __future__ import unicode_literals | |
from remi_json_view import JSONView | |
class InstallIndexView( JSONView ): | |
as_attribute = [ | |
".button" | |
] | |
def __init__(self): | |
super(InstallIndexView, self).__init__(_class="content") | |
def callback_button_click(self, event): | |
pass | |
class InstallDatabaseView( JSONView ): | |
as_attribute = [ | |
".button" | |
] | |
def __init__(self): | |
super(InstallIndexView, self).__init__(_class="content") | |
def callback_process_step_clicked(self, event): | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment