Code Polyglot!
Последние сниппеты
→
06-мар-2021 15:23:36
→
06-мар-2021 15:23:22
→
26-фев-2021 19:29:55
→
26-фев-2021 19:29:44
→
26-фев-2021 19:29:30
→
26-фев-2021 16:39:28
→
19-фев-2021 01:20:50
→
dtf-login.…
→
08-фев-2021 11:20:42
→
08-фев-2021 11:20:43
→
08-фев-2021 11:19:46
→
08-фев-2021 11:19:45
→
08-фев-2021 08:56:10
→
08-фев-2021 08:56:10
→
22-янв-2021 16:39:12
→
22-янв-2021 16:38:40
→
21-янв-2021 08:40:33
→
19-янв-2021 17:04:24
→
19-янв-2021 17:04:14
→
19-янв-2021 17:04:08
→
19-янв-2021 17:03:46
→
12-янв-2021 10:06:55
→
11-янв-2021 22:48:29
→
11-янв-2021 22:48:11
→
11-янв-2021 22:45:38
→
11-янв-2021 22:44:22
→
11-янв-2021 22:43:38
→
10-янв-2021 20:55:51
→
08-янв-2021 20:15:42
→
08-янв-2021 20:15:09
→
08-янв-2021 19:22:34
→
08-янв-2021 19:22:04
→
08-янв-2021 19:22:05
→
08-янв-2021 05:09:46
→
08-янв-2021 05:09:21
→
02-янв-2021 19:24:15
→
02-янв-2021 19:24:01
→
02-янв-2021 19:23:58
→
02-янв-2021 19:23:39
→
02-янв-2021 19:23:28
→
02-янв-2021 19:23:24
→
02-янв-2021 19:23:20
→
02-янв-2021 19:23:13
→
02-янв-2021 19:22:30
→
02-янв-2021 19:22:27
→
02-янв-2021 19:22:20
→
02-янв-2021 19:22:16
→
02-янв-2021 19:22:11
→
02-янв-2021 19:22:00
→
02-янв-2021 19:21:54
|
2 января, суббота, 2021 | 00:47:04
↓
Скопировано в буфер обмена!
1
import
dataclasses
2
import
mimetypes
3
import
os
4
from
datetime
import
datetime
5
from
functools
import
cached_property
6
from
typing
import
Optional
,
Tuple
7
from
urllib.parse
import
urlparse
8
9
from
feed_proxy.utils
import
make_hash_tags
10
11
MISSING
=
object
()
12
TYPES_MAPPING
=
{
13
bool
:
'getboolean'
,
14
float
:
'getfloat'
,
15
int
:
'getint'
,
16
tuple
:
'gettuple'
,
17
}
18
OPTIONS_MAPPING
=
{
19
'post_template'
:
'gettemplate'
,
20
'keys_mapping'
:
'getmapping'
,
21
}
22
23
24
@dataclasses
.
dataclass
(
frozen
=
True
)
25
class
Source
:
26
name
:
str
27
url
:
str
28
receiver
:
str
29
post_template
:
str
30
check_processed_until_first_match
:
bool
=
True
31
disable_link_preview
:
bool
=
False
32
tags
:
tuple
=
tuple
()
33
id_field
:
str
=
'id'
34
url_field
:
str
=
'link'
35
encoding
:
Optional
[
str
]
=
None
36
37
@cached_property
38
def
hash_tags
(
self
)
->
tuple
:
39
return
tuple
(
make_hash_tags
(
self
.
tags
))
40
41
classmethod
42
def
from_config
(
cls
,
config
):
43
fields
=
[(
f
.
name
,
f
.
type
)
for
f
in
dataclasses
.
fields
(
cls
)
if
f
.
init
and
f
.
name
!=
'name'
]
44
values
=
{
'name'
:
config
.
name
}
45
46
for
name
,
type_
in
fields
:
47
converter
=
OPTIONS_MAPPING
.
get
(
name
)
or
TYPES_MAPPING
.
get
(
type_
)
or
'get'
48
value
=
getattr
(
config
,
converter
)(
name
,
MISSING
)
49
if
value
is
not
MISSING
:
50
values
[
name
]
=
value
51
return
cls
(
**
values
)
52
53
54
@dataclasses
.
dataclass
(
frozen
=
True
)
55
class
Author
:
56
name
:
str
57
href
:
str
=
''
58
email
:
str
=
''
59
60
61
@dataclasses
.
dataclass
(
frozen
=
True
)
62
class
Attachment
:
63
href
:
str
64
type
:
str
65
length
:
int
66
67
@cached_property
68
def
is_audio
(
self
)
->
bool
:
69
return
self
.
type
.
startswith
(
'audio/'
)
70
71
def
guess_extension
(
self
)
->
Optional
[
str
]:
72
if
from_mime
:=
mimetypes
.
guess_extension
(
self
.
type
):
73
return
from_mime
74
75
path
=
urlparse
(
self
.
href
)
.
path
76
return
os
.
path
.
splitext
(
path
)[
1
]
or
None
77
78
79
@dataclasses
.
dataclass
(
frozen
=
True
)
80
class
Post
:
81
author
:
str
82
authors
:
Tuple
[
Author
,
...
]
83
id
:
str
84
url
:
str
85
summary
:
str
86
title
:
str
87
source
:
Source
88
89
tags
:
Tuple
[
str
,
...
]
=
tuple
()
90
attachments
:
Tuple
[
Attachment
,
...
]
=
tuple
()
91
published
:
Optional
[
datetime
]
=
None
92
93
def
has_audio
(
self
)
->
bool
:
94
return
any
(
item
.
is_audio
for
item
in
self
.
attachments
)
95
96
@cached_property
97
def
audio
(
self
)
->
Optional
[
Attachment
]:
98
return
next
((
item
for
item
in
self
.
attachments
if
item
.
is_audio
),
None
)
99
100
@cached_property
101
def
hash_tags
(
self
)
->
tuple
:
102
return
tuple
(
make_hash_tags
(
self
.
tags
))
103
104
@cached_property
105
def
message_text
(
self
)
->
str
:
106
source_tags
=
' '
.
join
(
self
.
source
.
hash_tags
)
107
post_tags
=
' '
.
join
(
self
.
hash_tags
)
108
published
=
''
109
if
self
.
published
:
110
published
=
self
.
published
.
strftime
(
'
%d
-%m-%Y %H:%M:%S'
)
111
112
return
self
.
source
.
post_template
.
format
(
113
all_tags
=
f
'
{
source_tags
}
{
post_tags
}
'
,
114
source_tags
=
source_tags
,
115
post_tags
=
post_tags
,
116
source_name
=
self
.
source
.
name
,
117
author
=
self
.
author
,
118
url
=
self
.
url
,
119
summary
=
self
.
summary
,
120
title
=
self
.
title
,
121
published
=
published
,
122
)
.
strip
()
```
import dataclasses import mimetypes import os from datetime import datetime from functools import cached_property from typing import Optional, Tuple from urllib.parse import urlparse from feed_proxy.utils import make_hash_tags MISSING = object() TYPES_MAPPING = { bool: 'getboolean', float: 'getfloat', int: 'getint', tuple: 'gettuple', } OPTIONS_MAPPING = { 'post_template': 'gettemplate', 'keys_mapping': 'getmapping', } @dataclasses.dataclass(frozen=True) class Source: name: str url: str receiver: str post_template: str check_processed_until_first_match: bool = True disable_link_preview: bool = False tags: tuple = tuple() id_field: str = 'id' url_field: str = 'link' encoding: Optional[str] = None @cached_property def hash_tags(self) -> tuple: return tuple(make_hash_tags(self.tags)) @classmethod def from_config(cls, config): fields = [(f.name, f.type) for f in dataclasses.fields(cls) if f.init and f.name != 'name'] values = {'name': config.name} for name, type_ in fields: converter = OPTIONS_MAPPING.get(name) or TYPES_MAPPING.get(type_) or 'get' value = getattr(config, converter)(name, MISSING) if value is not MISSING: values[name] = value return cls(**values) @dataclasses.dataclass(frozen=True) class Author: name: str href: str = '' email: str = '' @dataclasses.dataclass(frozen=True) class Attachment: href: str type: str length: int @cached_property def is_audio(self) -> bool: return self.type.startswith('audio/') def guess_extension(self) -> Optional[str]: if from_mime := mimetypes.guess_extension(self.type): return from_mime path = urlparse(self.href).path return os.path.splitext(path)[1] or None @dataclasses.dataclass(frozen=True) class Post: author: str authors: Tuple[Author, ...] id: str url: str summary: str title: str source: Source tags: Tuple[str, ...] = tuple() attachments: Tuple[Attachment, ...] = tuple() published: Optional[datetime] = None def has_audio(self) -> bool: return any(item.is_audio for item in self.attachments) @cached_property def audio(self) -> Optional[Attachment]: return next((item for item in self.attachments if item.is_audio), None) @cached_property def hash_tags(self) -> tuple: return tuple(make_hash_tags(self.tags)) @cached_property def message_text(self) -> str: source_tags = ' '.join(self.source.hash_tags) post_tags = ' '.join(self.hash_tags) published = '' if self.published: published = self.published.strftime('%d-%m-%Y %H:%M:%S') return self.source.post_template.format( all_tags=f'{source_tags} {post_tags}', source_tags=source_tags, post_tags=post_tags, source_name=self.source.name, author=self.author, url=self.url, summary=self.summary, title=self.title, published=published, ).strip()
Язык
Библиотека
VM
Скорость
JavaScript 20.3.0
Highlight.js 10.4.1
GraalVM
Быстро
Ruby 2.6.6
Rouge 3.26.0
GraalVM
Приемлемо
Время рендеринга подсветки синтаксиса на сервере:
458
ms.
```
Версия Code Polyglot:
1.0.0, 40b65db_190, 19-Jan-2021 15:55:44