nikepub 1.0 → 1.1
raw patch · 4 files changed
+79/−29 lines, 4 filesdep +filepathdep +jsondep +regex-posix
Dependencies added: filepath, json, regex-posix
Files
- README +7/−0
- nikepub.cabal +4/−1
- nikepub.hs +65/−27
- templates/mt_body.st +3/−1
README view
@@ -44,6 +44,8 @@ The distribution package contains an example template directory. It can be used directly or customized. The example template files have all the supported $fields$ in them. All three files must be present in a template directory. You might want to copy the template directory into a more convenient place.+Templates can contain special comments with JSON strings configuring the desired chart size +(more configuration properties to follow in later versions). Your Nike+ profile is assumed to be public. nikepub doesn't work with non-public profiles (if you publish your runs with nikepub you might as well have your profile public). Your Nike+ id is an integer. The simplest way@@ -53,6 +55,11 @@ The --message flag on the nikepub commandline lets you append an arbitrary message to the body of the generated blog entry.++If the --draft flag is present then the blog entry is not published but sent as a draft to the blogging system.++The flag --airport allows for the specification of an airport code. It is used to fetch the weather conditions+during the run. nikepub must be executed within 90 minutes of the run start time for it to fetch the weather. BUGS, SUGGESTIONS, COMMENTS
nikepub.cabal view
@@ -1,5 +1,5 @@ Name: nikepub-Version: 1.0+Version: 1.1 Category: Web Synopsis: Command line utility publishes Nike+ runs on blogs and Twitter Description: Simple commandline program that given a Nike+ user id will fetch the@@ -23,14 +23,17 @@ base >= 4.1.0.0 && < 5, containers >= 0.2.0.1, regex-compat >= 0.71.0.1,+ regex-posix >= 0.72.0.3, old-time >= 1.0.0.2, old-locale >= 1.0.0.1, time >= 1.1.3, syb >= 0.1.0.1, network >= 2.2.1,+ filepath >= 1.1.0.2, HTTP >= 4000.0.6, GoogleChart >= 0.2, haxr >= 3000.2.1, hxt >= 8.3.0,+ json >= 0.4.3, hs-twitter >= 0.2.8, HStringTemplate >= 0.5.1.2
nikepub.hs view
@@ -1,13 +1,30 @@+--------------------------------------------------------------------+-- |+-- Module : Main+-- Copyright : (c) Uwe Hoffmann 2009+-- License : LGPL+--+-- Maintainer: Uwe Hoffmann <uwe@codemanic.com>+-- Stability : provisional+-- Portability: portable+--+-- Main module for nikepub executable.+--+--------------------------------------------------------------------+ module Main (main) where import Codemanic.NikeRuns import Codemanic.Blogging+import Codemanic.Weather import System.Console.GetOpt import System import IO import Control.Monad import Data.Maybe+import Data.Time.Clock+import Data.Time.Calendar import Web.Twitter.Fetch import Web.Twitter.Monad import System.Environment@@ -15,28 +32,30 @@ data Options = Options { nikeId :: Int, templateDir :: String,- chartWidth :: Int,- chartHeight :: Int, mtUser :: Maybe String, mtPassword :: Maybe FilePath, mtUrl :: Maybe String,+ mtBlogId :: Int, twitterUser :: Maybe String, twitterPassword :: Maybe FilePath,- message :: Maybe String+ message :: Maybe String,+ airport :: Maybe String,+ draft :: Bool } deriving (Eq, Show) defaultOptions :: Options defaultOptions = Options { nikeId = 0, templateDir = "",- chartWidth = 600,- chartHeight = 200, mtUser = Nothing, mtPassword = Nothing, mtUrl = Nothing,+ mtBlogId = 1, twitterUser = Nothing, twitterPassword = Nothing,- message = Nothing+ message = Nothing,+ airport = Nothing,+ Main.draft = False } options :: [ OptDescr (Options -> IO Options) ]@@ -71,6 +90,12 @@ "STRING") "mt url" + , Option "" ["mtBlogId"]+ (ReqArg+ (\arg opt -> return opt { mtBlogId = (read arg) })+ "INT")+ "mt blog id"+ , Option "" ["twitterUser"] (ReqArg (\arg opt -> return opt { twitterUser = Just arg })@@ -89,22 +114,22 @@ "STRING") "message" - , Option [] ["chartWidth"]- (ReqArg- (\arg opt -> return opt { chartWidth = read arg })- "INT")- "chart width"+ , Option "" ["draft"]+ (NoArg+ (\opt -> return opt { Main.draft = True }))+ "Send as draft to blog" - , Option [] ["chartHeight"]+ , Option "" ["airport"] (ReqArg- (\arg opt -> return opt { chartHeight = read arg })- "INT")- "chart height"+ (\arg opt -> return opt { airport = Just arg })+ "STRING")+ "airport code of most nearest airport to fetch weather at run time, \+ \current weather is fetched iff nikepub is executed within 30 min of run end time" , Option "v" ["version"] (NoArg (\_ -> do- hPutStrLn stderr "Version 1.00"+ hPutStrLn stderr "Version 1.1" exitWith ExitSuccess)) "Print version" @@ -124,13 +149,24 @@ (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options)) where header = "Usage: nikepub [OPTION...]" +getWeather :: NikeRun -> Options -> IO (Maybe Weather)+getWeather nr opts = do+ case (airport opts) of+ Just airportCode -> do+ currentTime <- getCurrentTime+ let runStartTime = (startTime nr)+ if (((utctDay currentTime) == (utctDay runStartTime)) &&+ ((utctDayTime currentTime) < ((utctDayTime runStartTime) + (secondsToDiffTime 5400))))+ then (getCurrentWeather airportCode) else (return Nothing)+ Nothing -> return Nothing+ tweet :: NikeRun -> Options -> IO () tweet nr opts = do- let cw = chartWidth opts- let ch = chartHeight opts- case (twitterUser opts) of- Just twu -> do- twitterMsg <- renderNikeRun cw ch (templateDir opts) "twitter_status" nr ""+ case ((twitterUser opts), (Main.draft opts)) of+ (Just twu, False) -> do+ let msg = fromMaybe "" (message opts)+ wtr <- getWeather nr opts+ twitterMsg <- renderNikeRun (templateDir opts) "twitter_status" nr msg wtr twitterPswd <- readFile (fromJust $ twitterPassword opts) putStrLn $ "tweeting update " ++ twitterMsg runTM (AuthUser twu twitterPswd)@@ -138,27 +174,29 @@ $ restCall "update.json" (arg "status" twitterMsg []) putStrLn "done tweeting" return ()- Nothing -> return ()+ (Nothing, _) -> return ()+ (_, True) -> return () blog :: NikeRun -> Options -> IO () blog nr opts = do- let cw = chartWidth opts- let ch = chartHeight opts case (mtUrl opts) of Just u -> do- mtTitle <- renderNikeRun cw ch (templateDir opts) "mt_title" nr ""- mtBody <- renderNikeRun cw ch (templateDir opts) "mt_body" nr (fromMaybe "" (message opts))+ let msg = fromMaybe "" (message opts)+ wtr <- getWeather nr opts+ mtTitle <- renderNikeRun (templateDir opts) "mt_title" nr msg wtr+ mtBody <- renderNikeRun (templateDir opts) "mt_body" nr msg wtr mtPswd <- readFile (fromJust $ mtPassword opts) let blogEntry = BlogEntry { title = mtTitle, body = mtBody, keywords = ["running"],+ Codemanic.Blogging.draft = (Main.draft opts), publishTime = (startTime nr) } let blog = Blog { url = u, user = (fromJust $ mtUser opts), password = mtPswd, - blogId = 1}+ blogId = (mtBlogId opts)} publish blog blogEntry Nothing -> return ()
templates/mt_body.st view
@@ -1,6 +1,8 @@ <a href="http://nikeplus.nike.com/nikeplus/v1/services/widget/get_public_run.jsp?id=$runId$&userID=$userId$">run</a> $startTime$, $distance$ km, $duration$ min, $calories$ calories, $pace$ min/km avg pace -<img src="$chart$">+<img src="$chart$$!chartOptions{"width":600, "height":200}!$">++$weather$ $message$