Add a route to return used tags

This is part of the `/insights` route without queries for file usage.
This commit is contained in:
Eike Kettner 2020-08-08 07:56:55 +02:00
parent a4796f3f7f
commit 1c8b66194b
5 changed files with 52 additions and 32 deletions

View File

@ -27,6 +27,8 @@ trait OCollective[F[_]] {
def insights(collective: Ident): F[InsightData] def insights(collective: Ident): F[InsightData]
def tagCloud(collective: Ident): F[List[TagCount]]
def changePassword( def changePassword(
accountId: AccountId, accountId: AccountId,
current: Password, current: Password,
@ -116,6 +118,9 @@ object OCollective {
def insights(collective: Ident): F[InsightData] = def insights(collective: Ident): F[InsightData] =
store.transact(QCollective.getInsights(collective)) store.transact(QCollective.getInsights(collective))
def tagCloud(collective: Ident): F[List[TagCount]] =
store.transact(QCollective.tagCloud(collective))
def changePassword( def changePassword(
accountId: AccountId, accountId: AccountId,
current: Password, current: Password,

View File

@ -460,6 +460,7 @@ paths:
responses: responses:
200: 200:
description: Ok description: Ok
/sec/tag: /sec/tag:
get: get:
tags: [ Tags ] tags: [ Tags ]
@ -1011,6 +1012,22 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ItemInsights" $ref: "#/components/schemas/ItemInsights"
/sec/collective/cloud:
get:
tags: [ Collective ]
summary: Summary of used tags.
description: |
Returns all tags and how often each has been applied.
security:
- authTokenHeader: []
responses:
200:
description: Ok
content:
application/json:
schema:
$ref: "#/components/schemas/TagCloud"
/sec/collective/contacts: /sec/collective/contacts:
get: get:
tags: [ Collective ] tags: [ Collective ]
@ -3059,24 +3076,10 @@ components:
- count - count
properties: properties:
tag: tag:
$ref: "#/components/schemas/TagLight" $ref: "#/components/schemas/Tag"
count: count:
type: integer type: integer
format: int32 format: int32
TagLight:
description: |
A subset of tag properties.
required:
- id
- name
properties:
id:
type: string
format: ident
name:
type: string
category:
type: string
AttachmentMeta: AttachmentMeta:
description: | description: |
Extracted meta data of an attachment. Extracted meta data of an attachment.

View File

@ -31,11 +31,11 @@ trait Conversions {
d.incoming, d.incoming,
d.outgoing, d.outgoing,
d.bytes, d.bytes,
TagCloud(d.tags.map(tc => TagCount(mkTagLight(tc), tc.count))) mkTagCloud(d.tags)
) )
def mkTagLight(t: OCollective.TagCount): TagLight = def mkTagCloud(tags: List[OCollective.TagCount]) =
TagLight(t.id, t.name, t.category) TagCloud(tags.map(tc => TagCount(mkTag(tc.tag), tc.count)))
// attachment meta // attachment meta
def mkAttachmentMeta(rm: RAttachmentMeta): AttachmentMeta = def mkAttachmentMeta(rm: RAttachmentMeta): AttachmentMeta =

View File

@ -28,6 +28,12 @@ object CollectiveRoutes {
resp <- Ok(Conversions.mkItemInsights(ins)) resp <- Ok(Conversions.mkItemInsights(ins))
} yield resp } yield resp
case GET -> Root / "cloud" =>
for {
cloud <- backend.collective.tagCloud(user.account.collective)
resp <- Ok(Conversions.mkTagCloud(cloud))
} yield resp
case req @ POST -> Root / "settings" => case req @ POST -> Root / "settings" =>
for { for {
settings <- req.as[CollectiveSettings] settings <- req.as[CollectiveSettings]

View File

@ -11,7 +11,7 @@ import doobie._
import doobie.implicits._ import doobie.implicits._
object QCollective { object QCollective {
case class TagCount(id: Ident, name: String, category: Option[String], count: Int) case class TagCount(tag: RTag, count: Int)
case class InsightData( case class InsightData(
incoming: Int, incoming: Int,
@ -22,8 +22,6 @@ object QCollective {
def getInsights(coll: Ident): ConnectionIO[InsightData] = { def getInsights(coll: Ident): ConnectionIO[InsightData] = {
val IC = RItem.Columns val IC = RItem.Columns
val TC = RTag.Columns
val RC = RTagItem.Columns
val q0 = selectCount( val q0 = selectCount(
IC.id, IC.id,
RItem.table, RItem.table,
@ -52,25 +50,33 @@ object QCollective {
inner join filemeta m on m.id = a.file_id where a.id in (select aid from attachs) inner join filemeta m on m.id = a.file_id where a.id in (select aid from attachs)
) as t""".query[Option[Long]].unique ) as t""".query[Option[Long]].unique
for {
n0 <- q0
n1 <- q1
n2 <- fileSize
n3 <- tagCloud(coll)
} yield InsightData(n0, n1, n2.getOrElse(0L), n3)
}
def tagCloud(coll: Ident): ConnectionIO[List[TagCount]] = {
val TC = RTag.Columns
val RC = RTagItem.Columns
val q3 = fr"SELECT" ++ commas( val q3 = fr"SELECT" ++ commas(
TC.tid.prefix("t").f, TC.all.map(_.prefix("t").f) ++ Seq(fr"count(" ++ RC.itemId.prefix("r").f ++ fr")")
TC.name.prefix("t").f,
TC.category.prefix("t").f,
fr"count(" ++ RC.itemId.prefix("r").f ++ fr")"
) ++ ) ++
fr"FROM" ++ RTagItem.table ++ fr"r" ++ fr"FROM" ++ RTagItem.table ++ fr"r" ++
fr"INNER JOIN" ++ RTag.table ++ fr"t ON" ++ RC.tagId fr"INNER JOIN" ++ RTag.table ++ fr"t ON" ++ RC.tagId
.prefix("r") .prefix("r")
.is(TC.tid.prefix("t")) ++ .is(TC.tid.prefix("t")) ++
fr"WHERE" ++ TC.cid.prefix("t").is(coll) ++ fr"WHERE" ++ TC.cid.prefix("t").is(coll) ++
fr"GROUP BY" ++ commas(TC.name.prefix("t").f, TC.tid.prefix("t").f, TC.category.prefix("t").f) fr"GROUP BY" ++ commas(
TC.name.prefix("t").f,
TC.tid.prefix("t").f,
TC.category.prefix("t").f
)
for { q3.query[TagCount].to[List]
n0 <- q0
n1 <- q1
n2 <- fileSize
n3 <- q3.query[TagCount].to[List]
} yield InsightData(n0, n1, n2.getOrElse(0L), n3)
} }
def getContacts( def getContacts(