summaryrefslogtreecommitdiff
path: root/provider/posts
diff options
context:
space:
mode:
Diffstat (limited to 'provider/posts')
-rw-r--r--provider/posts/blog-documentation.md9
-rw-r--r--provider/posts/blog-rss.md43
-rw-r--r--provider/posts/pwutil.md122
3 files changed, 174 insertions, 0 deletions
diff --git a/provider/posts/blog-documentation.md b/provider/posts/blog-documentation.md
new file mode 100644
index 0000000..b0d4af6
--- /dev/null
+++ b/provider/posts/blog-documentation.md
@@ -0,0 +1,9 @@
1---
2title: On the Origin of dirty-haskell.org
3published: 2015-03-12
4tags: Blog Software
5---
6
7The software used is a trivially modified version of the one powering [math.kleen.org](http://math.kleen.org/lists/blog.html).
8
9The title is without deeper meaning.
diff --git a/provider/posts/blog-rss.md b/provider/posts/blog-rss.md
new file mode 100644
index 0000000..095ff56
--- /dev/null
+++ b/provider/posts/blog-rss.md
@@ -0,0 +1,43 @@
1---
2title: dirty-haskell.org´s rss feeds
3published: 2015-03-29
4tags: Blog Software
5---
6
7I extended the software suite inherited from [math.kleen.org](http://math.kleen.org) to include support for rss feeds.
8The heart of the issue is a ~80 line haskell script I chose to call, in a bout of creativity, "generate-rss.hs".
9The script uses the [feed](http://hackage.haskell.org/package/feed-0.3.9.2) package.
10
11generate-rss.hs gets passed a title and a list of paths below ./lists to incorporate as items.
12It generates an empty feed structure, adds title and a (hardcoded) base url for RSS metadata, and iterates over the given paths — generating for each path an item to be included in the finished feed.
13This procedure makes use of a state monad (StateT (Feed, Maybe ClockTime) IO ()) to sequentially add items to the feed and keep track of the modification/change time of the newest path examined.
14Each item carries a title, an url, a date, and contents as follows:
15
16- The date used is the modification/change time of the path supplied as a command line argument at the beginning of the program (usually a symbolic link in ./lists) — as such it is the time the post was linked into the particular list we´re generating a RSS feed for (this was not a deliberate design choice but a side effect of the canonical implementation — it was later decided that this behaviour was in fact the one expected all along).
17- The url is generated by following, recursively, the trail of symbolic links starting in ./lists, assuming the final target is indeed in ./posts, and forming the filename of that target into a (hopefully) functional url in a hardcoded fashion.
18- The title is extracted from the markdown file using a function shamelessly copied from extract-title.hs (The author wrote that one too, after all).
19- The contents are read into Pandoc and rendered into [AsciiDoc](http://en.wikipedia.org/wiki/AsciiDoc) format (it seemed convenient at the time).
20
21Along the way two helper functions were introduced — if an implementation of those already exists in Prelude or somewhere else common please mail in a comment:
22
23~~~ {.haskell}
24(<->) :: [(a -> b)] -> a -> [b]
25[] <-> _ = []
26(f:fs) <-> x = (f x:fs <-> x)
27
28(<-->) :: [(a -> a)] -> a -> a
29[] <--> x = x
30(f:fs) <--> x = fs <--> (f x)
31~~~
32
33## Update ##
34
35~~~ {.haskell}
36import Control.Applicative ((<*>), pure)
37
38(<->) fs = (<*>) fs . pure
39
40(<-->) = flip $ foldl (.) id
41~~~
42
43Thanks, viktor.
diff --git a/provider/posts/pwutil.md b/provider/posts/pwutil.md
new file mode 100644
index 0000000..a4b3757
--- /dev/null
+++ b/provider/posts/pwutil.md
@@ -0,0 +1,122 @@
1---
2title: A Tool to Manage a Set of YAML Objects Representing Account Information — pwutil
3published: 2015-04-07
4---
5
6A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later perl) to manage a, sometimes encrypted, file containing account information I get asked to create and remember on a daily basis—accounts for shopping websites spring to mind.
7
8[pwutil](git://git.yggdrasil.li/pwutil) is the newest iteration in this line of bunches of scripts.
9
10## Features
11
12 * Support for embedding common operation in any kind of record keeping
13
14 Thus support for almost any encryption known to man (with absolutely no online security), version control, and synchronisation
15 * [Human read- and writeable](https://en.wikipedia.org/wiki/YAML) backstore
16 * Machine parseable output
17 * [Command Line Interface](https://en.wikipedia.org/wiki/Command-line_interface)-only
18 * New accounts can be partially generated by user defined functions with out of the box support for [pwgen](http://sourceforge.net/projects/pwgen/) and SSH
19
20## Usage
21
22~~~
23pwget [<searchTerm> …]
24Looks up and returns all accounts which contain any <searchTerm> anywhere in their representation — case insensitive.
25
26pwadd [[--gen-<generator> [<generatorArgument> …] …] --] <identifier> [<attributeKey> <attributeValue> …]
27Adds an account to the store — does not overwrite.
28~~~
29
30## Documentation
31
32I shall document the project in a partial and file-wise fashion—amendments available on request.
33
34### Structure
35
36~~~ {#DirTree}
37pwutil
38├── default.nix
39├── PWAdd.hs
40├── PWGet.hs
41├── PWUtil
42│   ├── Extra
43│   │   ├── PWGen.hs
44│   │   └── SSHCmd.hs
45│   ├── Types.hs
46│   └── Util.hs
47├── pwutil.hs
48├── PWUtil.hs
49└── pwutil.nix
50~~~
51
52### `pwutil.nix`
53is a [nix](https://nixos.org/nix) expression allowing easy installation using the nix package manager.
54A `~/.nixpkgs/config.nix` allowing one to do so might look thus:
55
56~~~ {.numberLines}
57{
58 packageOverrides = pkgs: {
59 pwutil = pkgs.callPackage /path/to/pwutil.nix {};
60 };
61}
62~~~
63
64The derivation takes some arguments (write those in `{}` above):
65
66`main ? null`
67 ~ Overwrite `pwutil.hs` with a file path
68
69`with<Package> ? false`
70 ~ `<Package>` is one of Pwgen, or Ssh a the current time.
71 If `true` wraps executables to have `$PATH` include `<Package>`.
72
73### `Types.hs`
74
75Introducing `PW` (much as [xmonad](https://xmonad.org) did with `X`) is an easy way to keep track of the `PWConfig` without resorting to function arguments.
76`BackStore` is our (new and improved) way of encapsulating store access in a totally customisable way—`plain`, which is essential `readFile` and `writeFile` as provided by `ByteString`, is provided for convenience in `Util.hs`.
77`PWConfig` most importantly contains a definition of generators (called by passing `--gen-…` to `pwadd`).
78
79~~~ {#Types.hs .haskell .numberLines}
80module PWUtil.Types (
81 PW(..),
82 BackStore(..),
83 PWConfig(..),
84 Generator(..)
85 ) where
86
87import Control.Monad.State
88import qualified Data.Map as M
89import Data.Yaml
90import Data.ByteString
91
92type PW = StateT PWConfig IO
93
94data BackStore = BackStore
95 { readContents :: PW ByteString
96 , writeContents :: ByteString -> PW ()
97 }
98
99data PWConfig = PWConfig
100 { generators :: M.Map String Generator
101 , backstore :: BackStore
102 }
103
104type Generator = [String] -> PW Value
105~~~
106
107
108### `pwutil.hs`
109
110is, in a [xmonad](http://xmonad.org) kind of way, the configuration file—the shipped default is reproduced below as a template for custom configs.
111
112~~~ {#pwutil.hs .haskell .numberLines}
113import PWUtil
114
115import System.FilePath ((</>))
116import System.Directory (getHomeDirectory)
117
118main :: IO ()
119main = do
120 h <- getHomeDirectory
121 runPW (emptyConfig { backstore = plain (h </> "accounts.yaml") }) pwutil
122~~~