Posts display and step forward, boosted posts handled.

This commit is contained in:
Keith Edmunds 2023-01-07 23:25:48 +00:00
parent f034ef4f56
commit e6d8f10fe3
7 changed files with 1441 additions and 284 deletions

View File

@ -10,6 +10,7 @@ class Config(object):
DISPLAY_SQL = False DISPLAY_SQL = False
ERRORS_FROM = ['noreply@midnighthax.com'] ERRORS_FROM = ['noreply@midnighthax.com']
ERRORS_TO = ['kae@midnighthax.com'] ERRORS_TO = ['kae@midnighthax.com']
FOLLOWED_COLOUR = '#8ae234'
LOG_LEVEL_STDERR = logging.ERROR LOG_LEVEL_STDERR = logging.ERROR
LOG_LEVEL_SYSLOG = logging.DEBUG LOG_LEVEL_SYSLOG = logging.DEBUG
LOG_NAME = "urma" LOG_NAME = "urma"
@ -18,3 +19,4 @@ class Config(object):
MAIL_SERVER = os.environ.get('MAIL_SERVER') or "woodlands.midnighthax.com" MAIL_SERVER = os.environ.get('MAIL_SERVER') or "woodlands.midnighthax.com"
MAIL_USERNAME = os.environ.get('MAIL_USERNAME') MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
NORMAL_COLOUR = "#f6f5f4"

View File

@ -2,6 +2,7 @@ import os
import smtplib import smtplib
import ssl import ssl
from config import Config
from email.message import EmailMessage from email.message import EmailMessage
from config import Config from config import Config
@ -9,6 +10,8 @@ from log import log
from typing import Any, List from typing import Any, List
from PyQt5.QtWidgets import QMessageBox
def ask_yes_no(title: str, question: str) -> bool: def ask_yes_no(title: str, question: str) -> bool:
"""Ask question; return True for yes, False for no""" """Ask question; return True for yes, False for no"""
@ -18,6 +21,21 @@ def ask_yes_no(title: str, question: str) -> bool:
return button_reply == QMessageBox.Yes return button_reply == QMessageBox.Yes
def format_username(account) -> str:
"""
Format account username according to whether we follow that account
or not.
"""
username = account.username
if account.followed:
colour = Config.FOLLOWED_COLOUR
else:
colour = Config.NORMAL_COLOUR
return '<span style="color:' + colour + '">' + username + '</span>'
def index_ojects_by_parameter(object_list: List, param: Any): def index_ojects_by_parameter(object_list: List, param: Any):
""" """
Create a dictionary from passed list where each list entry is keyed Create a dictionary from passed list where each list entry is keyed

View File

@ -4,7 +4,7 @@ import os.path
from dbconfig import Session, scoped_session from dbconfig import Session, scoped_session
from typing import List from typing import List, Optional
from sqlalchemy import ( from sqlalchemy import (
Boolean, Boolean,
@ -47,8 +47,8 @@ class Accounts(Base):
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
f"<Accounts(id={self.id}, url={self.content[:60]}, " f"<Accounts(id={self.id}, username={self.username}, "
f"followed={self.followed}>" f"acct={self.acct}, followed={self.followed}>"
) )
def __init__(self, session: Session, account_id: str) -> None: def __init__(self, session: Session, account_id: str) -> None:
@ -212,8 +212,8 @@ class Posts(Base):
account_id = Column(Integer, ForeignKey('accounts.id'), nullable=True) account_id = Column(Integer, ForeignKey('accounts.id'), nullable=True)
account = relationship("Accounts", back_populates="posts") account = relationship("Accounts", back_populates="posts")
reblog = relationship("Posts") reblogged_by_post = relationship("Posts")
child_id = Column(Integer, ForeignKey("posts.id")) boosted_post_id = Column(Integer, ForeignKey("posts.id"))
media_attachments = relationship("Attachments") media_attachments = relationship("Attachments")
@ -232,6 +232,43 @@ class Posts(Base):
session.add(self) session.add(self)
session.commit() session.commit()
@classmethod
def get_unrated_before(cls, session: Session,
post_id: int) -> Optional["Posts"]:
"""
Return latest unrated Posts object before past post_id, or None
if there isn't one.
"""
return (
session.scalars(
select(cls)
.where(
(cls.rating.is_(None)),
(cls.post_id < post_id)
)
.order_by(cls.post_id.desc())
.limit(1)
).first()
)
@classmethod
def get_unrated_newest(cls, session: Session) -> Optional["Posts"]:
"""
Return most recent Posts object that has not been rated and which
is not a boosted post, or None if there isn't one.
"""
print("get_unrated_newest")
return (
session.scalars(
select(cls)
.where(cls.rating.is_(None))
.order_by(cls.post_id.desc())
.limit(1)
).first()
)
@classmethod @classmethod
def get_or_create(cls, session: Session, post_id: str) -> "Posts": def get_or_create(cls, session: Session, post_id: str) -> "Posts":
""" """
@ -250,21 +287,6 @@ class Posts(Base):
return rec return rec
@classmethod
def get_unrated_posts(cls, session: Session) -> List["Posts"]:
"""
Return a list of Posts object that have not been rated
"""
records = (
session.execute(
select(cls)
.where(cls.rating.is_(None))
).scalars().all()
)
return records
class PostTags(Base): class PostTags(Base):
__tablename__ = 'post_tags' __tablename__ = 'post_tags'

View File

@ -26,7 +26,7 @@
<x>10</x> <x>10</x>
<y>90</y> <y>90</y>
<width>351</width> <width>351</width>
<height>681</height> <height>671</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -56,10 +56,10 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="lblPicture"> <widget class="QLabel" name="lblPicture">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>10</x>
<y>770</y> <y>770</y>
<width>351</width> <width>351</width>
<height>191</height> <height>201</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -74,6 +74,9 @@ p, li { white-space: pre-wrap; }
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget> </widget>
<widget class="QTextEdit" name="txtHashtags"> <widget class="QTextEdit" name="txtHashtags">
<property name="geometry"> <property name="geometry">
@ -104,7 +107,7 @@ p, li { white-space: pre-wrap; }
<x>10</x> <x>10</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>31</height> <height>29</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -124,6 +127,9 @@ p, li { white-space: pre-wrap; }
<pointsize>13</pointsize> <pointsize>13</pointsize>
</font> </font>
</property> </property>
<property name="styleSheet">
<string notr="true">color:rgb(154, 153, 150)</string>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -141,12 +147,107 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#5e5c64;&quot;&gt;Boosted by&lt;/span&gt;&lt;span style=&quot; color:#f6f5f4;&quot;&gt; Jon&lt;/span&gt; &lt;span style=&quot; color:#8ae234;&quot;&gt;Baker&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#5e5c64;&quot;&gt;Boosted by&lt;/span&gt;&lt;span style=&quot; color:#f6f5f4;&quot;&gt; Jon&lt;/span&gt; &lt;span style=&quot; color:#8ae234;&quot;&gt;Baker&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QWidget" name="layoutWidget"> <widget class="QLabel" name="lblAcct">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>60</y>
<width>361</width>
<height>29</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>29</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>29</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(119, 118, 123);</string>
</property>
<property name="text">
<string>@JonBaker@mastodon.xyz</string>
</property>
</widget>
<widget class="QTextEdit" name="txtUsername">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>361</width>
<height>29</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>29</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>29</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#f6f5f4;&quot;&gt;Jon&lt;/span&gt; &lt;span style=&quot; color:#8ae234;&quot;&gt;Baker&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>366</x>
<y>90</y>
<width>2</width>
<height>871</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(119, 118, 123);</string>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<widget class="QLabel" name="lblDebug">
<property name="geometry">
<rect>
<x>390</x>
<y>10</y>
<width>311</width>
<height>21</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>11</x>
<y>980</y> <y>980</y>
<width>701</width> <width>692</width>
<height>63</height> <height>63</height>
</rect> </rect>
</property> </property>
@ -382,85 +483,6 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QLabel" name="lblAcct">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>361</width>
<height>29</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>29</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>29</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(119, 118, 123);</string>
</property>
<property name="text">
<string>@JonBaker@mastodon.xyz</string>
</property>
</widget>
<widget class="QTextEdit" name="txtUsername">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>361</width>
<height>29</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>29</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>29</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#f6f5f4;&quot;&gt;Jon&lt;/span&gt; &lt;span style=&quot; color:#8ae234;&quot;&gt;Baker&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>366</x>
<y>90</y>
<width>2</width>
<height>871</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(119, 118, 123);</string>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
<property name="geometry"> <property name="geometry">

View File

@ -20,7 +20,7 @@ class Ui_MainWindow(object):
self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget") self.centralwidget.setObjectName("centralwidget")
self.txtPost = QtWidgets.QTextEdit(self.centralwidget) self.txtPost = QtWidgets.QTextEdit(self.centralwidget)
self.txtPost.setGeometry(QtCore.QRect(10, 90, 351, 681)) self.txtPost.setGeometry(QtCore.QRect(10, 90, 351, 671))
self.txtPost.setMinimumSize(QtCore.QSize(341, 181)) self.txtPost.setMinimumSize(QtCore.QSize(341, 181))
self.txtPost.setStyleSheet("background-color: rgb(154, 153, 150); border-radius: 10px; \n" self.txtPost.setStyleSheet("background-color: rgb(154, 153, 150); border-radius: 10px; \n"
"") "")
@ -28,10 +28,11 @@ class Ui_MainWindow(object):
self.txtPost.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored) self.txtPost.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.txtPost.setObjectName("txtPost") self.txtPost.setObjectName("txtPost")
self.lblPicture = QtWidgets.QLabel(self.centralwidget) self.lblPicture = QtWidgets.QLabel(self.centralwidget)
self.lblPicture.setGeometry(QtCore.QRect(20, 770, 351, 191)) self.lblPicture.setGeometry(QtCore.QRect(10, 770, 351, 201))
self.lblPicture.setMinimumSize(QtCore.QSize(0, 181)) self.lblPicture.setMinimumSize(QtCore.QSize(0, 181))
self.lblPicture.setFrameShape(QtWidgets.QFrame.StyledPanel) self.lblPicture.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.lblPicture.setText("") self.lblPicture.setText("")
self.lblPicture.setScaledContents(True)
self.lblPicture.setObjectName("lblPicture") self.lblPicture.setObjectName("lblPicture")
self.txtHashtags = QtWidgets.QTextEdit(self.centralwidget) self.txtHashtags = QtWidgets.QTextEdit(self.centralwidget)
self.txtHashtags.setGeometry(QtCore.QRect(370, 90, 331, 871)) self.txtHashtags.setGeometry(QtCore.QRect(370, 90, 331, 871))
@ -39,102 +40,17 @@ class Ui_MainWindow(object):
self.txtHashtags.setFrameShadow(QtWidgets.QFrame.Sunken) self.txtHashtags.setFrameShadow(QtWidgets.QFrame.Sunken)
self.txtHashtags.setObjectName("txtHashtags") self.txtHashtags.setObjectName("txtHashtags")
self.txtBoosted = QtWidgets.QTextEdit(self.centralwidget) self.txtBoosted = QtWidgets.QTextEdit(self.centralwidget)
self.txtBoosted.setGeometry(QtCore.QRect(10, 0, 361, 31)) self.txtBoosted.setGeometry(QtCore.QRect(10, 0, 361, 29))
self.txtBoosted.setMinimumSize(QtCore.QSize(0, 29)) self.txtBoosted.setMinimumSize(QtCore.QSize(0, 29))
self.txtBoosted.setMaximumSize(QtCore.QSize(16777215, 29)) self.txtBoosted.setMaximumSize(QtCore.QSize(16777215, 29))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(13) font.setPointSize(13)
self.txtBoosted.setFont(font) self.txtBoosted.setFont(font)
self.txtBoosted.setStyleSheet("color:rgb(154, 153, 150)")
self.txtBoosted.setFrameShape(QtWidgets.QFrame.NoFrame) self.txtBoosted.setFrameShape(QtWidgets.QFrame.NoFrame)
self.txtBoosted.setFrameShadow(QtWidgets.QFrame.Plain) self.txtBoosted.setFrameShadow(QtWidgets.QFrame.Plain)
self.txtBoosted.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.txtBoosted.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.txtBoosted.setObjectName("txtBoosted") self.txtBoosted.setObjectName("txtBoosted")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(10, 980, 701, 63))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.btnFirst = QtWidgets.QPushButton(self.layoutWidget)
self.btnFirst.setMinimumSize(QtCore.QSize(61, 61))
self.btnFirst.setMaximumSize(QtCore.QSize(61, 61))
self.btnFirst.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/buttons/double-left.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnFirst.setIcon(icon)
self.btnFirst.setIconSize(QtCore.QSize(48, 48))
self.btnFirst.setObjectName("btnFirst")
self.horizontalLayout.addWidget(self.btnFirst)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.btnPrev = QtWidgets.QPushButton(self.layoutWidget)
self.btnPrev.setMinimumSize(QtCore.QSize(61, 61))
self.btnPrev.setMaximumSize(QtCore.QSize(61, 61))
self.btnPrev.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/buttons/icons8-prev-page-48.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnPrev.setIcon(icon1)
self.btnPrev.setIconSize(QtCore.QSize(48, 48))
self.btnPrev.setObjectName("btnPrev")
self.horizontalLayout.addWidget(self.btnPrev)
self.btnDislike = QtWidgets.QPushButton(self.layoutWidget)
self.btnDislike.setMinimumSize(QtCore.QSize(106, 61))
self.btnDislike.setMaximumSize(QtCore.QSize(106, 61))
self.btnDislike.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/buttons/red-cross.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnDislike.setIcon(icon2)
self.btnDislike.setIconSize(QtCore.QSize(48, 48))
self.btnDislike.setObjectName("btnDislike")
self.horizontalLayout.addWidget(self.btnDislike)
self.btnUnsure = QtWidgets.QPushButton(self.layoutWidget)
self.btnUnsure.setMinimumSize(QtCore.QSize(106, 61))
self.btnUnsure.setMaximumSize(QtCore.QSize(106, 61))
self.btnUnsure.setText("")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/buttons/dont-know-woman.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnUnsure.setIcon(icon3)
self.btnUnsure.setIconSize(QtCore.QSize(48, 48))
self.btnUnsure.setObjectName("btnUnsure")
self.horizontalLayout.addWidget(self.btnUnsure)
self.line_2 = QtWidgets.QFrame(self.layoutWidget)
self.line_2.setStyleSheet("background-color: rgb(94, 92, 100);")
self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.horizontalLayout.addWidget(self.line_2)
self.btnLike = QtWidgets.QPushButton(self.layoutWidget)
self.btnLike.setMinimumSize(QtCore.QSize(106, 61))
self.btnLike.setMaximumSize(QtCore.QSize(106, 61))
self.btnLike.setText("")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/buttons/green-tick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnLike.setIcon(icon4)
self.btnLike.setIconSize(QtCore.QSize(48, 48))
self.btnLike.setObjectName("btnLike")
self.horizontalLayout.addWidget(self.btnLike)
self.btnNext = QtWidgets.QPushButton(self.layoutWidget)
self.btnNext.setMinimumSize(QtCore.QSize(61, 61))
self.btnNext.setMaximumSize(QtCore.QSize(61, 61))
self.btnNext.setText("")
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/buttons/icons8-next-page-48.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnNext.setIcon(icon5)
self.btnNext.setIconSize(QtCore.QSize(48, 48))
self.btnNext.setObjectName("btnNext")
self.horizontalLayout.addWidget(self.btnNext)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.btnLast = QtWidgets.QPushButton(self.layoutWidget)
self.btnLast.setMinimumSize(QtCore.QSize(61, 61))
self.btnLast.setMaximumSize(QtCore.QSize(61, 61))
self.btnLast.setText("")
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap(":/buttons/double-right.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnLast.setIcon(icon6)
self.btnLast.setIconSize(QtCore.QSize(48, 48))
self.btnLast.setObjectName("btnLast")
self.horizontalLayout.addWidget(self.btnLast)
self.lblAcct = QtWidgets.QLabel(self.centralwidget) self.lblAcct = QtWidgets.QLabel(self.centralwidget)
self.lblAcct.setGeometry(QtCore.QRect(10, 60, 361, 29)) self.lblAcct.setGeometry(QtCore.QRect(10, 60, 361, 29))
self.lblAcct.setMinimumSize(QtCore.QSize(0, 29)) self.lblAcct.setMinimumSize(QtCore.QSize(0, 29))
@ -154,6 +70,91 @@ class Ui_MainWindow(object):
self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShape(QtWidgets.QFrame.VLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line") self.line.setObjectName("line")
self.lblDebug = QtWidgets.QLabel(self.centralwidget)
self.lblDebug.setGeometry(QtCore.QRect(390, 10, 311, 21))
self.lblDebug.setStyleSheet("color: rgb(255, 255, 255);")
self.lblDebug.setText("")
self.lblDebug.setObjectName("lblDebug")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(11, 980, 692, 63))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.btnFirst = QtWidgets.QPushButton(self.widget)
self.btnFirst.setMinimumSize(QtCore.QSize(61, 61))
self.btnFirst.setMaximumSize(QtCore.QSize(61, 61))
self.btnFirst.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/buttons/double-left.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnFirst.setIcon(icon)
self.btnFirst.setIconSize(QtCore.QSize(48, 48))
self.btnFirst.setObjectName("btnFirst")
self.horizontalLayout.addWidget(self.btnFirst)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.btnPrev = QtWidgets.QPushButton(self.widget)
self.btnPrev.setMinimumSize(QtCore.QSize(61, 61))
self.btnPrev.setMaximumSize(QtCore.QSize(61, 61))
self.btnPrev.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/buttons/icons8-prev-page-48.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnPrev.setIcon(icon1)
self.btnPrev.setIconSize(QtCore.QSize(48, 48))
self.btnPrev.setObjectName("btnPrev")
self.horizontalLayout.addWidget(self.btnPrev)
self.btnDislike = QtWidgets.QPushButton(self.widget)
self.btnDislike.setMinimumSize(QtCore.QSize(106, 61))
self.btnDislike.setMaximumSize(QtCore.QSize(106, 61))
self.btnDislike.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/buttons/red-cross.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnDislike.setIcon(icon2)
self.btnDislike.setIconSize(QtCore.QSize(48, 48))
self.btnDislike.setObjectName("btnDislike")
self.horizontalLayout.addWidget(self.btnDislike)
self.btnUnsure = QtWidgets.QPushButton(self.widget)
self.btnUnsure.setMinimumSize(QtCore.QSize(106, 61))
self.btnUnsure.setMaximumSize(QtCore.QSize(106, 61))
self.btnUnsure.setText("")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/buttons/dont-know-woman.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnUnsure.setIcon(icon3)
self.btnUnsure.setIconSize(QtCore.QSize(48, 48))
self.btnUnsure.setObjectName("btnUnsure")
self.horizontalLayout.addWidget(self.btnUnsure)
self.btnLike = QtWidgets.QPushButton(self.widget)
self.btnLike.setMinimumSize(QtCore.QSize(106, 61))
self.btnLike.setMaximumSize(QtCore.QSize(106, 61))
self.btnLike.setText("")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/buttons/green-tick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnLike.setIcon(icon4)
self.btnLike.setIconSize(QtCore.QSize(48, 48))
self.btnLike.setObjectName("btnLike")
self.horizontalLayout.addWidget(self.btnLike)
self.btnNext = QtWidgets.QPushButton(self.widget)
self.btnNext.setMinimumSize(QtCore.QSize(61, 61))
self.btnNext.setMaximumSize(QtCore.QSize(61, 61))
self.btnNext.setText("")
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/buttons/icons8-next-page-48.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnNext.setIcon(icon5)
self.btnNext.setIconSize(QtCore.QSize(48, 48))
self.btnNext.setObjectName("btnNext")
self.horizontalLayout.addWidget(self.btnNext)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.btnLast = QtWidgets.QPushButton(self.widget)
self.btnLast.setMinimumSize(QtCore.QSize(61, 61))
self.btnLast.setMaximumSize(QtCore.QSize(61, 61))
self.btnLast.setText("")
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap(":/buttons/double-right.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnLast.setIcon(icon6)
self.btnLast.setIconSize(QtCore.QSize(48, 48))
self.btnLast.setObjectName("btnLast")
self.horizontalLayout.addWidget(self.btnLast)
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 709, 26)) self.menubar.setGeometry(QtCore.QRect(0, 0, 709, 26))

View File

@ -4,15 +4,18 @@ import ipdb
import os import os
import pickle import pickle
import random import random
import requests
import stackprinter import stackprinter
import sys import sys
from config import Config from config import Config
from dbconfig import engine, Session, scoped_session from dbconfig import engine, Session, scoped_session
from helpers import ( from helpers import (
format_username,
index_ojects_by_parameter, index_ojects_by_parameter,
send_mail, send_mail,
) )
from helpers import show_OK
from log import log from log import log
from mastodon import Mastodon from mastodon import Mastodon
from models import ( from models import (
@ -24,8 +27,12 @@ from models import (
PostTags, PostTags,
) )
from typing import List from typing import List, Optional
from PyQt5.QtGui import (
QImage,
QPixmap,
)
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QApplication, QApplication,
QLabel, QLabel,
@ -119,55 +126,157 @@ class Window(QMainWindow, Ui_MainWindow):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.mastapi = MastodonAPI(Config.ACCESS_TOKEN) # self.mastapi = MastodonAPI(Config.ACCESS_TOKEN)
self.current_post_id = None
self.btnDislike.clicked.connect(self.dislike)
self.btnFirst.clicked.connect(self.first)
self.btnLast.clicked.connect(self.last)
self.btnLike.clicked.connect(self.like)
self.btnNext.clicked.connect(self.next) self.btnNext.clicked.connect(self.next)
self.btnPrev.clicked.connect(self.prev) self.btnPrev.clicked.connect(self.prev)
self.btnUnsure.clicked.connect(self.unsure)
with Session() as session: # Show first record
self.dataset = UnratedPosts(session) self.next()
record = self.dataset.next()
self.display(session, record)
self.update_followed_accounts(session)
self.update_followed_hashtags(session)
import ipdb; ipdb.set_trace()
def display(self, session: Session, record: UnratedPosts) -> None: def display(self, session: Session, post: Posts) -> None:
"""
Prepare to display post
"""
boosted_by = None
if post.boosted_post_id:
boosted_by = post.account
while post.boosted_post_id:
post = session.get(Posts, post.boosted_post_id)
self._display(session, post, boosted_by)
def _display(self, session: Session, post: int,
boosted_by: Optional[Accounts] = None) -> None:
""" """
Display passed post Display passed post
""" """
if not record: if post is None:
return return
if record not in session: # Boosted
session.add(record) if boosted_by:
self.txtUsername.setText(record.account.username) self.txtBoosted.setText(
if record.reblog: "Boosted by: " + format_username(boosted_by))
self.txtBoosted.setEnabled(True) self.txtBoosted.show()
self.display
elif record.child_id:
self.txtBoosted.setEnabled(True)
self.txtPost.setText("reblog child")
else: else:
self.txtPost.setHtml(record.content) self.txtBoosted.hide()
# Username
self.txtUsername.setText(format_username(post.account))
# Debug
self.lblDebug.setText(str(post.id))
# Account
self.lblAcct.setText(post.account.acct)
# Hashtags
unfollowed_hashtags = [ unfollowed_hashtags = [
a.name for a in record.hashtags if not a.followed] '#' + a.name for a in post.hashtags if not a.followed]
followed_hashtags = [a.name for a in record.hashtags if a.followed] followed_hashtags = [
hasttag_text = ( '#' + a.name for a in post.hashtags if a.followed]
f"Followed: {', '.join(followed_hashtags)}\n\n" hashtag_text = (
f"Unfollowed: {', '.join(unfollowed_hashtags)}\n\n" '<span style="color:' + Config.FOLLOWED_COLOUR + '">' +
'<br />'.join(followed_hashtags) +
'</span><br />' +
'<span style="color:' + Config.NORMAL_COLOUR + '">' +
'<br />'.join(unfollowed_hashtags) +
'</span>'
) )
self.txtHashtags.setText(hasttag_text) self.txtHashtags.setText(hashtag_text)
# Post
self.txtPost.setHtml(post.content)
# Image
if post.media_attachments:
image = QImage()
# TODO: handle multiple images, not just [0]
url_image = post.media_attachments[0].preview_url
image.loadFromData(requests.get(url_image).content)
self.lblPicture.setPixmap(QPixmap(image))
self.lblPicture.show()
else:
self.lblPicture.hide()
def dislike(self):
"""
actions
"""
pass
def first(self):
"""
actions
"""
pass
def last(self):
"""
actions
"""
pass
def like(self):
"""
actions
"""
pass
def next(self) -> None: def next(self) -> None:
with Session() as session: """
record = self.dataset.next() Display next post. We work BACKWARDS through posts, starting with the
self.display(session, record) most recent, so "next" is actually one older.
def prev(self) -> None: If we are called with self.current_post_id set to None, retrieve and
display newest unrated post.
"""
# Get post to display, but don't process posts that are boosted
# as they will be processed by the boosting post
with Session() as session: with Session() as session:
record = self.dataset.prev() if self.current_post_id is None:
self.display(session, record) post = Posts.get_unrated_newest(session)
while post and post.reblogged_by_post:
post = Posts.get_unrated_newest(session)
else:
post = Posts.get_unrated_before(session, self.current_post_id)
while post and post.reblogged_by_post:
post = Posts.get_unrated_before(session, post.post_id)
if not post:
self.current_post_id = None
show_OK("All done", "No more posts to process")
return
self.current_post_id = post.post_id
self.display(session, post)
def prev(self):
"""
actions
"""
pass
def unsure(self):
"""
actions
"""
pass
def update_followed_accounts(self, session: Session) -> None: def update_followed_accounts(self, session: Session) -> None:
""" """
@ -273,8 +382,8 @@ class Window(QMainWindow, Ui_MainWindow):
# rec.url = post.url # rec.url = post.url
# rec.content = post.content # rec.content = post.content
# #
# if post.reblog: # if post.reblogged_by_post:
# rec.child_id = process_post(post.reblog).id # rec.boosted_post_id = process_post(post.reblogged_by_post).id
# #
# return rec # return rec
# #

File diff suppressed because it is too large Load Diff