forked from sch/Slixfeed
Python : Set OMEMO as an optional dependency;
SVG : Add a selection of variations of the Slixfeed logo.
This commit is contained in:
parent
3913f740ef
commit
178f49cb86
13 changed files with 408 additions and 135 deletions
11
README.md
11
README.md
|
@ -57,9 +57,20 @@ It is possible to install Slixfeed using pip and pipx.
|
||||||
```
|
```
|
||||||
$ python3 -m venv .venv
|
$ python3 -m venv .venv
|
||||||
$ source .venv/bin/activate
|
$ source .venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Install
|
||||||
|
|
||||||
|
```
|
||||||
$ pip install git+https://git.xmpp-it.net/sch/Slixfeed
|
$ pip install git+https://git.xmpp-it.net/sch/Slixfeed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Install (OMEMO)
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pip install git+https://git.xmpp-it.net/sch/Slixfeed[omemo]
|
||||||
|
```
|
||||||
|
|
||||||
#### pipx
|
#### pipx
|
||||||
|
|
||||||
##### Install
|
##### Install
|
||||||
|
|
|
@ -37,33 +37,36 @@ keywords = [
|
||||||
"xml",
|
"xml",
|
||||||
"xmpp",
|
"xmpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
# urls = {Homepage = "https://gitgud.io/sjehuda/slixfeed"}
|
# urls = {Homepage = "https://gitgud.io/sjehuda/slixfeed"}
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aiofiles",
|
"aiofiles",
|
||||||
"aiohttp",
|
"aiohttp",
|
||||||
# "daemonize",
|
# "daemonize",
|
||||||
"feedparser",
|
"feedparser",
|
||||||
"lxml",
|
"lxml",
|
||||||
"omemo", # OMEMO
|
|
||||||
# "pysocks",
|
|
||||||
"protobuf==3.20.3", # OMEMO
|
|
||||||
"python-dateutil",
|
"python-dateutil",
|
||||||
"requests",
|
"requests",
|
||||||
"slixmpp",
|
"slixmpp",
|
||||||
"slixmpp-omemo", # OMEMO
|
|
||||||
"tomli", # Python 3.10
|
"tomli", # Python 3.10
|
||||||
"tomli_w",
|
"tomli_w",
|
||||||
"X3DH", # OMEMO
|
|
||||||
"XEdDSA", # OMEMO
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "http://slixfeed.i2p/"
|
Homepage = "https://slixfeed.woodpeckersnest.space"
|
||||||
Repository = "https://gitgud.io/sjehuda/slixfeed"
|
Repository = "https://git.xmpp-it.net/sch/Slixfeed"
|
||||||
Issues = "https://gitgud.io/sjehuda/slixfeed/issues"
|
Issues = "https://gitgud.io/sjehuda/slixfeed/issues"
|
||||||
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
omemo = [
|
||||||
|
"DoubleRatchet>=0.7.0,<0.8",
|
||||||
|
"OMEMO>=0.13.0,<0.15",
|
||||||
|
"protobuf==3.20.3",
|
||||||
|
"slixmpp-omemo",
|
||||||
|
"X3DH>=0.5.9,<0.6",
|
||||||
|
"XEdDSA<0.5,>=0.4.7",
|
||||||
|
]
|
||||||
proxy = ["pysocks"]
|
proxy = ["pysocks"]
|
||||||
|
|
||||||
# [project.readme]
|
# [project.readme]
|
||||||
|
|
|
@ -28,9 +28,9 @@ Good luck!
|
||||||
|
|
||||||
filetypes = "Atom, JSON, RDF, RSS, XML."
|
filetypes = "Atom, JSON, RDF, RSS, XML."
|
||||||
platforms = "XMPP"
|
platforms = "XMPP"
|
||||||
# platforms = "ActivityPub, Briar, DeltaChat, Email, IRC, LXMF, MQTT, Nostr, Session, Tox."
|
# platforms = "ActivityPub, BitMessage, Briar, DeltaChat, Email, IRC, LXMF, MQTT, Nostr, Session, Tox."
|
||||||
comment = "For ideal experience, we recommend using XMPP." # Nostr, Session or DeltaChat
|
comment = "For ideal experience, we recommend using XMPP." # Nostr, Session or DeltaChat
|
||||||
url = "https://gitgud.io/sjehuda/slixfeed"
|
url = "https://git.xmpp-it.net/sch/Slixfeed"
|
||||||
|
|
||||||
[[about]]
|
[[about]]
|
||||||
name = "slixmpp"
|
name = "slixmpp"
|
||||||
|
@ -260,7 +260,7 @@ Slixfeed is distributed in the hope that it will be useful, but WITHOUT ANY \
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR \
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR \
|
||||||
A PARTICULAR PURPOSE. See the MIT License for more details.
|
A PARTICULAR PURPOSE. See the MIT License for more details.
|
||||||
"""]
|
"""]
|
||||||
link = "https://gitgud.io/sjehuda/slixfeed"
|
link = "https://git.xmpp-it.net/sch/Slixfeed"
|
||||||
|
|
||||||
[[license]]
|
[[license]]
|
||||||
title = "License"
|
title = "License"
|
||||||
|
|
|
@ -1 +1,48 @@
|
||||||
<svg height="600" width="600" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0zm0 0" style="fill:#ffa000" transform="translate(44 44)"/><path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279zm0 0" style="fill:#ffa000" transform="translate(44 44)"/><path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47Zm0 0" style="fill:#ffa000" transform="translate(44 44)"/></svg>
|
<svg height="600" width="600" xmlns="http://www.w3.org/2000/svg" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="5" />
|
||||||
|
<feOffset dx="5" dy="5" result="offsetblur" />
|
||||||
|
<feFlood flood-color="rgba(0,0,0,0.5)" />
|
||||||
|
<feComposite in2="offsetblur" operator="in" />
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode />
|
||||||
|
<feMergeNode in="SourceGraphic" />
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Glass Gradient -->
|
||||||
|
<linearGradient id="glassGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.3); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(255, 255, 255, 0.1); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Black shapes with orange margins -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:#ffa000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:#ffa000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:#ffa000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<!-- Glass Shadow Effect Layer -->
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 2 KiB |
48
slixfeed/assets/image_black.svg
Normal file
48
slixfeed/assets/image_black.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<svg height="600" width="600" xmlns="http://www.w3.org/2000/svg" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="5" />
|
||||||
|
<feOffset dx="5" dy="5" result="offsetblur" />
|
||||||
|
<feFlood flood-color="rgba(0,0,0,0.5)" />
|
||||||
|
<feComposite in2="offsetblur" operator="in" />
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode />
|
||||||
|
<feMergeNode in="SourceGraphic" />
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Glass Gradient -->
|
||||||
|
<linearGradient id="glassGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.3); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(255, 255, 255, 0.1); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Black shapes with orange margins -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:#000000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:#000000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:#000000; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<!-- Glass Shadow Effect Layer -->
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
51
slixfeed/assets/image_semi_transparent.svg
Normal file
51
slixfeed/assets/image_semi_transparent.svg
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<svg height="600" width="600" xmlns="http://www.w3.org/2000/svg" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
<!-- Gradient for Glass Effect -->
|
||||||
|
<linearGradient id="glassGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.5); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(0, 0, 0, 0.2); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="glassHighlight" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.8); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(255, 255, 255, 0); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="5" />
|
||||||
|
<feOffset dx="5" dy="5" result="offsetblur" />
|
||||||
|
<feFlood flood-color="rgba(0, 0, 0, 0.3)" />
|
||||||
|
<feComposite in2="offsetblur" operator="in" />
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode />
|
||||||
|
<feMergeNode in="SourceGraphic" />
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Shapes with Glass Effect -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<!-- Highlights for Shiny Effect -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassHighlight); opacity:0.6;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassHighlight); opacity:0.6;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassHighlight); opacity:0.6;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
48
slixfeed/assets/image_transparent.svg
Normal file
48
slixfeed/assets/image_transparent.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<svg height="600" width="600" xmlns="http://www.w3.org/2000/svg" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="5" />
|
||||||
|
<feOffset dx="5" dy="5" result="offsetblur" />
|
||||||
|
<feFlood flood-color="rgba(0,0,0,0.5)" />
|
||||||
|
<feComposite in2="offsetblur" operator="in" />
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode />
|
||||||
|
<feMergeNode in="SourceGraphic" />
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Glass Gradient -->
|
||||||
|
<linearGradient id="glassGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.3); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(255, 255, 255, 0.1); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Black shapes with orange margins -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<!-- Glass Shadow Effect Layer -->
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
48
slixfeed/assets/image_white.svg
Normal file
48
slixfeed/assets/image_white.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<svg height="600" width="600" xmlns="http://www.w3.org/2000/svg" xml:space="preserve">
|
||||||
|
<defs>
|
||||||
|
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="5" />
|
||||||
|
<feOffset dx="5" dy="5" result="offsetblur" />
|
||||||
|
<feFlood flood-color="rgba(0,0,0,0.5)" />
|
||||||
|
<feComposite in2="offsetblur" operator="in" />
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode />
|
||||||
|
<feMergeNode in="SourceGraphic" />
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Glass Gradient -->
|
||||||
|
<linearGradient id="glassGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:rgba(255, 255, 255, 0.3); stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:rgba(255, 255, 255, 0.1); stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Black shapes with orange margins -->
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:#ffffff; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:#ffffff; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:#ffffff; stroke:#e15a00; stroke-width:10; filter:url(#shadow);"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<!-- Glass Shadow Effect Layer -->
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<path d="M167 406a60 60 0 1 1-120 0 60 60 0 0 1 120 0z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 186v80c110 0 199 89 199 199h80c0-154-125-279-279-279z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
|
||||||
|
<path d="M47 47v79c187 0 338 152 338 339h80C465 234 277 47 47 47z"
|
||||||
|
style="fill:url(#glassGradient); stroke:none;"
|
||||||
|
transform="translate(44 44)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -3032,7 +3032,7 @@ def check_entry_exist(db_file, feed_id, identifier=None, title=None, link=None,
|
||||||
"""
|
"""
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM entries_properties
|
FROM entries_properties
|
||||||
WHERE identifier = :identifier and feed_id = :feed_id
|
WHERE identifier = :identifier AND feed_id = :feed_id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
par = {
|
par = {
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
__version__ = '0.1.94'
|
__version__ = '0.1.95'
|
||||||
__version_info__ = (0, 1, 94)
|
__version_info__ = (0, 1, 95)
|
||||||
|
|
|
@ -36,7 +36,6 @@ import slixfeed.sqlite as sqlite
|
||||||
from slixfeed.syndication import FeedTask
|
from slixfeed.syndication import FeedTask
|
||||||
from slixfeed.utilities import Documentation, Html, MD, Task, Url
|
from slixfeed.utilities import Documentation, Html, MD, Task, Url
|
||||||
from slixfeed.xmpp.commands import XmppCommands
|
from slixfeed.xmpp.commands import XmppCommands
|
||||||
from slixfeed.xmpp.encryption import XmppOmemo
|
|
||||||
from slixfeed.xmpp.message import XmppMessage
|
from slixfeed.xmpp.message import XmppMessage
|
||||||
from slixfeed.xmpp.presence import XmppPresence
|
from slixfeed.xmpp.presence import XmppPresence
|
||||||
from slixfeed.xmpp.status import XmppStatusTask
|
from slixfeed.xmpp.status import XmppStatusTask
|
||||||
|
@ -48,6 +47,10 @@ import sys
|
||||||
import time
|
import time
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
try:
|
||||||
|
from slixfeed.xmpp.encryption import XmppOmemo
|
||||||
|
except Exception as e:
|
||||||
|
print('Encryption of type OMEMO is not enabled. Reason: ' + str(e))
|
||||||
|
|
||||||
logger = Logger(__name__)
|
logger = Logger(__name__)
|
||||||
|
|
||||||
|
@ -150,7 +153,7 @@ class XmppChat:
|
||||||
|
|
||||||
# await compose.message(self, jid_bare, message)
|
# await compose.message(self, jid_bare, message)
|
||||||
|
|
||||||
if self['xep_0384'].is_encrypted(message):
|
if self.omemo_present and self['xep_0384'].is_encrypted(message):
|
||||||
allow_untrusted=True # Temporary fix. This should be handled by "retry""
|
allow_untrusted=True # Temporary fix. This should be handled by "retry""
|
||||||
command, omemo_decrypted, retry = await XmppOmemo.decrypt(
|
command, omemo_decrypted, retry = await XmppOmemo.decrypt(
|
||||||
self, message, allow_untrusted)
|
self, message, allow_untrusted)
|
||||||
|
@ -229,8 +232,8 @@ class XmppChat:
|
||||||
case _ if command_lowercase in ['greetings', 'hallo', 'hello',
|
case _ if command_lowercase in ['greetings', 'hallo', 'hello',
|
||||||
'hey', 'hi', 'hola', 'holla',
|
'hey', 'hi', 'hola', 'holla',
|
||||||
'hollo']:
|
'hollo']:
|
||||||
response = ('Greeting! My name is {}.\n'
|
response = ('Greeting. My name is {}.\n'
|
||||||
'I am an RSS News Bot.\n'
|
'I am an Atom/RSS News Bot.\n'
|
||||||
'Send "help" for further instructions.\n'
|
'Send "help" for further instructions.\n'
|
||||||
.format(self.alias))
|
.format(self.alias))
|
||||||
case _ if command_lowercase.startswith('add'):
|
case _ if command_lowercase.startswith('add'):
|
||||||
|
@ -358,7 +361,7 @@ class XmppChat:
|
||||||
# XmppMessage.send_oob_reply_message(message, url, response)
|
# XmppMessage.send_oob_reply_message(message, url, response)
|
||||||
if url:
|
if url:
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if encrypted:
|
if self.omemo_present and encrypted:
|
||||||
url_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
url_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||||
self, message_from, url)
|
self, message_from, url)
|
||||||
XmppMessage.send_omemo_oob(self, message_from, url_encrypted, chat_type)
|
XmppMessage.send_omemo_oob(self, message_from, url_encrypted, chat_type)
|
||||||
|
@ -591,7 +594,7 @@ class XmppChat:
|
||||||
response = XmppCommands.search_items(db_file, query)
|
response = XmppCommands.search_items(db_file, query)
|
||||||
case 'start':
|
case 'start':
|
||||||
status_type = 'available'
|
status_type = 'available'
|
||||||
status_message = '📫️ Welcome back!'
|
status_message = '📫️ Welcome back.'
|
||||||
XmppPresence.send(self, jid_bare, status_message,
|
XmppPresence.send(self, jid_bare, status_message,
|
||||||
status_type=status_type)
|
status_type=status_type)
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(5)
|
||||||
|
@ -627,7 +630,7 @@ class XmppChat:
|
||||||
if response:
|
if response:
|
||||||
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
||||||
encrypted = True if encrypt_omemo else False
|
encrypted = True if encrypt_omemo else False
|
||||||
if encrypted and self['xep_0384'].is_encrypted(message):
|
if self.omemo_present and encrypted and self['xep_0384'].is_encrypted(message):
|
||||||
response_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
response_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||||
self, message_from, response)
|
self, message_from, response)
|
||||||
if omemo_decrypted and omemo_encrypted:
|
if omemo_decrypted and omemo_encrypted:
|
||||||
|
@ -732,17 +735,17 @@ class XmppChatAction:
|
||||||
media_url = None
|
media_url = None
|
||||||
|
|
||||||
if media_url and news_digest:
|
if media_url and news_digest:
|
||||||
if encrypt_omemo:
|
if self.omemo_present and encrypt_omemo:
|
||||||
news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||||
self, jid, news_digest)
|
self, jid, news_digest)
|
||||||
if encrypt_omemo and omemo_encrypted:
|
if self.omemo_present and encrypt_omemo and omemo_encrypted:
|
||||||
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
||||||
else:
|
else:
|
||||||
# Send textual message
|
# Send textual message
|
||||||
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
||||||
news_digest = ''
|
news_digest = ''
|
||||||
# Send media
|
# Send media
|
||||||
if encrypt_omemo:
|
if self.omemo_present and encrypt_omemo:
|
||||||
cache_dir = config.get_default_cache_directory()
|
cache_dir = config.get_default_cache_directory()
|
||||||
# if not media_url.startswith('data:'):
|
# if not media_url.startswith('data:'):
|
||||||
filename = media_url.split('/').pop().split('?')[0]
|
filename = media_url.split('/').pop().split('?')[0]
|
||||||
|
@ -796,9 +799,10 @@ class XmppChatAction:
|
||||||
media_url = None
|
media_url = None
|
||||||
|
|
||||||
if news_digest:
|
if news_digest:
|
||||||
if encrypt_omemo: news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
if self.omemo_present and encrypt_omemo:
|
||||||
|
news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||||
self, jid, news_digest)
|
self, jid, news_digest)
|
||||||
if encrypt_omemo and omemo_encrypted:
|
if self.omemo_present and encrypt_omemo and omemo_encrypted:
|
||||||
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
||||||
else:
|
else:
|
||||||
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
||||||
|
|
|
@ -54,7 +54,6 @@ from slixfeed.version import __version__
|
||||||
from slixfeed.xmpp.bookmark import XmppBookmark
|
from slixfeed.xmpp.bookmark import XmppBookmark
|
||||||
from slixfeed.xmpp.chat import XmppChat, XmppChatTask
|
from slixfeed.xmpp.chat import XmppChat, XmppChatTask
|
||||||
from slixfeed.xmpp.connect import XmppConnect, XmppConnectTask
|
from slixfeed.xmpp.connect import XmppConnect, XmppConnectTask
|
||||||
from slixfeed.xmpp.encryption import XmppOmemo
|
|
||||||
from slixfeed.xmpp.groupchat import XmppGroupchat
|
from slixfeed.xmpp.groupchat import XmppGroupchat
|
||||||
from slixfeed.xmpp.ipc import XmppIpcServer
|
from slixfeed.xmpp.ipc import XmppIpcServer
|
||||||
from slixfeed.xmpp.iq import XmppIQ
|
from slixfeed.xmpp.iq import XmppIQ
|
||||||
|
@ -69,8 +68,6 @@ from slixfeed.xmpp.status import XmppStatusTask
|
||||||
from slixfeed.xmpp.upload import XmppUpload
|
from slixfeed.xmpp.upload import XmppUpload
|
||||||
from slixfeed.xmpp.utilities import XmppUtilities
|
from slixfeed.xmpp.utilities import XmppUtilities
|
||||||
from slixmpp import JID
|
from slixmpp import JID
|
||||||
import slixmpp_omemo
|
|
||||||
from slixmpp_omemo import PluginCouldNotLoad
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -154,6 +151,17 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
self.register_plugin('xep_0363') # HTTP File Upload
|
self.register_plugin('xep_0363') # HTTP File Upload
|
||||||
self.register_plugin('xep_0402') # PEP Native Bookmarks
|
self.register_plugin('xep_0402') # PEP Native Bookmarks
|
||||||
self.register_plugin('xep_0444') # Message Reactions
|
self.register_plugin('xep_0444') # Message Reactions
|
||||||
|
|
||||||
|
try:
|
||||||
|
from slixfeed.xmpp.encryption import XmppOmemo
|
||||||
|
import slixmpp_omemo
|
||||||
|
from slixmpp_omemo import PluginCouldNotLoad
|
||||||
|
self.omemo_present = True
|
||||||
|
except Exception as e:
|
||||||
|
print('Encryption of type OMEMO is not enabled. Reason: ' + str(e))
|
||||||
|
self.omemo_present = False
|
||||||
|
|
||||||
|
if self.omemo_present:
|
||||||
try:
|
try:
|
||||||
self.register_plugin(
|
self.register_plugin(
|
||||||
'xep_0384',
|
'xep_0384',
|
||||||
|
@ -868,7 +876,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'PubSub')
|
form = self['xep_0004'].make_form('form', 'PubSub')
|
||||||
form['instructions'] = 'Publish news items to PubSub nodes.'
|
form['instructions'] = 'Publish news items to PubSub nodes.'
|
||||||
options = form.add_field(desc='From which medium source do you '
|
options = form.add_field(desc='From which medium source do you '
|
||||||
|
@ -889,16 +897,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['prev'] = None
|
session['prev'] = None
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -909,7 +917,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
values = payload['values']
|
values = payload['values']
|
||||||
form = self['xep_0004'].make_form('form', 'Publish')
|
form = self['xep_0004'].make_form('form', 'Publish')
|
||||||
form['instructions'] = ('Choose a PubSub Jabber ID and verify '
|
form['instructions'] = ('Choose a PubSub Jabber ID and verify '
|
||||||
|
@ -997,16 +1005,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['has_next'] = True
|
session['has_next'] = True
|
||||||
session['prev'] = self._handle_publish
|
session['prev'] = self._handle_publish
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -1413,13 +1421,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
return session
|
return session
|
||||||
|
|
||||||
async def _handle_filters(self, iq, session):
|
async def _handle_filters(self, iq, session):
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
jid = session['from'].bare
|
jid = session['from'].bare
|
||||||
db_file = config.get_pathname_to_database(jid_bare)
|
db_file = config.get_pathname_to_database(jid_bare)
|
||||||
form = self['xep_0004'].make_form('form', 'Filters')
|
form = self['xep_0004'].make_form('form', 'Filters')
|
||||||
|
@ -1458,16 +1467,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['next'] = self._handle_filters_complete
|
session['next'] = self._handle_filters_complete
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -1522,13 +1531,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
|
|
||||||
|
|
||||||
async def _handle_subscription_add(self, iq, session):
|
async def _handle_subscription_add(self, iq, session):
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'Subscribe')
|
form = self['xep_0004'].make_form('form', 'Subscribe')
|
||||||
# form['instructions'] = 'Add a new custom subscription.'
|
# form['instructions'] = 'Add a new custom subscription.'
|
||||||
form.add_field(desc='Enter a URL.',
|
form.add_field(desc='Enter a URL.',
|
||||||
|
@ -1570,16 +1580,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['prev'] = None
|
session['prev'] = None
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -2036,13 +2046,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
|
|
||||||
|
|
||||||
async def _handle_discover(self, iq, session):
|
async def _handle_discover(self, iq, session):
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'Discover & Search')
|
form = self['xep_0004'].make_form('form', 'Discover & Search')
|
||||||
form['instructions'] = 'Discover news subscriptions of all kinds'
|
form['instructions'] = 'Discover news subscriptions of all kinds'
|
||||||
options = form.add_field(desc='Select type of search.',
|
options = form.add_field(desc='Select type of search.',
|
||||||
|
@ -2059,16 +2070,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
session['prev'] = None
|
session['prev'] = None
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -2160,13 +2171,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
|
|
||||||
|
|
||||||
async def _handle_subscriptions(self, iq, session):
|
async def _handle_subscriptions(self, iq, session):
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'Subscriptions')
|
form = self['xep_0004'].make_form('form', 'Subscriptions')
|
||||||
form['instructions'] = ('Browse, view, toggle or remove '
|
form['instructions'] = ('Browse, view, toggle or remove '
|
||||||
'tags and subscriptions.')
|
'tags and subscriptions.')
|
||||||
|
@ -2210,16 +2222,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['next'] = self._handle_subscriptions_result
|
session['next'] = self._handle_subscriptions_result
|
||||||
session['has_next'] = True
|
session['has_next'] = True
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -2520,13 +2532,13 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
|
|
||||||
|
|
||||||
async def _handle_advanced(self, iq, session):
|
async def _handle_advanced(self, iq, session):
|
||||||
jid_full = session['from'].full
|
jid = session['from']
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'Advanced')
|
form = self['xep_0004'].make_form('form', 'Advanced')
|
||||||
form['instructions'] = 'Extended options'
|
form['instructions'] = 'Extended options'
|
||||||
options = form.add_field(ftype='list-single',
|
options = form.add_field(ftype='list-single',
|
||||||
|
@ -2547,16 +2559,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['next'] = self._handle_advanced_result
|
session['next'] = self._handle_advanced_result
|
||||||
session['prev'] = self._handle_advanced
|
session['prev'] = self._handle_advanced
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -2940,6 +2952,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
# TODO Attempt to look up for feeds of hostname of JID (i.e. scan
|
# TODO Attempt to look up for feeds of hostname of JID (i.e. scan
|
||||||
# jabber.de for feeds for juliet@jabber.de)
|
# jabber.de for feeds for juliet@jabber.de)
|
||||||
async def _handle_promoted(self, iq, session):
|
async def _handle_promoted(self, iq, session):
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
|
@ -2947,7 +2960,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
form = self['xep_0004'].make_form('form', 'Subscribe')
|
form = self['xep_0004'].make_form('form', 'Subscribe')
|
||||||
# NOTE Refresh button would be of use
|
# NOTE Refresh button would be of use
|
||||||
form['instructions'] = 'Featured subscriptions'
|
form['instructions'] = 'Featured subscriptions'
|
||||||
|
@ -2998,16 +3011,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
session['prev'] = self._handle_promoted
|
session['prev'] = self._handle_promoted
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -3646,13 +3659,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session. Additional, custom data may be saved
|
session. Additional, custom data may be saved
|
||||||
here to persist across handler callbacks.
|
here to persist across handler callbacks.
|
||||||
"""
|
"""
|
||||||
|
jid = session['from']
|
||||||
jid_full = session['from'].full
|
jid_full = session['from'].full
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
logger.debug('{}: jid_full: {}'
|
logger.debug('{}: jid_full: {}'
|
||||||
.format(function_name, jid_full))
|
.format(function_name, jid_full))
|
||||||
jid_bare = session['from'].bare
|
jid_bare = session['from'].bare
|
||||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
if XmppUtilities.is_access(self, jid, chat_type):
|
||||||
db_file = config.get_pathname_to_database(jid_bare)
|
db_file = config.get_pathname_to_database(jid_bare)
|
||||||
if jid_bare not in self.settings:
|
if jid_bare not in self.settings:
|
||||||
Config.add_settings_jid(self, jid_bare, db_file)
|
Config.add_settings_jid(self, jid_bare, db_file)
|
||||||
|
@ -3750,16 +3764,16 @@ class XmppClient(slixmpp.ClientXMPP):
|
||||||
session['next'] = self._handle_settings_complete
|
session['next'] = self._handle_settings_complete
|
||||||
session['payload'] = form
|
session['payload'] = form
|
||||||
else:
|
else:
|
||||||
if not XmppUtilities.is_operator(self, jid_bare):
|
if chat_type == 'error':
|
||||||
|
text_warn = ('Could not determine chat type of {}.'
|
||||||
|
.format(jid_bare))
|
||||||
|
elif not XmppUtilities.is_operator(self, jid_bare):
|
||||||
text_warn = 'This resource is restricted to operators.'
|
text_warn = 'This resource is restricted to operators.'
|
||||||
elif chat_type == 'groupchat':
|
elif chat_type == 'groupchat':
|
||||||
text_warn = ('This resource is restricted to moderators of {}.'
|
text_warn = ('This resource is restricted to moderators of {}.'
|
||||||
.format(jid_bare))
|
.format(jid_bare))
|
||||||
elif chat_type == 'error':
|
|
||||||
text_warn = ('Could not determine chat type of {}.'
|
|
||||||
.format(jid_bare))
|
|
||||||
else:
|
else:
|
||||||
text_warn = 'This resource is forbidden.'
|
text_warn = 'This resource is restricted.'
|
||||||
session['notes'] = [['warn', text_warn]]
|
session['notes'] = [['warn', text_warn]]
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,8 @@ logger = Logger(__name__)
|
||||||
# class XmppChat
|
# class XmppChat
|
||||||
# class XmppUtility:
|
# class XmppUtility:
|
||||||
|
|
||||||
|
|
||||||
class XmppUtilities:
|
class XmppUtilities:
|
||||||
|
|
||||||
|
|
||||||
async def get_chat_type(self, jid):
|
async def get_chat_type(self, jid):
|
||||||
"""
|
"""
|
||||||
Check chat (i.e. JID) type.
|
Check chat (i.e. JID) type.
|
||||||
|
@ -60,21 +58,18 @@ class XmppUtilities:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def is_access(self, jid, chat_type):
|
||||||
def is_access(self, jid_bare, jid_full, chat_type):
|
|
||||||
"""Determine access privilege"""
|
"""Determine access privilege"""
|
||||||
operator = XmppUtilities.is_operator(self, jid_bare)
|
room = jid_bare = jid.bare
|
||||||
if operator:
|
alias = jid.resource
|
||||||
if chat_type == 'groupchat':
|
if chat_type == 'groupchat':
|
||||||
if XmppUtilities.is_moderator(self, jid_bare, jid_full):
|
access = True if XmppUtilities.is_moderator(self, room, alias) else False
|
||||||
access = True
|
if access: print('Access granted to groupchat moderator ' + alias)
|
||||||
else:
|
else:
|
||||||
|
print('Access granted to chat ' + jid_bare)
|
||||||
access = True
|
access = True
|
||||||
else:
|
|
||||||
access = False
|
|
||||||
return access
|
return access
|
||||||
|
|
||||||
|
|
||||||
def is_operator(self, jid_bare):
|
def is_operator(self, jid_bare):
|
||||||
"""Check if given JID is an operator"""
|
"""Check if given JID is an operator"""
|
||||||
result = False
|
result = False
|
||||||
|
@ -85,24 +80,28 @@ class XmppUtilities:
|
||||||
break
|
break
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def is_admin(self, room, alias):
|
||||||
def is_moderator(self, jid_bare, jid_full):
|
"""Check if given JID is an administrator"""
|
||||||
"""Check if given JID is a moderator"""
|
affiliation = self.plugin['xep_0045'].get_jid_property(room, alias, 'affiliation')
|
||||||
alias = jid_full[jid_full.index('/')+1:]
|
result = True if affiliation == 'admin' else False
|
||||||
role = self.plugin['xep_0045'].get_jid_property(jid_bare, alias, 'role')
|
|
||||||
if role == 'moderator':
|
|
||||||
result = True
|
|
||||||
else:
|
|
||||||
result = False
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def is_owner(self, room, alias):
|
||||||
|
"""Check if given JID is an owner"""
|
||||||
|
affiliation = self.plugin['xep_0045'].get_jid_property(room, alias, 'affiliation')
|
||||||
|
result = True if affiliation == 'owner' else False
|
||||||
|
return result
|
||||||
|
|
||||||
|
def is_moderator(self, room, alias):
|
||||||
|
"""Check if given JID is a moderator"""
|
||||||
|
role = self.plugin['xep_0045'].get_jid_property(room, alias, 'role')
|
||||||
|
result = True if role == 'moderator' else False
|
||||||
|
return result
|
||||||
|
|
||||||
|
# NOTE Would this properly work when Alias and Local differ?
|
||||||
def is_member(self, jid_bare, jid_full):
|
def is_member(self, jid_bare, jid_full):
|
||||||
"""Check if given JID is a member"""
|
"""Check if given JID is a member"""
|
||||||
alias = jid_full[jid_full.index('/')+1:]
|
alias = jid_full[jid_full.index('/')+1:]
|
||||||
affiliation = self.plugin['xep_0045'].get_jid_property(jid_bare, alias, 'affiliation')
|
affiliation = self.plugin['xep_0045'].get_jid_property(jid_bare, alias, 'affiliation')
|
||||||
if affiliation == 'member':
|
result = True if affiliation == 'member' else False
|
||||||
result = True
|
|
||||||
else:
|
|
||||||
result = False
|
|
||||||
return result
|
return result
|
Loading…
Reference in a new issue