-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Model.hs
138 lines (125 loc) · 3.77 KB
/
Model.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{-# LANGUAGE FlexibleInstances, DeriveDataTypeable #-}
module Model (
-- Model
infoHashByName,
Torrent (..),
torrentByName,
purgeTorrent,
DirectoryEntry (..),
getDirectory,
-- Model.Query
QueryPage (..),
-- Model.Stats
StatsValue (..),
getCounter,
addCounter,
getGauge,
-- Model.Download
InfoHash (..),
infoHashToHex,
Download (..),
recentDownloads,
popularDownloads,
mostDownloaded,
userDownloads,
enclosureDownloads,
feedDownloads,
-- Model.Item
Item (..),
groupDownloads,
userItemImage,
-- Model.User
UserName (..),
UserDetails (..),
userDetailsByName,
setUserDetails,
UserSalt (..),
userSalt,
setUserSalted,
registerUser,
userByEmail,
-- Model.Feed
FeedXml (..),
feedXml,
feedEnclosures,
enclosureErrors,
FeedInfo (..),
userFeed,
userFeeds,
userFeedInfo,
addUserFeed,
deleteUserFeed,
FeedDetails (..),
userFeedDetails,
setUserFeedDetails,
-- Model.Token
Token (..),
generateToken,
validateToken,
peekToken
) where
import Prelude
import Data.Convertible
import Data.Text (Text)
import Database.HDBC
import Data.Data (Typeable)
import qualified Data.ByteString.Char8 as BC
import Control.Applicative
import Utils
import Model.Query
import Model.Download
import Model.Item
import Model.Feed
import Model.User
import Model.Token
import Model.Stats
infoHashByName :: UserName -> Text -> Text -> Query InfoHash
infoHashByName user slug name =
query "SELECT \"info_hash\" FROM user_feeds JOIN enclosures USING (feed) JOIN enclosure_torrents USING (url) JOIN torrents USING (info_hash) WHERE user_feeds.\"user\"=? AND user_feeds.\"slug\"=? AND torrents.\"name\"=?" [toSql user, toSql slug, toSql name]
data Torrent = Torrent {
torrentInfoHash :: InfoHash,
torrentName :: Text,
torrentSize :: Integer,
torrentTorrent :: BC.ByteString
} deriving (Show, Typeable)
instance Convertible [SqlValue] Torrent where
safeConvert (info_hash:name:size:torrent:[]) =
Torrent <$>
safeFromSql info_hash <*>
safeFromSql name <*>
safeFromSql size <*>
pure (fromBytea torrent)
safeConvert vals = convError "Torrent" vals
torrentByName :: UserName -> Text -> Text -> Query Torrent
torrentByName user slug name =
query "SELECT \"info_hash\", \"name\", \"size\", \"torrent\" FROM user_feeds JOIN enclosures USING (feed) JOIN enclosure_torrents USING (url) JOIN torrents USING (info_hash) WHERE user_feeds.\"user\"=? AND user_feeds.\"slug\"=? AND torrents.\"name\"=?" [toSql user, toSql slug, toSql name]
purgeTorrent :: IConnection conn =>
UserName -> Text -> Text -> conn -> IO Int
purgeTorrent user slug name db =
(fromSql . head . head) `fmap`
quickQuery' db "SELECT * FROM purge_download(?, ?, ?)"
[toSql user, toSql slug, toSql name]
data DirectoryEntry = DirectoryEntry
{ dirUser :: UserName
, dirUserTitle :: Text
, dirUserImage :: Text
, dirFeedSlug :: Text
, dirFeedTitle :: Text
, dirFeedLang :: Text
, dirFeedTypes :: Text
} deriving (Show, Typeable)
instance Convertible [SqlValue] DirectoryEntry where
safeConvert (userVal:userTitleVal:userImageVal:
feedSlugVal:feedTitleVal:feedLangVal:feedTypesVal:[]) =
DirectoryEntry <$>
safeFromSql userVal <*>
safeFromSql userTitleVal <*>
(fixUrl <$> safeFromSql userImageVal) <*>
safeFromSql feedSlugVal <*>
safeFromSql feedTitleVal <*>
safeFromSql feedLangVal <*>
safeFromSql feedTypesVal
safeConvert vals = convError "DirectoryEntry" vals
getDirectory :: Query DirectoryEntry
getDirectory =
query "SELECT \"user\", COALESCE(\"title\", \"user\"), COALESCE(\"image\", ''), \"slug\", COALESCE(\"feed_title\", \"slug\"), COALESCE(\"lang\", ''), array_to_string(\"types\", ',') FROM directory" []