bitly-cli (empty) → 0.1
raw patch · 4 files changed
+152/−0 lines, 4 filesdep +Bitlydep +basedep +directorysetup-changed
Dependencies added: Bitly, base, directory, filepath, regexpr
Files
- LICENSE +25/−0
- Setup.lhs +3/−0
- bitly-cli.cabal +41/−0
- bitly.hs +83/−0
+ LICENSE view
@@ -0,0 +1,25 @@+Copyright (c) 2009-2011, Sergey Astanin+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.+ * Neither the name of the Sergey Astanin nor the names of other+ contributors may be used to endorse or promote products derived from this+ software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ bitly-cli.cabal view
@@ -0,0 +1,41 @@+Name: bitly-cli+Version: 0.1+Cabal-version: >= 1.2+Build-type: Simple++Stability: experimental+Category: Web, Utils+License: BSD3+License-file: LICENSE+Maintainer: Sergey Astanin <s.astanin@gmail.com>+Homepage: http://bitbucket.org/jetxee/hs-bitly/+Bug-reports: http://bitbucket.org/jetxee/hs-bitly/issues/++Synopsis: A command line tool to access bit.ly URL shortener.+Description:+ This package provides a command line utility to shorten+ and expand URLs using bit.ly/j.mp service. To use this tool, an API+ key is required. Please find yours at <http://bit.ly/account/>.+ .+ Configuration file (`~/.bitly`) format:+ .+ > login = your_bit.ly_login+ > apikey = your_API_key+ .+ Usage examples:+ .+ > $ echo "Text with an URL: http://example.com/" | bitly+ > Text with an URL: http://bit.ly/2eSq1z+ > $ bitly shorten http://example.com+ > http://bit.ly/2eSq1z+ > $ bitly expand http://bit.ly/2eSq1z+ > http://example.com/++Executable bitly+ Main-is: bitly.hs+ Build-depends:+ Bitly >= 0.0.6+ , base >= 3 && < 5+ , filepath >= 1.1+ , directory >= 1.0 && < 1.1+ , regexpr >= 0.5
+ bitly.hs view
@@ -0,0 +1,83 @@+module Main where++import Network.Bitly++import Control.Applicative ((<$>))+import Data.Char (isSpace)+import Data.Maybe (fromJust, fromMaybe, isJust, isNothing)+import System.Directory (getHomeDirectory)+import System.Environment (getArgs)+import System.Exit (exitFailure, exitSuccess)+import System.FilePath (makeValid, combine)+import System.IO (hPutStrLn, stderr)+import Text.RegexPR++confFileName :: IO String+confFileName = makeValid <$> flip combine ".bitly" <$> getHomeDirectory++readConfig :: IO (Maybe Account)+readConfig = do+ file <- confFileName+ conf <- map (brk '=') . lines <$> readFile file `catch` (\_ -> return "")+ let l = lookup "login" conf+ let k = lookup "apikey" conf+ if isJust l && isJust k+ then return $ Just bitlyAccount { login = fromJust l, apikey = fromJust k }+ else return Nothing++brk d str =+ let (a,b) = break (== d) str+ in (trim a, trim . dropWhile (== d) $ b)++trim = dropWhile isSpace . reverse . dropWhile isSpace . reverse++errorExit s = hPutStrLn stderr s >> exitFailure++modifyUrl :: (String -> IO Result) -> String -> IO String+modifyUrl op url = do+ r <- op url+ case r of+ -- don't replace URL on error+ Left _ -> return url+ Right url' -> return url'++urlRE = "(http|ftp|https)://\\w+(\\.\\w+)+(:[0-9]+)?(/\\S+)?/?"++passThrough :: (String -> IO Result) -> String -> IO String+passThrough op txt =+ let m = matchRegexPR urlRE txt+ in case m of+ Nothing -> return txt+ Just ((url,(b,a)),_) -> do+ url' <- modifyUrl op url+ return . ((b ++ url') ++) =<< passThrough op a++-- process all given urls or read stdin and pass it through+runOp :: (String -> IO Result) -> [String] -> IO ()+runOp op [] = putStr =<< passThrough op =<< getContents+runOp op urls = mapM_ putStrLn =<< mapM (modifyUrl op) urls++usage = "Usage: bitly [ help | [shorten] [url ...] | expand [url ...] ]\n\n\+\If no url is given, bitly acts as a filter and replaces all found URLs.\n\+\Bitly shortens URLs by default.\n\n\+\Configuration file format (~/.bitly):\n\+\ login = your_bit.ly_login\n\+\ apikey = your_API_key"++main = do+ args <- getArgs+ if "help" `elem` args || "--help" `elem` args+ then putStrLn usage >> exitSuccess+ else do++ conf <- readConfig+ case conf of+ Nothing -> do+ f <- confFileName+ errorExit $ "Configuration file is incomplete or not found (" ++ f ++ ")"+ Just acc ->+ case args of+ ("expand":urls) -> runOp (expand acc) urls+ ("shorten":urls) -> runOp (shorten acc) urls+ _ -> runOp (shorten acc) args -- shorten by default+