Working code. Need to populate
This commit is contained in:
66
docketModel.py
Normal file
66
docketModel.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import datetime
|
||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt
|
||||
from PySide6.QtGui import QColor, QFont
|
||||
from PySide6.QtSql import QSqlQuery
|
||||
|
||||
from lib.utils import query_error
|
||||
|
||||
class docketModel(QAbstractTableModel):
|
||||
entries = []
|
||||
def __init__(self, case_id:int|None = None) -> None:
|
||||
super(docketModel,self).__init__()
|
||||
if case_id == None:
|
||||
return
|
||||
query = QSqlQuery()
|
||||
query.prepare("SELECT * FROM entries WHERE case_id = :cid "
|
||||
"ORDER BY entry_id")
|
||||
q2 = QSqlQuery()
|
||||
q2.prepare("SELECT * FROM documents WHERE entry_id = :eid")
|
||||
|
||||
query.bindValue(":cid", case_id)
|
||||
if not query.exec():
|
||||
query_error(query)
|
||||
while query.next():
|
||||
date = datetime.date.fromtimestamp(query.value(2))
|
||||
assert isinstance(date, datetime.date)
|
||||
row = [
|
||||
date.strftime("%B %-d, %Y"),
|
||||
query.value(3)
|
||||
]
|
||||
self.entries.append(row)
|
||||
q2.bindValue(":eid", query.value("entry_id"))
|
||||
if not q2.exec():
|
||||
query_error(q2)
|
||||
row = []
|
||||
while q2.next():
|
||||
row.append(q2.value('name'))
|
||||
if len(row) > 0:
|
||||
self.entries.append([None, " ".join(row)])
|
||||
return
|
||||
|
||||
def rowCount(self, parent:QModelIndex|None = None) -> int:
|
||||
return len(self.entries)
|
||||
|
||||
def columnCount(self, parent:QModelIndex|None = None) -> int:
|
||||
return 2
|
||||
|
||||
def data(self, index: QModelIndex, role:int):
|
||||
if not index.isValid():
|
||||
return ''
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
return self.entries[index.row()][index.column()]
|
||||
if role == Qt.ItemDataRole.TextAlignmentRole and index.column() == 0:
|
||||
return Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
|
||||
return
|
||||
|
||||
|
||||
def headerData(self, section:int, orientation:Qt.Orientation, role:int):
|
||||
if orientation == Qt.Orientation.Vertical:
|
||||
return
|
||||
if role == Qt.ItemDataRole.FontRole:
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
return font
|
||||
if role != Qt.ItemDataRole.DisplayRole:
|
||||
return
|
||||
return ['Date', 'Proceedings and Orders'][section]
|
||||
0
lib/__init__.py
Normal file
0
lib/__init__.py
Normal file
18
lib/utils.py
Normal file
18
lib/utils.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from typing import NoReturn
|
||||
from PySide6.QtCore import QCoreApplication
|
||||
from PySide6.QtSql import QSqlQuery
|
||||
|
||||
|
||||
translate = QCoreApplication.translate
|
||||
def query_error(query: QSqlQuery) -> NoReturn:
|
||||
"""Standarized query error reporter."""
|
||||
print(
|
||||
translate("MainWindow", "SQL Error:\n")
|
||||
+ "{}\n{}\n{}:{}".format(
|
||||
query.executedQuery(),
|
||||
query.boundValues(),
|
||||
query.lastError().type(),
|
||||
query.lastError().text(),
|
||||
)
|
||||
)
|
||||
raise Exception(translate("MainWindow", "SQL Error"))
|
||||
@@ -5,27 +5,16 @@ import sys
|
||||
import dateparser
|
||||
import requests
|
||||
from typing import NoReturn
|
||||
from PySide6.QtCore import QCoreApplication, QModelIndex, Signal, Qt
|
||||
from PySide6.QtCore import QCoreApplication, QModelIndex, Signal, Qt, Slot
|
||||
from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel
|
||||
from PySide6.QtWidgets import QAbstractItemView, QApplication, QHeaderView, QMainWindow, QStyledItemDelegate, QTableWidgetItem
|
||||
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
from docketModel import docketModel
|
||||
from ui.MainWindow import Ui_MainWindow
|
||||
|
||||
from lib.utils import query_error
|
||||
translate = QCoreApplication.translate
|
||||
def query_error(query: QSqlQuery) -> NoReturn:
|
||||
"""Standarized query error reporter."""
|
||||
print(
|
||||
translate("MainWindow", "SQL Error:\n")
|
||||
+ "{}\n{}\n{}:{}".format(
|
||||
query.executedQuery(),
|
||||
query.boundValues(),
|
||||
query.lastError().type(),
|
||||
query.lastError().text(),
|
||||
)
|
||||
)
|
||||
raise Exception(translate("MainWindow", "SQL Error"))
|
||||
|
||||
class dateDelegate(QStyledItemDelegate):
|
||||
def displayText(self, value, locale) -> str:
|
||||
@@ -64,40 +53,29 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.casesView.doubleClicked.connect(self.rowClicked)
|
||||
self.casesView.clicked.connect(self.rowClicked)
|
||||
|
||||
self.docketWidget.setColumnCount(2)
|
||||
self.docketWidget.setHorizontalHeaderLabels([
|
||||
'Date','Proceedings and Orders',
|
||||
])
|
||||
self.docketWidget.resizeColumnToContents(0)
|
||||
self.docketWidget.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
|
||||
return
|
||||
|
||||
def populateDocket(self, case_id:int) -> None:
|
||||
query = QSqlQuery()
|
||||
query.prepare("SELECT * FROM entries WHERE case_id=:cid ORDER BY entry_id")
|
||||
query.bindValue(":cid", case_id)
|
||||
if not query.exec():
|
||||
query_error(query)
|
||||
self.docketWidget.clearContents()
|
||||
row = 0
|
||||
while query.next():
|
||||
print(query.value(0), query.value(1), query.value(2), query.value(3))
|
||||
item = QTableWidgetItem()
|
||||
item.setData(Qt.ItemDataRole.DisplayRole, query.value(2))
|
||||
self.docketWidget.setItem(row,0, item)
|
||||
item = QTableWidgetItem()
|
||||
item.setData(Qt.ItemDataRole.DisplayRole, query.value(3))
|
||||
self.docketWidget.setItem(row, 1, item)
|
||||
row += 1
|
||||
self.docketWidget.setRowCount(row)
|
||||
|
||||
self.docketView.setModel(docketModel())
|
||||
self.docketView.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
|
||||
self.docketView.resizeRowsToContents()
|
||||
return
|
||||
|
||||
@Slot(QModelIndex)
|
||||
def rowClicked(self, index:QModelIndex) -> None:
|
||||
if not index.isValid():
|
||||
raise Exception("Bad index")
|
||||
docket = index.siblingAtColumn(1).data()
|
||||
print(docket)
|
||||
self.docketLabel.setText(docket)
|
||||
self.show_entries.emit(index.siblingAtColumn(0).data())
|
||||
self.populateDocket(index.siblingAtColumn(0).data())
|
||||
model = docketModel(index.siblingAtColumn(0).data())
|
||||
self.docketView.setModel(model)
|
||||
self.docketView.resizeColumnToContents(0)
|
||||
self.docketView.resizeRowsToContents()
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def on_updateButton_clicked(self):
|
||||
text = self.docketInput.toPlainText()
|
||||
update_db(text)
|
||||
self.update()
|
||||
return
|
||||
|
||||
SQL_CMDS = [
|
||||
@@ -107,6 +85,7 @@ SQL_CMDS = [
|
||||
"docket_id TEXT, "
|
||||
"linked INTEGER, "
|
||||
"petitioners TEXT, respondents TEXT, date INTEGER, "
|
||||
"active INTEGER, "
|
||||
"FOREIGN KEY(linked) REFERENCES cases(case_id))",
|
||||
#
|
||||
"CREATE TABLE IF NOT EXISTS entries ("
|
||||
@@ -141,7 +120,9 @@ def schema_update(db: QSqlDatabase) -> None:
|
||||
table_name = matches.group(2)
|
||||
create_cmd = (
|
||||
matches.group(1)
|
||||
+ '"'
|
||||
+ matches.group(2)
|
||||
+ '"'
|
||||
+ matches.group(3)
|
||||
)
|
||||
else:
|
||||
@@ -173,7 +154,6 @@ def schema_update(db: QSqlDatabase) -> None:
|
||||
# Step 4 create new table
|
||||
new_table_name = table_name + "_new"
|
||||
sql = matches.group(1) + new_table_name + matches.group(3)
|
||||
print(sql)
|
||||
if not query.exec(sql):
|
||||
query_error(query)
|
||||
# step 5 transfer content
|
||||
@@ -228,7 +208,7 @@ def update_proceedings(case_id: int, bs: BeautifulSoup) -> None:
|
||||
if not query.next():
|
||||
query.prepare("INSERT INTO entries (case_id, date, text) VALUES (:cid,:date,:text)")
|
||||
query.bindValue(':cid', case_id)
|
||||
query.bindValue(':date', date.timestamp)
|
||||
query.bindValue(':date', date.timestamp())
|
||||
query.bindValue(':text', text)
|
||||
if not query.exec():
|
||||
query_error(query)
|
||||
@@ -238,7 +218,6 @@ def update_proceedings(case_id: int, bs: BeautifulSoup) -> None:
|
||||
tr = trs.pop(0)
|
||||
assert isinstance(tr, Tag)
|
||||
assert isinstance(tr.contents[1], Tag)
|
||||
print(tr.contents[1])
|
||||
for a in tr.contents[1]:
|
||||
assert isinstance(a, Tag)
|
||||
url = a.attrs['href']
|
||||
@@ -256,7 +235,6 @@ def update_proceedings(case_id: int, bs: BeautifulSoup) -> None:
|
||||
query.bindValue(":url", url)
|
||||
if not query.exec():
|
||||
query_error(query)
|
||||
break
|
||||
return
|
||||
|
||||
def update_db(case_id) -> int:
|
||||
@@ -315,8 +293,6 @@ def update_db(case_id) -> int:
|
||||
assert isinstance(tr, Tag) and isinstance(tr.contents[0], Tag)
|
||||
linked = tr.contents[0].string
|
||||
|
||||
print(docket_id, petitioners, respondent, date, linked)
|
||||
|
||||
#
|
||||
# See if this case already exists.
|
||||
#
|
||||
@@ -376,8 +352,8 @@ def main() -> int:
|
||||
db.setDatabaseName("scotus.db")
|
||||
db.open()
|
||||
schema_update(db)
|
||||
#update_db('24-203')
|
||||
#update_db('23A1058')
|
||||
update_db('24-203')
|
||||
update_db('23A1058')
|
||||
window = MainWindow()
|
||||
return app.exec()
|
||||
|
||||
|
||||
@@ -15,15 +15,16 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QHeaderView, QMainWindow, QMenuBar,
|
||||
QSizePolicy, QStatusBar, QTableView, QTableWidget,
|
||||
QTableWidgetItem, QVBoxLayout, QWidget)
|
||||
from PySide6.QtWidgets import (QApplication, QFrame, QHBoxLayout, QHeaderView,
|
||||
QLabel, QMainWindow, QMenuBar, QPlainTextEdit,
|
||||
QPushButton, QSizePolicy, QStatusBar, QTableView,
|
||||
QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.resize(800, 600)
|
||||
MainWindow.resize(929, 710)
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.verticalLayout = QVBoxLayout(self.centralwidget)
|
||||
@@ -33,15 +34,55 @@ class Ui_MainWindow(object):
|
||||
|
||||
self.verticalLayout.addWidget(self.casesView)
|
||||
|
||||
self.docketWidget = QTableWidget(self.centralwidget)
|
||||
self.docketWidget.setObjectName(u"docketWidget")
|
||||
self.docketLabel = QLabel(self.centralwidget)
|
||||
self.docketLabel.setObjectName(u"docketLabel")
|
||||
|
||||
self.verticalLayout.addWidget(self.docketWidget)
|
||||
self.verticalLayout.addWidget(self.docketLabel)
|
||||
|
||||
self.docketView = QTableView(self.centralwidget)
|
||||
self.docketView.setObjectName(u"docketView")
|
||||
|
||||
self.verticalLayout.addWidget(self.docketView)
|
||||
|
||||
self.frame = QFrame(self.centralwidget)
|
||||
self.frame.setObjectName(u"frame")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
|
||||
self.frame.setSizePolicy(sizePolicy)
|
||||
self.frame.setFrameShape(QFrame.Shape.StyledPanel)
|
||||
self.frame.setFrameShadow(QFrame.Shadow.Raised)
|
||||
self.horizontalLayout = QHBoxLayout(self.frame)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.docketInput = QPlainTextEdit(self.frame)
|
||||
self.docketInput.setObjectName(u"docketInput")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.docketInput.sizePolicy().hasHeightForWidth())
|
||||
self.docketInput.setSizePolicy(sizePolicy1)
|
||||
self.docketInput.setMaximumSize(QSize(16777215, 27))
|
||||
|
||||
self.horizontalLayout.addWidget(self.docketInput)
|
||||
|
||||
self.updateButton = QPushButton(self.frame)
|
||||
self.updateButton.setObjectName(u"updateButton")
|
||||
|
||||
self.horizontalLayout.addWidget(self.updateButton)
|
||||
|
||||
self.searchButton = QPushButton(self.frame)
|
||||
self.searchButton.setObjectName(u"searchButton")
|
||||
|
||||
self.horizontalLayout.addWidget(self.searchButton)
|
||||
|
||||
|
||||
self.verticalLayout.addWidget(self.frame)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QMenuBar(MainWindow)
|
||||
self.menubar.setObjectName(u"menubar")
|
||||
self.menubar.setGeometry(QRect(0, 0, 800, 24))
|
||||
self.menubar.setGeometry(QRect(0, 0, 929, 24))
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QStatusBar(MainWindow)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
@@ -54,5 +95,8 @@ class Ui_MainWindow(object):
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||
self.docketLabel.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
|
||||
self.updateButton.setText(QCoreApplication.translate("MainWindow", u"Update Docket", None))
|
||||
self.searchButton.setText(QCoreApplication.translate("MainWindow", u"Search", None))
|
||||
# retranslateUi
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
<width>929</width>
|
||||
<height>710</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -19,7 +19,62 @@
|
||||
<widget class="QTableView" name="casesView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="docketWidget"/>
|
||||
<widget class="QLabel" name="docketLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="docketView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="docketInput">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>27</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="updateButton">
|
||||
<property name="text">
|
||||
<string>Update Docket</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -28,7 +83,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<width>929</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user