classify 2012.10.22 → 2012.10.23
raw patch · 5 files changed
+74/−6 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.Classify.DataTypes: DateVersion :: Int -> Int -> Int -> Version
- Data.Classify.DataTypes: Function :: Char -> (Int -> String) -> MarkupLayout
- Data.Classify.DataTypes: Literate :: Char -> MarkupStyle
- Data.Classify.DataTypes: Numeric :: Char -> Int -> MarkupStyle
- Data.Classify.DataTypes: Replace :: Char -> String -> MarkupLayout
- Data.Classify.DataTypes: Series :: Name -> Version -> Title -> LastName -> Int -> Element
- Data.Classify.DataTypes: Symbol :: Char -> MarkupStyle
- Data.Classify.DataTypes: Version :: Int -> Int -> Version
- Data.Classify.DataTypes: data Element
- Data.Classify.DataTypes: data MarkupLayout
- Data.Classify.DataTypes: data MarkupStyle
- Data.Classify.DataTypes: data Version
- Data.Classify.DataTypes: day :: Version -> Int
- Data.Classify.DataTypes: episode :: Version -> Int
- Data.Classify.DataTypes: instance Eq Element
- Data.Classify.DataTypes: instance Eq MarkupStyle
- Data.Classify.DataTypes: instance Eq Version
- Data.Classify.DataTypes: instance Ord Version
- Data.Classify.DataTypes: instance Read Element
- Data.Classify.DataTypes: instance Read Version
- Data.Classify.DataTypes: instance Show Element
- Data.Classify.DataTypes: instance Show Version
- Data.Classify.DataTypes: instance Typeable Element
- Data.Classify.DataTypes: lastname :: Element -> LastName
- Data.Classify.DataTypes: month :: Version -> Int
- Data.Classify.DataTypes: name :: Element -> Name
- Data.Classify.DataTypes: score :: Element -> Int
- Data.Classify.DataTypes: season :: Version -> Int
- Data.Classify.DataTypes: title :: Element -> Title
- Data.Classify.DataTypes: type LastName = Name
- Data.Classify.DataTypes: type Name = String
- Data.Classify.DataTypes: type Title = String
- Data.Classify.DataTypes: version :: Element -> Version
- Data.Classify.DataTypes: year :: Version -> Int
- Data.Classify.Parser: anyChar :: ReadP Char
- Data.Classify.Parser: digit :: ReadP Char
- Data.Classify.Parser: generateMarkup :: String -> [MarkupStyle]
- Data.Classify.Parser: getDigits :: Read b => t -> ReadP b
- Data.Classify.Parser: knownExtensions :: Set [Char]
- Data.Classify.Parser: makeVersion :: String -> String -> Version
- Data.Classify.Parser: mkDate :: MonadPlus m => Int -> Int -> Int -> t -> m (Version, t)
- Data.Classify.Parser: oneOf :: String -> ReadP Char
- Data.Classify.Parser: parseDateVersion :: ReadP (Version, Int)
- Data.Classify.Parser: parseElement :: Map [Char] Name -> ReadP Element
- Data.Classify.Parser: parseMarkup :: ReadP [MarkupStyle]
- Data.Classify.Parser: parseMarkupElement :: ReadP MarkupStyle
- Data.Classify.Parser: parseSeries :: Map [Char] Name -> ReadP Element
- Data.Classify.Parser: parseVersion :: ReadP (Version, Int)
- Data.Classify.Parser: parseYear :: ReadP (Int, Int)
- Data.Classify.Parser: putback :: ReadP a -> ReadP a
- Data.Classify.Parser: removeGarbage :: [Char] -> [Char]
- Data.Classify.Parser: run :: Eq a => ReadP a -> [Char] -> [a]
- Data.Classify.Parser: separator :: ReadP ()
- Data.Classify.Parser: trim :: [Char] -> [Char]
- Data.Classify.Parser: trunc :: [Char] -> [Char]
- Data.Classify.Printer: applyMarkup :: [MarkupStyle] -> [MarkupLayout] -> String
- Data.Classify.Printer: ppElement :: String -> Element -> String
- Data.Classify.Rank: selectBest :: [Element] -> Element
- Data.Classify.Rank: sortByRank :: [Element] -> [Element]
- Data.Classify.Rank: sortByRank' :: [Element] -> [(Element, Int)]
+ Data.Classify.Television: DateVersion :: Int -> Int -> Int -> Version
+ Data.Classify.Television: Version :: Int -> Int -> Version
+ Data.Classify.Television: classify :: [Name] -> String -> (Name, Version, Title)
+ Data.Classify.Television: data Version
+ Data.Classify.Television: day :: Version -> Int
+ Data.Classify.Television: episode :: Version -> Int
+ Data.Classify.Television: month :: Version -> Int
+ Data.Classify.Television: season :: Version -> Int
+ Data.Classify.Television: tryClassify :: [Name] -> String -> Maybe (Name, Version, Title)
+ Data.Classify.Television: type Name = String
+ Data.Classify.Television: type Title = String
+ Data.Classify.Television: year :: Version -> Int
Files
- classify.cabal +6/−4
- src/Data/Classify/DataTypes.hs +1/−1
- src/Data/Classify/Parser.hs +1/−1
- src/Data/Classify/Rank.hs +2/−0
- src/Data/Classify/Television.hs +64/−0
classify.cabal view
@@ -1,6 +1,6 @@ Cabal-version: >=1.6 Name: classify-Version: 2012.10.22+Version: 2012.10.23 Build-Type: Simple License: PublicDomain License-File: LICENSE@@ -13,9 +13,11 @@ Build-Depends: base >= 4 && <= 5, mtl, containers HS-Source-Dirs: src Exposed-Modules:- Data.Classify.DataTypes,- Data.Classify.Rank,- Data.Classify.Parser,+ Data.Classify.Television+ Other-Modules:+ Data.Classify.DataTypes+ Data.Classify.Rank+ Data.Classify.Parser Data.Classify.Printer Source-repository head type: darcs
src/Data/Classify/DataTypes.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE DeriveDataTypeable #-} module Data.Classify.DataTypes where import Data.Typeable
src/Data/Classify/Parser.hs view
@@ -59,7 +59,7 @@ , do string (drop 2 (show year)) return (year, 0) ]- | year <- [2001..2015]] -- Try years from 2001 to 2015+ | year <- [2000..2015]] -- Try years from 2000 to 2015 getDigits n = do ds <- many1 digit
src/Data/Classify/Rank.hs view
@@ -93,6 +93,8 @@ , ("the.colbert.report.9.19.07.dsr.xvid.iht.[VTV].avi", colbert, DateVersion 2007 9 19) , ("the.daily.show.9.19.07.dsr.xvid.iht.[VTV].avi", daily, DateVersion 2007 9 19) , ("Saturday Night Live S38E05 Bruno Mars PROPER HDTV x264-BAJSKORV", "Saturday Night Live", Version 38 5)+ , ("Conan 2010 11 08 Seth Rogen HDTV XviD-FQM", "Conan", DateVersion 2010 11 08)+ , ("Conan 2000 11 08 Seth Rogen HDTV XviD-FQM", "Conan", DateVersion 2000 11 08) , ("Time.Warp.S01E02.HDTV.XviD-GNARLY.avi", "Time Warp", Version 1 2) , ("True.Blood.S01E07.720p.HDTV.x264-2HD.mkv", "True Blood", Version 1 7)
+ src/Data/Classify/Television.hs view
@@ -0,0 +1,64 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.Classify.Television+-- Copyright : PublicDomain+--+-- Maintainer : lemmih@gmail.com+-- Portability : portable+--+-- This module defines a parser for television media files commonly found in+-- filesharing communities. The internals of the parser are non-deterministic+-- and heuristics are used to select the interpretation most likely to be correct.+--+module Data.Classify.Television+ ( -- * Types+ Name,+ Version(..),+ Title,+ -- * Classify+ tryClassify,+ classify+ ) where++import Data.Classify.DataTypes ( Element(..), Name, Version(..), Title )+import Data.Classify.Parser ( run, parseElement )+import Data.Classify.Rank ( sortByRank )++import qualified Data.Map as Map+import Data.Char ( isAlphaNum, isSpace, toLower )+import Data.List ( inits, tails, isPrefixOf )++tryClassify :: [Name] -> String -> Maybe (Name, Version, Title)+tryClassify knownNames inp =+ case sortByRank possibleParses of+ [] -> Nothing+ sorted ->+ let elt = last sorted+ in Just (name elt, version elt, title elt)+ where+ idx = Map.fromList [ (src, name) | name <- knownNames, src <- stripName name ]+ possibleParses = run (parseElement idx) inp++classify :: [Name] -> String -> (Name, Version, Title)+classify knownNames inp =+ case tryClassify knownNames inp of+ Nothing -> error $ "Data.Classify.Television.classify: Failed to parse: " ++ show inp+ Just result -> result++stripName :: String -> [String]+stripName = worker . filter isAlphaNum . filter (not . isSpace) . map toLower+ where+ alts = [ ("the", "")+ , ("newyork", "ny")+ , ("los angeles", "la") ]+ doesMatch key [] = Nothing+ doesMatch key (x:xs)+ | fst x `isPrefixOf` key = Just x+ | otherwise = doesMatch key xs+ expand lst = lst : concatMap expand [ before ++ new ++ drop (length old) after+ | (before, after) <- split lst+ , Just (old, new) <- [doesMatch after alts] ]+ worker lst = expand lst++split :: String -> [(String,String)]+split str = zip (inits str) (tails str)