Compare commits

...

22 Commits

Author SHA1 Message Date
knotteye 4d5b8e6bc1 Bump version to 1.0.3 3 years ago
knotteye ac324d0402 Properly mark chats as read 3 years ago
knotteye 2ede34c207 Open new chats when we don't have one yet 3 years ago
knotteye 26e904b5e9 Ask for new 2fa codes when one doesn't work 3 years ago
knotteye 0e34a3b196 Handle cases of bad login info 3 years ago
knotteye e73f9afa6c Add new assets and ship with makefile 3 years ago
knotteye a510f5faf3 Add sound to notifications, and a silence option 3 years ago
knotteye 4560215d7a Handle bad acctList settings 3 years ago
knotteye 4b55caca87 Fix .deb 3 years ago
knotteye a82116b1b5 Switch to running from source for dpkg 3 years ago
knotteye 51eea001d7 ignore a thing 3 years ago
knotteye edd5d87477 figure out .deb files for real haha totally this time 3 years ago
knotteye ab57a11a25 Update linux info 3 years ago
knotteye ade5c0d6d0 Manually clean up on debian 3 years ago
knotteye 691c79fc9a Update version, oops 3 years ago
knotteye 51ee61ff26 Tweak windows build targets 3 years ago
knotteye 863a0ef45c Update postinst script debian 3 years ago
knotteye 1cd48d60ce Pack up the windows installer 3 years ago
knotteye 3119434b29 fix an issue with makefile not making 3 years ago
knotteye 80fd4acb51 Ignore windows build system outputs 3 years ago
knotteye d3e9f3ac6f Clean up build system 3 years ago
knotteye 1c633628ee Update version 3 years ago
  1. 6
      .gitignore
  2. 57
      Makefile
  3. 4
      README.md
  4. 6
      deb/DEBIAN/control
  5. 9
      deb/DEBIAN/postinst
  6. 2
      deb/DEBIAN/postrm
  7. 34
      fedi_color.svg
  8. 6
      installer.cfg
  9. BIN
      notif.wav
  10. 115
      plchat.py
  11. 23
      pleroma.py

6
.gitignore vendored

@ -1,4 +1,8 @@
__pycache__ __pycache__
plchat.build plchat.build
dist dist
build build
plchatdeb.py
plchatwindows.py
deb/**/*
!deb/DEBIAN

@ -4,39 +4,60 @@ endif
ifeq ($(LIBDIR),) ifeq ($(LIBDIR),)
LIBDIR := lib/ LIBDIR := lib/
endif endif
PRODUCTVER=0101 VER = $(shell cat installer.cfg | grep version= | head -n 1 | sed s/version=//)
all: default pack all: default pack
fresh: clean default pack
systemlibs: systemlibtarget pack systemlibs: systemlibtarget pack
deb: debtarget pack packdeb dpkg: debtarget dpkg-build
windows: windowstarget windows: wtarget wpack
default: default:
python3 -m nuitka --follow-imports --file-reference-choice=runtime --include-module=certifi --include-module=keyring.backends.kwallet --include-module=keyring.backends.chainer --enable-plugin=qt-plugins --include-qt-plugins=all --python-flag=-O -o plchat plchat.py python3 -m nuitka --follow-imports --file-reference-choice=runtime --include-module=certifi --include-module=keyring.backends.kwallet --include-module=keyring.backends.chainer --enable-plugin=qt-plugins --include-qt-plugins=all --python-flag=-O -o plchat plchat.py
windowstarget:
python3 -m nuitka --follow-imports --include-module=win32ctypes --enable-plugin=qt-plugins --include-qt-plugins=all --windows-disable-console --windows-icon-from-ico=fedi.ico --windows-company-name=plchat --windows-product-name=plchat --windows-product-version=$(PRODUCTVER) --python-flag=-O -o plchat plchat.py
debtarget: debtarget:
echo "You will need to make .deb packages using bash, ensuring you are doing so." mkdir -p deb/usr/lib/plchat
sudo ./deb/DEBIAN/postinst echo "#!/usr/lib/plchat/venv/bin/python" > deb/usr/lib/plchat/plchatdeb.py
source /usr/lib/plchat/venv/bin/activate echo "" >> deb/usr/lib/plchat/plchatdeb.py
pip3 install keyring notify-py appdirs python-dateutil requests urllib3 websockets PyQt5 python-magic cat plchat.py >> deb/usr/lib/plchat/plchatdeb.py
python3 -m nuitka --file-reference-choice=runtime --follow-imports --include-module=certifi --include-module=keyring.backends.kwallet --include-module=keyring.backends.chainer --enable-plugin=qt-plugins --include-qt-plugins=all --python-flag=-O -o plchat plchat.py chmod +x deb/usr/lib/plchat/plchatdeb.py
cp fedi.svg deb/usr/lib/plchat
cp fedi_color.svg deb/usr/lib/plchat
cp fedi.ico deb/usr/lib/plchat
cp notif.wav deb/usr/lib/plchat
cp send.svg deb/usr/lib/plchat
cp unread.svg deb/usr/lib/plchat
cp README.md deb/usr/lib/plchat
cp LICENSE deb/usr/lib/plchat
cp COPYING deb/usr/lib/plchat
cp audiowidget.py deb/usr/lib/plchat
cp misc.py deb/usr/lib/plchat
cp pleroma.py deb/usr/lib/plchat
cp monkeypatch.py deb/usr/lib/plchat
cp timeconvert.py deb/usr/lib/plchat
cp videowidget.py deb/usr/lib/plchat
systemlibtarget: systemlibtarget:
python3 -m nuitka --file-reference-choice=runtime --nofollow-imports --follow-import-to=misc --follow-import-to=monkeypatch --follow-import-to=pleroma --follow-import-to=timeconvert --follow-import-to=videowidget --follow-import-to=audiowidget --python-flag=-O -o plchat plchat.py python3 -m nuitka --file-reference-choice=runtime --nofollow-imports --follow-import-to=misc --follow-import-to=monkeypatch --follow-import-to=pleroma --follow-import-to=timeconvert --follow-import-to=videowidget --follow-import-to=audiowidget --python-flag=-O -o plchat plchat.py
windowstarget:
cat windows.patch > plchatwindows.py
cat plchat.py >> plchatwindows.py
makensis -VERSION || die "No makensis in path"
python3 -m nsist installer.cfg
wpack:
mv build/nsis/PlChat_$(VER).exe .
zip plchat_windows.zip PlChat_$(VER).exe
pack: pack:
mkdir dist mkdir dist
mv plchat dist mv plchat dist
cp fedi.svg dist cp fedi.svg dist
cp notif.wav dist
cp fedi_color.svg dist
cp fedi.ico dist cp fedi.ico dist
cp send.svg dist cp send.svg dist
cp unread.svg dist cp unread.svg dist
@ -44,20 +65,22 @@ pack:
cp LICENSE dist cp LICENSE dist
cp COPYING dist cp COPYING dist
packdeb: dpkg-build:
mkdir -p deb/usr/lib/plchat
mv dist deb/usr/lib/plchat
dpkg --build deb dpkg --build deb
mv deb.deb plchat.deb mv deb.deb plchat.deb
clean: clean:
rm -r dist || true rm -r dist || true
rm -r build || true
rm -r deb/usr || true
install: install:
mkdir $(PREFIX)$(LIBDIR) mkdir $(PREFIX)$(LIBDIR)
install dist/plchat $(PREFIX)$(LIBDIR) install dist/plchat $(PREFIX)$(LIBDIR)
install dist/fedi.ico $(PREFIX)$(LIBDIR) install dist/fedi.ico $(PREFIX)$(LIBDIR)
install dist/fedi.svg $(PREFIX)$(LIBDIR) install dist/fedi.svg $(PREFIX)$(LIBDIR)
install dist/fedi_color.svg $(PREFIX)$(LIBDIR)
install dist/notif.wav $(PREFIX)$(LIBDIR)
install dist/send.svg $(PREFIX)$(LIBDIR) install dist/send.svg $(PREFIX)$(LIBDIR)
install dist/unread.svg $(PREFIX)$(LIBDIR) install dist/unread.svg $(PREFIX)$(LIBDIR)
ln -sf $(PREFIX)$(LIBDIR)plchat $(PREFIX)bin/plchat ln -sf $(PREFIX)$(LIBDIR)plchat $(PREFIX)bin/plchat

@ -14,9 +14,11 @@ Download and install the [k-lite codec pack](https://www.codecguide.com/download
Download the installer from https://pond.waldn.net/plchat/windows/latest.zip extract the zip file. Other versions can be found at, for example, https://pond.waldn.net/plchat/windows/1.0.1.zip . Run the installer. Download the installer from https://pond.waldn.net/plchat/windows/latest.zip extract the zip file. Other versions can be found at, for example, https://pond.waldn.net/plchat/windows/1.0.1.zip . Run the installer.
### Linux ### Linux
A prepackaged deb file is provided in https://git.waldn.net/git/knotteye/plchat/releases as well as a compiled binary for amd64 linux. A prepackaged deb file is provided in https://git.waldn.net/git/knotteye/plchat/releases as ~~well as a compiled binary for amd64 linux~~. The precompiled binary was extremely not-portable and did not work well. Use a package or build from source.
If you package plchat for your distro, please let me know and I will add it here. If you package plchat for your distro, please let me know and I will add it here.
Gentoo: can be found in [this overlay](https://git.waldn.net/git/knotteye/overlay)
### MacOS ### MacOS
~~Nuitka does not support cross compilation and I do not have a working MacOS machine or VM, but it should theoretically compile and run just fine. Feel free to message me for support, and I'll be glad to link to your site if you host any binaries you build.~~ ~~Nuitka does not support cross compilation and I do not have a working MacOS machine or VM, but it should theoretically compile and run just fine. Feel free to message me for support, and I'll be glad to link to your site if you host any binaries you build.~~
A macos binary has been provided by [~am](https://decept.org/users/am). You can find it on the releases page. Run `brew install libmagic` before running. A macos binary has been provided by [~am](https://decept.org/users/am). You can find it on the releases page. Run `brew install libmagic` before running.

@ -1,11 +1,11 @@
Package: plchat Package: plchat
Version: 1.0.1 Version: 1.0.3
Section: net Section: net
Priority: optional Priority: optional
Architecture: amd64 Architecture: all
Description: A pleroma chat client Description: A pleroma chat client
Homepage: https://git.waldn.net/git/knotteye/plchat Homepage: https://git.waldn.net/git/knotteye/plchat
Maintainer: Knott Eye <knotteye@airmail.cc> Maintainer: Knott Eye <knotteye@airmail.cc>
Pre-Depends: python3 (>= 3.8.0~), python3-pip (>= 19.3), python3-venv, bash Pre-Depends: python3 (>= 3.8.0~), python3-pip (>= 19.3), python3-venv, bash
Depends: dbus, libmagic1, libc6, gstreamer1.0-nice, gstreamer1.0-libav, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-good, gstreamer1.0-plugins-ugly, gstreamer1.0-qt5, gstreamer1.0-plugins-base, gstreamer1.0-python3-plugin-loader Depends: dbus, libmagic1, libc6, gstreamer1.0-nice, gstreamer1.0-libav, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-good, gstreamer1.0-plugins-ugly, gstreamer1.0-qt5, gstreamer1.0-plugins-base, gstreamer1.0-python3-plugin-loader, python3-keyring, python3-appdirs, python3-magic, python3-dateutil, python3-websockets, python3-requests, python3-dateutil, python3-urllib3
Suggests: gnome-keyring Suggests: gnome-keyring

@ -1,7 +1,10 @@
#!/bin/bash #!/bin/bash
mkdir -p /usr/lib/plchat mkdir -p /usr/lib/plchat
cd /usr/lib/plchat cd /usr/lib/plchat
python3 -m venv venv python3 -m venv --system-site-packages venv
source venv/bin/activate source venv/bin/activate
pip3 install PyQt5==5.15.4 PyQt5-Qt5 PyQt5-sip certifi cryptography pip3 install PyQt5==5.15.4 PyQt5-Qt5 PyQt5-sip notify-py
ln -sf /usr/lib/plchat/dist/plchat /usr/bin/plchat echo "#!/bin/sh" > /usr/bin/plchat
echo "/usr/lib/plchat/venv/bin/python /usr/plib/plchat/plchatdeb.py" >> /usr/bin/plchat
chmod +x /usr/bin/plchat

@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
rm -f /usr/bin/plchat rm -f /usr/bin/plchat
rm -rf /usr/lib/plchat

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="196.52mm" height="196.52mm" viewBox="0 0 196.52 196.52" version="1.1" id="svg8" inkscape:version="0.92.2 2405546, 2018-03-11" sodipodi:docname="Logo_penta_connectat-imbrincat_retallats-color.svg" inkscape:export-filename="/home/nestor/Pictures/Fediversal/Logo_penta_connectat-imbrincat_retallats-color-512x.png" inkscape:export-xdpi="66.175453" inkscape:export-ydpi="66.175453">
<defs id="defs2"/>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.50411932" inkscape:cx="-209.83484" inkscape:cy="399.15332" inkscape:document-units="mm" inkscape:current-layer="layer2" showgrid="false" inkscape:snap-smooth-nodes="true" inkscape:snap-midpoints="true" inkscape:snap-global="false" inkscape:window-width="1366" inkscape:window-height="736" inkscape:window-x="0" inkscape:window-y="32" inkscape:window-maximized="1" fit-margin-top="5" fit-margin-left="5" fit-margin-right="5" fit-margin-bottom="5"/>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:groupmode="layer" id="layer2" inkscape:label="Linies" style="display:inline" transform="translate(6.6789703,-32.495842)">
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#a730b8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 181.13086,275.13672 a 68.892408,68.892408 0 0 1 -29.46484,29.32812 l 161.75781,162.38868 38.99805,-19.76368 z m 213.36328,214.1875 -38.99805,19.76367 81.96289,82.2832 a 68.892409,68.892409 0 0 1 29.47071,-29.33203 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9722" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#5496be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 581.64648,339.39062 -91.57617,46.41016 6.75196,43.18945 103.61523,-52.51367 A 68.892409,68.892409 0 0 1 581.64648,339.39062 Z M 436.9082,412.74219 220.38281,522.47656 a 68.892408,68.892408 0 0 1 18.79492,37.08985 L 443.66016,455.93359 Z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9729" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ce3d1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 367.27539,142.4375 262.79492,346.4082 293.64258,377.375 404.26562,161.41797 A 68.892408,68.892408 0 0 1 367.27539,142.4375 Z m -131.6543,257.02148 -52.92187,103.31446 a 68.892409,68.892409 0 0 1 36.98633,18.97851 l 46.78125,-91.32812 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9713" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d0188f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 150.76758,304.91797 a 68.892408,68.892408 0 0 1 -34.41602,7.19531 68.892408,68.892408 0 0 1 -6.65039,-0.69531 l 30.90235,197.66211 a 68.892409,68.892409 0 0 1 34.41601,-7.19531 68.892409,68.892409 0 0 1 6.64649,0.69531 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1015" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#5b36e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 239.3418,560.54492 a 68.892408,68.892408 0 0 1 0.7207,13.87696 68.892408,68.892408 0 0 1 -7.26758,27.17968 l 197.62891,31.71289 a 68.892409,68.892409 0 0 1 -0.72266,-13.8789 68.892409,68.892409 0 0 1 7.26953,-27.17774 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1674" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#30b873;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 601.13281,377.19922 -91.21875,178.08203 a 68.892408,68.892408 0 0 1 36.99414,18.98242 L 638.125,396.18359 a 68.892409,68.892409 0 0 1 -36.99219,-18.98437 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1676" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ebe305;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 476.72266,125.33008 a 68.892408,68.892408 0 0 1 -29.47071,29.33203 l 141.26563,141.81055 a 68.892409,68.892409 0 0 1 29.46875,-29.33204 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1678" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f47601;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 347.78711,104.63086 -178.57617,90.49805 a 68.892409,68.892409 0 0 1 18.79297,37.08593 l 178.57421,-90.50195 a 68.892408,68.892408 0 0 1 -18.79101,-37.08203 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1680" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#57c115;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 446.92578,154.82617 a 68.892408,68.892408 0 0 1 -34.98242,7.48242 68.892408,68.892408 0 0 1 -6.0293,-0.63281 l 15.81836,101.29102 43.16211,6.92578 z m -16,167.02735 37.40039,239.48242 a 68.892409,68.892409 0 0 1 33.91406,-6.94336 68.892409,68.892409 0 0 1 7.20704,0.79101 L 474.08984,328.77734 Z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9758" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#dbb210;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 188.13086,232.97461 a 68.892408,68.892408 0 0 1 0.75781,14.0957 68.892408,68.892408 0 0 1 -7.16015,26.98242 l 101.36914,16.28125 19.92382,-38.9082 z m 173.73633,27.90039 -19.92578,38.91211 239.51367,38.4668 a 68.892409,68.892409 0 0 1 -0.69531,-13.71875 68.892409,68.892409 0 0 1 7.34961,-27.32422 z" transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9760" inkscape:connector-curvature="0"/>
</g>
<g inkscape:groupmode="layer" id="layer3" inkscape:label="Nodes" style="display:inline;opacity:1" transform="translate(6.6789703,-32.495842)">
<circle style="fill:#ffca00;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" id="path817" cx="106.26596" cy="51.535553" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path819" style="fill:#64ff00;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="171.42836" cy="110.19328" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path823" style="fill:#00a3ff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="135.76379" cy="190.27704" r="16.570711" transform="rotate(3.1178174)"/>
<circle style="fill:#9500ff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" id="path825" cx="48.559471" cy="181.1138" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path827" style="fill:#ff0000;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="30.328812" cy="95.366837" r="16.570711" transform="rotate(3.1178174)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

@ -1,7 +1,7 @@
[Application] [Application]
name=PlChat name=PlChat
version=1.0.1 version=1.0.3
script=plchat.py script=plchatwindows.py
icon=fedi.ico icon=fedi.ico
license_file=LICENSE license_file=LICENSE
console=false console=false
@ -51,4 +51,4 @@ packages= audiowidget
plchat plchat
pleroma pleroma
timeconvert timeconvert
videowidget videowidget

Binary file not shown.

@ -37,6 +37,8 @@ APPDATA = appdirs.AppDirs('plchat', 'plchat').user_data_dir
THREADS = {} THREADS = {}
STATIC_PREF = '' STATIC_PREF = ''
ICON_PATH = os.path.join(os.path.dirname(__file__), "fedi.svg") ICON_PATH = os.path.join(os.path.dirname(__file__), "fedi.svg")
ICON_PATH_COLOR = os.path.join(os.path.dirname(__file__), "fedi_color.svg")
NOTIF_SOUND = os.path.join(os.path.dirname(__file__), 'notif.wav')
class App(QMainWindow): class App(QMainWindow):
settings = QSettings(APPDATA+"/settings.ini") settings = QSettings(APPDATA+"/settings.ini")
@ -51,9 +53,15 @@ class App(QMainWindow):
def initUI(self): def initUI(self):
self.setWindowTitle(self.title) self.setWindowTitle(self.title)
self.setWindowIcon(QIcon(QPixmap(ICON_PATH))) if self.settings.value('colorIcon', type=bool):
self.setWindowIcon(QIcon(QPixmap(ICON_PATH_COLOR)))
else:
self.setWindowIcon(QIcon(QPixmap(ICON_PATH)))
self.setGeometry(self.settings.value('left', type=int) or 10, self.settings.value('top', type=int) or 10, self.settings.value('width', type=int) or 640, self.settings.value('height', type=int) or 480) self.setGeometry(self.settings.value('left', type=int) or 10, self.settings.value('top', type=int) or 10, self.settings.value('width', type=int) or 640, self.settings.value('height', type=int) or 480)
if self.settings.value('silenceNotifications', type=bool):
Notification._notification_audio = None
self._exit = False self._exit = False
self.totpReady = False self.totpReady = False
self.Err = QErrorMessage() self.Err = QErrorMessage()
@ -103,9 +111,15 @@ class App(QMainWindow):
self.darkModeAction.setChecked(self.settings.value('darkMode', type=bool)) self.darkModeAction.setChecked(self.settings.value('darkMode', type=bool))
self.darkModeAction.setToolTip("Only affects chat bubbles") self.darkModeAction.setToolTip("Only affects chat bubbles")
self.colorIconAction = QAction("Use Color Icon", self, checkable=True, triggered=self.useColorIcon)
self.colorIconAction.setChecked(self.settings.value('colorIcon', type=bool))
self.sendNotificationsAction = QAction("Send Notifications", self, checkable=True) self.sendNotificationsAction = QAction("Send Notifications", self, checkable=True)
self.sendNotificationsAction.setChecked(self.settings.value('sendNotifications', type=bool)) self.sendNotificationsAction.setChecked(self.settings.value('sendNotifications', type=bool))
self.silenceNotifsAction = QAction("Silence Notifications", self, checkable=True, triggered=self.silenceNotifs)
self.silenceNotifsAction.setChecked(self.settings.value('silenceNotifications', type=bool))
self.fetchHeadersAction = QAction("Fetch Headers", self, checkable=True) self.fetchHeadersAction = QAction("Fetch Headers", self, checkable=True)
self.fetchHeadersAction.setChecked(self.settings.value('fetchHeaders', type=bool)) self.fetchHeadersAction.setChecked(self.settings.value('fetchHeaders', type=bool))
@ -128,10 +142,14 @@ class App(QMainWindow):
systraymenu.addAction(showAction) systraymenu.addAction(showAction)
systraymenu.addAction(hideAction) systraymenu.addAction(hideAction)
systraymenu.addAction(self.silenceNotifsAction)
systraymenu.addAction(exitAction) systraymenu.addAction(exitAction)
self.trayIcon = QSystemTrayIcon() self.trayIcon = QSystemTrayIcon()
self.trayIcon.setIcon(QIcon(ICON_PATH)) if self.settings.value('colorIcon', type=bool):
self.trayIcon.setIcon(QIcon(ICON_PATH_COLOR))
else:
self.trayIcon.setIcon(QIcon(ICON_PATH))
self.trayIcon.setVisible(True) self.trayIcon.setVisible(True)
self.trayIcon.setToolTip("PlChat") self.trayIcon.setToolTip("PlChat")
self.trayIcon.setContextMenu(systraymenu) self.trayIcon.setContextMenu(systraymenu)
@ -154,7 +172,9 @@ class App(QMainWindow):
prefsmenu.addAction(self.openInTrayAction) prefsmenu.addAction(self.openInTrayAction)
prefsmenu.addAction(self.animatePicturesAction) prefsmenu.addAction(self.animatePicturesAction)
prefsmenu.addAction(self.darkModeAction) prefsmenu.addAction(self.darkModeAction)
prefsmenu.addAction(self.colorIconAction)
prefsmenu.addAction(self.sendNotificationsAction) prefsmenu.addAction(self.sendNotificationsAction)
prefsmenu.addAction(self.silenceNotifsAction)
prefsmenu.addAction(self.fetchBackgroundsAction) prefsmenu.addAction(self.fetchBackgroundsAction)
prefsmenu.addAction(self.fetchHeadersAction) prefsmenu.addAction(self.fetchHeadersAction)
prefsmenu.addAction(self.twoFourTimeAction) prefsmenu.addAction(self.twoFourTimeAction)
@ -200,9 +220,15 @@ class App(QMainWindow):
if not acctList: if not acctList:
self.newAcctDialog() self.newAcctDialog()
return return
for acct in acctList: for ind in range(0,len(acctList)):
CallThread(getAvi, None, acct['instance']) CallThread(getAvi, None, acctList[ind]['instance'])
self.initAcct(acct['instance'], acct['username']) try:
self.initAcct(acctList[ind]['instance'], acctList[ind]['username'])
except:
print("account info corrupted, deleting")
del acctList[ind]
if acctList:
self.settings.setValue('acctList', acctList)
def systrayClicked(self, reason): def systrayClicked(self, reason):
if reason == QSystemTrayIcon.Trigger: if reason == QSystemTrayIcon.Trigger:
@ -211,6 +237,23 @@ class App(QMainWindow):
else: else:
self.show() self.show()
def silenceNotifs(self, dothing):
if dothing:
# Definitely not supposed to be poking around in the internals like this lul
Notification._notification_audio = None
else:
Notification.audio = NOTIF_SOUND
def useColorIcon(self, dothing):
if dothing:
self.setWindowIcon(QIcon(QPixmap(ICON_PATH_COLOR)))
if self.trayIcon:
self.trayIcon.setIcon(QIcon(ICON_PATH_COLOR))
else:
self.setWindowIcon(QIcon(QPixmap(ICON_PATH)))
if self.trayIcon:
self.trayIcon.setIcon(QIcon(ICON_PATH))
def eventLoop(self): def eventLoop(self):
# Custom event loop to process queue events # Custom event loop to process queue events
self.processEvents() self.processEvents()
@ -237,6 +280,8 @@ class App(QMainWindow):
self.settings.setValue("sendNotifications", self.sendNotificationsAction.isChecked()) self.settings.setValue("sendNotifications", self.sendNotificationsAction.isChecked())
self.settings.setValue("fetchHeaders", self.fetchHeadersAction.isChecked()) self.settings.setValue("fetchHeaders", self.fetchHeadersAction.isChecked())
self.settings.setValue("twoFourTime", self.twoFourTimeAction.isChecked()) self.settings.setValue("twoFourTime", self.twoFourTimeAction.isChecked())
self.settings.setValue('colorIcon', self.colorIconAction.isChecked())
self.settings.setValue('silenceNotifications', self.silenceNotifsAction.isChecked())
event.accept() event.accept()
self._eventloop.stop() self._eventloop.stop()
@ -246,6 +291,10 @@ class App(QMainWindow):
# Returns username, instance # Returns username, instance
return self.acctComboBox.currentText().split('@')[1], self.acctComboBox.currentText().split('@')[2] return self.acctComboBox.currentText().split('@')[1], self.acctComboBox.currentText().split('@')[2]
def badLogin(self, name):
self.Err.showMessage("Bad login info for: "+name)
self.newAcctDialog()
def newAcctDialog(self): def newAcctDialog(self):
dialog = LoginDialog(self) dialog = LoginDialog(self)
dialog.getInput(self.initAcct) dialog.getInput(self.initAcct)
@ -409,17 +458,30 @@ class App(QMainWindow):
def handlePleromaEvent(self, acct, event): def handlePleromaEvent(self, acct, event):
if event['event'] == 'pleroma:chat_update': if event['event'] == 'pleroma:chat_update':
payload = json.loads(event['payload']) payload = json.loads(event['payload'])
tmp = 0 tmp = -1
for ind in range(0, self.tabs.count()): for ind in range(0, self.tabs.count()):
if self.tabs.widget(ind).acct == payload['account']['acct']: if self.tabs.widget(ind).acct == payload['account']['acct']:
self._eventloop.call_soon_threadsafe(self.tabs.widget(ind).addMessage, payload['last_message']) self._eventloop.call_soon_threadsafe(self.tabs.widget(ind).addMessage, payload['last_message'])
tmp = ind tmp = ind
#self.tabs.widget(ind).addMessage(payload['last_message'])
if payload['last_message']['account_id'] != acct.flakeid and (not self.hasFocus() or payload['account']['acct'] != self.tabs.widget(self.tabs.currentIndex()).acct): if payload['last_message']['account_id'] != acct.flakeid and (not self.hasFocus() or payload['account']['acct'] != self.tabs.widget(self.tabs.currentIndex()).acct):
if self.sendNotificationsAction.isChecked(): if self.sendNotificationsAction.isChecked():
CallThread(self.makeNotification, None, payload['last_message']['content'], payload['account']['acct'], payload['account']['avatar_static']).start() CallThread(self.makeNotification, None, payload['last_message']['content'], payload['account']['acct'], payload['account']['avatar_static']).start()
app.alert(self, 0) app.alert(self, 0)
self._eventloop.call_soon_threadsafe(self.setUrgent, tmp) if tmp > 0:
self._eventloop.call_soon_threadsafe(self.setUrgent, tmp)
else:
u, i = ex.getCurrentAcc()
tmp = self.tabs.count()
closedList = self.settings.value('closed'+u+i, type=list) or []
for ind in range(0,(len(closedList))):
if closedList[ind] == payload['account']['acct']:
del closedList[ind]
break
self.settings.setValue('closed'+u+i, closedList)
self._eventloop.call_soon_threadsafe(self.populateChats, payload)
while self.tabs.tabIcon(tmp).isNull():
time.sleep(0.3)
self._eventloop.call_soon_threadsafe(self.setUrgent, tmp)
def makeNotification(self, content, user, url): def makeNotification(self, content, user, url):
path = getPic(url) path = getPic(url)
@ -446,8 +508,14 @@ class App(QMainWindow):
flip = False flip = False
if flip: if flip:
if self.trayIcon: if self.trayIcon:
self.trayIcon.setIcon(QIcon(QPixmap(ICON_PATH))) if self.settings.value('colorIcon', type=bool):
self.setWindowIcon(QIcon(QPixmap(ICON_PATH))) self.trayIcon.setIcon(QIcon(ICON_PATH_COLOR))
else:
self.trayIcon.setIcon(QIcon(ICON_PATH))
if self.settings.value('colorIcon', type=bool):
self.setWindowIcon(QIcon(QPixmap(ICON_PATH_COLOR)))
else:
self.setWindowIcon(QIcon(QPixmap(ICON_PATH)))
self.tabs.widget(ind).markRead() self.tabs.widget(ind).markRead()
self.tabs.widget(ind).setFocus(Qt.NoFocusReason) self.tabs.widget(ind).setFocus(Qt.NoFocusReason)
@ -470,8 +538,14 @@ class App(QMainWindow):
flip = False flip = False
if flip: if flip:
if self.trayIcon: if self.trayIcon:
self.trayIcon.setIcon(QIcon(QPixmap(ICON_PATH))) if self.settings.value('colorIcon', type=bool):
self.setWindowIcon(QIcon(QPixmap(ICON_PATH))) self.trayIcon.setIcon(QIcon(ICON_PATH_COLOR))
else:
self.trayIcon.setIcon(QIcon(ICON_PATH))
if self.settings.value('colorIcon', type=bool):
self.setWindowIcon(QIcon(QPixmap(ICON_PATH_COLOR)))
else:
self.setWindowIcon(QIcon(QPixmap(ICON_PATH)))
self.tabs.widget(ind).markRead() self.tabs.widget(ind).markRead()
self.tabs.widget(ind).setFocus(Qt.NoFocusReason) self.tabs.widget(ind).setFocus(Qt.NoFocusReason)
@ -662,7 +736,7 @@ class MessageArea(QWidget):
if not self.last_read_id or not u or not i: if not self.last_read_id or not u or not i:
return return
acc = ex.accts[u+i] acc = ex.accts[u+i]
acc.markChatRead(self.chatID, self.last_read_id) CallThread(acc.markChatRead, None, self.chatID, self.last_read_id).start()
def addPage(self): def addPage(self):
if self.fetchingPage: if self.fetchingPage:
@ -682,6 +756,7 @@ class MessageArea(QWidget):
for message in messages: for message in messages:
if message['account_id'] == self.account['id']: if message['account_id'] == self.account['id']:
self.last_read_id = message['id'] self.last_read_id = message['id']
break
for i in reversed(range(self.layout.count())): for i in reversed(range(self.layout.count())):
self.layout.itemAt(i).widget().setParent(None) self.layout.itemAt(i).widget().setParent(None)
for message in reversed(messages): for message in reversed(messages):
@ -755,13 +830,13 @@ class SingleMessage(QWidget):
p = QPixmap(path) p = QPixmap(path)
if p.isNull(): if p.isNull():
p = QPixmap(APPDATA+'/'+ex.getCurrentAcc()[1]+'avi.png') p = QPixmap(APPDATA+'/'+ex.getCurrentAcc()[1]+'avi.png')
p = p.scaledToHeight(50, mode=Qt.SmoothTransformation) p = p.scaledToHeight(round(QDesktopWidget().screenGeometry(-1).height() / 21.6), mode=Qt.SmoothTransformation)
self.userPixmap = p self.userPixmap = p
def setConvoPixmap(self, path): def setConvoPixmap(self, path):
p = QPixmap(path) p = QPixmap(path)
if p.isNull(): if p.isNull():
p = QPixmap(APPDATA+'/'+ex.getCurrentAcc()[1]+'avi.png') p = QPixmap(APPDATA+'/'+ex.getCurrentAcc()[1]+'avi.png')
p = p.scaledToHeight(50, mode=Qt.SmoothTransformation) p = p.scaledToHeight(round(QDesktopWidget().screenGeometry(-1).height() / 21.6), mode=Qt.SmoothTransformation)
self.convoPixmap = p self.convoPixmap = p
class MessageAvatar(QLabel): class MessageAvatar(QLabel):
@ -1349,7 +1424,11 @@ class RegisterThread(threading.Thread):
def run(self): def run(self):
self.acct.register() self.acct.register()
self.acct.login() try:
self.acct.login()
except ValueError:
ex._eventloop.call_soon_threadsafe(ex.badLogin, self.acct.username+'@'+self.acct.instance)
return
NotifThread(self.acct).start() NotifThread(self.acct).start()
self.acct.setChatUpdate(ex.handlePleromaEvent) self.acct.setChatUpdate(ex.handlePleromaEvent)
self.callback(self.acct) self.callback(self.acct)
@ -1386,8 +1465,8 @@ class IconLabel(QLabel):
Notification = Notify( Notification = Notify(
default_notification_title="PlChat", default_notification_title="PlChat",
default_notification_icon=ICON_PATH default_notification_icon=ICON_PATH,
#default_notification_audio=NOTIF_SOUND default_notification_audio=NOTIF_SOUND
) )
def sendNotification(message, title=None, icon=None): def sendNotification(message, title=None, icon=None):

@ -86,14 +86,21 @@ class Account():
response = self.apiRequest('POST', '/oauth/token', request_data) response = self.apiRequest('POST', '/oauth/token', request_data)
if 'error' in response and response['error'] == 'mfa_required': if 'error' in response and response['error'] == 'mfa_required':
if response['supported_challenge_types'] == 'totp' or 'totp' in response['supported_challenge_types']: if response['supported_challenge_types'] == 'totp' or 'totp' in response['supported_challenge_types']:
mfa_code, code_type = self.totpFunc(self, response['supported_challenge_types']) ctypes = response['supported_challenge_types']
response = self.apiRequest('POST', '/oauth/mfa/challenge', { mfa_token = response['mfa_token']
'client_id': self.clientID, while True:
'client_secret': self.clientSecret, mfa_code, code_type = self.totpFunc(self, ctypes)
'mfa_token': response['mfa_token'], response = self.apiRequest('POST', '/oauth/mfa/challenge', {
'challenge_type': code_type, 'client_id': self.clientID,
'code': mfa_code 'client_secret': self.clientSecret,
}) 'mfa_token': mfa_token,
'challenge_type': code_type,
'code': mfa_code
})
if not 'error' in response:
break
elif 'error' in response:
raise ValueError
self.token = response['access_token'] self.token = response['access_token']
self.refresh_token = response['refresh_token'] self.refresh_token = response['refresh_token']
r = self.apiRequest('GET', '/api/v1/accounts/verify_credentials') r = self.apiRequest('GET', '/api/v1/accounts/verify_credentials')

Loading…
Cancel
Save