packages feed

corebot-bliki (empty) → 0.1

raw patch · 6 files changed

+298/−0 lines, 6 filesdep +aesondep +basedep +blaze-buildersetup-changed

Dependencies added: aeson, base, blaze-builder, bytestring, containers, directory, filepath, filestore, http-types, monads-tf, pandoc, template-haskell, text, time, yesod

Files

+ LICENSE view
@@ -0,0 +1,31 @@+Copyright Corey O'Connor++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Stefan O'Rear nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple+main = defaultMain+
+ corebot-bliki.cabal view
@@ -0,0 +1,49 @@+name:           corebot-bliki+version:        0.1+synopsis:       A bliki written using yesod. Uses pandoc to process files stored in git.+description:    Also provides a sample use of the library that uses $HOME/bliki for data and serves+                to port 8080.+                See http://www.corebotllc.com for public site built using this library.+cabal-version:  >= 1.8+build-type:     Simple+data-files:     static/*.js+license:        BSD3+license-file:   LICENSE+homepage:       http://github.com/coreyoconnor/corebot-bliki++source-repository head+    type:       git+    location:   git://github.com/coreyoconnor/corebot-bliki.git+    +executable corebot-bliki+    main-is: DefaultMain.hs+    hs-source-dirs: src+    extensions:     TemplateHaskell+                    QuasiQuotes+                    TypeFamilies+                    MultiParamTypeClasses+                    FlexibleInstances+                    NoMonomorphismRestriction+                    OverloadedStrings+                    RankNTypes+                    ScopedTypeVariables+                    UndecidableInstances+                    EmptyDataDecls+                    GADTs+                    FlexibleContexts+    ghc-options:    -threaded+    build-depends:  base             >= 4.4.0 && < 5,+                    aeson            >= 0.3.2.11,+                    blaze-builder    >= 0.3.0.1,+                    bytestring       >= 0.9.2.0,+                    containers       >= 0.4.1.0,+                    directory        >= 1.1.0.1,+                    filepath         >= 1.2.0.1,+                    filestore        >= 0.4.0.5,+                    http-types       >= 0.6.7,+                    monads-tf        >= 0.1.0.0,+                    pandoc           >= 1.9,+                    text             >= 0.11.1.5,+                    template-haskell >= 2.6.0.0,+                    time             >= 1.2.0.5,+                    yesod            >= 0.9.4.1
+ src/DefaultMain.hs view
@@ -0,0 +1,87 @@+module Main where+import Yesod++import Yesod.CoreBot.Bliki +import Yesod.CoreBot.Bliki.Widgets++import Paths_corebot_bliki++import Control.Applicative+import Control.Monad.Fix++import Data.Monoid ++import System.Directory ( getHomeDirectory )++import System.FilePath++data Main = Main+    { bliki :: Bliki_ Main+    }++type Bliki = Bliki_ Main++type Data = Data_ Main+get_data = data_res . bliki++type Blog = Blog_ Main+get_blog = blog_res . bliki++type Wiki = Wiki_ Main+get_wiki = wiki_res . bliki++get_static = static_config . config . data_res . bliki++instance Yesod Main where+    approot _ = "http://localhost:8080"+    defaultLayout w = do+        let page_w = mconcat [ w, toWidget NavWidget ]+        p <- widgetToPageContent page_w+        mmsg <- getMessage+        hamletToRepHtml [hamlet|+!!!++<html>+    <head>+        <title>#{pageTitle p}+        ^{pageHead p}+    <body>+        $maybe msg <- mmsg+            <p .message>#{msg}+        ^{pageBody p}+|]++getMainR = do+    bliki <- bliki <$> getYesod+    defaultLayout $ do+        default_blog_entry bliki++mkYesod "Main" [parseRoutes|+/       MainR   GET+/data   DataS   Data   get_data+/blog   BlogS   Blog   get_blog+/wiki   WikiS   Wiki   get_wiki+/static StaticS Static get_static+|]++main :: IO ()+main = do+    home_dir <- getHomeDirectory+    let store_dir = home_dir </> "bliki"+        cache_dir = home_dir </> "bliki/cache"+    static_dir <- getDataFileName "static"+    putStrLn $ "using static dir: " ++ static_dir+    app <- mfix $ \app -> do+                let config = Config { store_dir     = store_dir+                                    , cache_dir     = cache_dir+                                    , data_routes   = DataS+                                    , blog_routes   = BlogS+                                    , wiki_routes   = WikiS+                                    , static_routes = StaticS+                                    , static_config = UseDir static_dir+                                    , site = app+                                    }+                bliki <- mk_bliki config+                return $ Main bliki+    warpDebug 8080 app+
+ static/indirect_load.js view
@@ -0,0 +1,59 @@+var worker = new Worker('static/process_HTML_for_wiki.js');++function insertSubstr( str, index, sub_str )+{+    var str_pre = str.slice( 0, index );+    var str_post = str.slice( index );+    return str_pre + sub_str + str_post;+}++function process_HTML_for_wiki( data, target, wiki_node_URL )+{+    var edits = new Array;++    var apply_edits = function()+    {+        edits.reverse();++        for(var i = 0; i < edits.length ; ++i)+        {+            var edit = edits[i];+            var edit_region = edit.edit_region;+            // +- 2 accounts for the ]] and [[ respectively. +            // XXX: hackish+            data = insertSubstr( data, edit_region.end_index + 2, '</a>' );+            data = insertSubstr( data, edit_region.start_index - 2, '<a href="' + edit.node_URL + '">' );+        }++        target.html( data );+    }++    worker.postMessage( data );+    worker.onmessage = function(event)+        {+            edit_region = event.data;++            var node_URL = wiki_node_URL + '/' + edit_region.node_path;++            var http = new XMLHttpRequest();+            http.open('HEAD', node_URL, true);+            http.onload = function( pe )+                {+                    console.log( http.status );++                    // Thanks the gods of HTTP for making this next line so.+                    if( http.status < 400 )+                    {+                        edits.push( { edit_region: edit_region+                                    , node_URL: node_URL+                                    }+                                  );+                        +                        if( edit_region.is_final )+                            apply_edits();+                    }+                };+            http.send();+        };+}+
+ static/process_HTML_for_wiki.js view
@@ -0,0 +1,69 @@+onmessage = function(event) +{+    // This method assumes that double bracket *always* indicates a wiki node path regardless of+    // it's location in the source+    // I presume there is some way to use jquery from a web worker. Once I figure that out I think+    // this algo would be better: Parse the HTML fragment data and then use jquery to only scan the+    // wiki links that are not in code tags.+    //+    // for now we avoid just the HTML generated by ``[[wiki_word]]``. Every other instance of+    // [[wiki_word]] is assumed to be replacable by the a link+    var src = new String(event.data);++    var start_match = /[^>]\[\[/gm;++    var node_path_match = /(\w+(?:\/\w+)*)\]\]/g;++    var parse_state = 'pre_start';++    var pending = null;++    var step_parser = function()+    {+        switch( parse_state )+        {+            case 'pre_start':+                var m = start_match.exec( src );++                if( null == m && null != pending )+                    pending.is_final = true;++                if( null != pending )+                    postMessage( pending );++                pending = null;++                if( null == m )+                    return;++                node_path_match.lastIndex = start_match.lastIndex;++                parse_state = 'in_brackets';+                break;+            case 'in_brackets':+                var m = node_path_match.exec( src );++                if(null == m)+                {+                    parse_state = 'pre_start';+                    break;+                }++                pending = { node_path: m[1] +                          , start_index: start_match.lastIndex+                          , end_index: node_path_match.lastIndex - 2+                          , is_final: false+                          };++                start_match.lastIndex = node_path_match.lastIndex;++                parse_state = 'pre_start';+                break;+        }++        setTimeout( step_parser, 50 );+    };+    +    setTimeout( step_parser, 50 );+};+