Compare commits
22 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 |
|
@ -2,3 +2,7 @@ __pycache__
|
|||
plchat.build
|
||||
dist
|
||||
build
|
||||
plchatdeb.py
|
||||
plchatwindows.py
|
||||
deb/**/*
|
||||
!deb/DEBIAN
|
||||
|
|
57
Makefile
57
Makefile
|
@ -4,39 +4,60 @@ endif
|
|||
ifeq ($(LIBDIR),)
|
||||
LIBDIR := lib/
|
||||
endif
|
||||
PRODUCTVER=0101
|
||||
|
||||
VER = $(shell cat installer.cfg | grep version= | head -n 1 | sed s/version=//)
|
||||
|
||||
all: default pack
|
||||
|
||||
fresh: clean default pack
|
||||
|
||||
systemlibs: systemlibtarget pack
|
||||
|
||||
deb: debtarget pack packdeb
|
||||
dpkg: debtarget dpkg-build
|
||||
|
||||
windows: windowstarget
|
||||
windows: wtarget wpack
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
echo "You will need to make .deb packages using bash, ensuring you are doing so."
|
||||
sudo ./deb/DEBIAN/postinst
|
||||
source /usr/lib/plchat/venv/bin/activate
|
||||
pip3 install keyring notify-py appdirs python-dateutil requests urllib3 websockets PyQt5 python-magic
|
||||
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
|
||||
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:
|
||||
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:
|
||||
mkdir dist
|
||||
mv plchat dist
|
||||
cp fedi.svg dist
|
||||
cp notif.wav dist
|
||||
cp fedi_color.svg dist
|
||||
cp fedi.ico dist
|
||||
cp send.svg dist
|
||||
cp unread.svg dist
|
||||
|
@ -44,20 +65,22 @@ pack:
|
|||
cp LICENSE dist
|
||||
cp COPYING dist
|
||||
|
||||
packdeb:
|
||||
mkdir -p deb/usr/lib/plchat
|
||||
mv dist deb/usr/lib/plchat
|
||||
dpkg-build:
|
||||
dpkg --build deb
|
||||
mv deb.deb plchat.deb
|
||||
|
||||
clean:
|
||||
rm -r dist || true
|
||||
rm -r build || true
|
||||
rm -r deb/usr || true
|
||||
|
||||
install:
|
||||
mkdir $(PREFIX)$(LIBDIR)
|
||||
install dist/plchat $(PREFIX)$(LIBDIR)
|
||||
install dist/fedi.ico $(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/unread.svg $(PREFIX)$(LIBDIR)
|
||||
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.
|
||||
|
||||
### 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.
|
||||
|
||||
Gentoo: can be found in [this overlay](https://git.waldn.net/git/knotteye/overlay)
|
||||
|
||||
### 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.~~
|
||||
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
|
||||
Version: 1.0.1
|
||||
Version: 1.0.3
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Architecture: all
|
||||
Description: A pleroma chat client
|
||||
Homepage: https://git.waldn.net/git/knotteye/plchat
|
||||
Maintainer: Knott Eye <knotteye@airmail.cc>
|
||||
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
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#!/bin/bash
|
||||
mkdir -p /usr/lib/plchat
|
||||
cd /usr/lib/plchat
|
||||
python3 -m venv venv
|
||||
python3 -m venv --system-site-packages venv
|
||||
source venv/bin/activate
|
||||
pip3 install PyQt5==5.15.4 PyQt5-Qt5 PyQt5-sip certifi cryptography
|
||||
ln -sf /usr/lib/plchat/dist/plchat /usr/bin/plchat
|
||||
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,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
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]
|
||||
name=PlChat
|
||||
version=1.0.1
|
||||
script=plchat.py
|
||||
version=1.0.3
|
||||
script=plchatwindows.py
|
||||
icon=fedi.ico
|
||||
license_file=LICENSE
|
||||
console=false
|
||||
|
|
103
plchat.py
103
plchat.py
|
@ -37,6 +37,8 @@ APPDATA = appdirs.AppDirs('plchat', 'plchat').user_data_dir
|
|||
THREADS = {}
|
||||
STATIC_PREF = ''
|
||||
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):
|
||||
settings = QSettings(APPDATA+"/settings.ini")
|
||||
|
@ -51,9 +53,15 @@ class App(QMainWindow):
|
|||
|
||||
def initUI(self):
|
||||
self.setWindowTitle(self.title)
|
||||
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)
|
||||
|
||||
if self.settings.value('silenceNotifications', type=bool):
|
||||
Notification._notification_audio = None
|
||||
|
||||
self._exit = False
|
||||
self.totpReady = False
|
||||
self.Err = QErrorMessage()
|
||||
|
@ -103,9 +111,15 @@ class App(QMainWindow):
|
|||
self.darkModeAction.setChecked(self.settings.value('darkMode', type=bool))
|
||||
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.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.setChecked(self.settings.value('fetchHeaders', type=bool))
|
||||
|
||||
|
@ -128,9 +142,13 @@ class App(QMainWindow):
|
|||
|
||||
systraymenu.addAction(showAction)
|
||||
systraymenu.addAction(hideAction)
|
||||
systraymenu.addAction(self.silenceNotifsAction)
|
||||
systraymenu.addAction(exitAction)
|
||||
|
||||
self.trayIcon = QSystemTrayIcon()
|
||||
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.setToolTip("PlChat")
|
||||
|
@ -154,7 +172,9 @@ class App(QMainWindow):
|
|||
prefsmenu.addAction(self.openInTrayAction)
|
||||
prefsmenu.addAction(self.animatePicturesAction)
|
||||
prefsmenu.addAction(self.darkModeAction)
|
||||
prefsmenu.addAction(self.colorIconAction)
|
||||
prefsmenu.addAction(self.sendNotificationsAction)
|
||||
prefsmenu.addAction(self.silenceNotifsAction)
|
||||
prefsmenu.addAction(self.fetchBackgroundsAction)
|
||||
prefsmenu.addAction(self.fetchHeadersAction)
|
||||
prefsmenu.addAction(self.twoFourTimeAction)
|
||||
|
@ -200,9 +220,15 @@ class App(QMainWindow):
|
|||
if not acctList:
|
||||
self.newAcctDialog()
|
||||
return
|
||||
for acct in acctList:
|
||||
CallThread(getAvi, None, acct['instance'])
|
||||
self.initAcct(acct['instance'], acct['username'])
|
||||
for ind in range(0,len(acctList)):
|
||||
CallThread(getAvi, None, acctList[ind]['instance'])
|
||||
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):
|
||||
if reason == QSystemTrayIcon.Trigger:
|
||||
|
@ -211,6 +237,23 @@ class App(QMainWindow):
|
|||
else:
|
||||
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):
|
||||
# Custom event loop to process queue events
|
||||
self.processEvents()
|
||||
|
@ -237,6 +280,8 @@ class App(QMainWindow):
|
|||
self.settings.setValue("sendNotifications", self.sendNotificationsAction.isChecked())
|
||||
self.settings.setValue("fetchHeaders", self.fetchHeadersAction.isChecked())
|
||||
self.settings.setValue("twoFourTime", self.twoFourTimeAction.isChecked())
|
||||
self.settings.setValue('colorIcon', self.colorIconAction.isChecked())
|
||||
self.settings.setValue('silenceNotifications', self.silenceNotifsAction.isChecked())
|
||||
event.accept()
|
||||
self._eventloop.stop()
|
||||
|
||||
|
@ -246,6 +291,10 @@ class App(QMainWindow):
|
|||
# Returns username, instance
|
||||
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):
|
||||
dialog = LoginDialog(self)
|
||||
dialog.getInput(self.initAcct)
|
||||
|
@ -409,16 +458,29 @@ class App(QMainWindow):
|
|||
def handlePleromaEvent(self, acct, event):
|
||||
if event['event'] == 'pleroma:chat_update':
|
||||
payload = json.loads(event['payload'])
|
||||
tmp = 0
|
||||
tmp = -1
|
||||
for ind in range(0, self.tabs.count()):
|
||||
if self.tabs.widget(ind).acct == payload['account']['acct']:
|
||||
self._eventloop.call_soon_threadsafe(self.tabs.widget(ind).addMessage, payload['last_message'])
|
||||
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 self.sendNotificationsAction.isChecked():
|
||||
CallThread(self.makeNotification, None, payload['last_message']['content'], payload['account']['acct'], payload['account']['avatar_static']).start()
|
||||
app.alert(self, 0)
|
||||
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):
|
||||
|
@ -446,7 +508,13 @@ class App(QMainWindow):
|
|||
flip = False
|
||||
if flip:
|
||||
if self.trayIcon:
|
||||
self.trayIcon.setIcon(QIcon(QPixmap(ICON_PATH)))
|
||||
if self.settings.value('colorIcon', type=bool):
|
||||
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).setFocus(Qt.NoFocusReason)
|
||||
|
@ -470,7 +538,13 @@ class App(QMainWindow):
|
|||
flip = False
|
||||
if flip:
|
||||
if self.trayIcon:
|
||||
self.trayIcon.setIcon(QIcon(QPixmap(ICON_PATH)))
|
||||
if self.settings.value('colorIcon', type=bool):
|
||||
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).setFocus(Qt.NoFocusReason)
|
||||
|
@ -662,7 +736,7 @@ class MessageArea(QWidget):
|
|||
if not self.last_read_id or not u or not i:
|
||||
return
|
||||
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):
|
||||
if self.fetchingPage:
|
||||
|
@ -682,6 +756,7 @@ class MessageArea(QWidget):
|
|||
for message in messages:
|
||||
if message['account_id'] == self.account['id']:
|
||||
self.last_read_id = message['id']
|
||||
break
|
||||
for i in reversed(range(self.layout.count())):
|
||||
self.layout.itemAt(i).widget().setParent(None)
|
||||
for message in reversed(messages):
|
||||
|
@ -755,13 +830,13 @@ class SingleMessage(QWidget):
|
|||
p = QPixmap(path)
|
||||
if p.isNull():
|
||||
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
|
||||
def setConvoPixmap(self, path):
|
||||
p = QPixmap(path)
|
||||
if p.isNull():
|
||||
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
|
||||
|
||||
class MessageAvatar(QLabel):
|
||||
|
@ -1349,7 +1424,11 @@ class RegisterThread(threading.Thread):
|
|||
|
||||
def run(self):
|
||||
self.acct.register()
|
||||
try:
|
||||
self.acct.login()
|
||||
except ValueError:
|
||||
ex._eventloop.call_soon_threadsafe(ex.badLogin, self.acct.username+'@'+self.acct.instance)
|
||||
return
|
||||
NotifThread(self.acct).start()
|
||||
self.acct.setChatUpdate(ex.handlePleromaEvent)
|
||||
self.callback(self.acct)
|
||||
|
@ -1386,8 +1465,8 @@ class IconLabel(QLabel):
|
|||
|
||||
Notification = Notify(
|
||||
default_notification_title="PlChat",
|
||||
default_notification_icon=ICON_PATH
|
||||
#default_notification_audio=NOTIF_SOUND
|
||||
default_notification_icon=ICON_PATH,
|
||||
default_notification_audio=NOTIF_SOUND
|
||||
)
|
||||
|
||||
def sendNotification(message, title=None, icon=None):
|
||||
|
|
11
pleroma.py
11
pleroma.py
|
@ -86,14 +86,21 @@ class Account():
|
|||
response = self.apiRequest('POST', '/oauth/token', request_data)
|
||||
if 'error' in response and response['error'] == 'mfa_required':
|
||||
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']
|
||||
mfa_token = response['mfa_token']
|
||||
while True:
|
||||
mfa_code, code_type = self.totpFunc(self, ctypes)
|
||||
response = self.apiRequest('POST', '/oauth/mfa/challenge', {
|
||||
'client_id': self.clientID,
|
||||
'client_secret': self.clientSecret,
|
||||
'mfa_token': response['mfa_token'],
|
||||
'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.refresh_token = response['refresh_token']
|
||||
r = self.apiRequest('GET', '/api/v1/accounts/verify_credentials')
|
||||
|
|
Loading…
Reference in New Issue