packages feed

flickr 0.3.2 → 0.3.3

raw patch · 13 files changed

+350/−32 lines, 13 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Flickr.Types: type PlaceType = String
+ Flickr.Monad: fm_include_props :: FMEnv -> Maybe [String]
+ Flickr.Monad: onlyTheseProperties :: [String] -> FM a -> FM a
+ Flickr.Photos: s_is_commons :: SearchConstraints -> Maybe Bool
+ Flickr.Photos.Geo: batchCorrectLocation :: GeoLocation -> Either PlaceID WhereOnEarthID -> FM ()
+ Flickr.Photos.Geo: correctLocation :: PhotoID -> Either PlaceID WhereOnEarthID -> FM ()
+ Flickr.Photos.Geo: photosForLocation :: GeoLocation -> [PhotoInfo] -> FM (PhotoContext, [Photo])
+ Flickr.Photos.Geo: setContext :: PhotoID -> ContextID -> FM ()
+ Flickr.Places: getPlaceTypes :: FM [PlaceType]
+ Flickr.Places: placesForBoundingBox :: BoundingBox -> Maybe PlaceTypeName -> Maybe PlaceTypeId -> FM [Place]
+ Flickr.Places: placesForContacts :: Either PlaceTypeName WhereOnEarthID -> Maybe PlaceTypeId -> Maybe Threshold -> Maybe String -> FM [Place]
+ Flickr.Places: placesForTags :: Either PlaceTypeName WhereOnEarthID -> Maybe PlaceID -> Maybe Threshold -> Maybe [Tag] -> Maybe TagMode -> Maybe [MachineTag] -> Maybe TagMode -> DateDetails -> FM [Place]
+ Flickr.Places: tagsForPlace :: Either PlaceID WhereOnEarthID -> DateDetails -> FM [TagInfo]
+ Flickr.Types: DateDetails :: Maybe DateString -> Maybe DateString -> Maybe DateString -> Maybe DateString -> DateDetails
+ Flickr.Types: PlaceType :: PlaceTypeId -> PlaceTypeName -> PlaceType
+ Flickr.Types: TagInfo :: String -> Maybe Int -> TagInfo
+ Flickr.Types: data DateDetails
+ Flickr.Types: data PlaceType
+ Flickr.Types: data TagInfo
+ Flickr.Types: dateMaxTaken :: DateDetails -> Maybe DateString
+ Flickr.Types: dateMaxUpload :: DateDetails -> Maybe DateString
+ Flickr.Types: dateMinTaken :: DateDetails -> Maybe DateString
+ Flickr.Types: dateMinUpload :: DateDetails -> Maybe DateString
+ Flickr.Types: nullDateDetails :: DateDetails
+ Flickr.Types: nullTagInfo :: TagInfo
+ Flickr.Types: placeTypeId :: PlaceType -> PlaceTypeId
+ Flickr.Types: placeTypeName :: PlaceType -> PlaceTypeName
+ Flickr.Types: tagCount :: TagInfo -> Maybe Int
+ Flickr.Types: tagName :: TagInfo -> String
+ Flickr.Types: type ContextID = Integer
+ Flickr.Types: type PlaceTypeId = String
+ Flickr.Types: type PlaceTypeName = String
+ Flickr.Types: type TagMode = String
+ Flickr.Types.Import: eltPlaceType :: Element -> Maybe PlaceType
+ Flickr.Types.Import: eltPlaceTypeList :: Element -> Maybe [PlaceType]
+ Flickr.Types.Import: eltTagInfo :: Element -> Maybe TagInfo
+ Flickr.Types.Import: eltTagInfoList :: Element -> Maybe [TagInfo]
+ Flickr.Types.Import: toPlaceTypes :: String -> ErrM [PlaceType]
+ Flickr.Types.Import: toTagInfoList :: String -> ErrM [TagInfo]
- Flickr.Favorites: getList :: Maybe UserID -> [PhotoInfo] -> FM (PhotoContext, [Photo])
+ Flickr.Favorites: getList :: Maybe UserID -> [PhotoInfo] -> DateDetails -> FM (PhotoContext, [Photo])
- Flickr.Favorites: getPublicList :: UserID -> [PhotoInfo] -> FM (PhotoContext, [Photo])
+ Flickr.Favorites: getPublicList :: UserID -> [PhotoInfo] -> DateDetails -> FM (PhotoContext, [Photo])
- Flickr.Monad: FMEnv :: APIKey -> Bool -> Bool -> Maybe Int -> Maybe Int -> Bool -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> FMEnv
+ Flickr.Monad: FMEnv :: APIKey -> Bool -> Bool -> Maybe Int -> Maybe Int -> Bool -> Maybe [String] -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> FMEnv
- Flickr.Monad: flickFromException :: (Exception e) => SomeException -> Maybe e
+ Flickr.Monad: flickFromException :: Exception e => SomeException -> Maybe e
- Flickr.Monad: flickToException :: (Exception e) => e -> SomeException
+ Flickr.Monad: flickToException :: Exception e => e -> SomeException
- Flickr.Photos: SearchConstraints :: [Tag] -> Maybe Bool -> Maybe String -> Maybe DateInterval -> Maybe DateInterval -> Maybe [LicenseID] -> Maybe SortKey -> Maybe Privacy -> Maybe BoundingBox -> Maybe Accuracy -> Maybe Safety -> Maybe ContentType -> [Tag] -> Maybe Bool -> Maybe GroupID -> Maybe Bool -> Maybe WhereOnEarthID -> Maybe PlaceID -> Maybe MediaType -> Maybe Bool -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe String -> SearchConstraints
+ Flickr.Photos: SearchConstraints :: [Tag] -> Maybe Bool -> Maybe String -> Maybe DateInterval -> Maybe DateInterval -> Maybe [LicenseID] -> Maybe SortKey -> Maybe Privacy -> Maybe BoundingBox -> Maybe Accuracy -> Maybe Safety -> Maybe ContentType -> [Tag] -> Maybe Bool -> Maybe GroupID -> Maybe Bool -> Maybe WhereOnEarthID -> Maybe PlaceID -> Maybe MediaType -> Maybe Bool -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe String -> Maybe Bool -> SearchConstraints
- Flickr.Photos.Comments: getList :: PhotoID -> FM [Comment]
+ Flickr.Photos.Comments: getList :: PhotoID -> DateDetails -> FM [Comment]
- Flickr.Places: placesForUser :: PlaceType -> Maybe WhereOnEarthID -> Maybe PlaceID -> Maybe Threshold -> FM [Place]
+ Flickr.Places: placesForUser :: Either PlaceID WhereOnEarthID -> Either PlaceTypeName PlaceTypeId -> Maybe Threshold -> DateDetails -> FM [Place]
- Flickr.Types: LocationPlace :: PlaceID -> WhereOnEarthID -> Latitude -> Longitude -> URLString -> PlaceType -> [LocationPlace] -> String -> LocationPlace
+ Flickr.Types: LocationPlace :: PlaceID -> WhereOnEarthID -> Latitude -> Longitude -> URLString -> PlaceTypeName -> [LocationPlace] -> String -> LocationPlace
- Flickr.Types: Place :: PlaceID -> WhereOnEarthID -> Decimal -> Decimal -> URLString -> PlaceType -> String -> Place
+ Flickr.Types: Place :: PlaceID -> WhereOnEarthID -> Decimal -> Decimal -> URLString -> PlaceTypeName -> String -> Place
- Flickr.Types: locationPlaceType :: LocationPlace -> PlaceType
+ Flickr.Types: locationPlaceType :: LocationPlace -> PlaceTypeName
- Flickr.Types: placeType :: Place -> PlaceType
+ Flickr.Types: placeType :: Place -> PlaceTypeName
- Flickr.Types: type GeoLocation = (Latitude, Longitude, Accuracy)
+ Flickr.Types: type GeoLocation = (Latitude, Longitude, Maybe Accuracy)
- Flickr.Utils: readMb :: (Read a) => String -> Maybe a
+ Flickr.Utils: readMb :: Read a => String -> Maybe a

Files

Flickr/Favorites.hs view
@@ -11,7 +11,13 @@ -- -- flickr.favorites API, managing a user's favorite photos. ---------------------------------------------------------------------module Flickr.Favorites where+module Flickr.Favorites +       ( add            -- :: PhotoID -> FM ()+       , remove         -- :: PhotoID -> FM ()+       +       , getList        -- :: Maybe UserID -> [PhotoInfo] -> DateDetails -> FM (PhotoContext, [Photo])+       , getPublicList  -- :: UserID -> [PhotoInfo] -> DateDetails -> FM (PhotoContext, [Photo])+       ) where  import Flickr.Monad import Flickr.Types@@ -33,20 +39,27 @@ -- Only photos which the calling user has permission to see are returned. getList :: Maybe UserID         -> [PhotoInfo]+	-> DateDetails 	-> FM (PhotoContext, [Photo])-getList uid ps = withReadPerm $+getList uid ps mbDates = withReadPerm $   flickTranslate toPhotoList $    flickrCall "flickr.favorites.getList"               (mbArg "user_id" uid $+               mbArg "min_fave_date" (dateMinTaken mbDates) $+	       mbArg "max_fave_date" (dateMaxTaken mbDates) $ 	        lsArg "extras" (map show ps) []) 	 -- | Returns a list of favorite public photos for the given user. getPublicList :: UserID               -> [PhotoInfo]+	      -> DateDetails               -> FM (PhotoContext, [Photo])-getPublicList uid ps = +getPublicList uid ps mbDates =    flickTranslate toPhotoList $     flickrCall "flickr.favorites.getPublicList"-             (lsArg "extras" (map show ps) [("user_id", uid)])+             (mbArg "min_fave_date" (dateMinTaken mbDates) $+	      mbArg "max_fave_date" (dateMaxTaken mbDates) $+	      lsArg "extras" (map show ps) $+	        [("user_id", uid)])  	
Flickr/MachineTags.hs view
@@ -17,6 +17,8 @@ import Flickr.Types
 import Flickr.Types.Import
 
+import Control.Monad
+
 -- | Return a list of unique namespaces, optionally limited by a given predicate, in alphabetical order.
 getNamespaces :: Maybe String -- ^ optional predicate
               -> FM (NameContext, [Namespace])
@@ -45,7 +47,7 @@ 
 -- | Return a list of unique values for a namespace and predicate.
 getValues :: String -> String -> FM (ResContext MachineTag, [MachineTag])
-getValues ns pre = 
+getValues ns pre = liftM (\ (x,xs) -> (x, map (\ p -> p{mTagPredicate=pre,mTagNamespace=ns}) xs)) $
    flickTranslate toMachineTagList $
      flickrCall "flickr.machinetags.getValues"
                 [ ("namespace", ns)
Flickr/Monad.hs view
@@ -39,6 +39,7 @@     , fm_per_page        :: Maybe Int
     , fm_page            :: Maybe Int
     , fm_is_paged        :: Bool
+    , fm_include_props   :: Maybe [String] -- Just ls => when applicable, only return properties in 'ls'.
     , fm_perm_level      :: Maybe String
     , fm_auth_token      :: Maybe String
     , fm_auth_mini_token :: Maybe String
@@ -73,6 +74,7 @@       , fm_page            = Nothing
       , fm_perm_level      = Nothing
       , fm_is_paged        = False
+      , fm_include_props   = Nothing
       , fm_auth_token      = Nothing
       , fm_auth_mini_token = Nothing
       , fm_api_base        = Nothing
@@ -102,6 +104,9 @@ withPageSize :: Int -> FM a -> FM a
 withPageSize sz (FM x) = FM (\ env -> x env{fm_is_paged=True,fm_per_page=Just sz})
 
+onlyTheseProperties :: [String] -> FM a -> FM a
+onlyTheseProperties ps (FM x) = FM (\ env -> x env{fm_include_props=Just ps})
+
 pagedCall :: Maybe Int -> FM a -> FM a
 pagedCall mbPg (FM x) = FM (\ env -> x env{fm_is_paged=True,fm_page=mbPg})
 
@@ -179,6 +184,11 @@      mb x (Just v) = [(x,show v)]
      
      pgContext = fm_is_paged env
+     
+     includeProps ls = 
+       maybe ls
+             (\ x -> ("include",intercalate "," x):ls)
+	     (fm_include_props env)
 
      pageContext ls
       | not pgContext = ls
@@ -232,7 +242,8 @@ 
 --  print ("XX",args,fm_is_signed env, fm_auth_token env, api_sig_inp)
   restMeth (fromMaybe api_base (fm_api_base env))
-           (pageContext $
+           (includeProps $
+	    pageContext  $
             (withMethod 
               (("api_key", apiKey $ fm_api_key env) : 
 	          isSigned (withAToken $ withPerms args))))
Flickr/Photos.hs view
@@ -301,6 +301,7 @@ 		    mbArg "lon" (s_lon sc) $
 		    mbArg "radius" (s_radius sc) $
 		    mbArg "radius_units" (s_radius_units sc) $
+		    mbArg "is_commons"   (fmap showBool (s_is_commons sc)) $
 		    lsArg "extras" (map show extras) [])
  where
   mbUpload1 = fmap fst (s_upload sc)
@@ -335,6 +336,7 @@      , s_lon          :: Maybe Decimal
      , s_radius       :: Maybe Decimal
      , s_radius_units :: Maybe String
+     , s_is_commons   :: Maybe Bool
      }
 
 nullSearchConstraints :: SearchConstraints
@@ -363,6 +365,7 @@      , s_lon      = Nothing
      , s_radius   = Nothing
      , s_radius_units = Nothing
+     , s_is_commons = Nothing
      }
 
 -- | Set the content type of a photo.
Flickr/Photos/Comments.hs view
@@ -42,12 +42,14 @@ 	       ]  -- | Returns the comments for a photo.-getList :: PhotoID -> FM [Comment]-getList pid = +getList :: PhotoID -> DateDetails -> FM [Comment]+getList pid mbDates =    flickTranslate toCommentList $      flickrCall "flickr.photos.comments.getList"-               [ ("photo_id", pid)-	       ]+               (mbArg "min_comment_date" (dateMinTaken mbDates) $ +	        mbArg "max_comment_date" (dateMaxTaken mbDates) $+	         [ ("photo_id", pid)+	         ])   
Flickr/Photos/Geo.hs view
@@ -11,13 +11,47 @@ -- -- flickr.photos.geo API, setting/getting photo geo location. ---------------------------------------------------------------------module Flickr.Photos.Geo where+module Flickr.Photos.Geo +       ( getLocation          -- :: PhotoID -> FM GeoLocation+       , removeLocation       -- :: PhotoID -> FM ()+       , setLocation          -- :: PhotoID -> GeoLocation -> FM ()+       , batchCorrectLocation -- :: GeoLocation -> Either PlaceID WhereOnEarthID -> FM ()+       , correctLocation      -- :: PhotoID -> Either PlaceID WhereOnEarthID -> FM ()+       , photosForLocation    -- :: GeoLocation -> [PhotoInfo] -> FM [Photo]+       +       , setContext     -- :: PhotoID -> ContextID -> FM () +       , getPerms       -- :: PhotoID -> FM Permissions+       , setPerms       -- :: PhotoID -> Permissions -> FM ()+       +       ) where+ import Flickr.Monad import Flickr.Utils import Flickr.Types import Flickr.Types.Import +-- | Correct the places hierarchy for all the photos for a user at+-- a given latitude, longitude and accuracy. +-- +-- Batch corrections are processed in a delayed queue so it may take+-- a few minutes before the changes are reflected in a user's photos.+batchCorrectLocation :: GeoLocation -> Either PlaceID WhereOnEarthID -> FM ()+batchCorrectLocation (lat,lon,acc) ei = withWritePerm $ postMethod $ +  flickCall_ "flickr.photos.geo.batchCorrectLocation"+             (eiArg "place_id" "woe_id" ei $+	      mbArg "accuracy" (fmap show acc) $+	      [ ("latitude",  lat)+	      , ("longitude", lon)+	      ])++-- | update/correct the location of attached to a photo.+correctLocation :: PhotoID -> Either PlaceID WhereOnEarthID -> FM ()+correctLocation pid ei = withWritePerm $ postMethod $ +  flickCall_ "flickr.photos.geo.correctLocation"+             (eiArg "place_id" "woe_id" ei $+	      [ ("photo_id", pid) ])+ -- | Get the geo data (latitude and longitude and the accuracy level) for a photo. getLocation :: PhotoID -> FM GeoLocation getLocation pid = @@ -32,12 +66,33 @@     flickrCall "flickr.photos.geo.getPerms"                [ ("photo_id", pid) ] +-- | Return a list of photos for a user at a specific latitude, longitude and accuracy+photosForLocation :: GeoLocation -> [PhotoInfo] -> FM (PhotoContext, [Photo])+photosForLocation (lat,lon,acc) extras = withReadPerm $ +  flickTranslate toPhotoList $+    flickrCall "flickr.photo.geo.photosForLocation"+               (mbArg "accuracy" (fmap show acc) $+	        lsArg "extras"   (map show extras) $+		[ ("latitude", lat)+		, ("longitude", lon)+		])+ -- | Removes the geo data associated with a photo. removeLocation :: PhotoID -> FM () removeLocation pid = withWritePerm $ postMethod $     flickCall_ "flickr.photos.geo.removeLocation"                [ ("photo_id", pid) ] +-- | Indicate the state of a photo's geotagginess beyond+-- latitude and longitude. Photos passed to this method must+-- already be geotagged (using the 'setLocation' method).+setContext :: PhotoID -> ContextID -> FM ()+setContext pid ctxtId = withWritePerm $ postMethod $ +   flickCall_ "flickr.photos.geo.setContext"+              [ ("photo_id", pid)+	      , ("context",  show ctxtId)+	      ]+ -- | Sets the geo data (latitude and longitude and, optionally, -- the accuracy level) for a photo. Before users may assign -- location data to a photo they must define who, by default,@@ -48,11 +103,11 @@ setLocation :: PhotoID -> GeoLocation -> FM () setLocation pid (la,lo,ac) = withWritePerm $ postMethod $      flickCall_ "flickr.photos.geo.setLocation"-                 [ ("photo_id", pid)+               (mbArg "accuracy" (fmap show ac) $+	         [ ("photo_id", pid) 	         , ("lat", la) 	         , ("lon", lo)-		 , ("accuracy", show ac)-	         ]+	         ])  -- | Set the permission for who may view the geo data associated with a photo. setPerms :: PhotoID -> Permissions -> FM ()
Flickr/Places.hs view
@@ -11,12 +11,43 @@ -- -- flickr.places API, locating photos by places and geo. ---------------------------------------------------------------------module Flickr.Places where+module Flickr.Places +       ( find                        -- :: String -> FM (PlaceQuery, [Place])+       , findByLatLon                -- :: Latitude -> Longitude -> Maybe Accuracy -> FM (PlaceQuery, [Place)]+       , getChildrenWithPhotosPublic -- :: Either PlaceID WhereOnEarthID -> FM (PlaceQuery, [Place])+       , getInfo              -- :: Either PlaceID WhereOnEarthID -> FM LocationPlace+       , getInfoByUrl         -- :: URLString -> FM LocationPlace+       , getPlaceTypes        -- :: FM [PlaceType]+       +       , placesForBoundingBox -- :: BoundingBox -> Maybe PlaceTypeName -> Maybe PlaceTypeId -> FM [Place]+       , placesForContacts    -- :: PlaceType -> Maybe WhereOnEarthID+                              -- -> Maybe PlaceTypeId -> Maybe Threshold+			      -- -> Maybe String -> FM [Place]+       , placesForTags   -- :: PlaceType+                         -- -> Maybe WhereOnEarthID+	                 -- -> Maybe PlaceTypeId+	                 -- -> Maybe Threshold+	                 -- -> Maybe [Tag]+	                 -- -> Maybe String -- tag-mode+	                 -- -> Maybe MachineTag+	                 -- -> FM [Place]+       , placesForUser   -- :: PlaceTypeName+                         -- -> Maybe WhereOnEarthID+	                 -- -> Maybe PlaceTypeId+	                 -- -> Maybe Threshold+	                 -- -> FM [Place]+       , resolvePlaceId  -- :: PlaceID -> FM LocationPlace+       , resolvePlaceURL -- :: URLString -> FM LocationPlace+       +       , tagsForPlace    -- :: Either PlaceID WhereOnEarthID -> DateDetails -> FM [TagInfo]+       ) where  import Flickr.Monad import Flickr.Types import Flickr.Types.Import +import Data.List ( intercalate )+ -- | Return a list of place IDs for a query string. -- The flickr.places.find method is not a geocoder.  -- It will round up to the nearest place type to @@ -73,20 +104,116 @@     flickrCall "flickr.places.getInfo"                (eiArg "place_id" "woe_id" pw []) +-- | Fetches a list of available place types for Flickr.+getPlaceTypes :: FM [PlaceType]+getPlaceTypes = +  flickTranslate toPlaceTypes $+     flickrCall "flickr.places.getPlaceTypes" []++-- | return all the locations of a matching place type for a bounding box.+placesForBoundingBox :: BoundingBox+                     -> Maybe PlaceTypeName+		     -> Maybe PlaceTypeId+		     -> FM [Place]+placesForBoundingBox bbox pn pid = + flickTranslate toPlacesList $+   flickCall "flickr.places.placesForBoundingBox" +             (mbArg "place_type" pn  $+	      mbArg "place_type_id" pid   $+  	        [("bbox", intercalate "," $ map show $ +		            [ bboxMinLongitude bbox+			    , bboxMinLatitude  bbox+			    , bboxMaxLongitude bbox+			    , bboxMaxLatitude  bbox+			    ])])++-- | Return a list of the top 100 unique places clustered by a given placetype for a user's contacts. +placesForContacts :: Either PlaceTypeName WhereOnEarthID+	      -> Maybe PlaceTypeId+	      -> Maybe Threshold+	      -> Maybe String+	      -> FM [Place]+placesForContacts eiPW pid th contacts = withReadPerm $+ flickTranslate toPlacesList $+   flickCall "flickr.places.placesForContacts" +             (mbArg "woe_id" woe_id  $ +	      mbArg "place_type" pnm   $+	      mbArg "place_type_id" pid   $+	      mbArg "threshold" (fmap show th) $+	      mbArg "contacts" contacts $+ 	       [])+ where+   pnm    = either Just (const Nothing) eiPW+   woe_id = either (const Nothing) Just eiPW+ -- | Return a list of the top 100 unique places clustered by a given placetype for a user. -placesForUser :: PlaceType-              -> Maybe WhereOnEarthID-	      -> Maybe PlaceID+placesForUser :: Either PlaceID   WhereOnEarthID+	      -> Either PlaceTypeName PlaceTypeId 	      -> Maybe Threshold+	      -> DateDetails 	      -> FM [Place]-placesForUser pt woe_id pid th = withReadPerm $+placesForUser eiPW eiPP th mbDates = withReadPerm $  flickTranslate toPlacesList $    flickCall "flickr.places.placesForUser" +             (mbArg "place_id" place_id   $ +	      mbArg "woe_id"   woe_id     $ +	      mbArg "place_type_id" ptid  $+	      mbArg "place_type"    pt    $+	      mbArg "threshold" (fmap show th) $+	      mbArg "min_taken_date" (dateMinTaken mbDates) $+	      mbArg "max_taken_date" (dateMaxTaken mbDates) $+	      mbArg "min_upload_date" (dateMinUpload mbDates) $+	      mbArg "max_upload_date" (dateMaxUpload mbDates) +                [])+ where+   place_id = either Just (const Nothing) eiPW+   woe_id   = either (const Nothing) Just eiPW+   ptid     = either Just (const Nothing) eiPP+   pt       = either (const Nothing) Just eiPP++-- | Return a list of the top 100 unique places clustered by a given placetype for set of tags or machine tags. +placesForTags :: Either PlaceTypeName WhereOnEarthID+	      -> Maybe PlaceID+	      -> Maybe Threshold+	      -> Maybe [Tag]+	      -> Maybe TagMode -- tag-mode+	      -> Maybe [MachineTag]+	      -> Maybe TagMode+	      -> DateDetails+	      -> FM [Place]+placesForTags eiPW pid th tags tag_mode mt mt_mode mbDates = withReadPerm $+ flickTranslate toPlacesList $+   flickCall "flickr.places.placesForTags"               (mbArg "woe_id" woe_id  $ -	      mbArg "place_id" pid   $+	      mbArg "place_type" pnm   $+	      mbArg "place_type_id" pid   $ 	      mbArg "threshold" (fmap show th) $-  	            [("place_type", pt)])+	      mbArg "tags" (fmap (intercalate ",") tags) $+	      mbArg "tag_mode" tag_mode $+	      mbArg "machine_tags" (fmap (intercalate ",") $ fmap (map fromMT) mt) $ +	      mbArg "machine_tag_mode" mt_mode $+	      mbArg "min_taken_date" (dateMinTaken mbDates) $+	      mbArg "max_taken_date" (dateMaxTaken mbDates) $+	      mbArg "min_upload_date" (dateMinUpload mbDates) $+	      mbArg "max_upload_date" (dateMaxUpload mbDates) + 	       [])+ where+   pnm     = either Just (const Nothing) eiPW+   woe_id  = either (const Nothing) Just eiPW +fromMT :: MachineTag -> [Char]+fromMT mt = +  case mTagValue mt of+   "" -> case (mTagNamespace mt, mTagPredicate mt) of+           ("","") -> ""+	   (xs,"") -> xs ++ ":"+	   ("",xs) -> "*:" ++ xs+	   (as,bs) -> as ++ ':':bs+   t  -> toS (mTagNamespace mt) ++ ':':toS (mTagPredicate mt) ++ '=':t+ where+  toS "" = "*"+  toS x  = x+ -- | Find Flickr Places information by Place Id. resolvePlaceId :: PlaceID -> FM LocationPlace resolvePlaceId pid = @@ -100,3 +227,21 @@   flickTranslate toLocationPlace $     flickrCall "flickr.places.resolvePlaceURL"                 [("url", purl)]++-- | Return a list of the top 100 unique tags for a +-- Flickr Places or Where on Earth (WOE) ID.+tagsForPlace :: Either PlaceID WhereOnEarthID -> DateDetails -> FM [TagInfo]+tagsForPlace loc mbDates = +  flickTranslate toTagInfoList $+    flickrCall "flickr.places.tagsForPlace"+               (mbArg "woe_id"   mbw $+	        mbArg "place_id" mbp $+		mbArg "min_taken_date" (dateMinTaken mbDates) $+		mbArg "max_taken_date" (dateMaxTaken mbDates) $+		mbArg "min_upload_date" (dateMinUpload mbDates) $+		mbArg "max_upload_date" (dateMaxUpload mbDates) +		 [])+ where+   mbp  = either (const Nothing) Just loc+   mbw  = either Just (const Nothing) loc+  
Flickr/Prefs.hs view
@@ -11,7 +11,13 @@ -- -- flickr.prefs API, accessing a user's preferences. ---------------------------------------------------------------------module Flickr.Prefs where+module Flickr.Prefs +       ( getContentType -- :: FM ContentType+       , getGeoPerms    -- :: FM Privacy+       , getHidden      -- :: FM Bool+       , getPrivacy     -- :: FM Privacy+       , getSafetyLevel -- :: FM Int+       ) where  import Flickr.Monad import Flickr.Types
Flickr/Tags.hs view
@@ -11,7 +11,16 @@ --
 -- The flickr.tags API, fetching photos by tag or cluster membership.
 --------------------------------------------------------------------
-module Flickr.Tags where
+module Flickr.Tags 
+       ( getClusterPhotos   -- :: TagID -> ClusterID -> FM (PhotoContext, [Photo])
+       , getClusters        -- :: Tag -> FM [Cluster]
+       , getHotList         -- :: Maybe DayWeek -> Maybe Int -> FM [TagDetails]
+       , getListPhoto       -- :: PhotoID -> FM [TagDetails]
+       , getListUser        -- :: Maybe UserID -> FM [TagDetails]
+       , getListUserPopular -- :: Maybe UserID -> Maybe Int -> FM [TagDetails]
+       , getListUserRaw     -- :: Maybe Tag -> FM [TagDetails]
+       , getRelated         -- :: Tag -> FM [TagDetails]
+       ) where
 
 import Flickr.Monad
 import Flickr.Types
Flickr/Types.hs view
@@ -43,6 +43,7 @@ type ClusterID = String
 type DayWeek   = Bool -- False => Day; True => Week
 type PermissionID = String
+type ContextID = Integer
 
 type Date = DateString
 
@@ -363,7 +364,7 @@ 
 type Latitude  = Decimal
 type Longitude = Decimal
-type GeoLocation = (Latitude, Longitude, Accuracy)
+type GeoLocation = (Latitude, Longitude, Maybe Accuracy)
 
 data LocationPlace
  = LocationPlace
@@ -372,7 +373,7 @@      , locationPlaceLat     :: Latitude
      , locationPlaceLong    :: Longitude
      , locationPlaceURL     :: URLString
-     , locationPlaceType    :: PlaceType
+     , locationPlaceType    :: PlaceTypeName
      , locationPlaceDetails :: [LocationPlace]
      , locationPlaceDesc    :: String
      }
@@ -445,8 +446,15 @@ 
 type Threshold = Int
 
-type PlaceType = String
+type PlaceTypeName = String
+type PlaceTypeId   = String
 
+data PlaceType
+ = PlaceType
+     { placeTypeId   :: PlaceTypeId
+     , placeTypeName :: PlaceTypeName
+     }
+
 data Place
  = Place
      { placeId    :: PlaceID
@@ -454,7 +462,7 @@      , placeLat   :: Decimal
      , placeLong  :: Decimal
      , placeURL   :: URLString
-     , placeType  :: PlaceType -- accuracy string.
+     , placeType  :: PlaceTypeName -- accuracy string.
      , placeDesc  :: String
      }
 
@@ -579,6 +587,8 @@      , resCtxtTotal   :: Maybe Int
      }
 
+type TagMode = String
+
 data MachineTagPair
  = MachineTagPair
      { mtPairNamespace :: String
@@ -602,4 +612,30 @@      , mTagValue     :: String
      }
 
- 
+data DateDetails
+ = DateDetails 
+     { dateMinTaken  :: Maybe DateString
+     , dateMaxTaken  :: Maybe DateString
+     , dateMinUpload :: Maybe DateString
+     , dateMaxUpload :: Maybe DateString
+     }
+
+nullDateDetails :: DateDetails
+nullDateDetails = DateDetails
+     { dateMinTaken  = Nothing
+     , dateMaxTaken  = Nothing
+     , dateMinUpload = Nothing
+     , dateMaxUpload = Nothing
+     }
+     
+data TagInfo
+ = TagInfo
+     { tagName  :: String
+     , tagCount :: Maybe Int
+     }
+
+nullTagInfo :: TagInfo
+nullTagInfo = TagInfo
+    { tagName  = ""
+    , tagCount = Nothing
+    }
Flickr/Types/Import.hs view
@@ -163,6 +163,25 @@     , blogURL     = url     } +toPlaceTypes :: String -> ErrM [PlaceType]+toPlaceTypes s = parseDoc eltPlaceTypeList s++eltPlaceTypeList :: Element -> Maybe [PlaceType]+eltPlaceTypeList e = ifNamed "place_types" e $ do+  let ls = pNodes "place_type" (children e)+  mapM eltPlaceType ls++eltPlaceType :: Element -> Maybe PlaceType+eltPlaceType e = ifNamed "place_type" e $ do+  bid   <- pAttr "id" e+  nm    <- pAttr "name" e+  npwd  <- eltBool "needspassword" e+  url   <- pAttr "url" e+  return PlaceType+    { placeTypeId   = fromMaybe "" (pAttr "place_type_id" e)+    , placeTypeName = strContent e+    }+ toLocationPlace :: String -> ErrM LocationPlace toLocationPlace s = parseDoc eltLocationPlace s @@ -738,7 +757,7 @@ eltGeoLocation e = ifNamed "location" e $ do    la  <- pAttr "latitude" e    lo  <- pAttr "longitude" e-   ac  <- eltIntAttr "accuracy" e+   let ac = eltIntAttr "accuracy" e    return (la,lo,ac)  toLicenseList :: String -> ErrM [License]@@ -882,3 +901,17 @@   c  <- eltResContext e   return (c, ls) +toTagInfoList :: String -> ErrM [TagInfo]+toTagInfoList s = parseDoc eltTagInfoList s++eltTagInfoList :: Element -> Maybe [TagInfo]+eltTagInfoList e = ifNamed "tags" e $ do+  mapM eltTagInfo $ pNodes "tag" (children e)++eltTagInfo :: Element -> Maybe TagInfo+eltTagInfo e = do+  let c = pAttr "count" e+  return TagInfo+    { tagName  = strContent e+    , tagCount = maybe Nothing id (fmap readMb c)+    }
examples/Gallery.hs view
@@ -11,6 +11,9 @@   On the Flickr API side, it demonstrates how to use the
   search-by-tag + interestingness.
   
+  foo$ gallery -o g.html portland
+  # generate mini gallery for 'portland'-related photos.
+  
 -}
 module Main(main) where
 
flickr.cabal view
@@ -1,13 +1,13 @@ name: flickr
-version: 0.3.2
+version: 0.3.3
 Synopsis: Haskell binding to the Flickr API
 Description:
    The flickr API binding lets you access flickr.com's
    resources and methods from Haskell.
-
+   .
    Implements the full API, as specified by <http://flickr.com/services/api/>
 category      : Web
-license       :  BSD3
+license       : BSD3
 license-file  : LICENSE
 author        : Sigbjorn Finne <sof@forkIO.com>
 maintainer    : sof@forkIO.com