From bbca1d6b3875df82af3b2c11b57efef2fb8e319d Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Mon, 18 May 2015 20:22:56 -0700 Subject: Initial import --- .gitignore | 3 + MANIFEST.in | 1 + mcrute_theme/__init__.py | 0 mcrute_theme/crute_modernized.py | 68 +++++++++++++++ setup.py | 42 ++++++++++ static/dnd-upload.js | 173 +++++++++++++++++++++++++++++++++++++++ static/favicon.ico | Bin 0 -> 1150 bytes static/iphone-icon.png | Bin 0 -> 15261 bytes static/logo.png | Bin 0 -> 8472 bytes static/mcrute.css | 90 ++++++++++++++++++++ 10 files changed, 377 insertions(+) create mode 100644 .gitignore create mode 100644 MANIFEST.in create mode 100644 mcrute_theme/__init__.py create mode 100644 mcrute_theme/crute_modernized.py create mode 100644 setup.py create mode 100644 static/dnd-upload.js create mode 100644 static/favicon.ico create mode 100644 static/iphone-icon.png create mode 100644 static/logo.png create mode 100644 static/mcrute.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b116e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/*.egg-info +*.pyc +.DS_Store diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..f19dc7a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include static/* diff --git a/mcrute_theme/__init__.py b/mcrute_theme/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mcrute_theme/crute_modernized.py b/mcrute_theme/crute_modernized.py new file mode 100644 index 0000000..0e04abe --- /dev/null +++ b/mcrute_theme/crute_modernized.py @@ -0,0 +1,68 @@ +from MoinMoin.theme.modernized import Theme as _Theme +from MoinMoin.Page import Page +from MoinMoin import wikiutil + + +class Theme(_Theme): + + # Hook to add an override stylesheet, favicon, iPhone icon, and viewport + # tag + def universal_edit_button(self, d, **k): + return u'\n'.join([ + (''), + + (''), + + (''), + + (''), + + (''), + ]) + _Theme.universal_edit_button(self, d, **k) + + # Hook to add a Home link to the header links next to the logo + def username(self, d): + html = _Theme.username(self, d) + first_tag = html.index('>') + 1 + + page = wikiutil.getFrontPage(self.request) + + return u'{} {} | {}'.format( + html[:first_tag], page.link_to_raw(self.request, "Home"), + html[first_tag:]) + + def editbarItems(self, page): + actions = _Theme.editbarItems(self, page) + + # Add quick link actions for starting/stopping activities + if page.pi['format'] == 'timecsv': + actions.insert(len(actions) - 1, page.link_to( + self.request, text='Start Activity', + querystr={ 'action': 'StartActivity' }, rel='nofollow')) + + actions.insert(len(actions) - 1, page.link_to( + self.request, text='Stop Activity', + querystr={ 'action': 'StopActivity' }, rel='nofollow')) + + return actions + + def send_title(self, text, **keywords): + if 'editor_mode' in keywords: + if 'body_attr' in keywords: + keywords['body_attr'] += 'id="page-editor"' + else: + keywords['body_attr'] = 'id="page-editor"' + + return _Theme.send_title(self, text, **keywords) + + +def execute(request): + return Theme(request) + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..d9963bd --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +from setuptools import setup, find_packages + +setup( + name="CruteMoinModernizedTheme", + version="1.0", + description="", + author="Michael Crute ", + license="MIT", + packages=find_packages(), + entry_points={ +# "moin.plugins.action": [ +# ], +# "moin.plugins.converter": [ +# ], +# "moin.plugins.events": [ +# ], +# "moin.plugins.filter": [ +# ], +# "moin.plugins.formatter": [ +# ], +# "moin.plugins.macro": [ +# ], +# "moin.plugins.parser": [ +# ], + "moin.plugins.theme": [ + "crute_modernized = mcrute_theme.crute_modernized:Theme", + ], +# "moin.plugins.userprefs": [ +# ], +# "moin.plugins.xmlrpc": [ +# ], + }, + data_files=[ + ("static", ( + "static/dnd-upload.js", + "static/favicon.ico", + "static/iphone-icon.png", + "static/logo.png", + "static/mcrute.css", + )), + ] +) diff --git a/static/dnd-upload.js b/static/dnd-upload.js new file mode 100644 index 0000000..2623cc2 --- /dev/null +++ b/static/dnd-upload.js @@ -0,0 +1,173 @@ +function template(text, data) { + var render; + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; + var settings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g + }; + + // Combine delimiters into one regular expression via alternation. + var matcher = new RegExp([ + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function('obj', source); + } catch (e) { + e.source = source; + throw e; + } + + if (data) return render(data); + var template = function(data) { + return render.call(this, data); + }; + + // Provide the compiled function source as a convenience for precompilation. + template.source = 'function(obj){\n' + source + '}'; + + return template; +} + +var tests = { + filereader: typeof FileReader != 'undefined', + dnd: 'draggable' in document.createElement('span'), + formdata: !!window.FormData, + progress: "upload" in new XMLHttpRequest +}; + +var UploadTemplate = template( +'
' + + '' + + '
' + +'
' +); + +var oldOnReady = document.onreadystatechange; +document.onreadystatechange = function() { + if (document.readyState !== "complete") { + return; + } + + if (typeof oldOnReady === "function") { + oldOnReady(); + } + + if (document.title.indexOf("Attachments for ") == -1) { + return; + } + + for (key in tests) { + if (tests[key] !== true) { + return; + } + } + + document.getElementsByTagName("h2")[0].insertAdjacentHTML('afterend', UploadTemplate()); + var holder = document.getElementById('dnd-upload'); + + holder.ondragover = function () { + this.className = 'hover'; + return false; + }; + + holder.ondragend = function () { + this.className = ''; + return false; + }; + + holder.ondrop = function (e) { + this.className = ''; + e.preventDefault(); + readfiles(e.dataTransfer.files); + } +}; + +function createElement(tag, attributes, innerHTML) { + var element = document.createElement(tag); + + for (key in attributes) { + element.setAttribute(key, attributes[key]); + } + + if (typeof innerHTML !== "undefined") { + element.innerHTML = innerHTML; + } + + return element; +}; + +function postFile(file) { + var size = file.size; + var units = ['G', 'M', 'K', 'B']; + var xhr = new XMLHttpRequest(); + var formData = new FormData(); + + formData.append('ticket', document.getElementsByName("ticket")[0].value); + formData.append('action', 'AttachFile'); + formData.append('do', 'upload'); + formData.append('file', file); + + if (document.getElementById("overwrite-check").checked) { + formData.append('overwrite', '1'); + } + + while (size >= 1024) { + size = size / 1024 | 0; + units.pop(); + } + + var progress = createElement('progress', { min: 0, max: 100, value: 0 }); + var progContainer = createElement('div', { "class": "progressbar" }); + var sizeSpan = createElement("span", { "class": "size" }, size + units[units.length - 1]); + var item = createElement('li'); + + progContainer.appendChild(progress); + progContainer.appendChild(sizeSpan); + + item.appendChild(createElement('span', { "class": "filename" }, file.name)); + item.appendChild(progContainer); + + document.getElementById("dnd-upload").appendChild(item); + + xhr.open('POST', window.location.pathname); + xhr.onload = function() { progress.value = 100; }; + + xhr.upload.onprogress = function (event) { + if (!event.lengthComputable) { return; } + progress.value = (event.loaded / event.total * 100 | 0); + } + + xhr.send(formData); +} + +function readfiles(files) { + for (var i = 0; i < files.length; i++) { + postFile(files[i]); + } +} diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..6bddf19 Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/iphone-icon.png b/static/iphone-icon.png new file mode 100644 index 0000000..a30c344 Binary files /dev/null and b/static/iphone-icon.png differ diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000..d01667a Binary files /dev/null and b/static/logo.png differ diff --git a/static/mcrute.css b/static/mcrute.css new file mode 100644 index 0000000..c579ae0 --- /dev/null +++ b/static/mcrute.css @@ -0,0 +1,90 @@ +h1, h2, h3, h4, h5 { + font-family: Georgia, serif; + font-weight: bolder; +} + +ul#pagelocation, +ul#pagelocation li { + font-family: Georgia, serif; + font-weight: bolder; + color: #0044B3; +} + +table.navigation { + float: none; + margin: 0px; +} + +table.navigation a { + display: block; +} + +pre { + font-family: "Courier New", "Courier", monospace; +} + +table.timecsv { + width: 50%; +} + +table.timecsv tr.active { + background-color: #66FF66; +} + +table.timecsv thead tr { + background-color: #CCCCCC; +} + +.hcolumn0, .hcolumn1, .hcolumn2, .hcolumn3, .hcolumn4, .hcolumn5, .hcolumn6, +.hcolumn7, .hcolumn8, .hcolumn9, .hcolumn10, .hcolumn11, .hcolumn12, +.hcolumn13, .hcolumn14, .hcolumn15, .hcolumn16, .hcolumn17, .hcolumn18, +.hcolumn19, .hcolumn20, .hcolumn21, .hcolumn22, .hcolumn23, .hcolumn24, +.hcolumn25, .hcolumn26, .hcolumn27, .hcolumn28, .hcolumn29, .hcolumn30 { + background-color: #CCCCCC; +} + + + +/* iPhone */ +@media screen and (max-width: 500px) { + #logo, #locationline, #pagetrail, #navibar, #pageline, #pageinfo { display: none; } + #page { padding: 0 0.5em; } + #header .editbar form { display: none; } + table.timecsv { width: 97%; } + + /* Editor Page */ + #page-editor input[name="button_switch"], + #page-editor input[name="button_spellcheck"], + #page-editor #chktrivialtop, + #page-editor label[for="chktrivialtop"] + { + display: none !important; + } + + #page-editor #header, #page-editor #footer, #page-editor #editor-help, #page-editor form p { + display: none; + } + + #page-editor #page { + margin: 0; + padding: 0; + } + + #page-editor textarea { + border: none; + height: 90vh; + width: 100%; + } +} + + +/* DND Upload Control */ +#dnd-upload { border: 10px dashed #ccc; min-height: 100px; margin: 20px auto; padding: 1em;} +#dnd-upload.hover { border: 10px dashed #0c0; } +.dnd-overwrite { color: red; display: block; text-align: right; } + +#dnd-upload li { list-style: none; padding: 1em; } +#dnd-upload .filename { font-weight: bolder; } +.progressbar { float: right; } +.progressbar progress { margin-right: 1em; } +.progressbar .size { display: inline-block; width: 3em; text-align: right; } -- cgit v1.2.3