Skip to content

Instantly share code, notes, and snippets.

@robertpi
Created December 6, 2019 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertpi/aed438bbc59e7c9685bc7c33afae077b to your computer and use it in GitHub Desktop.
Save robertpi/aed438bbc59e7c9685bc7c33afae077b to your computer and use it in GitHub Desktop.
open System
open System.Data.SqlClient
open System.IO
open System.Text.RegularExpressions
type BlogPost =
{ Id: int
Title: string
Date: DateTime
Text: string }
type Feedback =
{ PostId: int
Title: string
Date: DateTime
Text: string
Author: string
Url: string }
let tagsRegex = new Regex(@"<div[^>]+?class=""(tags(\s*clear)?|wlWriterEditableSmartContent)"">.*?</div>", RegexOptions.Compiled ||| RegexOptions.Singleline);
// Strip the DIVs for tags that Windows Live Writer inserts.
// <div class="tags">Technorati Tags:...</div>
// <div class="tags clear">Technorati Tags:...</div>
// <div style="..." id="scid:..." class="wlWriterEditableSmartContent">
let stripTagsDiv (content: string) =
tagsRegex.Replace(content, "");
[<EntryPoint>]
let main argv =
use conn = new SqlConnection(argv.[0])
conn.Open()
use cmd = new SqlCommand("select * from subtext_Content", conn)
use reader = cmd.ExecuteReader()
let posts =
[| while reader.Read() do
{ Id = reader.GetInt32(0)
Title = reader.GetString(1)
Date = reader.GetDateTime(2)
Text = reader.GetString(9) } |]
reader.Close()
use cmd = new SqlCommand("select * from subtext_FeedBack where StatusFlag in (3, 1)", conn)
use reader = cmd.ExecuteReader()
let feedback =
[| while reader.Read() do
{ PostId = reader.GetInt32(4)
Title = reader.GetString(1)
Date = reader.GetDateTime(16)
Text = reader.GetString(2)
Author = if reader.IsDBNull(5) then null else reader.GetString(5)
Url = if reader.IsDBNull(8) then null else reader.GetString(8) } |]
let feedbackPerPost =
feedback
|> Seq.groupBy (fun x -> x.PostId)
|> Map.ofSeq
let routDir = @"C:\code\strangelights_new\content"
for post in posts do
let fileName =
Path.GetInvalidFileNameChars()
|> Seq.fold(fun (acc: string) c -> acc.Replace(c, ' '))
(post.Title.ToLower().Replace(' ', '-').Replace("#", "sharp"))
let fullPath = Path.Combine(routDir, sprintf @"achrive\%i\%i\%i\%s.aspx.md" post.Date.Year post.Date.Month post.Date.Day fileName)
let dir = Path.GetDirectoryName(fullPath)
Directory.CreateDirectory(dir) |> ignore
printfn "Writing: %s" fullPath
use out = new StreamWriter(File.Open(fullPath, FileMode.Create))
let nl = Environment.NewLine
let header =
sprintf @"---%stitle: ""%s""%sdate: %s%sdraft: false%s---"
nl (post.Title.Replace("&ndash;", "-"))
nl (post.Date.ToString("o")) nl nl
out.WriteLine(header)
out.WriteLine()
out.WriteLine(stripTagsDiv post.Text)
let postFeedbacks = feedbackPerPost.TryFind post.Id
match postFeedbacks with
| Some feedbacks ->
out.WriteLine()
out.WriteLine("### Feedback:")
out.WriteLine()
out.WriteLine("*Feedback was imported from my only blog engine, it's no longer possible to post feedback here.*")
out.WriteLine()
for feedback in feedbacks do
out.Write(sprintf "**%s - " (feedback.Title.Trim()))
match String.IsNullOrWhiteSpace(feedback.Author), String.IsNullOrWhiteSpace(feedback.Url) with
| true, true -> out.WriteLine("Anon**")
| false, true -> out.WriteLine(feedback.Author.Trim() + "**")
| true, false -> out.WriteLine(feedback.Url + "**")
| false, false -> out.WriteLine(sprintf "[%s](%s)**" (feedback.Author.Trim()) feedback.Url)
out.WriteLine()
out.WriteLine(feedback.Text.Trim())
out.WriteLine()
| None -> ()
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment