Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Lyse
libtwtxt
Commits
cdc4c41c
Commit
cdc4c41c
authored
Aug 03, 2021
by
Lysander Trischler
Browse files
Add subject
parent
fe122d6f
Changes
3
Hide whitespace changes
Inline
Side-by-side
libgotwtxt.py
View file @
cdc4c41c
...
...
@@ -55,18 +55,38 @@ class _Link(ctypes.Structure):
def
to_python
(
self
):
link
=
Link
()
if
self
.
text
is
not
None
:
if
self
.
text
:
link
.
text
=
self
.
text
.
decode
(
"utf-8"
)
if
self
.
target
is
not
None
:
if
self
.
target
:
link
.
target
=
self
.
target
.
decode
(
"utf-8"
)
return
link
class
Subject
:
def
__init__
(
self
,
text
=
None
,
tag
=
None
):
self
.
text
=
text
self
.
tag
=
tag
class
_Subject
(
ctypes
.
Structure
):
_fields_
=
[(
"text"
,
ctypes
.
c_char_p
),
(
"tag"
,
ctypes
.
POINTER
(
_Link
))]
def
to_python
(
self
):
subject
=
Subject
()
if
self
.
text
:
subject
.
text
=
self
.
text
.
decode
(
"utf-8"
)
if
self
.
tag
:
subject
.
tag
=
self
.
tag
.
contents
.
to_python
()
return
subject
class
Twt
:
def
__init__
(
self
,
twter
=
None
,
created
=
None
,
hash
=
None
,
links
=
None
):
def
__init__
(
self
,
twter
=
None
,
created
=
None
,
hash
=
None
,
subject
=
None
,
links
=
None
):
self
.
twter
=
twter
self
.
created
=
created
self
.
hash
=
hash
self
.
subject
=
subject
self
.
links
=
links
...
...
@@ -74,6 +94,7 @@ class _Twt(ctypes.Structure):
_fields_
=
[(
"twter"
,
ctypes
.
POINTER
(
_Twter
)),
(
"created"
,
ctypes
.
c_char_p
),
(
"hash"
,
ctypes
.
c_char_p
),
(
"subject"
,
ctypes
.
POINTER
(
_Subject
)),
(
"links"
,
ctypes
.
POINTER
(
ctypes
.
POINTER
(
_Link
))),
(
"links_len"
,
ctypes
.
c_int
)]
...
...
@@ -85,6 +106,8 @@ class _Twt(ctypes.Structure):
twt
.
created
=
datetime
.
datetime
.
fromisoformat
(
self
.
created
.
decode
(
"utf-8"
))
if
self
.
hash
is
not
None
:
twt
.
hash
=
self
.
hash
.
decode
(
"utf-8"
)
if
self
.
subject
is
not
None
:
twt
.
subject
=
self
.
subject
.
contents
.
to_python
()
twt
.
links
=
[]
for
i
in
range
(
self
.
links_len
):
...
...
libtwtxt.go
View file @
cdc4c41c
...
...
@@ -24,7 +24,7 @@ struct twt {
struct twter *twter;
char *created;
char *hash;
//
struct subject *subject;
struct subject *subject;
//struct twter *mentions[];
struct link *links;
int links_len;
...
...
@@ -127,6 +127,9 @@ func convertTwt(t types.Twt) *C.struct_twt {
twt
.
twter
=
convertTwter
(
t
.
Twter
())
twt
.
created
=
C
.
CString
(
t
.
Created
()
.
Format
(
time
.
RFC3339
))
twt
.
hash
=
C
.
CString
(
t
.
Hash
())
if
subject
,
ok
:=
t
.
Subject
()
.
(
*
lextwt
.
Subject
);
ok
&&
subject
!=
nil
{
twt
.
subject
=
convertSubject
(
subject
)
}
linksPtr
:=
C
.
malloc
(
C
.
size_t
(
len
(
t
.
Links
()))
*
C
.
size_t
(
unsafe
.
Sizeof
(
uintptr
(
0
))))
links
:=
(
*
[
1
<<
30
-
1
]
*
C
.
struct_link
)(
linksPtr
)
...
...
@@ -144,6 +147,7 @@ func freeTwt(t *C.struct_twt) {
freeTwter
(
t
.
twter
)
free_string
(
t
.
created
)
free_string
(
t
.
hash
)
freeSubject
(
t
.
subject
)
freeLinks
(
t
.
links
,
t
.
links_len
)
C
.
free
(
unsafe
.
Pointer
(
t
))
}
...
...
@@ -159,6 +163,32 @@ func freeTwts(t *C.struct_twt, length C.int) {
}
}
func
convertSubject
(
s
types
.
Subject
)
*
C
.
struct_subject
{
ptr
:=
C
.
malloc
(
C
.
sizeof_struct_subject
)
subject
:=
(
*
C
.
struct_subject
)(
ptr
)
subject
.
text
=
C
.
CString
(
s
.
Text
())
if
tag
,
ok
:=
s
.
Tag
()
.
(
*
lextwt
.
Tag
);
ok
&&
tag
!=
nil
{
subject
.
tag
=
convertTag
(
tag
)
}
return
subject
}
func
freeSubject
(
s
*
C
.
struct_subject
)
{
if
s
!=
nil
{
free_string
(
s
.
text
)
freeLink
(
s
.
tag
)
C
.
free
(
unsafe
.
Pointer
(
s
))
}
}
func
convertTag
(
t
types
.
TwtTag
)
*
C
.
struct_link
{
ptr
:=
C
.
malloc
(
C
.
sizeof_struct_link
)
link
:=
(
*
C
.
struct_link
)(
ptr
)
link
.
text
=
C
.
CString
(
t
.
Text
())
link
.
target
=
C
.
CString
(
t
.
Target
())
return
link
}
func
convertLink
(
l
types
.
TwtLink
)
*
C
.
struct_link
{
ptr
:=
C
.
malloc
(
C
.
sizeof_struct_link
)
link
:=
(
*
C
.
struct_link
)(
ptr
)
...
...
test_libgotwtxt.py
View file @
cdc4c41c
...
...
@@ -2,7 +2,7 @@
import
datetime
import
unittest
from
libgotwtxt
import
Link
,
parse_file
,
Twt
,
Twter
from
libgotwtxt
import
Link
,
parse_file
,
Subject
,
Twt
,
Twter
UTC_PLUS_2
=
datetime
.
timezone
(
datetime
.
timedelta
(
hours
=
2
))
TWTER
=
Twter
(
nick
=
"hugo"
,
...
...
@@ -18,7 +18,9 @@ class ParseFileTest(unittest.TestCase):
self
.
assertEqual
(
1
,
len
(
twtfile
.
twts
),
"number of twts does not match"
)
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
2
,
10
,
27
,
42
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"slrnx6a"
,
links
=
[]),
hash
=
"slrnx6a"
,
subject
=
Subject
(
text
=
"#slrnx6a"
,
tag
=
Link
(
text
=
"slrnx6a"
,
target
=
None
)),
links
=
[]),
twtfile
.
twts
[
0
])
...
...
@@ -32,11 +34,15 @@ class ParseFileTest(unittest.TestCase):
self
.
assertEqual
(
2
,
len
(
twtfile
.
twts
),
"number of twts does not match"
)
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
2
,
10
,
27
,
42
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"slrnx6a"
,
links
=
[]),
hash
=
"slrnx6a"
,
subject
=
Subject
(
text
=
"#slrnx6a"
,
tag
=
Link
(
text
=
"slrnx6a"
,
target
=
None
)),
links
=
[]),
twtfile
.
twts
[
0
],
"first twt does not match"
)
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
3
,
9
,
28
,
45
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"zm7fnka"
,
links
=
[]),
hash
=
"zm7fnka"
,
subject
=
Subject
(
text
=
"#zm7fnka"
,
tag
=
Link
(
text
=
"zm7fnka"
,
target
=
None
)),
links
=
[]),
twtfile
.
twts
[
1
],
"second twt does not match"
)
...
...
@@ -51,10 +57,33 @@ class ParseFileTest(unittest.TestCase):
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
3
,
11
,
16
,
13
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"zv6vujq"
,
subject
=
Subject
(
text
=
"#zv6vujq"
,
tag
=
Link
(
text
=
"zv6vujq"
,
target
=
None
)),
links
=
[
Link
(
text
=
"wonderful"
,
target
=
"https://example.com/"
),
Link
(
text
=
"nice"
,
target
=
"https://example.com/test"
)]),
twtfile
.
twts
[
0
])
def
test_subjects
(
self
):
twtfile
=
parse_file
(
"2021-08-03T12:28:26+02:00
\t
(#<1234567 https://example.com/1234567>) I agree!
\n
"
"2021-08-03T12:33:17+02:00
\t
(re: foo) Well, it's quite complicated.
\n
"
,
TWTER
)
self
.
assertIsNotNone
(
twtfile
,
"parse_file returned None"
)
self
.
assertTwterEqual
(
TWTER
,
twtfile
.
twter
,
"twter of twt file does not match"
)
self
.
assertEqual
(
2
,
len
(
twtfile
.
twts
),
"number of twts does not match"
)
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
3
,
12
,
28
,
26
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"g2xdgsq"
,
subject
=
Subject
(
text
=
"#<1234567 https://example.com/1234567>"
,
tag
=
Link
(
text
=
"1234567"
,
target
=
"https://example.com/1234567"
)),
links
=
[]),
twtfile
.
twts
[
0
],
"first twt does not match"
)
self
.
assertTwtEqual
(
Twt
(
twter
=
TWTER
,
created
=
datetime
.
datetime
(
2021
,
8
,
3
,
12
,
33
,
17
,
tzinfo
=
UTC_PLUS_2
),
hash
=
"wqw7ipq"
,
subject
=
Subject
(
text
=
"re: foo"
,
tag
=
None
),
links
=
[]),
twtfile
.
twts
[
1
],
"second twt does not match"
)
def
msg
(
self
,
message_prefix
):
"""Construct a message factory using the prefix, if present."""
...
...
@@ -78,6 +107,8 @@ class ParseFileTest(unittest.TestCase):
self
.
assertTwterEqual
(
expected
.
twter
,
actual
.
twter
,
msg
(
"twter of twt does not match"
))
self
.
assertEqual
(
expected
.
created
,
actual
.
created
,
msg
(
"twt creation timestamp does not match"
))
self
.
assertEqual
(
expected
.
hash
,
actual
.
hash
,
msg
(
"twt hash does not match"
))
self
.
assertSubjectEqual
(
expected
.
subject
,
actual
.
subject
,
"twt subject does not match"
)
if
expected
.
links
is
None
:
self
.
assertIsNone
(
actual
.
links
,
"twt links do not match"
)
else
:
...
...
@@ -89,9 +120,22 @@ class ParseFileTest(unittest.TestCase):
def
assertLinkEqual
(
self
,
expected
,
actual
,
msg
=
None
):
msg
=
self
.
msg
(
msg
)
if
expected
is
None
:
self
.
assertIsNone
(
actual
,
msg
(
"link must be None"
))
return
self
.
assertIsNotNone
(
actual
,
msg
(
"link is None"
))
self
.
assertEqual
(
expected
.
text
,
actual
.
text
,
msg
(
"link text does not match"
))
self
.
assertEqual
(
expected
.
target
,
actual
.
target
,
msg
(
"link target does not match"
))
def
assertSubjectEqual
(
self
,
expected
,
actual
,
msg
=
None
):
msg
=
self
.
msg
(
msg
)
if
expected
is
None
:
self
.
assertIsNone
(
actual
,
msg
(
"subject must be None"
))
return
self
.
assertIsNotNone
(
actual
,
msg
(
"subject is None"
))
self
.
assertEqual
(
expected
.
text
,
actual
.
text
,
msg
(
"subject text does not match"
))
self
.
assertLinkEqual
(
expected
.
tag
,
actual
.
tag
,
msg
(
"subject tag does not match"
))
if
__name__
==
"__main__"
:
unittest
.
main
()
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment