mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-04 06:05:59 +00:00
Add routes to retrieve sent mails
This commit is contained in:
parent
b795a22992
commit
2ecfb679d9
@ -6,17 +6,13 @@ import cats.implicits._
|
|||||||
import cats.data.OptionT
|
import cats.data.OptionT
|
||||||
import emil._
|
import emil._
|
||||||
import emil.javamail.syntax._
|
import emil.javamail.syntax._
|
||||||
|
import bitpeace.{FileMeta, RangeDef}
|
||||||
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.store._
|
import docspell.store._
|
||||||
import docspell.store.records.RUserEmail
|
import docspell.store.records._
|
||||||
import OMail.{ItemMail, SmtpSettings}
|
import docspell.store.queries.QMails
|
||||||
import docspell.store.records.RAttachment
|
import OMail.{ItemMail, Sent, SmtpSettings}
|
||||||
import bitpeace.FileMeta
|
|
||||||
import bitpeace.RangeDef
|
|
||||||
import docspell.store.records.RItem
|
|
||||||
import docspell.store.records.RSentMail
|
|
||||||
import docspell.store.records.RSentMailItem
|
|
||||||
|
|
||||||
trait OMail[F[_]] {
|
trait OMail[F[_]] {
|
||||||
|
|
||||||
@ -31,10 +27,32 @@ trait OMail[F[_]] {
|
|||||||
def deleteSettings(accId: AccountId, name: Ident): F[Int]
|
def deleteSettings(accId: AccountId, name: Ident): F[Int]
|
||||||
|
|
||||||
def sendMail(accId: AccountId, name: Ident, m: ItemMail): F[SendResult]
|
def sendMail(accId: AccountId, name: Ident, m: ItemMail): F[SendResult]
|
||||||
|
|
||||||
|
def getSentMailsForItem(accId: AccountId, itemId: Ident): F[Vector[Sent]]
|
||||||
|
|
||||||
|
def getSentMail(accId: AccountId, mailId: Ident): OptionT[F, Sent]
|
||||||
|
|
||||||
|
def deleteSentMail(accId: AccountId, mailId: Ident): F[Int]
|
||||||
}
|
}
|
||||||
|
|
||||||
object OMail {
|
object OMail {
|
||||||
|
|
||||||
|
case class Sent(
|
||||||
|
id: Ident,
|
||||||
|
senderLogin: Ident,
|
||||||
|
connectionName: Ident,
|
||||||
|
recipients: List[MailAddress],
|
||||||
|
subject: String,
|
||||||
|
body: String,
|
||||||
|
created: Timestamp
|
||||||
|
)
|
||||||
|
|
||||||
|
object Sent {
|
||||||
|
|
||||||
|
def create(r: RSentMail, login: Ident): Sent =
|
||||||
|
Sent(r.id, login, r.connName, r.recipients, r.subject, r.body, r.created)
|
||||||
|
}
|
||||||
|
|
||||||
case class ItemMail(
|
case class ItemMail(
|
||||||
item: Ident,
|
item: Ident,
|
||||||
subject: String,
|
subject: String,
|
||||||
@ -155,6 +173,7 @@ object OMail {
|
|||||||
accId,
|
accId,
|
||||||
msgId,
|
msgId,
|
||||||
cfg.mailFrom,
|
cfg.mailFrom,
|
||||||
|
name,
|
||||||
m.subject,
|
m.subject,
|
||||||
m.recipients,
|
m.recipients,
|
||||||
m.body
|
m.body
|
||||||
@ -180,5 +199,17 @@ object OMail {
|
|||||||
} yield conv).getOrElse(SendResult.NotFound)
|
} yield conv).getOrElse(SendResult.NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getSentMailsForItem(accId: AccountId, itemId: Ident): F[Vector[Sent]] =
|
||||||
|
store
|
||||||
|
.transact(QMails.findMails(accId.collective, itemId))
|
||||||
|
.map(_.map(t => Sent.create(t._1, t._2)))
|
||||||
|
|
||||||
|
def getSentMail(accId: AccountId, mailId: Ident): OptionT[F, Sent] =
|
||||||
|
OptionT(store.transact(QMails.findMail(accId.collective, mailId))).map(t =>
|
||||||
|
Sent.create(t._1, t._2)
|
||||||
|
)
|
||||||
|
|
||||||
|
def deleteSentMail(accId: AccountId, mailId: Ident): F[Int] =
|
||||||
|
store.transact(QMails.delete(accId.collective, mailId))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,8 @@ paths:
|
|||||||
|
|
||||||
The result shows all items that contains a file with the given
|
The result shows all items that contains a file with the given
|
||||||
checksum.
|
checksum.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/checksum"
|
- $ref: "#/components/parameters/checksum"
|
||||||
responses:
|
responses:
|
||||||
@ -159,6 +161,8 @@ paths:
|
|||||||
* application/pdf
|
* application/pdf
|
||||||
|
|
||||||
Support for more types might be added.
|
Support for more types might be added.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
multipart/form-data:
|
multipart/form-data:
|
||||||
@ -1188,6 +1192,8 @@ paths:
|
|||||||
Get the current state of the job qeue. The job qeue contains
|
Get the current state of the job qeue. The job qeue contains
|
||||||
all processing tasks and other long-running operations. All
|
all processing tasks and other long-running operations. All
|
||||||
users/collectives share processing resources.
|
users/collectives share processing resources.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Ok
|
description: Ok
|
||||||
@ -1203,6 +1209,8 @@ paths:
|
|||||||
Tries to cancel a job and remove it from the queue. If the job
|
Tries to cancel a job and remove it from the queue. If the job
|
||||||
is running, a cancel request is send to the corresponding joex
|
is running, a cancel request is send to the corresponding joex
|
||||||
instance. Otherwise the job is removed from the queue.
|
instance. Otherwise the job is removed from the queue.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/id"
|
- $ref: "#/components/parameters/id"
|
||||||
responses:
|
responses:
|
||||||
@ -1224,6 +1232,8 @@ paths:
|
|||||||
Multiple e-mail settings can be specified, they are
|
Multiple e-mail settings can be specified, they are
|
||||||
distinguished by their `name`. The query `q` parameter does a
|
distinguished by their `name`. The query `q` parameter does a
|
||||||
simple substring search in the connection name.
|
simple substring search in the connection name.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/q"
|
- $ref: "#/components/parameters/q"
|
||||||
responses:
|
responses:
|
||||||
@ -1238,6 +1248,8 @@ paths:
|
|||||||
summary: Create new email settings
|
summary: Create new email settings
|
||||||
description: |
|
description: |
|
||||||
Create new e-mail settings.
|
Create new e-mail settings.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -1259,6 +1271,8 @@ paths:
|
|||||||
description: |
|
description: |
|
||||||
Return the stored e-mail settings for the given connection
|
Return the stored e-mail settings for the given connection
|
||||||
name.
|
name.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Ok
|
description: Ok
|
||||||
@ -1271,6 +1285,8 @@ paths:
|
|||||||
summary: Change specific email settings.
|
summary: Change specific email settings.
|
||||||
description: |
|
description: |
|
||||||
Changes all settings for the connection with the given `name`.
|
Changes all settings for the connection with the given `name`.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -1288,6 +1304,8 @@ paths:
|
|||||||
summary: Delete e-mail settings.
|
summary: Delete e-mail settings.
|
||||||
description: |
|
description: |
|
||||||
Deletes the e-mail settings with the specified `name`.
|
Deletes the e-mail settings with the specified `name`.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Ok
|
description: Ok
|
||||||
@ -1301,10 +1319,11 @@ paths:
|
|||||||
tags: [ E-Mail ]
|
tags: [ E-Mail ]
|
||||||
summary: Send an email.
|
summary: Send an email.
|
||||||
description: |
|
description: |
|
||||||
Sends an email as specified with all attachments of the item
|
Sends an email as specified in the body of the request.
|
||||||
with `id` as mail attachments. If the item has no attachments,
|
|
||||||
then the mail is sent without any. If the item's attachments
|
The item's attachment are added to the mail if requested.
|
||||||
exceed a specific size, the mail will not be sent.
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/name"
|
- $ref: "#/components/parameters/name"
|
||||||
- $ref: "#/components/parameters/id"
|
- $ref: "#/components/parameters/id"
|
||||||
@ -1320,9 +1339,100 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/BasicResult"
|
$ref: "#/components/schemas/BasicResult"
|
||||||
|
/sec/email/sent/item/{id}:
|
||||||
|
get:
|
||||||
|
tags: [ E-Mail ]
|
||||||
|
summary: Get sent mail related to an item
|
||||||
|
description: |
|
||||||
|
Return all mails that have been sent related to the item with
|
||||||
|
id `id`.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/id"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SentMails"
|
||||||
|
/sec/email/sent/mail/{mailId}:
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/mailId"
|
||||||
|
get:
|
||||||
|
tags: [ E-Mail ]
|
||||||
|
summary: Get sent single mail related to an item
|
||||||
|
description: |
|
||||||
|
Return one mail with the given id.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SentMail"
|
||||||
|
delete:
|
||||||
|
tags: [ E-Mail ]
|
||||||
|
summary: Delete a sent mail.
|
||||||
|
description: |
|
||||||
|
Delete a sent mail.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicResult"
|
||||||
|
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
SentMails:
|
||||||
|
description: |
|
||||||
|
A list of sent mails.
|
||||||
|
required:
|
||||||
|
- items
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/SentMail"
|
||||||
|
SentMail:
|
||||||
|
description: |
|
||||||
|
A mail that has been sent previously related to an item.
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- sender
|
||||||
|
- connection
|
||||||
|
- recipients
|
||||||
|
- subject
|
||||||
|
- body
|
||||||
|
- created
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
format: ident
|
||||||
|
sender:
|
||||||
|
type: string
|
||||||
|
format: ident
|
||||||
|
connection:
|
||||||
|
type: string
|
||||||
|
format: ident
|
||||||
|
recipients:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
subject:
|
||||||
|
type: string
|
||||||
|
body:
|
||||||
|
type: string
|
||||||
|
created:
|
||||||
|
type: integer
|
||||||
|
format: date-time
|
||||||
SimpleMail:
|
SimpleMail:
|
||||||
description: |
|
description: |
|
||||||
A simple e-mail related to an item.
|
A simple e-mail related to an item.
|
||||||
@ -1330,7 +1440,8 @@ components:
|
|||||||
The mail may contain the item attachments as mail attachments.
|
The mail may contain the item attachments as mail attachments.
|
||||||
If all item attachments should be send, set
|
If all item attachments should be send, set
|
||||||
`addAllAttachments` to `true`. Otherwise set it to `false` and
|
`addAllAttachments` to `true`. Otherwise set it to `false` and
|
||||||
specify a list of file-ids that you want to include.
|
specify a list of file-ids that you want to include. This list
|
||||||
|
is ignored, if `addAllAttachments` is set to `true`.
|
||||||
required:
|
required:
|
||||||
- recipients
|
- recipients
|
||||||
- subject
|
- subject
|
||||||
@ -2369,3 +2480,10 @@ components:
|
|||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
mailId:
|
||||||
|
name: mailId
|
||||||
|
in: path
|
||||||
|
description: The id of a sent mail.
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
@ -71,7 +71,8 @@ object RestServer {
|
|||||||
"upload" -> UploadRoutes.secured(restApp.backend, cfg, token),
|
"upload" -> UploadRoutes.secured(restApp.backend, cfg, token),
|
||||||
"checkfile" -> CheckFileRoutes.secured(restApp.backend, token),
|
"checkfile" -> CheckFileRoutes.secured(restApp.backend, token),
|
||||||
"email/send" -> MailSendRoutes(restApp.backend, token),
|
"email/send" -> MailSendRoutes(restApp.backend, token),
|
||||||
"email/settings" -> MailSettingsRoutes(restApp.backend, token)
|
"email/settings" -> MailSettingsRoutes(restApp.backend, token),
|
||||||
|
"email/sent" -> SentMailRoutes(restApp.backend, token)
|
||||||
)
|
)
|
||||||
|
|
||||||
def openRoutes[F[_]: Effect](cfg: Config, restApp: RestApp[F]): HttpRoutes[F] =
|
def openRoutes[F[_]: Effect](cfg: Config, restApp: RestApp[F]): HttpRoutes[F] =
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package docspell.restserver.routes
|
||||||
|
|
||||||
|
import cats.effect._
|
||||||
|
import cats.implicits._
|
||||||
|
import cats.data.OptionT
|
||||||
|
import org.http4s._
|
||||||
|
import org.http4s.dsl.Http4sDsl
|
||||||
|
import org.http4s.circe.CirceEntityEncoder._
|
||||||
|
|
||||||
|
import docspell.backend.BackendApp
|
||||||
|
import docspell.backend.auth.AuthToken
|
||||||
|
import docspell.backend.ops.OMail.Sent
|
||||||
|
import docspell.common._
|
||||||
|
import docspell.restapi.model._
|
||||||
|
import docspell.store.EmilUtil
|
||||||
|
|
||||||
|
object SentMailRoutes {
|
||||||
|
|
||||||
|
def apply[F[_]: Effect](backend: BackendApp[F], user: AuthToken): HttpRoutes[F] = {
|
||||||
|
val dsl = new Http4sDsl[F] {}
|
||||||
|
import dsl._
|
||||||
|
|
||||||
|
HttpRoutes.of {
|
||||||
|
case GET -> Root / "item" / Ident(id) =>
|
||||||
|
for {
|
||||||
|
all <- backend.mail.getSentMailsForItem(user.account, id)
|
||||||
|
resp <- Ok(SentMails(all.map(convert).toList))
|
||||||
|
} yield resp
|
||||||
|
|
||||||
|
case GET -> Root / "mail" / Ident(mailId) =>
|
||||||
|
(for {
|
||||||
|
mail <- backend.mail.getSentMail(user.account, mailId)
|
||||||
|
resp <- OptionT.liftF(Ok(convert(mail)))
|
||||||
|
} yield resp).getOrElseF(NotFound())
|
||||||
|
|
||||||
|
case DELETE -> Root / "mail" / Ident(mailId) =>
|
||||||
|
for {
|
||||||
|
n <- backend.mail.deleteSentMail(user.account, mailId)
|
||||||
|
resp <- Ok(BasicResult(n > 0, s"Mails deleted: $n"))
|
||||||
|
} yield resp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def convert(s: Sent): SentMail =
|
||||||
|
SentMail(
|
||||||
|
s.id,
|
||||||
|
s.senderLogin,
|
||||||
|
s.connectionName,
|
||||||
|
s.recipients.map(EmilUtil.mailAddressString),
|
||||||
|
s.subject,
|
||||||
|
s.body,
|
||||||
|
s.created
|
||||||
|
)
|
||||||
|
}
|
@ -20,6 +20,7 @@ CREATE TABLE "sentmail" (
|
|||||||
"uid" varchar(254) not null,
|
"uid" varchar(254) not null,
|
||||||
"message_id" varchar(254) not null,
|
"message_id" varchar(254) not null,
|
||||||
"sender" varchar(254) not null,
|
"sender" varchar(254) not null,
|
||||||
|
"conn_name" varchar(254) not null,
|
||||||
"subject" varchar(254) not null,
|
"subject" varchar(254) not null,
|
||||||
"recipients" varchar(254) not null,
|
"recipients" varchar(254) not null,
|
||||||
"body" text not null,
|
"body" text not null,
|
||||||
|
@ -65,12 +65,6 @@ trait DoobieSyntax {
|
|||||||
Fragment.const("SELECT DISTINCT(") ++ commas(cols.map(_.f)) ++
|
Fragment.const("SELECT DISTINCT(") ++ commas(cols.map(_.f)) ++
|
||||||
Fragment.const(") FROM ") ++ table ++ this.where(where)
|
Fragment.const(") FROM ") ++ table ++ this.where(where)
|
||||||
|
|
||||||
// def selectJoinCollective(cols: Seq[Column], fkCid: Column, table: Fragment, wh: Fragment): Fragment =
|
|
||||||
// selectSimple(cols.map(_.prefix("a"))
|
|
||||||
// , table ++ fr"a," ++ RCollective.table ++ fr"b"
|
|
||||||
// , if (isEmpty(wh)) fkCid.prefix("a") is RCollective.Columns.id.prefix("b")
|
|
||||||
// else and(wh, fkCid.prefix("a") is RCollective.Columns.id.prefix("b")))
|
|
||||||
|
|
||||||
def selectCount(col: Column, table: Fragment, where: Fragment): Fragment =
|
def selectCount(col: Column, table: Fragment, where: Fragment): Fragment =
|
||||||
Fragment.const("SELECT COUNT(") ++ col.f ++ Fragment.const(") FROM ") ++ table ++ this.where(
|
Fragment.const("SELECT COUNT(") ++ col.f ++ Fragment.const(") FROM ") ++ table ++ this.where(
|
||||||
where
|
where
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package docspell.store.queries
|
||||||
|
|
||||||
|
import cats.data.OptionT
|
||||||
|
import doobie._
|
||||||
|
import doobie.implicits._
|
||||||
|
|
||||||
|
import docspell.common._
|
||||||
|
import docspell.store.impl.Column
|
||||||
|
import docspell.store.impl.Implicits._
|
||||||
|
import docspell.store.records.{RItem, RSentMail, RSentMailItem, RUser}
|
||||||
|
|
||||||
|
object QMails {
|
||||||
|
|
||||||
|
def delete(coll: Ident, mailId: Ident): ConnectionIO[Int] =
|
||||||
|
(for {
|
||||||
|
m <- OptionT(findMail(coll, mailId))
|
||||||
|
k <- OptionT.liftF(RSentMailItem.deleteMail(mailId))
|
||||||
|
n <- OptionT.liftF(RSentMail.delete(m._1.id))
|
||||||
|
} yield k + n).getOrElse(0)
|
||||||
|
|
||||||
|
def findMail(coll: Ident, mailId: Ident): ConnectionIO[Option[(RSentMail, Ident)]] = {
|
||||||
|
val iColl = RItem.Columns.cid.prefix("i")
|
||||||
|
val mId = RSentMail.Columns.id.prefix("m")
|
||||||
|
|
||||||
|
val (cols, from) = partialFind
|
||||||
|
|
||||||
|
val cond = Seq(mId.is(mailId), iColl.is(coll))
|
||||||
|
|
||||||
|
selectSimple(cols, from, and(cond)).query[(RSentMail, Ident)].option
|
||||||
|
}
|
||||||
|
|
||||||
|
def findMails(coll: Ident, itemId: Ident): ConnectionIO[Vector[(RSentMail, Ident)]] = {
|
||||||
|
val iColl = RItem.Columns.cid.prefix("i")
|
||||||
|
val tItem = RSentMailItem.Columns.itemId.prefix("t")
|
||||||
|
val mCreated = RSentMail.Columns.created.prefix("m")
|
||||||
|
|
||||||
|
val (cols, from) = partialFind
|
||||||
|
|
||||||
|
val cond = Seq(tItem.is(itemId), iColl.is(coll))
|
||||||
|
|
||||||
|
(selectSimple(cols, from, and(cond)) ++ orderBy(mCreated.f) ++ fr"DESC")
|
||||||
|
.query[(RSentMail, Ident)]
|
||||||
|
.to[Vector]
|
||||||
|
}
|
||||||
|
|
||||||
|
private def partialFind: (Seq[Column], Fragment) = {
|
||||||
|
val iId = RItem.Columns.id.prefix("i")
|
||||||
|
val tItem = RSentMailItem.Columns.itemId.prefix("t")
|
||||||
|
val tMail = RSentMailItem.Columns.sentMailId.prefix("t")
|
||||||
|
val mId = RSentMail.Columns.id.prefix("m")
|
||||||
|
val mUser = RSentMail.Columns.uid.prefix("m")
|
||||||
|
val uId = RUser.Columns.uid.prefix("u")
|
||||||
|
val uLogin = RUser.Columns.login.prefix("u")
|
||||||
|
|
||||||
|
val cols = RSentMail.Columns.all.map(_.prefix("m")) :+ uLogin
|
||||||
|
val from = RSentMail.table ++ fr"m INNER JOIN" ++
|
||||||
|
RSentMailItem.table ++ fr"t ON" ++ tMail.is(mId) ++
|
||||||
|
fr"INNER JOIN" ++ RItem.table ++ fr"i ON" ++ tItem.is(iId) ++
|
||||||
|
fr"INNER JOIN" ++ RUser.table ++ fr"u ON" ++ uId.is(mUser)
|
||||||
|
|
||||||
|
(cols, from)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,6 +16,7 @@ case class RSentMail(
|
|||||||
uid: Ident,
|
uid: Ident,
|
||||||
messageId: String,
|
messageId: String,
|
||||||
sender: MailAddress,
|
sender: MailAddress,
|
||||||
|
connName: Ident,
|
||||||
subject: String,
|
subject: String,
|
||||||
recipients: List[MailAddress],
|
recipients: List[MailAddress],
|
||||||
body: String,
|
body: String,
|
||||||
@ -28,6 +29,7 @@ object RSentMail {
|
|||||||
uid: Ident,
|
uid: Ident,
|
||||||
messageId: String,
|
messageId: String,
|
||||||
sender: MailAddress,
|
sender: MailAddress,
|
||||||
|
connName: Ident,
|
||||||
subject: String,
|
subject: String,
|
||||||
recipients: List[MailAddress],
|
recipients: List[MailAddress],
|
||||||
body: String
|
body: String
|
||||||
@ -35,24 +37,26 @@ object RSentMail {
|
|||||||
for {
|
for {
|
||||||
id <- Ident.randomId[F]
|
id <- Ident.randomId[F]
|
||||||
now <- Timestamp.current[F]
|
now <- Timestamp.current[F]
|
||||||
} yield RSentMail(id, uid, messageId, sender, subject, recipients, body, now)
|
} yield RSentMail(id, uid, messageId, sender, connName, subject, recipients, body, now)
|
||||||
|
|
||||||
def forItem(
|
def forItem(
|
||||||
itemId: Ident,
|
itemId: Ident,
|
||||||
accId: AccountId,
|
accId: AccountId,
|
||||||
messageId: String,
|
messageId: String,
|
||||||
sender: MailAddress,
|
sender: MailAddress,
|
||||||
|
connName: Ident,
|
||||||
subject: String,
|
subject: String,
|
||||||
recipients: List[MailAddress],
|
recipients: List[MailAddress],
|
||||||
body: String
|
body: String
|
||||||
): OptionT[ConnectionIO, (RSentMail, RSentMailItem)] =
|
): OptionT[ConnectionIO, (RSentMail, RSentMailItem)] =
|
||||||
for {
|
for {
|
||||||
user <- OptionT(RUser.findByAccount(accId))
|
user <- OptionT(RUser.findByAccount(accId))
|
||||||
sm <- OptionT.liftF(RSentMail[ConnectionIO](user.uid, messageId, sender, subject, recipients, body))
|
sm <- OptionT.liftF(
|
||||||
|
RSentMail[ConnectionIO](user.uid, messageId, sender, connName, subject, recipients, body)
|
||||||
|
)
|
||||||
si <- OptionT.liftF(RSentMailItem[ConnectionIO](itemId, sm.id, Some(sm.created)))
|
si <- OptionT.liftF(RSentMailItem[ConnectionIO](itemId, sm.id, Some(sm.created)))
|
||||||
} yield (sm, si)
|
} yield (sm, si)
|
||||||
|
|
||||||
|
|
||||||
val table = fr"sentmail"
|
val table = fr"sentmail"
|
||||||
|
|
||||||
object Columns {
|
object Columns {
|
||||||
@ -60,6 +64,7 @@ object RSentMail {
|
|||||||
val uid = Column("uid")
|
val uid = Column("uid")
|
||||||
val messageId = Column("message_id")
|
val messageId = Column("message_id")
|
||||||
val sender = Column("sender")
|
val sender = Column("sender")
|
||||||
|
val connName = Column("conn_name")
|
||||||
val subject = Column("subject")
|
val subject = Column("subject")
|
||||||
val recipients = Column("recipients")
|
val recipients = Column("recipients")
|
||||||
val body = Column("body")
|
val body = Column("body")
|
||||||
@ -70,6 +75,7 @@ object RSentMail {
|
|||||||
uid,
|
uid,
|
||||||
messageId,
|
messageId,
|
||||||
sender,
|
sender,
|
||||||
|
connName,
|
||||||
subject,
|
subject,
|
||||||
recipients,
|
recipients,
|
||||||
body,
|
body,
|
||||||
@ -83,10 +89,12 @@ object RSentMail {
|
|||||||
insertRow(
|
insertRow(
|
||||||
table,
|
table,
|
||||||
all,
|
all,
|
||||||
sql"${v.id},${v.uid},${v.messageId},${v.sender},${v.subject},${v.recipients},${v.body},${v.created}"
|
sql"${v.id},${v.uid},${v.messageId},${v.sender},${v.connName},${v.subject},${v.recipients},${v.body},${v.created}"
|
||||||
).update.run
|
).update.run
|
||||||
|
|
||||||
def findByUser(userId: Ident): Stream[ConnectionIO, RSentMail] =
|
def findByUser(userId: Ident): Stream[ConnectionIO, RSentMail] =
|
||||||
selectSimple(all, table, uid.is(userId)).query[RSentMail].stream
|
selectSimple(all, table, uid.is(userId)).query[RSentMail].stream
|
||||||
|
|
||||||
|
def delete(mailId: Ident): ConnectionIO[Int] =
|
||||||
|
deleteFrom(table, id.is(mailId)).update.run
|
||||||
}
|
}
|
||||||
|
@ -52,4 +52,6 @@ object RSentMailItem {
|
|||||||
sql"${v.id},${v.itemId},${v.sentMailId},${v.created}"
|
sql"${v.id},${v.itemId},${v.sentMailId},${v.created}"
|
||||||
).update.run
|
).update.run
|
||||||
|
|
||||||
|
def deleteMail(mailId: Ident): ConnectionIO[Int] =
|
||||||
|
deleteFrom(table, sentMailId.is(mailId)).update.run
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user