Compare commits
31 Commits
Author | SHA1 | Date |
---|---|---|
knotteye | 4d5b8e6bc1 | |
knotteye | ac324d0402 | |
knotteye | 2ede34c207 | |
knotteye | 26e904b5e9 | |
knotteye | 0e34a3b196 | |
knotteye | e73f9afa6c | |
knotteye | a510f5faf3 | |
knotteye | 4560215d7a | |
knotteye | 4b55caca87 | |
knotteye | a82116b1b5 | |
knotteye | 51eea001d7 | |
knotteye | edd5d87477 | |
knotteye | ab57a11a25 | |
knotteye | ade5c0d6d0 | |
knotteye | 691c79fc9a | |
knotteye | 51ee61ff26 | |
knotteye | 863a0ef45c | |
knotteye | 1cd48d60ce | |
knotteye | 3119434b29 | |
knotteye | 80fd4acb51 | |
knotteye | d3e9f3ac6f | |
knotteye | 1c633628ee | |
knotteye | d3f3f5933e | |
knotteye | 1e1ee7cae5 | |
knotteye | 724a31d4ab | |
knotteye | 27106a9bb4 | |
knotteye | a4f5e25994 | |
knotteye | d32a4d5a06 | |
knotteye | 8af9de903c | |
knotteye | 7f2533c1be | |
Matilde Park | 373c1c0820 |
|
@ -1,3 +1,8 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
plchat.build
|
plchat.build
|
||||||
dist
|
dist
|
||||||
|
build
|
||||||
|
plchatdeb.py
|
||||||
|
plchatwindows.py
|
||||||
|
deb/**/*
|
||||||
|
!deb/DEBIAN
|
||||||
|
|
56
Makefile
56
Makefile
|
@ -4,30 +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
|
||||||
|
|
||||||
windows: windowstarget
|
dpkg: debtarget dpkg-build
|
||||||
|
|
||||||
|
windows: wtarget wpack
|
||||||
|
|
||||||
default:
|
default:
|
||||||
python -m nuitka --follow-imports --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:
|
debtarget:
|
||||||
python -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
|
mkdir -p deb/usr/lib/plchat
|
||||||
|
echo "#!/usr/lib/plchat/venv/bin/python" > deb/usr/lib/plchat/plchatdeb.py
|
||||||
|
echo "" >> deb/usr/lib/plchat/plchatdeb.py
|
||||||
|
cat plchat.py >> deb/usr/lib/plchat/plchatdeb.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:
|
||||||
python -m nuitka --nofollow-imports --follow-import=misc --follow-import=monkeypatch --follow-import=pleroma --follow-import=timeconvert --follow-import=videowidget --follow-import=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
|
||||||
|
@ -35,14 +65,22 @@ pack:
|
||||||
cp LICENSE dist
|
cp LICENSE dist
|
||||||
cp COPYING dist
|
cp COPYING dist
|
||||||
|
|
||||||
|
dpkg-build:
|
||||||
|
dpkg --build 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
|
|
@ -9,15 +9,16 @@ Run the binary or `python plchat.py`. Log in to your account on the fediverse an
|
||||||
Installation instructions for PlChat. If you are looking to package this program or build from source, skip to Building From Source or Packaging down below.
|
Installation instructions for PlChat. If you are looking to package this program or build from source, skip to Building From Source or Packaging down below.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
Download and install [python 3.8.9](https://www.python.org/downloads/windows/) from the python.org and the [k-lite codec pack](https://www.codecguide.com/download_kl.htm). The basic version with default options should work fine.
|
Download and install the [k-lite codec pack](https://www.codecguide.com/download_kl.htm). The basic version with default options should work fine.
|
||||||
|
|
||||||
Download the latest plchat_windows.zip from https://git.waldn.net/git/knotteye/plchat/releases extract the zip file. Run setup.bat, and keep the setup-log file if something does not work. Run plchat.exe and log in!
|
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.
|
||||||
No guarantees on Windows 7, but windows 8 and 10 should work fine.
|
|
||||||
|
|
||||||
### 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,10 +1,11 @@
|
||||||
Package: plchat
|
Package: plchat
|
||||||
Version: 1.0
|
Version: 1.0.3
|
||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: linux-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>
|
||||||
Depends: python3 (>=3.8.0), PyQt5 (=5.15.2), dbus, libmagic1, python-pyqt5.qtmultimedia, libc6, libgstreamer-plugins-bad1.0-0, qtgstreamer-plugins-qt5
|
Pre-Depends: python3 (>= 3.8.0~), python3-pip (>= 19.3), python3-venv, bash
|
||||||
Suggests: gnome-keyring (>= 2.30)
|
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
|
||||||
|
|
|
@ -1,2 +1,10 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
ln -sf /usr/lib/plchat/plchat /usr/bin/plchat
|
mkdir -p /usr/lib/plchat
|
||||||
|
cd /usr/lib/plchat
|
||||||
|
python3 -m venv --system-site-packages venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip3 install PyQt5==5.15.4 PyQt5-Qt5 PyQt5-sip notify-py
|
||||||
|
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,2 +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 |
|
@ -0,0 +1,54 @@
|
||||||
|
[Application]
|
||||||
|
name=PlChat
|
||||||
|
version=1.0.3
|
||||||
|
script=plchatwindows.py
|
||||||
|
icon=fedi.ico
|
||||||
|
license_file=LICENSE
|
||||||
|
console=false
|
||||||
|
|
||||||
|
[Python]
|
||||||
|
version=3.8.9
|
||||||
|
include_msvcrt=true
|
||||||
|
|
||||||
|
[Include]
|
||||||
|
pypi_wheels = PyQt5==5.15.2
|
||||||
|
PyQt5-sip==12.8.1
|
||||||
|
appdirs==1.4.4
|
||||||
|
keyring==23.0.1
|
||||||
|
python-magic-bin==0.4.14
|
||||||
|
notify-py==0.3.1
|
||||||
|
python-dateutil==2.8.1
|
||||||
|
requests==2.25.1
|
||||||
|
urllib3==1.26.4
|
||||||
|
websockets==8.1
|
||||||
|
importlib-metadata==3.10.1
|
||||||
|
certifi==2020.12.5
|
||||||
|
chardet==4.0.0
|
||||||
|
colorama==0.4.4
|
||||||
|
idna==2.10
|
||||||
|
importlib-metadata==3.10.1
|
||||||
|
loguru==0.5.3
|
||||||
|
pywin32-ctypes==0.2.0
|
||||||
|
requests-download==0.1.2
|
||||||
|
six==1.15.0
|
||||||
|
urllib3==1.26.4
|
||||||
|
websockets==8.1
|
||||||
|
win32-setctime==1.0.3
|
||||||
|
yarg==0.1.9
|
||||||
|
zipp==3.4.1
|
||||||
|
|
||||||
|
files = COPYING
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
|
send.svg
|
||||||
|
unread.svg
|
||||||
|
fedi.svg
|
||||||
|
fedi.ico
|
||||||
|
|
||||||
|
packages= audiowidget
|
||||||
|
misc
|
||||||
|
monkeypatch
|
||||||
|
plchat
|
||||||
|
pleroma
|
||||||
|
timeconvert
|
||||||
|
videowidget
|
115
plchat.py
115
plchat.py
|
@ -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):
|
||||||
|
|
23
pleroma.py
23
pleroma.py
|
@ -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')
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!python3.8
|
||||||
|
import sys, os
|
||||||
|
import site
|
||||||
|
|
||||||
|
scriptdir, script = os.path.split(os.path.abspath(__file__))
|
||||||
|
pkgdir = os.path.join(scriptdir, 'pkgs')
|
||||||
|
# Ensure .pth files in pkgdir are handled properly
|
||||||
|
site.addsitedir(pkgdir)
|
||||||
|
sys.path.insert(0, pkgdir)
|
Loading…
Reference in New Issue