Interim commit
Nowhere close to executable (though everything builds)
This commit is contained in:
parent
99b3c14ec6
commit
b86ba7b6f6
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
21
src/myWebLog.Data/AssemblyInfo.fs
Normal file
21
src/myWebLog.Data/AssemblyInfo.fs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace myWebLog.Data.AssemblyInfo
|
||||
|
||||
open System.Reflection
|
||||
open System.Runtime.CompilerServices
|
||||
open System.Runtime.InteropServices
|
||||
|
||||
[<assembly: AssemblyTitle("myWebLog.Data")>]
|
||||
[<assembly: AssemblyDescription("Data access for myWebLog")>]
|
||||
[<assembly: AssemblyConfiguration("")>]
|
||||
[<assembly: AssemblyCompany("DJS Consulting")>]
|
||||
[<assembly: AssemblyProduct("myWebLog.Data")>]
|
||||
[<assembly: AssemblyCopyright("Copyright © 2016")>]
|
||||
[<assembly: AssemblyTrademark("")>]
|
||||
[<assembly: AssemblyCulture("")>]
|
||||
[<assembly: ComVisible(false)>]
|
||||
[<assembly: Guid("1fba0b84-b09e-4b16-b9b6-5730dea27192")>]
|
||||
[<assembly: AssemblyVersion("0.9.1.0")>]
|
||||
[<assembly: AssemblyFileVersion("1.0.0.0")>]
|
||||
|
||||
do
|
||||
()
|
9
src/myWebLog.Data/DataConfig.fs
Normal file
9
src/myWebLog.Data/DataConfig.fs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace myWebLog.Data
|
||||
|
||||
open RethinkDb.Driver.Net
|
||||
|
||||
type DataConfig = {
|
||||
database : string
|
||||
conn : IConnection
|
||||
}
|
||||
|
265
src/myWebLog.Data/Entities.fs
Normal file
265
src/myWebLog.Data/Entities.fs
Normal file
@ -0,0 +1,265 @@
|
||||
namespace myWebLog.Entities
|
||||
|
||||
open Newtonsoft.Json
|
||||
|
||||
// ---- Constants ----
|
||||
|
||||
/// Constants to use for revision source language
|
||||
module RevisionSource =
|
||||
let Markdown = "markdown"
|
||||
let HTML = "html"
|
||||
|
||||
/// Constants to use for authorization levels
|
||||
module AuthorizationLevel =
|
||||
let Administrator = "Administrator"
|
||||
let User = "User"
|
||||
|
||||
/// Constants to use for post statuses
|
||||
module PostStatus =
|
||||
let Draft = "Draft"
|
||||
let Published = "Published"
|
||||
|
||||
// ---- Entities ----
|
||||
|
||||
/// A revision of a post or page
|
||||
type Revision = {
|
||||
/// The instant which this revision was saved
|
||||
asOf : int64
|
||||
/// The source language
|
||||
sourceType : string
|
||||
/// The text
|
||||
text : string
|
||||
}
|
||||
|
||||
|
||||
/// A page with static content
|
||||
type Page = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The Id of the web log to which this page belongs
|
||||
webLogId : string
|
||||
/// The Id of the author of this page
|
||||
authorId : string
|
||||
/// The title of the page
|
||||
title : string
|
||||
/// The link at which this page is displayed
|
||||
permalink : string
|
||||
/// The instant this page was published
|
||||
publishedOn : int64
|
||||
/// The instant this page was last updated
|
||||
lastUpdatedOn : int64
|
||||
/// Whether this page shows as part of the web log's navigation
|
||||
showInPageList : bool
|
||||
/// The current text of the page
|
||||
text : string
|
||||
/// Revisions of this page
|
||||
revisions : Revision list
|
||||
}
|
||||
with
|
||||
static member empty =
|
||||
{ id = ""
|
||||
webLogId = ""
|
||||
authorId = ""
|
||||
title = ""
|
||||
permalink = ""
|
||||
publishedOn = int64 0
|
||||
lastUpdatedOn = int64 0
|
||||
showInPageList = false
|
||||
text = ""
|
||||
revisions = List.empty
|
||||
}
|
||||
|
||||
|
||||
/// A web log
|
||||
type WebLog = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The name
|
||||
name : string
|
||||
/// The subtitle
|
||||
subtitle : string option
|
||||
/// The default page ("posts" or a page Id)
|
||||
defaultPage : string
|
||||
/// The path of the theme (within /views)
|
||||
themePath : string
|
||||
/// The URL base
|
||||
urlBase : string
|
||||
/// The time zone in which dates/times should be displayed
|
||||
timeZone : string
|
||||
/// A list of pages to be rendered as part of the site navigation
|
||||
[<JsonIgnore>]
|
||||
pageList : Page list
|
||||
}
|
||||
with
|
||||
/// An empty web log
|
||||
static member empty =
|
||||
{ id = ""
|
||||
name = ""
|
||||
subtitle = None
|
||||
defaultPage = ""
|
||||
themePath = "default"
|
||||
urlBase = ""
|
||||
timeZone = "America/New_York"
|
||||
pageList = List.empty
|
||||
}
|
||||
|
||||
|
||||
/// An authorization between a user and a web log
|
||||
type Authorization = {
|
||||
/// The Id of the web log to which this authorization grants access
|
||||
webLogId : string
|
||||
/// The level of access granted by this authorization
|
||||
level : string
|
||||
}
|
||||
|
||||
|
||||
/// A user of myWebLog
|
||||
type User = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The user name (e-mail address)
|
||||
userName : string
|
||||
/// The first name
|
||||
firstName : string
|
||||
/// The last name
|
||||
lastName : string
|
||||
/// The user's preferred name
|
||||
preferredName : string
|
||||
/// The hash of the user's password
|
||||
passwordHash : string
|
||||
/// The URL of the user's personal site
|
||||
url : string option
|
||||
/// The user's authorizations
|
||||
authorizations : Authorization list
|
||||
}
|
||||
with
|
||||
/// An empty user
|
||||
static member empty =
|
||||
{ id = ""
|
||||
userName = ""
|
||||
firstName = ""
|
||||
lastName = ""
|
||||
preferredName = ""
|
||||
passwordHash = ""
|
||||
url = None
|
||||
authorizations = List.empty
|
||||
}
|
||||
|
||||
/// Claims for this user
|
||||
[<JsonIgnore>]
|
||||
member this.claims = this.authorizations
|
||||
|> List.map (fun auth -> sprintf "%s|%s" auth.webLogId auth.level)
|
||||
|
||||
|
||||
/// A category to which posts may be assigned
|
||||
type Category = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The displayed name
|
||||
name : string
|
||||
/// The slug (used in category URLs)
|
||||
slug : string
|
||||
/// A longer description of the category
|
||||
description : string option
|
||||
/// The parent Id of this category (if a subcategory)
|
||||
parentId : string option
|
||||
/// The categories for which this category is the parent
|
||||
children : string list
|
||||
}
|
||||
with
|
||||
/// An empty category
|
||||
static member empty =
|
||||
{ id = ""
|
||||
name = ""
|
||||
slug = ""
|
||||
description = None
|
||||
parentId = None
|
||||
children = List.empty
|
||||
}
|
||||
|
||||
|
||||
/// A comment (applies to a post)
|
||||
type Comment = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The Id of the post to which this comment applies
|
||||
postId : string
|
||||
/// The Id of the comment to which this comment is a reply
|
||||
inReplyToId : string option
|
||||
/// The name of the commentor
|
||||
name : string
|
||||
/// The e-mail address of the commentor
|
||||
email : string
|
||||
/// The URL of the commentor's personal website
|
||||
url : string option
|
||||
/// The instant the comment was posted
|
||||
postedOn : int64
|
||||
/// The text of the comment
|
||||
text : string
|
||||
}
|
||||
with
|
||||
static member empty =
|
||||
{ id = ""
|
||||
postId = ""
|
||||
inReplyToId = None
|
||||
name = ""
|
||||
email = ""
|
||||
url = None
|
||||
postedOn = int64 0
|
||||
text = ""
|
||||
}
|
||||
|
||||
|
||||
/// A post
|
||||
type Post = {
|
||||
/// The Id
|
||||
id : string
|
||||
/// The Id of the web log to which this post belongs
|
||||
webLogId : string
|
||||
/// The Id of the author of this post
|
||||
authorId : string
|
||||
/// The status
|
||||
status : string
|
||||
/// The title
|
||||
title : string
|
||||
/// The link at which the post resides
|
||||
permalink : string
|
||||
/// The instant on which the post was originally published
|
||||
publishedOn : int64
|
||||
/// The instant on which the post was last updated
|
||||
updatedOn : int64
|
||||
/// The text of the post
|
||||
text : string
|
||||
/// The Ids of the categories to which this is assigned
|
||||
categoryIds : string list
|
||||
/// The tags for the post
|
||||
tags : string list
|
||||
/// The permalinks at which this post may have once resided
|
||||
priorPermalinks : string list
|
||||
/// Revisions of this post
|
||||
revisions : Revision list
|
||||
/// The categories to which this is assigned
|
||||
[<JsonIgnore>]
|
||||
categories : Category list
|
||||
/// The comments
|
||||
[<JsonIgnore>]
|
||||
comments : Comment list
|
||||
}
|
||||
with
|
||||
static member empty =
|
||||
{ id = ""
|
||||
webLogId = ""
|
||||
authorId = ""
|
||||
status = PostStatus.Draft
|
||||
title = ""
|
||||
permalink = ""
|
||||
publishedOn = int64 0
|
||||
updatedOn = int64 0
|
||||
text = ""
|
||||
categoryIds = List.empty
|
||||
tags = List.empty
|
||||
priorPermalinks = List.empty
|
||||
revisions = List.empty
|
||||
categories = List.empty
|
||||
comments = List.empty
|
||||
}
|
23
src/myWebLog.Data/Rethink.fs
Normal file
23
src/myWebLog.Data/Rethink.fs
Normal file
@ -0,0 +1,23 @@
|
||||
module myWebLog.Data.Rethink
|
||||
|
||||
open RethinkDb.Driver.Ast
|
||||
open RethinkDb.Driver.Net
|
||||
|
||||
let private r = RethinkDb.Driver.RethinkDB.R
|
||||
let private await task = task |> Async.AwaitTask |> Async.RunSynchronously
|
||||
|
||||
let delete (expr : ReqlExpr) = expr.Delete ()
|
||||
let get (expr : obj) (table : Table) = table.Get expr
|
||||
let getAll (exprs : obj[]) (table : Table) = table.GetAll exprs
|
||||
let insert (expr : obj) (table : Table) = table.Insert expr
|
||||
let optArg key (value : obj) (expr : GetAll) = expr.OptArg (key, value)
|
||||
let orderBy (exprA : obj) (expr : ReqlExpr) = expr.OrderBy exprA
|
||||
let replace (exprA : obj) (expr : ReqlExpr) = expr.Replace exprA
|
||||
let runAtomAsync<'T> (conn : IConnection) (ast : ReqlAst) = ast.RunAtomAsync<'T> conn |> await
|
||||
let runCursorAsync<'T> (conn : IConnection) (ast : ReqlAst) = ast.RunCursorAsync<'T> conn |> await
|
||||
let runListAsync<'T> (conn : IConnection) (ast : ReqlAst) = ast.RunAtomAsync<System.Collections.Generic.List<'T>> conn
|
||||
|> await
|
||||
let runResultAsync (conn : IConnection) (ast : ReqlAst) = ast.RunResultAsync conn |> await
|
||||
let table (expr : obj) = r.Table expr
|
||||
let update (exprA : obj) (expr : ReqlExpr) = expr.Update exprA
|
||||
let without (exprs : obj[]) (expr : ReqlExpr) = expr.Without exprs
|
154
src/myWebLog.Data/SetUp.fs
Normal file
154
src/myWebLog.Data/SetUp.fs
Normal file
@ -0,0 +1,154 @@
|
||||
module myWebLog.Data.SetUp
|
||||
|
||||
open RethinkDb.Driver
|
||||
open System
|
||||
open Rethink
|
||||
open RethinkDb.Driver.Ast
|
||||
|
||||
let private r = RethinkDB.R
|
||||
let private logStep step = Console.Out.WriteLine(sprintf "[myWebLog] %s" step)
|
||||
let private logStepStart text = Console.Out.Write (sprintf "[myWebLog] %s..." text)
|
||||
let private logStepDone () = Console.Out.WriteLine(" done.")
|
||||
|
||||
let private result task = task |> Async.AwaitTask |> Async.RunSynchronously
|
||||
|
||||
let checkDatabase (cfg : DataConfig) =
|
||||
logStep "|> Checking database"
|
||||
let dbs = r.DbList()
|
||||
|> runListAsync<string> cfg.conn
|
||||
match dbs.Contains cfg.database with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf " %s database not found - creating" cfg.database)
|
||||
r.DbCreate cfg.database
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
|
||||
let checkTables cfg =
|
||||
logStep "|> Checking tables"
|
||||
let tables = r.Db(cfg.database).TableList()
|
||||
|> runListAsync<string> cfg.conn
|
||||
[ Table.Category; Table.Comment; Table.Page; Table.Post; Table.User; Table.WebLog ]
|
||||
|> List.map (fun tbl -> match tables.Contains tbl with
|
||||
| true -> None
|
||||
| _ -> Some (tbl, r.TableCreate tbl))
|
||||
|> List.filter (fun create -> create.IsSome)
|
||||
|> List.map (fun create -> create.Value)
|
||||
|> List.iter (fun (tbl, create) -> logStepStart (sprintf " Creating table %s" tbl)
|
||||
create
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ())
|
||||
|
||||
let tbl cfg table = r.Db(cfg.database).Table(table)
|
||||
|
||||
let createIndex cfg table index =
|
||||
logStepStart (sprintf """ Creating index "%s" on table %s""" index table)
|
||||
(tbl cfg table).IndexCreate(index)
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg table).IndexWait(index)
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
|
||||
let chkIndexes cfg table (indexes : string list) =
|
||||
let idx = (tbl cfg table).IndexList()
|
||||
|> runListAsync<string> cfg.conn
|
||||
indexes
|
||||
|> List.iter (fun index -> match idx.Contains index with
|
||||
| true -> ()
|
||||
| _ -> createIndex cfg table index)
|
||||
idx
|
||||
|
||||
let checkCategoryIndexes cfg =
|
||||
chkIndexes cfg Table.Category [ "webLogId"; "slug" ]
|
||||
|> ignore
|
||||
|
||||
let checkCommentIndexes cfg =
|
||||
chkIndexes cfg Table.Comment [ "postId" ]
|
||||
|> ignore
|
||||
|
||||
let checkPageIndexes cfg =
|
||||
let idx = chkIndexes cfg Table.Page [ "webLogId" ]
|
||||
match idx.Contains "permalink" with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf """ Creating index "permalink" on table %s""" Table.Page)
|
||||
(tbl cfg Table.Page)
|
||||
.IndexCreate("permalink", ReqlFunction1(fun row -> upcast r.Array(row.["webLogId"], row.["permalink"])))
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg Table.Page).IndexWait "permalink"
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
match idx.Contains "pageList" with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf """ Creating index "pageList" on table %s""" Table.Page)
|
||||
(tbl cfg Table.Page)
|
||||
.IndexCreate("pageList", ReqlFunction1(fun row -> upcast r.Array(row.["webLogId"], row.["showInPageList"])))
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg Table.Page).IndexWait "pageList"
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
|
||||
let checkPostIndexes cfg =
|
||||
let idx = chkIndexes cfg Table.Post [ "webLogId" ]
|
||||
match idx.Contains "webLogAndStatus" with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf """ Creating index "webLogAndStatus" on table %s""" Table.Post)
|
||||
(tbl cfg Table.Post)
|
||||
.IndexCreate("webLogAndStatus", ReqlFunction1(fun row -> upcast r.Array(row.["webLogId"], row.["status"])))
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg Table.Post).IndexWait "webLogAndStatus"
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
match idx.Contains "permalink" with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf """ Creating index "permalink" on table %s""" Table.Post)
|
||||
(tbl cfg Table.Post)
|
||||
.IndexCreate("permalink", ReqlFunction1(fun row -> upcast r.Array(row.["webLogId"], row.["permalink"])))
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg Table.Post).IndexWait "permalink"
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
|
||||
let checkUserIndexes cfg =
|
||||
let idx = chkIndexes cfg Table.User [ ]
|
||||
match idx.Contains "logOn" with
|
||||
| true -> ()
|
||||
| _ -> logStepStart (sprintf """ Creating index "logOn" on table %s""" Table.User)
|
||||
(tbl cfg Table.User)
|
||||
.IndexCreate("logOn", ReqlFunction1(fun row -> upcast r.Array(row.["userName"], row.["passwordHash"])))
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
(tbl cfg Table.User).IndexWait "logOn"
|
||||
|> runResultAsync cfg.conn
|
||||
|> ignore
|
||||
logStepDone ()
|
||||
|
||||
let checkWebLogIndexes cfg =
|
||||
chkIndexes cfg Table.WebLog [ "urlBase" ]
|
||||
|> ignore
|
||||
|
||||
let checkIndexes cfg =
|
||||
logStep "|> Checking indexes"
|
||||
checkCategoryIndexes cfg
|
||||
checkCommentIndexes cfg
|
||||
checkPageIndexes cfg
|
||||
checkPostIndexes cfg
|
||||
checkUserIndexes cfg
|
||||
checkWebLogIndexes cfg
|
||||
|
||||
let startUpCheck cfg =
|
||||
logStep "Database Start Up Checks Starting"
|
||||
checkDatabase cfg
|
||||
checkTables cfg
|
||||
checkIndexes cfg
|
||||
logStep "Database Start Up Checks Complete"
|
19
src/myWebLog.Data/Table.fs
Normal file
19
src/myWebLog.Data/Table.fs
Normal file
@ -0,0 +1,19 @@
|
||||
module myWebLog.Data.Table
|
||||
|
||||
/// The Category table
|
||||
let Category = "Category"
|
||||
|
||||
/// The Comment table
|
||||
let Comment = "Comment"
|
||||
|
||||
/// The Page table
|
||||
let Page = "Page"
|
||||
|
||||
/// The Post table
|
||||
let Post = "Post"
|
||||
|
||||
/// The WebLog table
|
||||
let WebLog = "WebLog"
|
||||
|
||||
/// The User table
|
||||
let User = "User"
|
20
src/myWebLog.Data/WebLog.fs
Normal file
20
src/myWebLog.Data/WebLog.fs
Normal file
@ -0,0 +1,20 @@
|
||||
module myWebLog.Data.WebLog
|
||||
|
||||
open myWebLog.Entities
|
||||
open Rethink
|
||||
open RethinkDb.Driver
|
||||
|
||||
let private r = RethinkDB.R
|
||||
|
||||
type PageList = { pageList : Ast.CoerceTo }
|
||||
|
||||
/// Detemine the web log by the URL base
|
||||
let tryFindWebLogByUrlBase (cfg : DataConfig) (urlBase : string) =
|
||||
r.Table(Table.WebLog).GetAll([| urlBase |]).OptArg("index", "urlBase")
|
||||
.Merge(fun webLog -> { pageList = r.Table(Table.Page)
|
||||
.GetAll([| webLog.["id"], true |]).OptArg("index", "pageList")
|
||||
.OrderBy("title")
|
||||
.Pluck([| "title", "permalink" |])
|
||||
.CoerceTo("array") })
|
||||
|> runCursorAsync<WebLog> cfg.conn
|
||||
|> Seq.tryHead
|
94
src/myWebLog.Data/myWebLog.Data.fsproj
Normal file
94
src/myWebLog.Data/myWebLog.Data.fsproj
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>1fba0b84-b09e-4b16-b9b6-5730dea27192</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>myWebLog.Data</RootNamespace>
|
||||
<AssemblyName>myWebLog.Data</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Name>myWebLog.Data</Name>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<Tailcalls>false</Tailcalls>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<DocumentationFile>bin\Debug\myWebLog.Data.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<Tailcalls>true</Tailcalls>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<DocumentationFile>bin\Release\myWebLog.Data.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '11.0'">
|
||||
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
|
||||
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
|
||||
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<Import Project="$(FSharpTargetsPath)" />
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.fs" />
|
||||
<Compile Include="Entities.fs" />
|
||||
<Compile Include="Table.fs" />
|
||||
<Compile Include="DataConfig.fs" />
|
||||
<Compile Include="Rethink.fs" />
|
||||
<Compile Include="SetUp.fs" />
|
||||
<Compile Include="WebLog.fs" />
|
||||
<Content Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Common.Logging">
|
||||
<HintPath>..\packages\Common.Logging.3.3.0\lib\net40\Common.Logging.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Common.Logging.Core">
|
||||
<HintPath>..\packages\Common.Logging.Core.3.3.0\lib\net40\Common.Logging.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RethinkDb.Driver">
|
||||
<HintPath>..\packages\RethinkDb.Driver.2.3.8\lib\net45\RethinkDb.Driver.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
</ItemGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
7
src/myWebLog.Data/packages.config
Normal file
7
src/myWebLog.Data/packages.config
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Common.Logging" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Common.Logging.Core" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="RethinkDb.Driver" version="2.3.8" targetFramework="net452" />
|
||||
</packages>
|
17
src/myWebLog.Resources/Properties/AssemblyInfo.cs
Normal file
17
src/myWebLog.Resources/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("myWebLog.Resources")]
|
||||
[assembly: AssemblyDescription("Resources for the myWebLog package")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("myWebLog.Resources")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: Guid("a12ea8da-88bc-4447-90cb-a0e2dcc37523")]
|
||||
[assembly: AssemblyVersion("0.9.1.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: NeutralResourcesLanguage("en-US")]
|
72
src/myWebLog.Resources/Resources.Designer.cs
generated
Normal file
72
src/myWebLog.Resources/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace myWebLog {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("myWebLog.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Log On.
|
||||
/// </summary>
|
||||
public static string LogOn {
|
||||
get {
|
||||
return ResourceManager.GetString("LogOn", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
src/myWebLog.Resources/Resources.resx
Normal file
123
src/myWebLog.Resources/Resources.resx
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LogOn" xml:space="preserve">
|
||||
<value>Log On</value>
|
||||
</data>
|
||||
</root>
|
64
src/myWebLog.Resources/myWebLog.Resources.csproj
Normal file
64
src/myWebLog.Resources/myWebLog.Resources.csproj
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>myWebLog</RootNamespace>
|
||||
<AssemblyName>myWebLog.Resources</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
127
src/myWebLog.Web/App.fs
Normal file
127
src/myWebLog.Web/App.fs
Normal file
@ -0,0 +1,127 @@
|
||||
module myWebLog.App
|
||||
|
||||
open myWebLog
|
||||
open myWebLog.Data
|
||||
open myWebLog.Data.SetUp
|
||||
open myWebLog.Data.WebLog
|
||||
open myWebLog.Entities
|
||||
open Nancy
|
||||
open Nancy.Authentication.Forms
|
||||
open Nancy.Bootstrapper
|
||||
open Nancy.Cryptography
|
||||
open Nancy.Owin
|
||||
open Nancy.Security
|
||||
open Nancy.Session
|
||||
open Nancy.Session.Persistable
|
||||
open Nancy.Session.RethinkDb
|
||||
open Nancy.TinyIoc
|
||||
open Nancy.ViewEngines.SuperSimpleViewEngine
|
||||
open RethinkDb.Driver
|
||||
open RethinkDb.Driver.Net
|
||||
open Suave
|
||||
open Suave.Owin
|
||||
open System.Text.RegularExpressions
|
||||
|
||||
/// Set up a database connection
|
||||
let cfg =
|
||||
{ database = "myWebLog"
|
||||
conn = RethinkDB.R.Connection()
|
||||
.Hostname(RethinkDBConstants.DefaultHostname)
|
||||
.Port(RethinkDBConstants.DefaultPort)
|
||||
.AuthKey(RethinkDBConstants.DefaultAuthkey)
|
||||
.Db("myWebLog")
|
||||
.Timeout(RethinkDBConstants.DefaultTimeout)
|
||||
.Connect() }
|
||||
|
||||
do
|
||||
startUpCheck cfg
|
||||
|
||||
type TranslateTokenViewEngineMatcher() =
|
||||
static let regex = Regex("@Translate\.(?<TranslationKey>[a-zA-Z0-9-_]+);?", RegexOptions.Compiled)
|
||||
interface ISuperSimpleViewEngineMatcher with
|
||||
member this.Invoke (content, model, host) =
|
||||
regex.Replace(content, fun m -> let key = m.Groups.["TranslationKey"].Value
|
||||
match Resources.ResourceManager.GetString key with
|
||||
| null -> key
|
||||
| xlat -> xlat)
|
||||
|
||||
|
||||
/// Handle forms authentication
|
||||
type MyWebLogUser(name, claims) =
|
||||
interface IUserIdentity with
|
||||
member this.UserName with get() = name
|
||||
member this.Claims with get() = claims
|
||||
member this.UserName with get() = (this :> IUserIdentity).UserName
|
||||
member this.Claims with get() = (this :> IUserIdentity).Claims
|
||||
|
||||
type MyWebLogUserMapper(container : TinyIoCContainer) =
|
||||
|
||||
interface IUserMapper with
|
||||
member this.GetUserFromIdentifier (identifier, context) =
|
||||
match context.Request.PersistableSession.GetOrDefault(Keys.User, User.empty) with
|
||||
| user when user.id = string identifier -> upcast MyWebLogUser(user.preferredName, user.claims)
|
||||
| _ -> null
|
||||
|
||||
|
||||
/// Set up the RethinkDB connection instance to be used by the IoC container
|
||||
type ApplicationBootstrapper() =
|
||||
inherit DefaultNancyBootstrapper()
|
||||
override this.ConfigureRequestContainer (container, context) =
|
||||
base.ConfigureRequestContainer (container, context)
|
||||
container.Register<IUserMapper, MyWebLogUserMapper>()
|
||||
|> ignore
|
||||
override this.ApplicationStartup (container, pipelines) =
|
||||
base.ApplicationStartup (container, pipelines)
|
||||
// Data configuration
|
||||
container.Register<DataConfig>(cfg)
|
||||
|> ignore
|
||||
// I18N in SSVE
|
||||
container.Register<seq<ISuperSimpleViewEngineMatcher>>(fun _ _ ->
|
||||
Seq.singleton (TranslateTokenViewEngineMatcher() :> ISuperSimpleViewEngineMatcher))
|
||||
|> ignore
|
||||
// Forms authentication configuration
|
||||
let salt = (System.Text.ASCIIEncoding()).GetBytes "NoneOfYourBeesWax"
|
||||
let auth =
|
||||
FormsAuthenticationConfiguration(
|
||||
CryptographyConfiguration = CryptographyConfiguration
|
||||
(RijndaelEncryptionProvider(PassphraseKeyGenerator("Secrets", salt)),
|
||||
DefaultHmacProvider(PassphraseKeyGenerator("Clandestine", salt))),
|
||||
RedirectUrl = "~/user/logon",
|
||||
UserMapper = container.Resolve<IUserMapper>())
|
||||
FormsAuthentication.Enable (pipelines, auth)
|
||||
// CSRF
|
||||
Csrf.Enable pipelines
|
||||
// Sessions
|
||||
let sessions = RethinkDbSessionConfiguration(cfg.conn)
|
||||
sessions.Database <- cfg.database
|
||||
PersistableSessions.Enable (pipelines, sessions)
|
||||
()
|
||||
|
||||
|
||||
let version =
|
||||
let v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version
|
||||
match v.Build with
|
||||
| 0 -> match v.Minor with
|
||||
| 0 -> string v.Major
|
||||
| _ -> sprintf "%d.%d" v.Major v.Minor
|
||||
| _ -> sprintf "%d.%d.%d" v.Major v.Minor v.Build
|
||||
|> sprintf "v%s"
|
||||
|
||||
/// Set up the request environment
|
||||
type RequestEnvironment() =
|
||||
interface IRequestStartup with
|
||||
member this.Initialize (pipelines, context) =
|
||||
pipelines.BeforeRequest.AddItemToStartOfPipeline
|
||||
(fun ctx -> ctx.Items.["requestStart"] <- System.DateTime.Now.Ticks
|
||||
match tryFindWebLogByUrlBase cfg ctx.Request.Url.HostName with
|
||||
| Some webLog -> ctx.Items.["webLog"] <- webLog
|
||||
| None -> System.ApplicationException
|
||||
(sprintf "%s is not properly configured for myWebLog" ctx.Request.Url.HostName)
|
||||
|> raise
|
||||
ctx.Items.["version"] <- version
|
||||
null)
|
||||
|
||||
|
||||
let app = OwinApp.ofMidFunc "/" (NancyMiddleware.UseNancy (NancyOptions()))
|
||||
|
||||
let run () = startWebServer defaultConfig app // webPart
|
21
src/myWebLog.Web/AssemblyInfo.fs
Normal file
21
src/myWebLog.Web/AssemblyInfo.fs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace myWebLog.Web.AssemblyInfo
|
||||
|
||||
open System.Reflection
|
||||
open System.Runtime.CompilerServices
|
||||
open System.Runtime.InteropServices
|
||||
|
||||
[<assembly: AssemblyTitle("myWebLog.Web")>]
|
||||
[<assembly: AssemblyDescription("Main Nancy assembly for myWebLog")>]
|
||||
[<assembly: AssemblyConfiguration("")>]
|
||||
[<assembly: AssemblyCompany("DJS Consulting")>]
|
||||
[<assembly: AssemblyProduct("myWebLog.Web")>]
|
||||
[<assembly: AssemblyCopyright("Copyright © 2016")>]
|
||||
[<assembly: AssemblyTrademark("")>]
|
||||
[<assembly: AssemblyCulture("")>]
|
||||
[<assembly: ComVisible(false)>]
|
||||
[<assembly: Guid("e6ee110a-27a6-4a19-b0cb-d24f48f71b53")>]
|
||||
[<assembly: AssemblyVersion("0.9.1.0")>]
|
||||
[<assembly: AssemblyFileVersion("1.0.0.0")>]
|
||||
|
||||
do
|
||||
()
|
3
src/myWebLog.Web/Keys.fs
Normal file
3
src/myWebLog.Web/Keys.fs
Normal file
@ -0,0 +1,3 @@
|
||||
module myWebLog.Keys
|
||||
|
||||
let User = "user"
|
123
src/myWebLog.Web/myWebLog.Web.fsproj
Normal file
123
src/myWebLog.Web/myWebLog.Web.fsproj
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>e6ee110a-27a6-4a19-b0cb-d24f48f71b53</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>myWebLog.Web</RootNamespace>
|
||||
<AssemblyName>myWebLog.Web</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Name>myWebLog.Web</Name>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<Tailcalls>false</Tailcalls>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<DocumentationFile>bin\Debug\myWebLog.Web.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<Tailcalls>true</Tailcalls>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<DocumentationFile>bin\Release\myWebLog.Web.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '11.0'">
|
||||
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
|
||||
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
|
||||
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<Import Project="$(FSharpTargetsPath)" />
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.fs" />
|
||||
<Compile Include="Keys.fs" />
|
||||
<Compile Include="App.fs" />
|
||||
<Content Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Common.Logging">
|
||||
<HintPath>..\packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Common.Logging.Core">
|
||||
<HintPath>..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FSharp.Core">
|
||||
<HintPath>..\packages\FSharp.Core.4.0.0.1\lib\net40\FSharp.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="Nancy">
|
||||
<HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nancy.Authentication.Forms">
|
||||
<HintPath>..\packages\Nancy.Authentication.Forms.1.4.1\lib\net40\Nancy.Authentication.Forms.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nancy.Session.Persistable">
|
||||
<HintPath>..\packages\Nancy.Session.Persistable.0.8.6\lib\net452\Nancy.Session.Persistable.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nancy.Session.RethinkDb">
|
||||
<HintPath>..\packages\Nancy.Session.RethinkDB.0.8.6\lib\net452\Nancy.Session.RethinkDb.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RethinkDb.Driver">
|
||||
<HintPath>..\packages\RethinkDb.Driver.2.3.8\lib\net45\RethinkDb.Driver.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Suave">
|
||||
<HintPath>..\packages\Suave.1.1.3\lib\net40\Suave.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\myWebLog.Data\myWebLog.Data.fsproj">
|
||||
<Name>myWebLog.Data</Name>
|
||||
<Project>{1fba0b84-b09e-4b16-b9b6-5730dea27192}</Project>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\myWebLog.Resources\myWebLog.Resources.csproj">
|
||||
<Name>myWebLog.Resources</Name>
|
||||
<Project>{a12ea8da-88bc-4447-90cb-a0e2dcc37523}</Project>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
13
src/myWebLog.Web/packages.config
Normal file
13
src/myWebLog.Web/packages.config
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Common.Logging" version="3.3.1" targetFramework="net452" />
|
||||
<package id="Common.Logging.Core" version="3.3.1" targetFramework="net452" />
|
||||
<package id="FSharp.Core" version="4.0.0.1" targetFramework="net452" />
|
||||
<package id="Nancy" version="1.4.3" targetFramework="net452" />
|
||||
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net452" />
|
||||
<package id="Nancy.Session.Persistable" version="0.8.6" targetFramework="net452" />
|
||||
<package id="Nancy.Session.RethinkDB" version="0.8.6" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="RethinkDb.Driver" version="2.3.8" targetFramework="net452" />
|
||||
<package id="Suave" version="1.1.3" targetFramework="net452" />
|
||||
</packages>
|
40
src/myWebLog.sln
Normal file
40
src/myWebLog.sln
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "myWebLog", "myWebLog\myWebLog.csproj", "{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "myWebLog.Web", "myWebLog.Web\myWebLog.Web.fsproj", "{E6EE110A-27A6-4A19-B0CB-D24F48F71B53}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "myWebLog.Data", "myWebLog.Data\myWebLog.Data.fsproj", "{1FBA0B84-B09E-4B16-B9B6-5730DEA27192}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "myWebLog.Resources", "myWebLog.Resources\myWebLog.Resources.csproj", "{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E6EE110A-27A6-4A19-B0CB-D24F48F71B53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E6EE110A-27A6-4A19-B0CB-D24F48F71B53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E6EE110A-27A6-4A19-B0CB-D24F48F71B53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E6EE110A-27A6-4A19-B0CB-D24F48F71B53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1FBA0B84-B09E-4B16-B9B6-5730DEA27192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FBA0B84-B09E-4B16-B9B6-5730DEA27192}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FBA0B84-B09E-4B16-B9B6-5730DEA27192}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FBA0B84-B09E-4B16-B9B6-5730DEA27192}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A12EA8DA-88BC-4447-90CB-A0E2DCC37523}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
6
src/myWebLog/App.config
Normal file
6
src/myWebLog/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
10
src/myWebLog/Program.cs
Normal file
10
src/myWebLog/Program.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace myWebLog
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
App.run();
|
||||
}
|
||||
}
|
||||
}
|
15
src/myWebLog/Properties/AssemblyInfo.cs
Normal file
15
src/myWebLog/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("myWebLog")]
|
||||
[assembly: AssemblyDescription("A lightweight blogging platform built on Nancy and RethinkDB")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("myWebLog")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: Guid("b9f6db52-65a1-4c2a-8c97-739e08a1d4fb")]
|
||||
[assembly: AssemblyVersion("0.9.1.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
80
src/myWebLog/myWebLog.csproj
Normal file
80
src/myWebLog/myWebLog.csproj
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B9F6DB52-65A1-4C2A-8C97-739E08A1D4FB}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>myWebLog</RootNamespace>
|
||||
<AssemblyName>myWebLog</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\myWebLog.Data\myWebLog.Data.fsproj">
|
||||
<Project>{1fba0b84-b09e-4b16-b9b6-5730dea27192}</Project>
|
||||
<Name>myWebLog.Data</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\myWebLog.Resources\myWebLog.Resources.csproj">
|
||||
<Project>{a12ea8da-88bc-4447-90cb-a0e2dcc37523}</Project>
|
||||
<Name>myWebLog.Resources</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\myWebLog.Web\myWebLog.Web.fsproj">
|
||||
<Project>{e6ee110a-27a6-4a19-b0cb-d24f48f71b53}</Project>
|
||||
<Name>myWebLog.Web</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Content Include="views\default\index-content.html" />
|
||||
<Content Include="views\default\index.html" />
|
||||
<Content Include="views\default\layout.html" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
38
src/myWebLog/views/default/index-content.html
Normal file
38
src/myWebLog/views/default/index-content.html
Normal file
@ -0,0 +1,38 @@
|
||||
@If.subTitle
|
||||
<h2>
|
||||
<span class="label label-info">@Model.subTitle</span>
|
||||
</h2>
|
||||
@EndIf
|
||||
@Each.posts
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<article>
|
||||
<h1>
|
||||
<a href="/@Current.permalink" title="Permanent Link to "@Current.title@quot;">@Current.title</a>
|
||||
</h1>
|
||||
<!-- var pubDate = moment(post.publishedDate) -->
|
||||
<p>
|
||||
<i class="fa fa-calendar" title="@Translate.Date" /> @Current.publishedDate <!-- #{pubDate.format('MMMM Do, YYYY')} -->
|
||||
<i class="fa fa-clock-o" title="@Translate.Time" /> @Current.publishedTime <!-- #{pubDate.format('h:mma')} -->
|
||||
</p>
|
||||
@Current.text
|
||||
</article>
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
@EndEach
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-3">
|
||||
// TODO: stopped here
|
||||
if hasNext
|
||||
- var nextLink = (2 < page) ? '/page/' + (page - 1) : '/'
|
||||
if '/posts' == extraUrl && 2 == page
|
||||
//- Leave the "next" link at '/'
|
||||
else
|
||||
- nextLink = extraUrl + nextLink
|
||||
p: a.btn.btn-primary(href="#{nextLink}")= __("Newer Posts")
|
||||
</div>
|
||||
.col-xs-3.text-right
|
||||
if hasPrior
|
||||
p: a.btn.btn-primary(href=extraUrl + '/page/' + (page + 1))= __("Older Posts")
|
||||
</div>
|
5
src/myWebLog/views/default/index.html
Normal file
5
src/myWebLog/views/default/index.html
Normal file
@ -0,0 +1,5 @@
|
||||
@Master['default/layout']
|
||||
|
||||
@Section['Content']
|
||||
@Partial['default/index-content', Model]
|
||||
@EndSection
|
46
src/myWebLog/views/default/layout.html
Normal file
46
src/myWebLog/views/default/layout.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content="@Model.generator" />
|
||||
<title>@Model.pageTitle | @Model.webLog.name</title>
|
||||
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/styles/bootstrap-theme.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
|
||||
@Section['Head'];
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/">@Model.webLog.name</a>
|
||||
</div>
|
||||
<p class="navbar-text">@Model.webLog.subtitle</p>
|
||||
<ul class="nav navbar-nav navbar-left">
|
||||
@Each.webLog.pageList
|
||||
<li>
|
||||
<a href="/@Current.permalink">@Current.title</a>
|
||||
@EndEach
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
@If.isAuthenticated
|
||||
<li><a href="/admin">@Translate.Dashboard</a></li>
|
||||
<li><a href="/user/logoff">@Translate.LogOff</a></li>
|
||||
@EndIf
|
||||
@IfNot.isAuthenticated
|
||||
<li><a href="/user/logon">@Translate.LogOn</a></li>
|
||||
@EndIf
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container">
|
||||
@Section['Content'];
|
||||
</div>
|
||||
@Section['Footer'];
|
||||
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
||||
@Section['Scripts'];
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user