follow alternatives and similar packages
Based on the "Web" category.
Alternatively, view follow alternatives based on common mentions on social networks and blogs.
-
swagger-petstore
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition. -
servant
Main repository for the servant libraries — DSL for describing, serving, querying, mocking, documenting web applications and more! -
haskell-bitmex-rest
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition. -
neuron
Future-proof note-taking and publishing based on Zettelkasten (superseded by Emanote: https://github.com/srid/emanote) -
tagsoup
Haskell library for parsing and extracting information from (possibly malformed) HTML/XML documents -
keera-hails-reactive-htmldom
Keera Hails: Haskell on Rails - Reactive Programming Framework for Interactive Haskell applications -
ghcjs-dom
Make Document Object Model (DOM) apps that run in any browser and natively using WebKitGtk -
ghcjs-base
base library for GHCJS for JavaScript interaction and marshalling, used by higher level libraries like JSC
InfluxDB - Power Real-Time Data Analytics at Scale
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of follow or a related project?
README
Follow
Follow
is a Haskell library to build recipes which allow you to
follow the content published about any subject you are interested.
Here bellow you have a quick tutorial you can follow. Just run the snippets of code in the repl.
:set -XOverloadedStrings
import Follow
import Data.Time (LocalTime)
import qualified Data.Text.IO as T (writeFile)
import Data.Yaml (decodeFileThrough)
Subject
A subject is just a bunch of information about what is being followed. It consists of a title, a description and a list of tags,
haskell =
Subject
{ sTitle = "Haskell"
, sDescription = "Some resources about Haskell"
, sTags = ["haskell", "programming"]
}
Directory
A directory is just a subject and a list of entries.
An entry is an item meant to contain an URI with content relative to the associated subject along with associated information.
manualDirectory =
Directory
{ dSubject = haskell
, dEntries =
[ Entry
{ eURI =
Just "https://bartoszmilewski.com/2013/06/19/basics-of-haskell/"
, eGUID = Just "basics-of-haskell"
, eTitle = Just "Basics of Haskell"
, eDescription = Just "Introductory material for Haskell"
, eAuthor = Just "Bartosz Milewski"
, ePublishDate = Just (read "2013-06-19 14:14:00" :: LocalTime)
}
]
}
Fetchers
Of course, building list of entries by hand is not very useful. Fetchers are functions which usually reach the outside world to return a list of entries and which can throw an error.
Any fetcher can be used, but Follow
tries to ship with common
ones. Right now there are two fetchers available:
- [Feed](src/Follow/Fetchers/Feed.hs): Take entries from a RSS or Atom feed.
- [Web Scraping](src/Follow/Fetchers/WebScraping.hs): Take entries scraping the HTML of a web page.
The function directoryFromFetched
can be used to glue a subject with
some fetched content:
import qualified Follow.Fetchers.Feed as Feed
directory =
directoryFromFetched (Feed.fetch "https://bartoszmilewski.com/feed/") haskell
Middlewares
Fetched content may need some further processing in order to fit what is actually desired. A middleware is a function which transforms a directory into another directory, allowing us to do any kind of transformation.
The aim of Follow
is to provide some common middlewares. For now,
there are these ones:
- [Filter](src/Follow/Middlewares/Filter.hs): Filter entries according some predicate.
- [Sort](src/Follow/Middlewares/Sort.hs): Sort entries.
- [Decode](src/Follow/Middlewares/Decode.hs): Decodes entries from UTF8 or other encodings.
import qualified Follow.Middlewares.Sort as Sort
sortedDirectory =
Sort.apply (Sort.byGetter eTitle) <$> directory
Digesters
Once you have your distillate content, you need some way to consume
it. A Digester
is a function which transforms a directory into
anything that can be consumed by an end user.
As before, Follow
aims to provide useful ones out of the box. Right
now the following are available:
- [Simple Text](src/Follow/Digesters/SimpleText.hs): Simple textual representation of the directory.
- [Pocket](src/Follow/Digesters/Pocket.hs): Send fetched links to Pocket.
import qualified Follow.Digesters.SimpleText as SimpleText
content = SimpleText.digest <$> sortedDirectory
Now, for example, you are ready to save the content to a file:
content >>= T.writeFile "/your/path/haskell.txt"
Recipes: Combining sources and middlewares
Content is not limited to be fetched from a single source. Instead, a directory can be built merging the entries fetched from different sources. Also, the stack of middlewares to be applied to each source can be given in a single shot.
This whole process specification is called a Recipe
, and it contains
all the information needed to follow a subject.
To build the recipe you need to provide three fields:
- The subject being followed.
- A list of two field tuples where:
- First field is some fetched content.
- Second field is a list of middlewares to apply to the fetched content in the first field.
- A list of middlewares to apply to the directory resulted after applying the list of fetched/middlewares.
haskellRecipe =
Recipe
{ rSubject = haskell
, rSteps =
[ ( Feed.fetch "https://bartoszmilewski.com/feed/"
, [Sort.apply (Sort.byGetter eTitle)])
, (Feed.fetch "https://planet.haskell.org/rss20.xml", [])
]
, rMiddlewares = []
}
You can combine the function directoryFromRecipe
and some digester
to quickly consume a recipe:
SimpleText.digest <$> directoryFromRecipe haskellRecipe
Collecting recipes
One nice thing in Follow is that you don't need to create the recipes programmatically each time you need them. Instead, you can store them in a YAML file and just parse them when you need.
For example, the previous recipe can be represented in a file
recipe.yml
as the following:
subject:
title: Haskell
description: Some resources about Haskell
tags: [haskell, programming]
steps:
-
- type: feed
options:
url: "https://bartoszmilewski.com/feed/"
-
- type: sort
options:
function:
type: by_field
options:
field: title
middlewares: []
You can use now decode functions in
Data.Yaml
to get the
recipe back:
recipe' <- decodeFileThrow "/your/path/recipe.yml" :: IO (Recipe IO)
directory' = directoryFromRecipe recipe'
Look at [src/Follow/Parser.hs
](src/Follow/Parser.hs) for details about
encoding each kind of fetcher and middleware.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/waiting-for-dev/follow. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The package is available as open source under the terms of the GNU LGPLv3 License.
*Note that all licence references and agreements mentioned in the follow README section above
are relevant to that project's source code only.