Skip to content

Commit

Permalink
Merge pull request #26 from crempp/release/v0.2
Browse files Browse the repository at this point in the history
Release v0.2
  • Loading branch information
crempp committed Feb 27, 2016
2 parents cf3bb76 + c424f55 commit 3e86759
Show file tree
Hide file tree
Showing 71 changed files with 1,290 additions and 521 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ _mailinglist
shippable
nosetests.xml
.coverage
wsgi.py
16 changes: 16 additions & 0 deletions .landscape.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
doc-warnings: yes
test-warnings: yes
strictness: veryhigh
max-line-length: 80
autodetect: yes

ignore-paths:
- themes
- content

uses:
- flask

python-targets:
- 2
- 3
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Markdown based web site framework
# Markdown based web site framework [![Code Health](https://landscape.io/github/crempp/mdweb/feature/PylintCleanup/landscape.svg?style=flat)](https://landscape.io/github/crempp/mdweb/feature/PylintCleanup) [![Build Status](https://img.shields.io/shippable/56bc32841895ca447473c981.svg)](https://app.shippable.com/projects/56bc32841895ca447473c981)

MDWeb is painstakingly designed to be as minimalistic as possible while taking
less than 5 minutes to setup and less than a minute to add content.
Expand Down Expand Up @@ -207,6 +207,21 @@ created \]
13. *post-boot:* Triggered after all site setup is complete and the application
is ready to start handling requests.

## Running in Production

* Setup a site module and class as outlined above.

* Copy `wsgi.py.example` to `wsgi.py`. Inside the copied file rename
`MySite` to the site class name used in the previous step. Set the
sitename parameter and app_options appropriately.

* Point your webserver to the `wsgi.py` file. For example, for Gunicorn
a command similar to the following would run the site
`gunicorn -b 0.0.0.0:5010 -b [::1]:5010 --pythonpath /srv/mysite wsgi:app`

Any further setup is outside the scope of this README. I'll try to add
example cases as time allows.

## Credits
* Alpha theme modified from the [Alpha site template](http://html5up.net/alpha) on [html5up.net](http://html5up.net).
This site template was licensed under [CCA 3.0](html5up.net/license)
Expand Down
28 changes: 7 additions & 21 deletions VERSIONS.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
MDWeb versions
====

v0.1 [2016-02-22]
v0.2 \[future\]
----
1. ✓ Basic markdown page hosting
1. ✓ File change watcher
1. ✓ Arbitrary depth navigation with page metadata definition
1. ✓ >90% test coverage
1. Asset support in content directory

v0.2 [future]
v0.1 \[2016-02-22\]
----
1. Support for favicon.ico and similar root-level files
1. Ordering nav levels
1. Navigation level metadata
1. Basic markdown page hosting
1. File change watcher
1. Arbitrary depth navigation with page metadata definition
1. \>90% test coverage

v0.3 [future]
----
1. Plugin architecture
1. Sphinx documentation (http://www.sphinx-doc.org/en/stable/)

v0.4 [future]
----
1. Caching architecture
1. Figure out how to test watchdog
1. Test blinker signals

v1.0 [future]
----
1. Everything works
2 changes: 2 additions & 0 deletions demo-content/about/_navlevel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Nav Name: About
Order: 1
37 changes: 34 additions & 3 deletions demo-content/about/history.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
/*
Title: MDWeb History
Description: The long and storied history of MDWeb
Nav Name: History
Author: Chad Rempp
Order: 8
Order: 3
Sitemap Priority: 0.5
Sitemap Changefreq: monthly
*/
This all began in 1993...

MDWeb began out of my need for a framework to host a site for my
personal projects called lapinlabs.com. Over the past four years I went
through the following iterations:

### ~July 2012
Started building a site in Python, Django and Django-CMS. This
iteration was never completed.

### ~March 2013
Started over again, this time using PHP and Drupal. This iteration was
never completed.

### May 2014
Started over again, this time using PHP and the Pico framework. I
completed a basic version of this iteration but there were some issues
I found with the Pico framework. Despite the issues I realized that
the project was onto something. I decided to try a Markdown-based
framework of my own.

### Jan 2015
Started over again, this time building my own Markdown framework on
top of Python and Flask. So far so good...

### The Present
That brings us to the present. My projects site is now hosted on MDWeb
(lapinlabs.com)[http://lapinlabs.com] and I consider my journey
complete. I have opensourced the framework and hope others find it
useful.

21 changes: 16 additions & 5 deletions demo-content/about/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
/*
Title: MDWeb
Nav Name: About
Title: About MDWeb
Description: This description will go in the meta description tag
Author: Chad Rempp
Order: 8
Nav Name: About MDWeb
Sitemap Priority: 0.9
Sitemap Changefreq: monthly
*/

This is me
MDWeb is painstakingly designed to be as minimalistic as possible while
taking less than 5 minutes to setup and less than a minute to add
content.

This project was borne out of my frustration with maintaining websites
and adding content. I'm a firm believer in the ethos that CMS is an
evil that should be rid from this world. I spent years fighting
horrific battles with enemies such as Drupal, Wordpress and Joomla.
The things I saw during those dark days can not be unseen.

After years of battle, this weary web developmer built himself a tiny
oasis. This is MDWeb, I hope you find respite in it.
10 changes: 9 additions & 1 deletion demo-content/license/index.md → demo-content/about/license.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
##Source Code
/*
Title: MDWeb License
Description: MDWeb Opensource License
Nav Name: License
Order: 99
Sitemap Priority: 0.1
Sitemap Changefreq: never
*/
## MDWeb License

MDWeb is released under the MIT license.

Expand Down
Binary file added demo-content/assets/MDWeb_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-content/assets/MDWeb_logo_275x190.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-content/assets/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
2 changes: 2 additions & 0 deletions demo-content/documentation/_navlevel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Nav Name: Documentation
Order: 10
2 changes: 2 additions & 0 deletions demo-content/download/_navlevel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Nav Name: Download
Order: 5
12 changes: 11 additions & 1 deletion demo-content/download/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
/*
Title: Download MDWeb
Description: Download MDWeb
Nav Name: Download
Sitemap Priority: 0.9
Sitemap Changefreq: weekly
*/
# Download MDWeb

MDWeb is ready for you to use.

<a href="https://github.com/crempp/mdweb" target="_blank">MDWeb on Github <img src='/static/images/github.png'></img></a>
<a href="https://github.com/crempp/mdweb" target="_blank">
MDWeb on Github
<img src='/contentassets/github.png' />
</a>

## Requirements
* Python 2.7+, 3.x
Expand Down
2 changes: 2 additions & 0 deletions demo-content/examples/_navlevel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Nav Name: Examples
Order: 15
1 change: 0 additions & 1 deletion demo-content/examples/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/*
Title: Markdown Examples
Description: Examples of how to use MDWeb
Order: 4
*/

Examples taken from https://daringfireball.net/projects/markdown/basics
Expand Down
Binary file added demo-content/favicon.ico
Binary file not shown.
File renamed without changes.
5 changes: 3 additions & 2 deletions demo-content/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ Title: MDWeb
Description: The minimalistic markdown NaCMS
Order: 1
Template: page_home.html
Sitemap Priority: 0.9
Sitemap Changefreq: daily
*/


##MDWeb is Not a CMS (NaCMS)
<img src="/contentassets/MDWeb_logo_275x190.png"/>

MDWeb is a markdown based web site framework.

Expand Down
File renamed without changes.
65 changes: 65 additions & 0 deletions mdweb/BaseObjects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""MDWeb Base Navigation Item.
This is broken out into a separate file to avoid circular imports.
"""
import re

from mdweb.Exceptions import PageMetaInfFieldException


class NavigationBaseItem(object): # pylint: disable=R0903

"""Base object for navigation items such as nav-levels or pages."""

#: Type of navigation item
@property
def nav_type(self):
"""Return the type of this nav item (the class name)."""
return self.__class__.__name__


class MetaInfParser(object): # pylint: disable=R0903

"""Base Meta Inf Parser."""

FIELD_TYPES = {}
FIELD_VALUE_REGEX = r'^(?P<key>[a-zA-Z0-9 ]*):(?P<value>.*)$'

def __init__(self, meta_string):
"""Initialize the parser."""
# Initialize attributes defined in FIELD_TYPES
for attribute, attribute_details in self.FIELD_TYPES.items():
setattr(self, attribute, attribute_details[1])

self._parse_meta_inf(meta_string)

def _parse_meta_inf(self, meta_inf_string):
"""Parse given meta information string into a dictionary.
:param meta_inf_string: Raw meta content
"""
lines = meta_inf_string.split('\n')

for line in lines:
if line.strip(' ') == '' or re.match(r'^ *#', line):
continue
match = re.search(self.FIELD_VALUE_REGEX, line)
key = match.group('key').strip().lower().replace(' ', '_')
value = match.group('value').strip()
if key not in self.FIELD_TYPES.keys():
raise PageMetaInfFieldException("Unsupported field '%s'" % key)
# Cast field value to appropriate type
if '' == value:
raise PageMetaInfFieldException(
"Empty value for meta-inf field '%s'" % key)
if 'int' == self.FIELD_TYPES[key][0]:
value = int(value)
elif 'unicode' == self.FIELD_TYPES[key][0]:
if 'unicode' in __builtins__.keys():
# Python 2.x
value = __builtins__['unicode'](value)
else:
# Python 3.x
value = str(value)

setattr(self, key, value)
34 changes: 34 additions & 0 deletions mdweb/Exceptions.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,56 @@
"""MDWeb Exceptions."""

class ThemeException(Exception):

"""Theme directory or content error."""

pass


class ConfigException(Exception):

"""Configuration error."""

pass


class ContentException(Exception):

"""Markdown content exception."""

pass


class ContentStructureException(Exception):

"""Invalid structure of content directory."""

pass


class PageMetaInfFieldException(Exception):

"""Invalid field in page metadata."""

pass


class PageParseException(Exception):

"""Error parsing page markdown."""

pass


class FileExistsError(Exception): # pylint: disable=W0622

"""Shim for FileExistsError in Python 2.x."""

pass


class PermissionError(Exception): # pylint: disable=W0622

"""Shim for FileExistsError in Python 2.x."""

pass
14 changes: 8 additions & 6 deletions mdweb/Index.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
"""MDWeb Index View."""
from flask.views import View
from flask import render_template, abort, current_app as app


class Index(View):
"""The one view to rule them all. MDWeb has one single entry point. The
MDWeb routing system (not Flasks) determines the how to handle the request
and what markdown file to load.

"""The one view to rule them all.
MDWeb has one single entry point. The MDWeb routing system (not Flasks)
determines the how to handle the request and what markdown file to load.
"""

methods = ['GET']

def dispatch_request(self, path):
"""Dispatch request"""

def dispatch_request(self, path): # pylint: disable=W0221
"""Dispatch request."""
page = app.get_page(path)

if page is None:
Expand Down
Loading

0 comments on commit 3e86759

Please sign in to comment.