diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..f6c2e41
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,28 @@
+# fabricad
+#
+# VERSION 0.0.1
+
+FROM ubuntu:14.04
+MAINTAINER Oliver Marks "olymk2@gmail.com"
+
+# make sure the package repository is up to date
+
+RUN \
+ apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install -y software-properties-common python-software-properties && \
+ apt-get install -y python-requests python-lxml python-flask
+
+RUN add-apt-repository -y ppa:oly/ppa
+RUN apt-get update
+RUN apt-get install -y python-scaffold
+
+ADD site /var/www/
+
+
+#allow access to flask
+EXPOSE 5000 5000
+
+#RUN /bin/sh -c 'cd /var/www; python index.py'
+
+ENTRYPOINT /bin/sh -c 'cd /var/www; python index.py'
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
index 16ca8fc..2167e8f 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,8 @@
# maidstone-hackspace
Repository for the maidstone hackspace website
+
+The simplest way to setup this site locally to make changes is to run.
+
+ docker build -t maidstone-hackspace .
+ docker run -p 5000:5000 maidstone-hackspace
+
diff --git a/site/__init__.py b/site/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/site/constants.py b/site/constants.py
new file mode 100755
index 0000000..ca4c09c
--- /dev/null
+++ b/site/constants.py
@@ -0,0 +1,13 @@
+
+page_menu = [
+ ('Home', '#home'),
+ #('About', '#about'),
+ ('Contact', '#mailing-list')]
+
+banner_images = [
+ ('/static/template/images/example-01.jpg', 'http://www.google.co.uk', 'title', 'intro text'),
+ ('/static/template/images/example-02.jpg', 'http://www.google.co.uk', 'title', 'intro text')]
+
+tile_images = [
+ ('/static/template/images/tile-01.jpg',),
+ ('/static/template/images/tile-02.jpg',)]
diff --git a/site/generate.py b/site/generate.py
new file mode 100644
index 0000000..e430e13
--- /dev/null
+++ b/site/generate.py
@@ -0,0 +1,180 @@
+import argparse
+
+import os
+import sys
+import requests
+import requests.exceptions
+from lxml import etree
+import lxml
+
+from settings import *
+from scaffold.web import web as html
+from scaffold.web import www
+
+import constants as site
+
+web = html()
+web.load_widgets('widgets')
+web.template.create('Maidstone Hackspace', 'Hackspace for Maidstone, kent. for collaberation and discussion for artists, designers, makers, hackers, programmers, tinkerer, professionals and hobbyists.')
+web.template.append('')
+
+#paths
+web.document_root = os.path.abspath('./')
+web.template.theme_full_path = os.path.abspath('./static/template') + os.sep
+domain = 'http://192.168.21.41:5000/'
+image_path = domain + os.sep + 'template' + os.sep + 'images' + os.sep
+
+web.template.css_includes.append('/static/template/default.css')
+web.template.css_includes.append('/static/template/js/jquery-ui/themes/base/jquery-ui.css')
+
+def todict(data):
+ new_dict = {}
+ for key, value in data.items():
+ new_dict[key] = value
+ return new_dict
+
+def dict_to_list(data, keys):
+ return [data.get(k) for k in keys]
+
+class feed_reader:
+ def __init__(self, url):
+ #~ self.feed = requests.get(url, stream=True)
+ fp = open('rss_example.xml', 'r')
+ self.feed = etree.parse(fp)
+ self.feed = self.feed.getroot()
+ #~ self.channel = self.feed.xpath('.//item')
+ #~ print self.channel
+
+ #for channel in feed.xpath(".//item"):
+ self.title = self.feed.xpath('./channel/title/text()')[-1]
+ self.link = self.feed.xpath('./channel/link/text()')[-1]
+ self.description = self.feed.xpath('./channel/description/text()')[-1]
+
+ self.channel_image = self.feed.xpath('.//image/url/text()')[-1]
+ self.channel_image_title = self.feed.xpath('.//image/title/text()')[-1]
+ self.channel_image_link = self.feed.xpath('.//image/link/text()')[-1]
+
+ def __iter__(self):
+ for item in self.feed.xpath('.//item'):
+ title = item.xpath('./title/text()')
+ link = item.xpath('./link/text()')
+ description = item.xpath('./description/text()')
+ yield title, link, description
+
+#~ class page:
+ #~ def __enter__(self):
+ #~ header()
+ #~
+ #~ def __exit(self):
+ #~ footer()
+
+def header():
+ web.menu.create('/', 'leftNav')
+ web.menu * site.page_menu
+ web.template.body.append(web.header_strip.create({}).render())
+ web.template.body.append(web.menu.render())
+ web.google_analytics.create('maidstone-hackspace.org.uk', 'UA-63373181-1')
+
+def footer():
+ web.template.body.append(web.footer_content.render())
+ web.google_analytics.create('maidstone-hackspace.org.uk', 'UA-63373181-1')
+ web.template.body.append(web.google_analytics.render())
+ return web.render()
+
+def examples():
+ """ page for testing new components"""
+ header()
+ print 'examples page'
+ #~ web.template.create('examples')
+ web.page.create('examples')
+ web.twitter_feed.create('olymk2')
+ web.page.section(web.twitter_feed.render())
+ footer()
+
+ web.template.body.append(web.page.render())
+ with open('examples.html', 'w') as fp:
+ fp.write(footer())
+
+def index():
+ header()
+
+ web.menu.create('/', 'leftNav')
+ web.menu * site.page_menu
+
+ web.template.body.append(web.header_strip.create({}).render())
+ web.template.body.append(web.menu.render())
+
+ web.page.create('')
+ web.page.section(web.images.create('/static/template/images/tile-01.jpg').set_classes('tile-right').append('/static/template/images/tile-01.jpg').render())
+ web.banner_slider.reset()
+ web.banner_slider * site.banner_images
+
+ web.page.append(web.banner_slider.render())
+
+ web.page.section(web.title.create('Introduction').render())
+
+ web.paragraph.create(
+ """Hackspaces are a shared space where artists, designers, makers, hackers, programmers, tinkerers, professionals and hobbyists
+ can work on their projects, share knowledge and collaborate.""")
+
+ web.paragraph.append(
+ """We are in the process of developing Maidstone Hackspace. We're previous members of (ICMP) and looking to form a new space in the future.
+ At the moment, communication is via google groups, email, and the website. If you're at all intrested please join our mailing list
+ and make yourself known!""")
+ web.page.section(web.paragraph.render())
+
+ web.page.section(web.title.create('Proposed activities').render())
+
+ bullet_list = []
+ bullet_list.append(
+ ("""Workshop on building a mobile application which can run on ios and android, potentially game oriented for a bit of fun, but open to suggestions.""",))
+ bullet_list.append(
+ ("""Build an interactive splash screen to feature on this site.""",))
+ bullet_list.append(
+ (web.link.create('Suggest a new activity', 'Suggest a new activity', '#mailing-list').render(),))
+
+
+
+ web.list.create(ordered=False).set_classes('bullet-list')
+ web.list * bullet_list
+ web.page.append(web.list.render())
+
+ web.footer_content.create().append(
+ web.google_groups.create(' and make yourself known','maidstone-hackspace').set_id('mailing-list').render())
+
+ web.div.create('').set_classes('panel')
+
+ web.tiles.create()
+ #~ for project in get_users_projects({'user_id': data.get('user_id')}):
+ #~ web.tiles.append(project.get('title'), project.get('id'))
+ #~ return web.tiles.render()
+
+ feed = feed_reader('')
+ for row in feed:
+ web.tiles.append(
+ title = feed.title,
+ link = feed.link,
+ image = feed.channel_image,
+ description = 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum.')
+ web.div.append(str(row))
+ web.page.append(web.tiles.render())
+
+ web.page.append(web.twitter_feed.render())
+
+ web.template.body.append(web.page.render())
+
+ #~ web.google_analytics.create('maidstone-hackspace.org.uk', 'UA-63373181-1')
+ #~ web.template.body.append(web.google_analytics.render())
+
+ #~ with open('index.html', 'w') as fp:
+ #~ fp.write()
+ return footer()
+
+parser = argparse.ArgumentParser(description = 'Generate static pages')
+#~ parser.add_argument('--help', help='Return help')
+#~ parser.add_argument('--folder', dest='folder', nargs='?', help='output folder')
+#~ args = parser.parse_args()
+#~ print(args.accumulate(args.integers))
+
+index()
+examples()
diff --git a/site/index.py b/site/index.py
new file mode 100644
index 0000000..deec659
--- /dev/null
+++ b/site/index.py
@@ -0,0 +1,21 @@
+import os
+import sys
+import requests
+from lxml import etree
+from flask import Flask
+from flask import make_response
+
+import generate as pages
+
+app = Flask(__name__, static_url_path='/static')
+
+@app.route("/examples", methods=['GET'])
+def examples():
+ return make_response(pages.examples())
+
+@app.route("/", methods=['GET'])
+def index():
+ return make_response(pages.index())
+
+if __name__ == '__main__':
+ app.run(host='0.0.0.0', port=5000, debug=True)
diff --git a/site/static/template/default.css b/site/static/template/default.css
new file mode 100755
index 0000000..3090976
--- /dev/null
+++ b/site/static/template/default.css
@@ -0,0 +1,86 @@
+html {background-color:#fff;height:100%;font-family:'Arial';font-size:18px;}
+body {margin:0px;padding:0px;}
+
+.header span{font-size:100px;}
+.headerbar {background-color:#E7EAEF;}
+.footer {width:100%:margin:auto;height:40px;background-color:#dddddd;border-top:1px solid #aaaaaa;border-bottom:1px solid #aaaaaa;}
+.footerbar {background-color:#E7EAEF;border-top:1px solid #D2D2D2;border-bottom:1px solid #D2D2D2;margin-top:60px;}
+.pageFooter{clear:both;}
+
+.pagination{height:40px;font-size:16px;}
+.pagination li.active{background-color:#0a2024;}
+.pagination li{float:left;list-style-type: none;margin-left:12px;background-color:#7eabb8;padding:2px;border:2px solid #000;border-radius:6px;}
+.pagination li:hover{background-color:#0a2128;}
+.pagination li a{text-decoration:none;color:#000;}
+
+.on{background-color:#1e424c !important;}
+.clear{clear:both;}
+
+table {width:100%;background-color: #eee;font-size:11px;border-collapse: collapse;border-spacing: 0px;box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.12), 0px 1px 2px 0px rgba(0, 0, 0, 0.24);}
+table tr {transition: all 0.3s ease 0s;}
+table th {padding:16px;}
+table td{padding:16px;border-bottom: 1px solid rgba(0, 0, 0, 0.12);}
+table caption{font-size:16px;}
+tbody tr:nth-child(odd) {
+ background-color: #eee;
+ font-size:11px;
+}
+.tabrow1(background-color:#eee;)
+
+
+#topbar {position:relative;position:absolute;top:0px;width:100%;z-index:10;}
+
+
+.hover:hover {background-color:#9fa8da;}
+.hover:hover {background-color:#9fa8da;}
+.hover-expand:hover .children { display: block; }
+
+
+/* new styles */
+.copyright {float:right;margin-top:20px;color:#fff;}
+
+p {margin:25px;}
+h2 {margin-left:25px;color:#fff;}
+h3 {color:#fff;}
+
+label {margin-bottom:10px;float:left;clear:both;display:block;color:#fff;}
+input {width:100%;margin:0px;margin-bottom:20px;padding:10px;}
+button {margin-bottom:20px;background-color: #fff; height: 48px; width:100%; border-radius: 3px;box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.2);}
+
+.tile-right {float:right;clear:right;}
+#headerstrip{position:absolute;left:0px;right:0px;height:68px;top:0px;background-color:#00232D;}
+#headerstrip .navstrip{margin:10px;height:48px;}
+#headerstrip .mini-logo{font-size:22px;padding-top: 12px;color:#fff;font-weight:bold;padding-left:58px;height:48px;background-image:url('/static/template/images/hackspace.png');background-repeat:no-repeat;}
+#headerstrip .middle{}
+
+#navstrip{}
+
+.menu {position:absolute;left:0px;right:0px;height:40px;height:388px;top:68px;background-color:#00232D;z-index:-1;}
+.menu ul {width:960px;margin:auto;height:40px;padding-left:20px;background-color:#0087A8;}
+.menu li {width:130px;float:left;list-style-type:none;margin:11px;text-align:center;}
+.menu li:hover {width:130px;float:left;list-style-type:none;border-bottom:4px solid #1C4085;}
+.menu a {color:#ffffff;font-weight:bold;text-decoration:none;}
+.menu li:hover {}
+
+.page {width:980px;margin:auto;margin-top:155px;padding-bottom:48px;background-color:#0087A8;}
+
+.google-groups-signup {width:300px;float:left;}
+.google-groups-signup input{width:274px;}
+.google-groups-signup a{color:#fff;}
+
+.banner-slide {position:absolute;width:750px;}
+.banner-slide ul{position:relative;overflow:hidden;width:750px;height:300px;margin:0px;}
+.banner-slide li{position:absolute;left:0px;top:0px;list-style-type:none;}
+.banner-slide .content{display:none;position:absolute;top:250px;width:100%;background-color: #eee;}
+.banner-slide .left{text-align:left;padding:6px;font-size:48px;color:#fff;position:absolute;top:122px;left:0px;width:60px;height:60px;background-color: transparent;}
+.banner-slide .right{text-align:right;padding:6px;font-size:48px;color:#fff;position:absolute;top:122px;right:0px;width:60px;height:60px;background-color: transparent;}
+
+.bullet-list li {margin:10px;}
+
+.tile {background-color:#eee;width:300px;height:350px;margin:10px;float:left;box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.26);}
+.tile img{width:300px;height:200px;}
+
+#footertop {background-color:#00232D;height:48px;}
+#footerbottom {background-color:#0087A8;height:300px;}
+#footerbottom div.container {margin:auto;background-color:#0087A8;height:250px;width:960px;}
+.twitter-feed {width:460px;margin:10px;}
diff --git a/site/static/template/images/example-01.jpg b/site/static/template/images/example-01.jpg
new file mode 100755
index 0000000..8bafc02
Binary files /dev/null and b/site/static/template/images/example-01.jpg differ
diff --git a/site/static/template/images/example-02.jpg b/site/static/template/images/example-02.jpg
new file mode 100755
index 0000000..e8acede
Binary files /dev/null and b/site/static/template/images/example-02.jpg differ
diff --git a/site/static/template/images/example-03.jpg b/site/static/template/images/example-03.jpg
new file mode 100755
index 0000000..c32cc49
Binary files /dev/null and b/site/static/template/images/example-03.jpg differ
diff --git a/site/static/template/images/hackspace.png b/site/static/template/images/hackspace.png
new file mode 100755
index 0000000..4735fec
Binary files /dev/null and b/site/static/template/images/hackspace.png differ
diff --git a/site/static/template/images/hackspace.svg b/site/static/template/images/hackspace.svg
new file mode 100755
index 0000000..7c83db6
--- /dev/null
+++ b/site/static/template/images/hackspace.svg
@@ -0,0 +1,393 @@
+
+
+
+
\ No newline at end of file
diff --git a/site/static/template/images/icon.png b/site/static/template/images/icon.png
new file mode 100755
index 0000000..ab5c068
Binary files /dev/null and b/site/static/template/images/icon.png differ
diff --git a/site/static/template/images/tile-01.jpg b/site/static/template/images/tile-01.jpg
new file mode 100755
index 0000000..56161d3
Binary files /dev/null and b/site/static/template/images/tile-01.jpg differ
diff --git a/site/static/template/images/tile-02.jpg b/site/static/template/images/tile-02.jpg
new file mode 100755
index 0000000..ed99a95
Binary files /dev/null and b/site/static/template/images/tile-02.jpg differ
diff --git a/site/widgets/__init__.py b/site/widgets/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/site/widgets/__init__.pyc b/site/widgets/__init__.pyc
new file mode 100755
index 0000000..bfacda0
Binary files /dev/null and b/site/widgets/__init__.pyc differ
diff --git a/site/widgets/banner_slider.py b/site/widgets/banner_slider.py
new file mode 100755
index 0000000..501ff51
--- /dev/null
+++ b/site/widgets/banner_slider.py
@@ -0,0 +1,40 @@
+from scaffold.web import www
+
+class control(www.default.html_ui):
+ """Image cycle widgets"""
+ view=[]
+ buttons=[]
+ content=[]
+ count=0
+ offset=60
+ height=300
+ width=400
+
+ def javascript(self):
+ js=("",)
+ return "\n".join(js)
+
+ def create(self):
+ self.reset()
+
+ def reset(self):
+ self.view=[]
+ self.buttons=[]
+ self.content=[]
+
+ def append(self,image,link,title,intro=''):
+ htm='
%s