Skip to content

Commit

Permalink
Convert links from Telegram to XMPP (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Aug 14, 2019
1 parent 8239d4e commit 7cbc428
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
103 changes: 103 additions & 0 deletions Emulsion.Tests/Telegram/FunogramTests.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module Emulsion.Tests.Telegram.Client

open System

open Funogram.Types
open Xunit

Expand Down Expand Up @@ -29,6 +31,19 @@ let private telegramMessage author text =
let private telegramReplyMessage author text replyTo =
{ main = { author = author; text = text }; replyTo = Some replyTo }

let private createEntity t offset length url = {
Type = t
Offset = offset
Length = length
Url = Some url
User = None
}

let private createEntities t offset length url = Some <| seq {
yield createEntity t offset length url
}


let private originalUser = createUser (Some "originalUser") "" None
let private replyingUser = createUser (Some "replyingUser") "" None

Expand Down Expand Up @@ -91,6 +106,94 @@ module ReadMessageTests =
readMessage replyMessage
)

[<Fact>]
let readTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "text_link" 0L 8L "https://example.com" }

Assert.Equal(
telegramMessage "@originalUser" "Original [https://example.com] text",
readMessage message
)

[<Fact>]
let readMultipleTextLinksMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = Some <| upcast [| createEntity "text_link" 0L 8L "https://example.com/1"
createEntity "text_link" 9L 4L "https://example.com/2" |] }
Assert.Equal(
telegramMessage "@originalUser" "Original [https://example.com/1] text [https://example.com/2]",
readMessage message
)

[<Fact>]
let readInvalidTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "text_link" 0L 800L "https://example.com" }
Assert.Equal(
telegramMessage "@originalUser" "Original text [https://example.com]",
readMessage message
)

[<Fact>]
let readNegativeOffsetTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "text_link" -1L 5L "https://example.com" }
Assert.Equal(
telegramMessage "@originalUser" "Original text",
readMessage message
)

[<Fact>]
let readZeroLengthTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "text_link" 0L 0L "https://example.com" }
Assert.Equal(
telegramMessage "@originalUser" "Original text",
readMessage message
)

[<Fact>]
let readSuperLongLengthTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "text_link" Int64.MaxValue Int64.MaxValue "https://example.com" }
Assert.Equal(
telegramMessage "@originalUser" "Original text",
readMessage message
)

[<Fact>]
let readOverlappingTextLinksMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = Some <| upcast [| createEntity "text_link" 0L 8L "https://example.com/1"
createEntity "text_link" 0L 13L "https://example.com/2" |] }
Assert.Equal(
telegramMessage "@originalUser" "Original [https://example.com/1] text [https://example.com/2]",
readMessage message
)

[<Fact>]
let readNonTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = createEntities "not_link" 0L 0L "https://example.com" }
Assert.Equal(
telegramMessage "@originalUser" "Original text",
readMessage message
)

[<Fact>]
let readNoneTextLinkMessage() =
let message = { createMessage (Some originalUser) (Some "Original text") with
Entities = Some <| upcast [| { Type = "text_link"
Url = None
Offset = 0L
Length = 5L
User = None } |] }
Assert.Equal(
telegramMessage "@originalUser" "Original text",
readMessage message
)

module FlattenMessageTests =
let private flattenMessage = Funogram.MessageConverter.flatten Funogram.MessageConverter.DefaultQuoteSettings
let private flattenMessageLineLimit limit =
Expand Down
33 changes: 32 additions & 1 deletion Emulsion/Telegram/Funogram.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Emulsion.Telegram.Funogram

open System
open System.Threading

open Funogram
Expand All @@ -8,6 +9,7 @@ open Funogram.Api
open Funogram.Types
open Serilog

open System.Text
open Emulsion
open Emulsion.Settings

Expand Down Expand Up @@ -51,10 +53,39 @@ module MessageConverter =
| Some lastName -> sprintf "%s %s" user.FirstName lastName
| None -> user.FirstName

let private getTextLinkEntity = function
| { Type = "text_link"; Url = Some url; Offset = o; Length = l }
when o >= 0L
&& l > 0L
&& o < int64 Int32.MaxValue
&& l < int64 Int32.MaxValue
&& o + l < int64 Int32.MaxValue ->
Some {| Url = url; Offset = o; Length = l |}
| _ -> None

let private applyEntities entities (text: string) =
match entities with
| None -> text
| Some entities ->
let links =
entities
|> Seq.choose getTextLinkEntity
|> Seq.sortBy (fun e -> e.Offset)
let result = StringBuilder()
let mutable pos = 0
for link in links do
let linkEndOffset = min text.Length (int32 (link.Offset + link.Length))
result
.Append(text.Substring(pos, linkEndOffset - pos))
.AppendFormat(" [{0}]", link.Url)
|> ignore
pos <- linkEndOffset
result.Append(text.Substring(pos, text.Length - pos)).ToString()

let private getMessageBodyText (message: FunogramMessage) =
match message.Text with
| None -> "[DATA UNRECOGNIZED]"
| Some text -> text
| Some text -> applyEntities message.Entities text

let private applyLimits limits text =
let applyMessageLengthLimit (original: {| text: string; wasLimited: bool |}) =
Expand Down

0 comments on commit 7cbc428

Please sign in to comment.