-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4ef79d8
commit d7028d3
Showing
10 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .transcript import Transcript # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .transcript import Transcript # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .factory import transcribe # noqa: F401 | ||
from .item import Item # noqa: F401 |
16 changes: 16 additions & 0 deletions
16
securedrop_client/conversation/transcript/items/factory.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from typing import Optional | ||
|
||
from securedrop_client import db as database | ||
|
||
from .file import File | ||
from .item import Item | ||
from .message import Message | ||
|
||
|
||
def transcribe(record: database.Base) -> Optional[Item]: | ||
if isinstance(record, database.Message) or isinstance(record, database.Reply): | ||
return Message(record) | ||
if isinstance(record, database.File): | ||
return File(record) | ||
else: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from gettext import gettext as _ | ||
from typing import Optional | ||
|
||
from securedrop_client import db as database | ||
|
||
from .item import Item | ||
|
||
|
||
class File(Item): | ||
def __init__(self, record: database.File): | ||
super().__init__() | ||
|
||
self.filename = record.filename | ||
self.sender = record.source.journalist_designation | ||
|
||
@property | ||
def context(self) -> Optional[str]: | ||
return _("{username} sent:\n").format(username=self.sender) | ||
|
||
@property | ||
def transcript(self) -> str: | ||
return _("File: {filename}\n").format(filename=self.filename) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from typing import Optional | ||
|
||
|
||
class Item: | ||
@property | ||
def transcript(self) -> str: | ||
"""A transcription of the conversation item.""" | ||
raise NotImplementedError # pragma: nocover | ||
|
||
@property | ||
def context(self) -> Optional[str]: | ||
"""Some context about the conversation item.""" | ||
raise NotImplementedError # pragma: nocover |
26 changes: 26 additions & 0 deletions
26
securedrop_client/conversation/transcript/items/message.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from gettext import gettext as _ | ||
from typing import Optional, Union | ||
|
||
from securedrop_client import db as database | ||
|
||
from .item import Item | ||
|
||
|
||
class Message(Item): | ||
def __init__(self, record: Union[database.Message, database.Reply]): | ||
super().__init__() | ||
|
||
self.content = record.content | ||
|
||
if isinstance(record, database.Message): | ||
self.sender = record.source.journalist_designation | ||
else: | ||
self.sender = record.journalist.username | ||
|
||
@property | ||
def context(self) -> Optional[str]: | ||
return _("{username} wrote:\n").format(username=self.sender) | ||
|
||
@property | ||
def transcript(self) -> str: | ||
return self.content + "\n" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from typing import List, Optional | ||
|
||
from securedrop_client import db as database | ||
|
||
from .items import Item | ||
from .items import transcribe as transcribe_item | ||
|
||
|
||
def transcribe(record: database.Base) -> Optional[Item]: | ||
return transcribe_item(record) | ||
|
||
|
||
_ENTRY_SEPARATOR = "------\n" | ||
|
||
|
||
class Transcript: | ||
def __init__(self, conversation: database.Source) -> None: | ||
|
||
self._items = [transcribe(record) for record in conversation.collection] | ||
|
||
def __str__(self) -> str: | ||
if len(self._items) <= 0: | ||
return "No messages." | ||
|
||
entries: List[str] = [] | ||
|
||
context: Optional[str] = None | ||
|
||
for item in self._items: | ||
if item is None: | ||
continue | ||
|
||
if context is not None and context == item.context: | ||
entry = item.transcript | ||
elif item.context is None: | ||
entry = item.transcript # pragma: nocover | ||
else: | ||
entry = f"{item.context}{item.transcript}" | ||
|
||
entries.append(entry) | ||
|
||
context = item.context | ||
|
||
return _ENTRY_SEPARATOR.join(entries) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import unittest | ||
from datetime import datetime | ||
from textwrap import dedent | ||
|
||
from securedrop_client import conversation | ||
from securedrop_client import db as database | ||
|
||
|
||
class TestConversationTranscript(unittest.TestCase): | ||
def setUp(self): | ||
|
||
source = database.Source( | ||
journalist_designation="happy-bird", | ||
) | ||
files = [ | ||
database.File( | ||
filename="4-memo.pdf.gpg", | ||
is_downloaded=True, | ||
), | ||
database.File( | ||
filename="9-memo.zip.gpg", | ||
is_downloaded=True, | ||
), | ||
] | ||
messages = [ | ||
database.Message( | ||
filename="1-message.gpg", | ||
is_downloaded=True, | ||
content="Hello! I think this is newsworthy: ...", | ||
), | ||
database.Message( | ||
filename="6-message.gpg", | ||
is_downloaded=True, | ||
content="I can send you more if you're interested.", | ||
), | ||
database.Message( | ||
filename="5-message.gpg", | ||
is_downloaded=True, | ||
content="Here is a document with details!", | ||
), | ||
database.Message( | ||
filename="8-message.gpg", | ||
is_downloaded=True, | ||
content="Sure.", | ||
), | ||
] | ||
interested_journalist = database.User(username="interested-journalist") | ||
other_journalist = database.User(username="other-journalist") | ||
replies = [ | ||
database.Reply( | ||
journalist=interested_journalist, | ||
filename="2-reply.gpg", | ||
is_downloaded=True, | ||
content=dedent( | ||
"""\ | ||
Thank you for the tip! | ||
Can you tell me more about... ? | ||
""" | ||
), | ||
), | ||
database.Reply( | ||
journalist=interested_journalist, | ||
filename="3-reply.gpg", | ||
is_downloaded=True, | ||
content=dedent( | ||
"""\ | ||
Do you have proof of...? | ||
""" | ||
), | ||
), | ||
database.Reply( | ||
journalist=other_journalist, | ||
filename="7-reply.gpg", | ||
is_downloaded=True, | ||
content=dedent("Yes, the document you sent was useful, I'd love to see more."), | ||
), | ||
] | ||
draft_reply = database.DraftReply( | ||
content="Let me think...", | ||
file_counter=2, | ||
timestamp=datetime.now(), | ||
) | ||
source.files = files | ||
source.messages = messages | ||
source.replies = replies | ||
source.draftreplies = [draft_reply] | ||
|
||
self._source = source | ||
|
||
def test_indicates_explicitly_absence_of_messages(self): | ||
source = database.Source() | ||
assert str(conversation.Transcript(source)) == "No messages." | ||
|
||
def test_renders_all_messages(self): | ||
assert str(conversation.Transcript(self._source)) == dedent( | ||
"""\ | ||
happy-bird wrote: | ||
Hello! I think this is newsworthy: ... | ||
------ | ||
interested-journalist wrote: | ||
Thank you for the tip! | ||
Can you tell me more about... ? | ||
------ | ||
Do you have proof of...? | ||
------ | ||
happy-bird sent: | ||
File: 4-memo.pdf.gpg | ||
------ | ||
happy-bird wrote: | ||
Here is a document with details! | ||
------ | ||
I can send you more if you're interested. | ||
------ | ||
other-journalist wrote: | ||
Yes, the document you sent was useful, I'd love to see more. | ||
------ | ||
happy-bird wrote: | ||
Sure. | ||
------ | ||
happy-bird sent: | ||
File: 9-memo.zip.gpg | ||
""" | ||
) |