diff --git a/data/db.sql b/data/db.sql index 00e019d946752a5bd9d1eeb5ae13c1873c3c2ba7..2958af2044dc5bb7075526ad775d7fb3b395696d 100644 --- a/data/db.sql +++ b/data/db.sql @@ -33,17 +33,17 @@ DROP TABLE IF EXISTS `acara`; CREATE TABLE `acara` ( `id_acara` int(11) NOT NULL AUTO_INCREMENT, `nama_acara` varchar(255) NOT NULL, - `video_introduksi` varchar(255) DEFAULT NULL, - `syarat_pendaftaran` text DEFAULT NULL, - `kuota_pendaftar` int(11) DEFAULT NULL, - `deskripsi` text DEFAULT NULL, + `video_introduksi` varchar(255) DEFAULT "" NOT NULL, + `syarat_pendaftaran` text DEFAULT "" NOT NULL, + `kuota_pendaftar` int(11) DEFAULT 0 NOT NULL, + `deskripsi` text DEFAULT "" NOT NULL, `waktu` datetime NOT NULL, - `harga` int(11) DEFAULT NULL, - `link` varchar(255) DEFAULT NULL, + `harga` int(11) DEFAULT 0 NOT NULL, + `link` varchar(255) DEFAULT "" NOT NULL, `id_penyelenggara` int(11) NOT NULL, PRIMARY KEY (`id_acara`), KEY `fk_penyelenggara_acara` (`id_penyelenggara`), - CONSTRAINT `fk_penyelenggara_acara` FOREIGN KEY (`id_penyelenggara`) REFERENCES `penyelenggara` (`id_penyelenggara`) + CONSTRAINT `fk_penyelenggara_acara` FOREIGN KEY (`id_penyelenggara`) REFERENCES `penyelenggara` (`id_penyelenggara`) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -66,10 +66,10 @@ DROP TABLE IF EXISTS `foto_acara`; CREATE TABLE `foto_acara` ( `id_acara` int(11) NOT NULL, `id_foto` int(11) NOT NULL AUTO_INCREMENT, - `foto` blob DEFAULT NULL, + `foto` mediumblob DEFAULT NULL, PRIMARY KEY (`id_foto`), KEY `fk_foto_acara` (`id_acara`), - CONSTRAINT `fk_foto_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) + CONSTRAINT `fk_foto_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -116,7 +116,7 @@ CREATE TABLE `kategori_acara` ( `id_acara` int(11) NOT NULL, `nama_kategori` varchar(255) NOT NULL, PRIMARY KEY (`id_acara`,`nama_kategori`), - CONSTRAINT `fk_kategori_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) + CONSTRAINT `fk_kategori_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -140,7 +140,7 @@ CREATE TABLE `kategori_member` ( `id_member` int(11) NOT NULL, `nama_kategori` varchar(255) NOT NULL, PRIMARY KEY (`id_member`,`nama_kategori`), - CONSTRAINT `fk_kategori_member` FOREIGN KEY (`id_member`) REFERENCES `member` (`id_member`) + CONSTRAINT `fk_kategori_member` FOREIGN KEY (`id_member`) REFERENCES `member` (`id_member`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -164,7 +164,7 @@ CREATE TABLE `member` ( `id_member` int(11) NOT NULL AUTO_INCREMENT, `nama_depan` varchar(255) NOT NULL, `nama_belakang` varchar(255) NOT NULL, - `foto_profil` blob DEFAULT NULL, + `foto_profil` mediumblob DEFAULT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `nomor_telepon` varchar(15) DEFAULT NULL, @@ -197,8 +197,8 @@ CREATE TABLE `mengikuti` ( `jumlah` int(11) DEFAULT NULL, KEY `fk_member_mengikuti` (`id_member`), KEY `fk_mengikuti_acara` (`id_acara`), - CONSTRAINT `fk_member_mengikuti` FOREIGN KEY (`id_member`) REFERENCES `member` (`id_member`), - CONSTRAINT `fk_mengikuti_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) + CONSTRAINT `fk_member_mengikuti` FOREIGN KEY (`id_member`) REFERENCES `member` (`id_member`) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT `fk_mengikuti_acara` FOREIGN KEY (`id_acara`) REFERENCES `acara` (`id_acara`) ON UPDATE CASCADE ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -222,7 +222,7 @@ CREATE TABLE `penyelenggara` ( `id_penyelenggara` int(11) NOT NULL AUTO_INCREMENT, `nama_organisasi` varchar(255) NOT NULL, `penanggung_jawab` varchar(255) NOT NULL, - `foto_profil` blob DEFAULT NULL, + `foto_profil` mediumblob DEFAULT NULL, `video_introduksi` varchar(255) DEFAULT NULL, `deskripsi` text DEFAULT NULL, `email` varchar(255) NOT NULL, diff --git a/makefile b/makefile index 241d222e89334be4b804f998ae46ec5d36594ffa..4bdbcd8d0e1b591dc37490f55b8a30f096e194bc 100644 --- a/makefile +++ b/makefile @@ -10,4 +10,4 @@ run: test $(PY) $(main_dir)/$(main_py) test: - $(PY) -m pytest src/* \ No newline at end of file + $(PY) -m pytest src/test/* diff --git a/src/app/main.py b/src/app/main.py index c8f6cd83486e7bf471625d03ebc3cd152bbac56c..acf30ecad3209498899210aca70e5283ab7611fc 100644 --- a/src/app/main.py +++ b/src/app/main.py @@ -1,13 +1,42 @@ from app.ui.main_window_ui import * from app.db import init_db +import datetime +import sys +from PyQt5.QtWidgets import ( + QApplication, QDialog, QMainWindow, QMessageBox +) +from PyQt5.uic import loadUi + +from app.ui import main_window_ui if __name__ == '__main__': conn = init_db() - cur = conn.cursor() + + windows = [] app = QtWidgets.QApplication(sys.argv) YesManagement = QtWidgets.QMainWindow() - ui = Ui_YesManagement(conn) + ui = Ui_YesManagement(conn, windows) ui.setupUi(YesManagement) YesManagement.show() - sys.exit(app.exec_()) \ No newline at end of file + sys.exit(app.exec_()) + + + # app = QApplication(sys.argv) + # main_window_ui.Ui_YesManagement(conn) + # sys.exit(app.exec()) + + # cur = conn.cursor() + # ################### + # # BUAT DETAIL ACARA + # # Ini tinggal diganti aja + # PATH = "./ui/assets/" + # currIDUser = 2 + # currIDAcara = 1 + # isMember = True + + # # execute SQL query + # # lengkapnya: https://mariadb.com/resources/blog/how-to-connect-python-programs-to-mariadb/ + # ################# + + conn.close() diff --git a/src/app/modules/linimasa.py b/src/app/modules/linimasa.py index 8cb1754a0c4accd1d5a8891fd48ff2852deaf993..c175be03bd89f62d0e3264e5596d6b62e2ae6f1f 100644 --- a/src/app/modules/linimasa.py +++ b/src/app/modules/linimasa.py @@ -1,83 +1,89 @@ -import mariadb +"""Modul linimasa""" -def linimasa(conn, extraFilter, params=None): - """Fungsi untuk mengembalikan list acara untuk linimasa - Parameters - ---------- - conn: connection - Connection ke database yang digunakan - extraFilter: string - klausa WHERE untuk query yang akan dilakukan - params: list (optional) - List parameter untuk prepared statement - Returns - ------- - list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) - """ - cursor = conn.cursor() - cursor.execute(\ - f'SELECT\ - id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu\ - FROM acara'+\ - extraFilter, params - ) +def linimasa(conn, extra_filter, params=None): + """Fungsi untuk mengembalikan list acara untuk linimasa + Parameters + ---------- + conn: connection + Connection ke database yang digunakan + extraFilter: string + klausa WHERE untuk query yang akan dilakukan + params: list (optional) + List parameter untuk prepared statement + Returns + ------- + list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) + """ - ret = [] - for res in cursor.fetchall(): - cursor.execute('SELECT nama_kategori FROM kategori_acara WHERE id_acara = ?', (res[0],)) - kategori = cursor.fetchall() - ret.append((*res, list(*kategori))) - return ret + cursor = conn.cursor() + cursor.execute(\ + 'SELECT\ + id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu\ + FROM acara'+\ + extra_filter, params + ) -def linimasaPengguna(conn, kategFilter=[], search=""): - """Fungsi untuk mengambil acara pada linimasa pengguna - Parameters - ---------- - conn : connection - Connection ke database yang digunakan - kategFilter: list - list filter yang digunakan - search: string - kata kunci pencarian - Returns - ------- - list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) - """ - - # setup parameter untuk klausa WHERE - where = "" - params = [] - if len(kategFilter) != 0: - where += " WHERE id_acara in\ - (SELECT id_acara FROM kategori_acara WHERE kategori_acara IN\ - (" + ",".join(["?" for _ in range(len(kategFilter))]) + ")" - params.extend(kategFilter) - if search != '': - where += ' WHERE' if where == '' else '' - where += ' nama_acara LIKE ?' - params.append(search) - - # gunakan fungsi pembantu linimasa - return linimasa(conn, where) + ret = [] + for res in cursor.fetchall(): + cursor.execute('SELECT nama_kategori FROM kategori_acara WHERE id_acara = ?', (res[0],)) + kategori = cursor.fetchall() + ret.append((*res, [k[0] for k in kategori])) + return ret -def linimasaPenyelenggara(conn, endedFilter=None): - """Fungsi untuk mengambil acara pada linimasa penyelenggara - Parameters - ---------- - conn: connection - Connection ke database yang digunakan - endedFilter: bool (optional) - Filter yang digunakan untuk memfilter linimasa: sudah apakah acara yang - ditampilkan yang sudah berakhir (`True`) atau belum (`False`) - Returns - ------- - list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) - """ +def linimasa_pengguna(conn, kateg_filter=None, search=""): + """Fungsi untuk mengambil acara pada linimasa pengguna + Parameters + ---------- + conn : connection + Connection ke database yang digunakan + kateg_filter: list + list filter yang digunakan + search: string + kata kunci pencarian + Returns + ------- + list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) + """ - # setup parameter untuk klausa WHERE - where = "" - if endedFilter is not None: - where = f' WHERE waktu {"<" if endedFilter else ">="} NOW()' - - # gunakan fungsi pembantu linimasa - return linimasa(conn, where) \ No newline at end of file + # setup parameter untuk klausa WHERE + where = "" + params = [] + if kateg_filter is not None: + where += " WHERE id_acara in\ + (SELECT id_acara FROM kategori_acara WHERE nama_kategori IN\ + (" + ",".join(["?" for _ in range(len(kateg_filter))]) + "))" + params.extend(kateg_filter) + if search != '': + where += ' WHERE' if where == '' else ' AND' + where += ' nama_acara LIKE ?' + params.append(search) + + # gunakan fungsi pembantu linimasa + return linimasa(conn, where, params) + +def linimasa_penyelenggara(conn, ended_filter=None, search=""): + """Fungsi untuk mengambil acara pada linimasa penyelenggara + Parameters + ---------- + conn: connection + Connection ke database yang digunakan + ended_filter: bool (optional) + Filter yang digunakan untuk memfilter linimasa: sudah apakah acara yang + ditampilkan yang sudah berakhir (`True`) atau belum (`False`) + Returns + ------- + list (id_acara, nama_acara, kuota_pendaftar, deskripsi, waktu, list_kategori) + """ + + # setup parameter untuk klausa WHERE + where = "" + params = None + if ended_filter is not None: + where = f' WHERE waktu {"<" if ended_filter else ">="} NOW()' + if search != '': + where += ' AND' if where != '' else ' WHERE' + where += ' nama_acara LIKE ?' + params = [search] + + # gunakan fungsi pembantu linimasa + return linimasa(conn, where, params) diff --git a/src/app/modules/pesan.py b/src/app/modules/pesan.py index 51fca5e7c6a08b7e289be027a78da86390778a8f..0bab5f99f2d60753024521f43eb2a8f7e396c6c8 100644 --- a/src/app/modules/pesan.py +++ b/src/app/modules/pesan.py @@ -31,10 +31,10 @@ def pesanTiket(conn,idAcara,idMember,jml): memberAcara.append(val[0]) if (jml <= kuota-kuotaPesan and not idMember in memberAcara): - print(kuota-kuotaPesan) - print(jml) - # cur.execute("INSERT INTO mengikuti(id_member,id_acara,order_valid,jumlah) VALUES (%s,%s,%s,%s)",(idMember,idAcara,1,jml)) - # cur.execute("SELECT * FROM mengikuti") + # print(kuota-kuotaPesan) + # print(jml) + cur.execute("INSERT INTO mengikuti(id_member,id_acara,order_valid,jumlah) VALUES (%s,%s,%s,%s)",(idMember,idAcara,1,jml)) + conn.commit() # for val in cur: # print(val) return True diff --git a/src/app/modules/tambahAcara.py b/src/app/modules/tambahAcara.py deleted file mode 100644 index 7508727e2829063ae361e7a6a29b101a2229d500..0000000000000000000000000000000000000000 --- a/src/app/modules/tambahAcara.py +++ /dev/null @@ -1,117 +0,0 @@ -''' -Modul untuk operasi edit dan tambah acara -''' -from datetime import datetime -from app.db import init_db -import mariadb - - -def tambah_acara(id_penyelenggara, - nama_acara, - kuota_pendaftar, - waktu, - harga, - conn, - link=None, - deskripsi=None, - syarat=None, - video_introduksi=None, - id_acara=None) -> bool: - ''' Fungsi untuk menambahkan sebuah acara baru ke database atau mengubah - keterangan acara jika sudah ada - Parameters - ---------- - id_penyelenggara : int - id penyelenggara yang melaksanakan acara - nama_acara : str - nama acara - kuota_pendaftar : int - kuota pendaftar acara - waktu : datetime | str - waktu acara diadakan. Jika str akan otomatis diubah ke datetime, str - dalam format YYYY-MM-DD HH:MM:SS - harga : int - harga tiket acara - conn : mariadb._mariadb.connection - koneksi ke database - video_introduksi : str (optional) - link ke video penyelenggara - syarat : str (optional) - syarat acara - deskripsi : str (optional) - deskripsi acara - link : str (optional) - URL ke tempat pertemuan acara - id_acara : int (optional) - id acara, nilai default adalah None. Jika tidak bukan None artinya - mengubah acara. - Returns - ------- - True jika berhasil menambahkan atau memperbarui acara, selain itu False - ''' - if isinstance(waktu, str): - try: - waktu = datetime.strptime(waktu, "%Y-%m-%d %H:%M:%S") - except ValueError: - return False - - # conn = init_db() - cur = conn.cursor() - - if id_acara == None: - try: - cur.execute( - '''INSERT INTO acara - (nama_acara, - video_introduksi, - syarat_pendaftaran, - kuota_pendaftar, - deskripsi, - waktu, - harga, - link, - id_penyelenggara) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)''', ( - nama_acara, - video_introduksi, - syarat, - kuota_pendaftar, - deskripsi, - waktu, - harga, - link, - id_penyelenggara - )) - conn.commit() - return True - except mariadb.Error: - return False - else: - try: - cur.execute( - '''UPDATE acara - SET - nama_acara = ?, - video_introduksi = ?, - syarat_pendaftaran = ?, - kuota_pendaftar = ?, - deskripsi = ?, - waktu = ?, - harga = ?, - link = ? - WHERE id_acara = ?''', ( - nama_acara, - video_introduksi, - syarat, - kuota_pendaftar, - deskripsi, - waktu, - harga, - link, - id_acara - )) - conn.commit() - return True - except mariadb.Error as e: - print(e) - return False diff --git a/src/app/modules/tambah_acara.py b/src/app/modules/tambah_acara.py new file mode 100644 index 0000000000000000000000000000000000000000..a9727c49a43f21ac2439c9e8f2f27ff5abf22de4 --- /dev/null +++ b/src/app/modules/tambah_acara.py @@ -0,0 +1,260 @@ +''' +Modul untuk operasi edit dan tambah acara +''' +from datetime import datetime +from app.db import init_db +import mariadb + +def __add_foto(photos, id_acara, cur): + ''' + Fungsi untuk menambahkan foto-foto ke database + + Parameters + ---------- + photos : list[bytes] + path ke foto-foto yang ingin ditambahkan + nama_acara : str + nama acara + id_acara : int + id acara + cur : cursor + cursor koneksi ke database + + Throws + ------ + mariadb.Error + ''' + # Foto-foto sebelumnya dikirim bersamaan array photos + cur.execute('''DELETE FROM foto_acara WHERE id_acara = ?''', (id_acara,)) + # Bikin file gambar dan masukin ke database + for foto in photos: + cur.execute(''' + INSERT INTO foto_acara (id_acara, foto) + VALUES (?, ?)''', (id_acara, foto)) + +def __add_kategori(kategori, id_acara, cur): + ''' + Fungsi untuk menambahkan kategori acara ke database + + Parameters + ---------- + kategori : list[bytes] + kategori-kategori acara + id_acara : int + id acara + cur : cursor + cursor koneksi ke database + + Throws + ------ + mariadb.Error + ''' + cur.execute('''DELETE FROM kategori_acara WHERE id_acara = ?''', (id_acara,)) + for kateg in kategori: + cur.execute('''INSERT INTO kategori_acara VALUES (?, ?)''', (id_acara, kateg)) + +def remove_foto(id_acara, id_foto, conn) -> bool: + ''' + Fungsi untuk menghapus sebuah foto acara + + Parameters + ---------- + id_acara : int + id acara + id_foto : int + id foto + conn : mariadb.connection + koneksi ke db + + Returns + ------- + True jika operasi berhasil (tidak menghasilkan error); selain itu False + ''' + cur = conn.cursor() + try: + cur.execute('''DELETE FROM foto_acara WHERE id_acara = ? AND id_foto = ?''', (id_acara, id_foto)) + conn.commit() + return True + except mariadb.Error as e: + print(e) + return False + +def remove_category(id_acara, kateg, conn) -> bool: + ''' + Fungsi untuk menghapus kategori suatu acara + + Parameters + ---------- + id_acara : int + id acara + kateg : str + nama kategori + conn : mariadb.connection + koneksi ke db + + Returns + ------- + True jika operasi berhasil (tidak menghasilkan error); selain itu False + ''' + cur = conn.cursor() + try: + cur.execute('''DELETE FROM kategori_acara WHERE id_acara = ? AND nama_kategori = ?''', (id_acara, kateg)) + conn.commit() + return True + except mariadb.Error as e: + print(e) + return False + +def tambah_acara(id_penyelenggara, + nama_acara, + waktu, + harga, + kategori, + conn, + kuota_pendaftar=0, + link="", + deskripsi="", + syarat="", + video_introduksi="", + foto=None, + id_acara=None) -> bool: + ''' + Fungsi untuk menambahkan sebuah acara baru ke database atau mengubah + keterangan acara jika sudah ada + + Parameters + ---------- + id_penyelenggara : int + id penyelenggara yang melaksanakan acara + nama_acara : str + nama acara + waktu : datetime | str + waktu acara diadakan. Jika str akan otomatis diubah ke datetime, str + dalam format YYYY-MM-DD HH:MM:SS + harga : int + harga tiket acara + kategori : list[str] + kategori-kategori acara + conn : mariadb._mariadb.connection + koneksi ke database + kuota_pendaftar : int (optional) + kuota pendaftar acara, kalo None artinya ga ada kuota + foto : list[bytes] (optional) + Sekumpulan path ke file foto + link : str (optional) + URL ke tempat pertemuan acara + deskripsi : str (optional) + deskripsi acara + syarat : str (optional) + syarat acara + video_introduksi : str (optional) + link ke video penyelenggara + id_acara : int (optional) + id acara, nilai default adalah None. Jika tidak bukan None artinya + mengubah acara. + + Returns + ------- + True jika berhasil menambahkan atau memperbarui acara, selain itu False + ''' + if isinstance(waktu, str): + try: + waktu = datetime.strptime(waktu, "%Y-%m-%d %H:%M") + except ValueError: + return False + + # conn = init_db() + cur = conn.cursor() + + if len(kategori) == 0: + return False + + if id_acara is None: + try: + cur.execute( + '''INSERT INTO acara + (nama_acara, + syarat_pendaftaran, + kuota_pendaftar, + deskripsi, + waktu, + harga, + link, + video_introduksi, + id_penyelenggara) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)''', ( + nama_acara, + syarat, + kuota_pendaftar, + deskripsi, + waktu, + harga, + link, + video_introduksi, + id_penyelenggara + )) + + # Dapetin id acara + cur.execute('''SELECT id_acara FROM acara WHERE + nama_acara = ? AND + kuota_pendaftar = ? AND + waktu = ? AND + harga = ? AND + id_penyelenggara = ?''', ( + nama_acara, + kuota_pendaftar, + waktu, + harga, + id_penyelenggara + )) + id_acara = cur.fetchone()[0] + + # Tambah kategori + __add_kategori(kategori, id_acara, cur) + + # Tambah foto + if foto is not None: + __add_foto(foto, id_acara, cur) + + conn.commit() + return True + except mariadb.Error as e: + print(e) + return False + else: + try: + cur.execute( + '''UPDATE acara + SET + nama_acara = ?, + syarat_pendaftaran = ?, + kuota_pendaftar = ?, + deskripsi = ?, + waktu = ?, + harga = ?, + link = ?, + video_introduksi = ? + WHERE id_acara = ?''', ( + nama_acara, + syarat, + kuota_pendaftar, + deskripsi, + waktu, + harga, + link, + video_introduksi, + id_acara + )) + + # Tambah kategori + __add_kategori(kategori, id_acara, cur) + + # Tambah foto + if foto is not None: + __add_foto(foto, id_acara, cur) + + conn.commit() + return True + except mariadb.Error as e: + print(e) + return False diff --git a/src/app/ui/assets/no-image-available.jpeg b/src/app/ui/assets/no-image-available.jpeg new file mode 100755 index 0000000000000000000000000000000000000000..28b5b93702fdef2fc50fec7bb2fbad9fa7cc064a Binary files /dev/null and b/src/app/ui/assets/no-image-available.jpeg differ diff --git a/src/app/ui/auth_ui.py b/src/app/ui/auth_ui.py index d389cd4116a3ce7d24a9808bf30ed2710112d9c9..0e67f31df670fffd88659a43d0b4b26600f2ca1d 100644 --- a/src/app/ui/auth_ui.py +++ b/src/app/ui/auth_ui.py @@ -11,6 +11,7 @@ import sys import re from PyQt5 import QtCore, QtGui, QtWidgets from app.modules.auth import * +from app.ui.linimasa_ui import * from app.ui.util_ui import * EMAIL_REGEX = re.compile(r"[^@]+@[^@]+\.[^@]+") @@ -122,8 +123,10 @@ class Ui_Register_Member_Dialog(object): callInfoDialog(str(err)) class Ui_Login_Dialog(object): - def __init__(self, conn): + def __init__(self, conn, Window): self.conn = conn + self.linimasa = None + self.Window = Window def setupUi(self, Dialog): Dialog.setObjectName("Dialog") @@ -185,9 +188,13 @@ class Ui_Login_Dialog(object): def okHandle(self): try: - login(self.conn, self.textEditEmail.toPlainText(), self.lineEditPassword.text()) + (id, isPenyelenggara) = login(self.conn, self.textEditEmail.toPlainText(), self.lineEditPassword.text()) + self.id = id + self.isPenyelenggara = isPenyelenggara + callInfoDialog("Successfully logged in") - self.Dialog.close() + + self.Dialog.accept() except Exception as err: callInfoDialog(str(err)) diff --git a/src/app/ui/detail_acara_window_ui.py b/src/app/ui/detail_acara_window_ui.py new file mode 100644 index 0000000000000000000000000000000000000000..88469d9a9772848636131a8c57369b4fa1cbe254 --- /dev/null +++ b/src/app/ui/detail_acara_window_ui.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file './ui/main_window.ui' +# +# Created by: PyQt5 UI code generator 5.15.2 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets +import datetime +from app import db +from app.modules import pesan +from app.ui.linimasa_ui import * +from app.ui.tambah_acara_ui import * + +class Ui_Dialog(object): + def setupUi(self, Dialog, first): + Dialog.setObjectName("Dialog") + Dialog.resize(311, 79) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(210, 10, 81, 241)) + self.buttonBox.setOrientation(QtCore.Qt.Vertical) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + self.buttonBox.setObjectName("buttonBox") + self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 161, 41)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setSpacing(80) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(self.horizontalLayoutWidget) + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + self.spinBox = QtWidgets.QSpinBox(self.horizontalLayoutWidget) + self.spinBox.setObjectName("spinBox") + self.horizontalLayout.addWidget(self.spinBox) + + if first: + self.retranslateUi(Dialog) + else: + self.revalidationUi(Dialog) + + self.buttonBox.accepted.connect(Dialog.accept) + self.buttonBox.rejected.connect(Dialog.reject) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Jumlah")) + + def revalidationUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Pemesanan gagal")) + self.label.setText(_translate("Dialog", "Jumlah")) + + def getQuantity(self): + return self.spinBox.value() + +class Ui_DetailAcaraWindow(object): + def setupUi(self, MainWindow, content, kategori, isMember): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(813, 600) + + self.idAcara = content[0] + self.idUser = content[11] + self.isMember = isMember + + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + + self.frame = QtWidgets.QFrame(self.centralwidget) + self.frame.setGeometry(QtCore.QRect(10, 310, 781, 261)) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + + self.textBrowser = QtWidgets.QTextBrowser(self.frame) + self.textBrowser.setGeometry(QtCore.QRect(10, 50, 256, 192)) + self.textBrowser.setObjectName("textBrowser") + + self.label_2 = QtWidgets.QLabel(self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 10, 241, 31)) + font = QtGui.QFont() + font.setPointSize(20) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + + self.scrollArea = QtWidgets.QScrollArea(self.frame) + self.scrollArea.setGeometry(QtCore.QRect(290, 10, 481, 231)) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setObjectName("scrollArea") + self.scrollAreaWidgetContents = QtWidgets.QWidget() + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 479, 229)) + self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") + + self.textBrowser_2 = QtWidgets.QTextBrowser(self.scrollAreaWidgetContents) + self.textBrowser_2.setGeometry(QtCore.QRect(0, 0, 481, 231)) + self.textBrowser_2.setObjectName("textBrowser_2") + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + + self.idxPhoto = 0 + self.photos = content[12] + self.label_5 = QtWidgets.QLabel(self.centralwidget) + if len(self.photos)!=0: + self.label_5.setGeometry(QtCore.QRect(230, 10, 311, 211)) + self.label_5.setText("") + img = QtGui.QImage() + img.loadFromData(self.photos[self.idxPhoto]) + self.label_5.setPixmap(QtGui.QPixmap.fromImage(img)) + self.label_5.setScaledContents(True) + self.label_5.setObjectName("label_5") + else: + self.label_5.setGeometry(QtCore.QRect(340, 10, 311, 211)) + font = QtGui.QFont() + font.setPointSize(16) + self.label_5.setText("No Photos") + self.label_5.setFont(font) + + self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) + self.pushButton_2.setGeometry(QtCore.QRect(20, 10, 75, 23)) + self.pushButton_2.setObjectName("pushButton_2") + self.pushButton_2.clicked.connect(self.back) + + self.frame_2 = QtWidgets.QFrame(self.centralwidget) + self.frame_2.setGeometry(QtCore.QRect(10, 230, 781, 81)) + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + + self.pushButton = QtWidgets.QPushButton(self.frame_2) + self.pushButton.setGeometry(QtCore.QRect(660, 20, 111, 41)) + self.pushButton.setObjectName("pushButton") + self.pushButton.clicked.connect(self.buttonHandler) + + self.label_3 = QtWidgets.QLabel(self.frame_2) + self.label_3.setGeometry(QtCore.QRect(520, 22, 120, 20)) + self.label_3.setObjectName("label_3") + + self.label_4 = QtWidgets.QLabel(self.frame_2) + self.label_4.setGeometry(QtCore.QRect(540, 45, 90, 20)) + self.label_4.setObjectName("label_4") + + self.label = QtWidgets.QLabel(self.frame_2) + self.label.setGeometry(QtCore.QRect(10, 15, 211, 41)) + font = QtGui.QFont() + font.setPointSize(18) + self.label.setFont(font) + self.label.setObjectName("label") + + self.widget = QtWidgets.QWidget(self.frame_2) + self.widget.setGeometry(QtCore.QRect(240, 25, 281, 16)) + self.widget.setObjectName("widget") + + self.label_6 = QtWidgets.QLabel(self.widget) + self.label_6.setGeometry(QtCore.QRect(10, 0, 61, 16)) + font = QtGui.QFont() + font.setPointSize(10) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + + self.label_7 = QtWidgets.QLabel(self.widget) + self.label_7.setGeometry(QtCore.QRect(80, 0, 61, 16)) + font = QtGui.QFont() + font.setPointSize(10) + self.label_7.setFont(font) + self.label_7.setObjectName("label_7") + + self.label_8 = QtWidgets.QLabel(self.widget) + self.label_8.setGeometry(QtCore.QRect(150, 0, 61, 16)) + font = QtGui.QFont() + font.setPointSize(10) + self.label_8.setFont(font) + self.label_8.setObjectName("label_8") + + self.label_9 = QtWidgets.QLabel(self.widget) + self.label_9.setGeometry(QtCore.QRect(220, 0, 61, 16)) + font = QtGui.QFont() + font.setPointSize(10) + self.label_9.setFont(font) + self.label_9.setObjectName("label_9") + + self.label_10 = QtWidgets.QLabel(self.frame_2) + self.label_10.setObjectName(u"label_10") + self.label_10.setGeometry(QtCore.QRect(10, 50, 161, 20)) + font.setPointSize(12) + self.label_10.setFont(font) + + self.label_11 = QtWidgets.QLabel(self.frame_2) + self.label_11.setObjectName(u"label_11") + self.label_11.setGeometry(QtCore.QRect(250, 45, 191, 16)) + + self.line = QtWidgets.QFrame(self.frame_2) + self.line.setObjectName(u"line") + self.line.setGeometry(QtCore.QRect(0, 70, 781, 16)) + self.line.setFrameShape(QtWidgets.QFrame.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Sunken) + + self.line_2 = QtWidgets.QFrame(self.frame_2) + self.line_2.setObjectName(u"line_2") + self.line_2.setGeometry(QtCore.QRect(0, 0, 781, 16)) + self.line_2.setFrameShape(QtWidgets.QFrame.HLine) + self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) + + self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) + self.pushButton_3.setObjectName(u"pushButton_3") + self.pushButton_3.setGeometry(QtCore.QRect(580, 110, 75, 23)) + self.pushButton_3.clicked.connect(self.nextPicture) + + self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget) + self.pushButton_4.setObjectName(u"pushButton_4") + self.pushButton_4.setGeometry(QtCore.QRect(130, 110, 75, 23)) + self.pushButton_4.clicked.connect(self.prevPicture) + + self.widget.raise_() + self.pushButton.raise_() + self.label_3.raise_() + self.label_4.raise_() + self.label.raise_() + self.line.raise_() + self.line_2.raise_() + + self.line_3 = QtWidgets.QFrame(self.centralwidget) + self.line_3.setObjectName(u"line_3") + self.line_3.setGeometry(QtCore.QRect(10, 560, 781, 16)) + self.line_3.setFrameShape(QtWidgets.QFrame.HLine) + self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken) + MainWindow.setCentralWidget(self.centralwidget) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.MainWindow = MainWindow + + self.retranslateUi(MainWindow,content,kategori) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow, content, kategori): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + + syarat = content[3] if content[3] != None else "Tidak ada syarat" + htmlSyarat = '''<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n +<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n +p, li {0}\n +</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt;\">{val}</span></p></body></html>'''.format("{white-space: pre-wrap;}",val=syarat) + self.textBrowser.setHtml(_translate("MainWindow", htmlSyarat)) + + self.label_2.setText(_translate("MainWindow", "Syarat")) + + desc = content[5] if content[5] != None else "-" + contact = content[9] + link = content[8] if content[8]!="" else "Belum ada" + htmlInfo = """<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n +<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n +p, li {0}\n +</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:20pt;\">Deskripsi</span></p>\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt;\">{descVal}</span></p>\n +<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;\"><br /></p>\n +<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;\"><br /></p>\n +<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;\"><br /></p>\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:20pt;\">Contact Person</span></p>\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt;\">{contactVal}</span></p></body></html> +<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;\"><br /></p>\n +<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt;\">Link Acara :{linkVal}</span></p></body></html>""".format("{ white-space: pre-wrap; }",descVal=desc,contactVal=contact,linkVal=link) + self.textBrowser_2.setHtml(_translate("MainWindow", htmlInfo)) + + self.pushButton_2.setText(_translate("MainWindow", "Back")) + + if not self.isMember: + self.pushButton.setText(_translate("MainWindow", "Edit Acara")) + else: + conn = db.init_db() + cur = conn.cursor() + + cur.execute("SELECT id_member FROM mengikuti WHERE id_acara = "+str(content[0])) + already = [i[0] for i in cur.fetchall()] + + if self.idUser in already: + self.pushButton.setEnabled(False) + self.pushButton.setText(_translate("MainWindow", "Pemesanan Berhasil!")) + else: + self.pushButton.setText(_translate("MainWindow", "Pesan Tiket")) + + tanggal = content[6].strftime("%d %b %Y %H:%M:%S") + self.label_3.setText(_translate("MainWindow", tanggal)) + + self.maxQ = str(content[4]) + self.quantity = content[13] if content[13] != None else 0 + kuota = "Kuota: " + str(self.quantity) + "/" + str(self.maxQ) + self.label_4.setText(_translate("MainWindow", kuota)) + + nama = content[1] + self.label.setText(_translate("MainWindow", nama)) + + kat1 = kategori[0] + self.label_6.setText(_translate("MainWindow", kat1)) + + kat2 = kategori[1] if len(kategori) > 1 else "" + self.label_7.setText(_translate("MainWindow", kat2)) + + kat3 = kategori[2] if len(kategori) > 2 else "" + self.label_8.setText(_translate("MainWindow", kat3)) + + kat4 = kategori[3] if len(kategori) > 3 else "" + self.label_9.setText(_translate("MainWindow", kat4)) + + organisasi = content[10] + self.label_10.setText(_translate("MainWindow", organisasi)) + + price = "Harga: Rp." + str(content[7]) + self.label_11.setText(_translate("MainWindow", price)) + + self.pushButton_3.setText(_translate("MainWindow", u"Next", None)) + self.pushButton_4.setText(_translate("MainWindow", u"Prev", None)) + + def back(self): + self.MainWindow.close() + + def nextPicture(self): + self.idxPhoto = self.idxPhoto +1 if self.idxPhoto +1<len(self.photos) else 0 + img = QtGui.QImage() + img.loadFromData(self.photos[self.idxPhoto]) + self.label_5.setPixmap(QtGui.QPixmap.fromImage(img)) + + def prevPicture(self): + self.idxPhoto = self.idxPhoto -1 if self.idxPhoto -1>=0 else len(self.photos)-1 + img = QtGui.QImage() + img.loadFromData(self.photos[self.idxPhoto]) + self.label_5.setPixmap(QtGui.QPixmap.fromImage(img)) + + def buttonHandler(self): + if self.isMember: + first = True + pesan_dialog = PesanDialog(first) + + while pesan_dialog.exec(): + quantity = pesan_dialog.getQuantity() + conn = db.init_db() + + if quantity>0 and pesan.pesanTiket(conn,self.idAcara,self.idUser,quantity): + _translate = QtCore.QCoreApplication.translate + self.pushButton.setEnabled(False) + self.pushButton.setText(_translate("MainWindow", "Periksa Link Acara!")) + kuota = "Kuota: " + str(self.quantity+quantity) + "/" + str(self.maxQ) + self.label_4.setText(_translate("MainWindow", kuota)) + break + else: + first = False + pesan_dialog = PesanDialog(first) + else: + conn = db.init_db() + self.w = TambahAcaraWindow(conn=conn, + id_acara=self.idAcara, + id_penyelenggara=self.idUser) + self.w.show() + +class DetailAcaraWindow(QMainWindow, Ui_DetailAcaraWindow): + def __init__(self, idAcara, idMember, isMember, parent=None): + super().__init__(parent) + + conn = db.init_db() + cur = conn.cursor() + + # Ambil info acara + cur.execute('SELECT * FROM acara WHERE id_acara = {0} LIMIT 1'.format(idAcara)) + content = cur.fetchone() + + # Ambil kontak penanggungjawab + cur.execute("SELECT penanggung_jawab,no_wa,nama_organisasi FROM penyelenggara WHERE id_penyelenggara = "+str(content[9])) + val = cur.fetchone() + contact = val[0] + ": " + val[1] + contact = (contact,val[2]) + content = tuple([content[i] for i in range(9)]) + content += contact + + # Ambil foto acara + cur.execute("SELECT id_foto,foto FROM foto_acara WHERE id_acara ="+str(idAcara)) + files = cur.fetchall() + images = [] + for aFile in files: + images.append(aFile[1]) + + # Ambil kategori acara + cur.execute("SELECT nama_kategori FROM kategori_acara WHERE id_acara = "+str(idAcara)) + query = cur.fetchall() + kategori = () + for val in query: + kategori += val + + # Ambil jumlah tiket yang udah dipesan + cur.execute("SELECT SUM(jumlah) FROM mengikuti WHERE id_acara = "+str(idAcara)) + jmlPesanan = cur.fetchone() + jmlPesanan = jmlPesanan[0] + content += (idMember,images,jmlPesanan) + + print(content) + # content = (idAcara,namaAcara,linkVideo,syarat,kuota,desc,waktu,harga,link,namapenanggungjwb: noWA,namaOrganisasi,idMember,foto,jmlPesanan) + self.setupUi(self,content,kategori,isMember) + + def about(self): + QMessageBox.about( + self, + "About Sample Editor", + "<p>A sample text editor app built with:</p>" + "<p>- PyQt</p>" + "<p>- Qt Designer</p>" + "<p>- Python</p>", + ) + +class PesanDialog(QtWidgets.QDialog, Ui_Dialog): + def __init__(self,first,parent=None): + super().__init__(parent) + self.setupUi(self, first) + diff --git a/src/app/ui/edit_account.py b/src/app/ui/edit_account.py index 89128ef55dd3dbd7918af14dcbe8e1644acead58..de009718a6274514e7603c0181fa7316076b3a07 100644 --- a/src/app/ui/edit_account.py +++ b/src/app/ui/edit_account.py @@ -21,6 +21,8 @@ class Ui_EditMember(object): def setupUi(self, EditMember): EditMember.setObjectName("EditMember") EditMember.resize(460, 472) + self.Dialog = EditMember + self.buttonBox = QtWidgets.QDialogButtonBox(EditMember) self.buttonBox.setGeometry(QtCore.QRect(90, 420, 341, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) @@ -77,6 +79,7 @@ class Ui_EditMember(object): self.lineEdit_password = QtWidgets.QLineEdit(self.horizontalLayoutWidget) self.lineEdit_password.setObjectName("lineEdit_password") + self.lineEdit_password.setEchoMode(QtWidgets.QLineEdit.Password) self.verticalLayout_2.addWidget(self.lineEdit_password) self.textEdit_no_telp = QtWidgets.QTextEdit(self.horizontalLayoutWidget) @@ -93,7 +96,7 @@ class Ui_EditMember(object): self.pic_profile = QtWidgets.QLabel(EditMember) self.pic_profile.setGeometry(QtCore.QRect(170, 20, 100, 100)) self.pic_profile.setText("") - self.pic_profile.setPixmap(QtGui.QPixmap("Downloads/default_user.png")) + self.pic_profile.setPixmap(QtGui.QPixmap("assets/default_user.png")) self.pic_profile.setScaledContents(True) self.pic_profile.setObjectName("pic_profile") @@ -130,6 +133,8 @@ class Ui_EditMember(object): raise Exception("Invalid email") edit_account_member(self.conn, self.id_member, nama_dpn, nama_blkg, None, email, password, no_telp, desc) callInfoDialog("Successfully edited account") + + self.Dialog.close() except Exception as err: callInfoDialog(str(err)) @@ -142,6 +147,8 @@ class Ui_EditPenyelenggara(object): def setupUi(self, EditPenyelenggara): EditPenyelenggara.setObjectName("EditPenyelenggara") EditPenyelenggara.resize(460, 474) + self.Dialog = EditPenyelenggara + self.buttonBox = QtWidgets.QDialogButtonBox(EditPenyelenggara) self.buttonBox.setGeometry(QtCore.QRect(90, 420, 341, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) @@ -185,9 +192,9 @@ class Ui_EditPenyelenggara(object): self.textEdit_pj.setObjectName("textEdit_pj") self.verticalLayout_2.addWidget(self.textEdit_pj) - self.textEdit_no_telp = QtWidgets.QTextEdit(self.horizontalLayoutWidget) - self.textEdit_no_telp.setObjectName("textEdit_no_telp") - self.verticalLayout_2.addWidget(self.textEdit_no_telp) + self.textEdit_no_wa = QtWidgets.QTextEdit(self.horizontalLayoutWidget) + self.textEdit_no_wa.setObjectName("textEdit_no_wa") + self.verticalLayout_2.addWidget(self.textEdit_no_wa) self.textEdit_email = QtWidgets.QTextEdit(self.horizontalLayoutWidget) self.textEdit_email.setObjectName("textEdit_email") @@ -195,6 +202,7 @@ class Ui_EditPenyelenggara(object): self.lineEdit_password = QtWidgets.QLineEdit(self.horizontalLayoutWidget) self.lineEdit_password.setObjectName("lineEdit_password") + self.lineEdit_password.setEchoMode(QtWidgets.QLineEdit.Password) self.verticalLayout_2.addWidget(self.lineEdit_password) self.textEdit_deskripsi = QtWidgets.QTextEdit(self.horizontalLayoutWidget) @@ -207,7 +215,7 @@ class Ui_EditPenyelenggara(object): self.pic_profile = QtWidgets.QLabel(EditPenyelenggara) self.pic_profile.setGeometry(QtCore.QRect(170, 10, 100, 100)) self.pic_profile.setText("") - self.pic_profile.setPixmap(QtGui.QPixmap("Downloads/default_user.png")) + self.pic_profile.setPixmap(QtGui.QPixmap("assets/default_user.png")) self.pic_profile.setScaledContents(True) self.pic_profile.setObjectName("pic_profile") @@ -244,5 +252,6 @@ class Ui_EditPenyelenggara(object): raise Exception("Invalid email") edit_account_penyelenggara(self.conn, self.id_penyelenggara, nama_org, pj, None, None, email, password, no_wa, desc) callInfoDialog("Successfully edited account") + self.Dialog.close() except Exception as err: callInfoDialog(str(err)) \ No newline at end of file diff --git a/src/app/ui/file_input_dialog.py b/src/app/ui/file_input_dialog.py new file mode 100644 index 0000000000000000000000000000000000000000..7d0f4030cadb4195bcd0ef1e25d791ff3b7989ce --- /dev/null +++ b/src/app/ui/file_input_dialog.py @@ -0,0 +1,48 @@ +from PyQt5 import QtWidgets + + +class FileInput(QtWidgets.QWidget): + def __init__(self): + super().__init__() + self.title = 'Masukkan file-file gambar Anda' + self.left = 10 + self.top = 10 + self.width = 640 + self.height = 480 + + def spawn(self, multiple: bool): + self.setWindowTitle(self.title) + self.setGeometry(self.left, self.top, self.width, self.height) + if multiple: + files = self.openFileNamesDialog() + else: + files = self.openFileNameDialog() + + self.show() + + return files + + def openFileNameDialog(self): + options = QtWidgets.QFileDialog.Options() + options |= QtWidgets.QFileDialog.DontUseNativeDialog + fileName, _ = QtWidgets.QFileDialog.getOpenFileName( + self, + "QFileDialog.getOpenFileName()", + "", + "All Files (*);;Python Files (*.py)", + options=options) + if fileName: + print(fileName) + + def openFileNamesDialog(self): + options = QtWidgets.QFileDialog.Options() + options |= QtWidgets.QFileDialog.DontUseNativeDialog + files, _ = QtWidgets.QFileDialog.getOpenFileNames( + self, + self.title, + "", + "Semua File (*);;File Gambar (*.png *.jpg *.jpeg)", + options=options) + + if files: + return files diff --git a/src/app/ui/linimasa_pengguna_ui.ui b/src/app/ui/linimasa_pengguna_ui.ui new file mode 100644 index 0000000000000000000000000000000000000000..d755c4173ef59b8c5ef929edb6d479597ff72abd --- /dev/null +++ b/src/app/ui/linimasa_pengguna_ui.ui @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Linimasa</class> + <widget class="QMainWindow" name="Linimasa"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="sizeConstraint"> + <enum>QLayout::SetMaximumSize</enum> + </property> + <item alignment="Qt::AlignRight"> + <widget class="QPushButton" name="edit_akun"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Edit Akun</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QCheckBox" name="teknologi"> + <property name="text"> + <string>Teknologi</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="motivasi"> + <property name="text"> + <string>Motivasi</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="ekonomi"> + <property name="text"> + <string>Ekonomi</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="kompetisi"> + <property name="text"> + <string>Kompetisi</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Search Query</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="searchquery"> + <property name="baseSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="searchbutton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Search</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="linimasa_widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>776</width> + <height>473</height> + </rect> + </property> + <layout class="QVBoxLayout" name="linimasa"/> + </widget> + </widget> + </item> + </layout> + </widget> + <action name="actionpush1"> + <property name="text"> + <string>push1</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/app/ui/linimasa_penyelenggara_ui.ui b/src/app/ui/linimasa_penyelenggara_ui.ui new file mode 100644 index 0000000000000000000000000000000000000000..2e908db6dedfe1177c5c24b45835c60fe8a1d7c9 --- /dev/null +++ b/src/app/ui/linimasa_penyelenggara_ui.ui @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Linimasa</class> + <widget class="QMainWindow" name="Linimasa"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>807</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="sizeConstraint"> + <enum>QLayout::SetMaximumSize</enum> + </property> + <item alignment="Qt::AlignRight"> + <widget class="QPushButton" name="tambah_acara"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Tambah Acara</string> + </property> + </widget> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QPushButton" name="edit_akun"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Edit Akun</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="no_filter"> + <property name="text"> + <string>Tanpa filter</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="filter_before"> + <property name="text"> + <string>Belum diselenggarakan</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="filter_after"> + <property name="text"> + <string>Sudah diselenggarakan</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Search Query</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="searchquery"> + <property name="baseSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="searchbutton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Search</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="linimasa_widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>783</width> + <height>473</height> + </rect> + </property> + <layout class="QVBoxLayout" name="linimasa"/> + </widget> + </widget> + </item> + </layout> + </widget> + <action name="actionpush1"> + <property name="text"> + <string>push1</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/app/ui/linimasa_ui.py b/src/app/ui/linimasa_ui.py new file mode 100644 index 0000000000000000000000000000000000000000..0fec2735a08add36a123c71d4a23c83cc2e6b548 --- /dev/null +++ b/src/app/ui/linimasa_ui.py @@ -0,0 +1,131 @@ +import sys,os +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtCore as QtCore +from PyQt5.QtWidgets import ( + QMainWindow, QMessageBox, QLabel, QVBoxLayout, + QHBoxLayout, QWidget, QPushButton, QDialog +) +from PyQt5.uic import loadUi + +from app.modules import linimasa +from app import main + +import app.ui.detail_acara_window_ui as detail +import app.ui.edit_account as edit_account +import app.ui.tambah_acara_ui as tambah_acara_ui + +class LinimasaPenggunaWindow(QMainWindow): + def __init__(self, id_member, windows, parent=None): + super().__init__(parent) + self.windows = windows + self.id_member = id_member + loadUi(os.path.join(os.path.dirname(__file__), 'linimasa_pengguna_ui.ui'), self) + self.connectSignalsSlots() + self.attemptSearch() + + def connectSignalsSlots(self): + self.searchbutton.clicked.connect(self.attemptSearch) + self.edit_akun.clicked.connect(self.editakun) + + # ini + def attemptSearch(self): + kategs = ['motivasi', 'teknologi', 'ekonomi', 'kompetisi'] + katfil = [x for x in kategs if getattr(self, x).isChecked()] + query = self.searchquery.text() + conn = main.init_db() + result = linimasa.linimasa_pengguna(conn, katfil if len(katfil) > 0 else None, query) + for i in reversed(range(self.linimasa.count())): + self.linimasa.itemAt(i).widget().deleteLater() + for r in result: + container = QWidget(self.linimasa_widget) + layout = QHBoxLayout(container) + layout.addWidget(QLabel(str(r[0]))) + _w = QWidget(layout.widget()) + namadetail = QVBoxLayout(_w) + namadetail.addWidget(QLabel(f'Nama acara: {r[1]}')) + namadetail.addWidget(QLabel(f'Deskripsi: {r[3]}')) + layout.addWidget(_w) + layout.addWidget(QLabel(f'Kuota Pendaftar: {r[2]}')) + layout.addWidget(QLabel(f'{r[4]}')) + button = QPushButton('Lihat acara') + button.clicked.connect(lambda: self.showDetails(r[0])) + layout.addWidget(button) + self.linimasa.addWidget(container) + + def showDetails(self, id): + w = detail.DetailAcaraWindow(id, self.id_member, True) + self.windows.append(w) + w.show() + + def editakun(self): + conn = main.init_db() + Dialog = QtWidgets.QDialog() + w = edit_account.Ui_EditMember(conn, self.id_member) + w.setupUi(Dialog) + Dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose) + Dialog.exec_() + + +class LinimasaPenyelenggaraWindow(QMainWindow): + def __init__(self, id_penyelenggara, windows, parent=None): + super().__init__(parent) + self.windows = windows + self.id_penyelenggara = id_penyelenggara + loadUi(os.path.join(os.path.dirname(__file__),'linimasa_penyelenggara_ui.ui'), self) + self.connectSignalsSlots() + self.attemptSearch() + + def connectSignalsSlots(self): + self.searchbutton.clicked.connect(self.attemptSearch) + self.edit_akun.clicked.connect(self.editakun) + self.tambah_acara.clicked.connect(self.tambahacara) + + # ini + def attemptSearch(self): + ended = None + if self.no_filter.isChecked(): + ended = None + elif self.filter_before.isChecked(): + ended = False + elif self.filter_after.isChecked(): + ended = True + query = self.searchquery.text() + conn = main.init_db() + result = linimasa.linimasa_penyelenggara(conn, ended, query) + for i in reversed(range(self.linimasa.count())): + self.linimasa.itemAt(i).widget().deleteLater() + for r in result: + container = QWidget(self.linimasa_widget) + layout = QHBoxLayout(container) + layout.addWidget(QLabel(str(r[0]))) + _w = QWidget(layout.widget()) + namadetail = QVBoxLayout(_w) + namadetail.addWidget(QLabel(f'Nama acara: {r[1]}')) + namadetail.addWidget(QLabel(f'Deskripsi: {r[3]}')) + layout.addWidget(_w) + layout.addWidget(QLabel(f'Kuota Pendaftar: {r[2]}')) + layout.addWidget(QLabel(f'{r[4]}')) + button = QPushButton('Lihat acara') + button.clicked.connect(lambda: self.showDetails(r[0])) + layout.addWidget(button) + self.linimasa.addWidget(container) + + def editakun(self): + conn = main.init_db() + dialog = QtWidgets.QDialog() + ui = edit_account.Ui_EditPenyelenggara(conn, self.id_penyelenggara) + ui.setupUi(dialog) + dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose) + dialog.exec_() + conn.close() + + def showDetails(self, id): + w = detail.DetailAcaraWindow(id, self.id_penyelenggara, False) + self.windows.append(w) + w.show() + + def tambahacara(self): + conn = main.init_db() + w = tambah_acara_ui.TambahAcaraWindow(conn, self.id_penyelenggara) + self.windows.append(w) + w.show() diff --git a/src/app/ui/main_window_ui.py b/src/app/ui/main_window_ui.py index 36ac8f68b6fdb4840dc829630290a9f5f7a6e169..8b6239b76756a8df2b53e7240d2dd46f938bf280 100644 --- a/src/app/ui/main_window_ui.py +++ b/src/app/ui/main_window_ui.py @@ -7,16 +7,21 @@ # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets -from .auth_ui import * +from PyQt5.QtWidgets import QMainWindow +from app.ui.auth_ui import * +from app.ui.linimasa_ui import * class Ui_YesManagement(object): - def __init__(self, conn): + def __init__(self, conn, windows): self.conn = conn + self.windows = windows def setupUi(self, YesManagement): YesManagement.setObjectName("YesManagement") YesManagement.resize(800, 456) YesManagement.setUnifiedTitleAndToolBarOnMac(False) + + self.MainWindow = YesManagement self.centralwidget = QtWidgets.QWidget(YesManagement) self.centralwidget.setObjectName("centralwidget") @@ -44,6 +49,7 @@ class Ui_YesManagement(object): YesManagement.setStatusBar(self.statusbar) self.retranslateUi(YesManagement) + QtCore.QMetaObject.connectSlotsByName(YesManagement) def retranslateUi(self, YesManagement): @@ -67,10 +73,19 @@ class Ui_YesManagement(object): def loginButtonHandler(self): Dialog = QtWidgets.QDialog() - ui = Ui_Login_Dialog(self.conn) + ui = Ui_Login_Dialog(self.conn, self.MainWindow) ui.setupUi(Dialog) Dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose) - Dialog.exec_() + if Dialog.exec_(): + linimasa = None + if ui.isPenyelenggara: + linimasa = LinimasaPenyelenggaraWindow(ui.id, self.windows) + else: + linimasa = LinimasaPenggunaWindow(ui.id, self.windows) + self.windows.append(linimasa) + + linimasa.show() + self.MainWindow.close() def registerPenyelenggaraButtonHandler(self): Dialog = QtWidgets.QDialog() diff --git a/src/app/ui/tambah_acara.ui b/src/app/ui/tambah_acara.ui index 345f32f37d64cb88ef81982be2edc56cabe07b66..7f288942d282b9a3f51496e4b0751c1a78842f97 100644 --- a/src/app/ui/tambah_acara.ui +++ b/src/app/ui/tambah_acara.ui @@ -51,12 +51,12 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> - <layout class="QHBoxLayout" name="ImageArea"> + <layout class="QHBoxLayout" name="area_image"> <property name="topMargin"> <number>0</number> </property> <item> - <widget class="QToolButton" name="ImagePrev"> + <widget class="QToolButton" name="button_image_prev"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -116,7 +116,7 @@ </spacer> </item> <item> - <widget class="QLabel" name="Image"> + <widget class="QLabel" name="image"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> @@ -172,7 +172,7 @@ </spacer> </item> <item> - <widget class="QToolButton" name="ImageNext"> + <widget class="QToolButton" name="button_image_next"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -218,7 +218,7 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> + <layout class="QHBoxLayout" name="area_add_image"> <property name="topMargin"> <number>0</number> </property> @@ -236,7 +236,7 @@ </spacer> </item> <item> - <widget class="QPushButton" name="pushButton"> + <widget class="QPushButton" name="button_add_image"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -262,7 +262,7 @@ </widget> </item> <item> - <widget class="QLabel" name="label_13"> + <widget class="QLabel" name="catatan_image"> <property name="font"> <font> <pointsize>10</pointsize> @@ -318,27 +318,27 @@ <x>0</x> <y>0</y> <width>1387</width> - <height>425</height> + <height>388</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_2"> - <item row="1" column="2"> - <widget class="QLabel" name="label"> + <item row="6" column="2"> + <widget class="QLabel" name="label_deskripsi"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> <property name="text"> - <string>Nama Acara</string> + <string>Deskripsi</string> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="1" column="6"> - <spacer name="horizontalSpacer_11"> + <item row="1" column="0"> + <spacer name="horizontalSpacer_10"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -347,14 +347,14 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>500</width> + <width>40</width> <height>20</height> </size> </property> </spacer> </item> - <item row="3" column="3"> - <widget class="QLabel" name="label_18"> + <item row="2" column="3"> + <widget class="QLabel" name="wajib_waktu"> <property name="font"> <font> <pointsize>12</pointsize> @@ -368,67 +368,61 @@ </property> </widget> </item> - <item row="4" column="3"> - <widget class="QLabel" name="label_19"> + <item row="2" column="5"> + <widget class="QDateTimeEdit" name="input_waktu"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="styleSheet"> - <string notr="true">color: rgb(255, 0, 0);</string> - </property> - <property name="text"> - <string>*</string> + <property name="displayFormat"> + <string>yyyy/MM/dd HH:mm</string> </property> </widget> </item> - <item row="3" column="5"> - <widget class="QSpinBox" name="spinBox_2"> + <item row="5" column="5"> + <widget class="QLineEdit" name="input_link"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="maximum"> - <number>1000000000</number> - </property> </widget> </item> - <item row="10" column="2"> - <widget class="QLabel" name="label_15"> + <item row="3" column="5"> + <widget class="QSpinBox" name="input_harga"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="text"> - <string>Link ke Video Introduksi Acara</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="maximum"> + <number>1000000000</number> </property> </widget> </item> - <item row="4" column="5"> - <widget class="QSpinBox" name="spinBox"> + <item row="3" column="3"> + <widget class="QLabel" name="wajib_harga"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="maximum"> - <number>1000000000</number> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> + </property> + <property name="text"> + <string>*</string> </property> </widget> </item> - <item row="1" column="0"> - <spacer name="horizontalSpacer_10"> + <item row="1" column="4"> + <spacer name="horizontalSpacer_12"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -438,8 +432,8 @@ </property> </spacer> </item> - <item row="8" column="5"> - <widget class="QPlainTextEdit" name="plainTextEdit_2"> + <item row="1" column="5"> + <widget class="QLineEdit" name="input_nama_acara"> <property name="font"> <font> <pointsize>12</pointsize> @@ -447,92 +441,81 @@ </property> </widget> </item> - <item row="4" column="2"> - <widget class="QLabel" name="label_4"> - <property name="font"> - <font> - <pointsize>12</pointsize> - </font> - </property> - <property name="text"> - <string>Kuota</string> + <item row="1" column="6"> + <spacer name="horizontalSpacer_11"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> </property> - </widget> - </item> - <item row="6" column="5"> - <widget class="QPlainTextEdit" name="plainTextEdit"> - <property name="font"> - <font> - <pointsize>12</pointsize> - </font> + <property name="sizeHint" stdset="0"> + <size> + <width>500</width> + <height>20</height> + </size> </property> - </widget> + </spacer> </item> - <item row="2" column="3"> - <widget class="QLabel" name="label_17"> + <item row="5" column="2"> + <widget class="QLabel" name="label_link"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="styleSheet"> - <string notr="true">color: rgb(255, 0, 0);</string> - </property> <property name="text"> - <string>*</string> + <string>Link ke Conference</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="8" column="2"> - <widget class="QLabel" name="label_6"> + <item row="4" column="2"> + <widget class="QLabel" name="label_kuota"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> <property name="text"> - <string>Syarat</string> + <string>Kuota</string> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="6" column="2"> - <widget class="QLabel" name="label_5"> + <item row="3" column="2"> + <widget class="QLabel" name="label_harga"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> <property name="text"> - <string>Deskripsi</string> + <string>Harga</string> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="1" column="3"> - <widget class="QLabel" name="label_16"> + <item row="4" column="5"> + <widget class="QSpinBox" name="input_kuota"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="styleSheet"> - <string notr="true">color: rgb(255, 0, 0);</string> - </property> - <property name="text"> - <string>*</string> + <property name="maximum"> + <number>1000000000</number> </property> </widget> </item> <item row="2" column="2"> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="label_waktu"> <property name="font"> <font> <pointsize>12</pointsize> @@ -546,89 +529,67 @@ </property> </widget> </item> - <item row="10" column="5"> - <widget class="QLineEdit" name="lineEdit_3"> + <item row="8" column="2"> + <widget class="QLabel" name="label_syarat"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - </widget> - </item> - <item row="1" column="4"> - <spacer name="horizontalSpacer_12"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> + <property name="text"> + <string>Syarat</string> </property> - </spacer> - </item> - <item row="1" column="5"> - <widget class="QLineEdit" name="lineEdit"> - <property name="font"> - <font> - <pointsize>12</pointsize> - </font> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="2" column="5"> - <widget class="QDateTimeEdit" name="dateTimeEdit"> + <item row="1" column="2"> + <widget class="QLabel" name="label_nama_acara"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="displayFormat"> - <string>yyyy/MM/dd HH:mm</string> + <property name="text"> + <string>Nama Acara</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item row="3" column="2"> - <widget class="QLabel" name="label_3"> + <item row="8" column="5"> + <widget class="QPlainTextEdit" name="input_syarat"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="text"> - <string>Harga</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> </widget> </item> - <item row="5" column="2"> - <widget class="QLabel" name="label_14"> + <item row="6" column="5"> + <widget class="QPlainTextEdit" name="input_deskripsi"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> - <property name="text"> - <string>Link ke Conference</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> </widget> </item> - <item row="5" column="5"> - <widget class="QLineEdit" name="lineEdit_2"> + <item row="1" column="3"> + <widget class="QLabel" name="wajib_nama"> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> + </property> + <property name="text"> + <string>*</string> + </property> </widget> </item> </layout> @@ -636,7 +597,7 @@ </widget> </item> <item> - <layout class="QGridLayout" name="KategoriArea"> + <layout class="QGridLayout" name="area_kategori"> <property name="leftMargin"> <number>50</number> </property> @@ -669,7 +630,7 @@ </spacer> </item> <item row="2" column="1"> - <widget class="QCheckBox" name="Kompetisi"> + <widget class="QCheckBox" name="kompetisi"> <property name="font"> <font> <pointsize>11</pointsize> @@ -694,7 +655,7 @@ </spacer> </item> <item row="1" column="2"> - <widget class="QCheckBox" name="Motivasi"> + <widget class="QCheckBox" name="motivasi"> <property name="font"> <font> <pointsize>11</pointsize> @@ -706,7 +667,7 @@ </widget> </item> <item row="2" column="2"> - <widget class="QCheckBox" name="Ekonomi"> + <widget class="QCheckBox" name="ekonomi"> <property name="font"> <font> <pointsize>11</pointsize> @@ -718,7 +679,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="QCheckBox" name="Teknologi"> + <widget class="QCheckBox" name="teknologi"> <property name="font"> <font> <pointsize>11</pointsize> @@ -756,7 +717,7 @@ </spacer> </item> <item row="0" column="1" colspan="2"> - <widget class="QLabel" name="KategoriAreaText"> + <widget class="QLabel" name="kategori_area_text"> <property name="font"> <font> <pointsize>14</pointsize> @@ -781,7 +742,7 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="ButtonArea"> + <layout class="QHBoxLayout" name="area_button"> <property name="topMargin"> <number>25</number> </property> @@ -802,7 +763,7 @@ </spacer> </item> <item> - <widget class="QPushButton" name="Simpan"> + <widget class="QPushButton" name="button_simpan"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> @@ -848,7 +809,7 @@ </spacer> </item> <item> - <widget class="QPushButton" name="Batal"> + <widget class="QPushButton" name="button_batal"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> diff --git a/src/app/ui/tambah_acara_ui.py b/src/app/ui/tambah_acara_ui.py new file mode 100644 index 0000000000000000000000000000000000000000..a1c465fb68f21379278e58171cbe2526d6db3660 --- /dev/null +++ b/src/app/ui/tambah_acara_ui.py @@ -0,0 +1,238 @@ +from PyQt5 import uic, QtWidgets, QtGui, QtCore +import sys, os +from app.modules.tambah_acara import tambah_acara +from app.db import init_db +from file_input_dialog import FileInput + + +class TambahAcaraWindow(QtWidgets.QMainWindow): + def __init__(self, conn, id_penyelenggara, id_acara=None): + ''' + Asumsi `data` valid, memiliki key: + - id_penyelenggara: int + - nama_acara: str + - kuota_pendaftar: int + - waktu: datetime (year, month, date, hour, minute) + - harga: int + - kategori: list[str], nilai yang boleh: Teknologi, Motivasi, + Ekonomi, Kompetisi + - foto: list[bytes] isi file foto + - link: str + - syarat: str + - video_introduksi: str + - id_acara: str + ''' + super(TambahAcaraWindow, self).__init__() + uic.loadUi(os.path.join(os.path.dirname(__file__), 'tambah_acara.ui'), self) + + default_img_content = b'' + with open(os.path.join(os.path.dirname(__file__), 'assets/no-image-available.jpeg'), 'rb') as f: + default_img_content = f.read() + + self.__conn = conn + self.__id_penyelenggara = id_penyelenggara # ga boleh None + self.__id_acara = id_acara + data_acara = dict( + id_penyelenggara=self.__id_penyelenggara, + nama_acara=None, + kuota_pendaftar=None, + waktu=None, + harga=None, + kategori=list(), + foto=list(), + link=None, + deskripsi=None, + syarat=None, + id_acara=None, + ) + if id_acara is not None: + cur = conn.cursor() + self.__get_data_from_db(data_acara=data_acara, cur=cur) + + self.__current_image_counter = 0 + self.__photos =\ + list() if data_acara['foto'] is None else data_acara['foto'] + # self.__penyelenggara = data_acara['id_penyelenggara'] # ga boleh None + self.__penyelenggara = 1 + self.__id_acara = data_acara['id_acara'] + + # setting default image + self.__default_img = QtGui.QImage() + assert self.__default_img.loadFromData(default_img_content) + + self.__fill_data(data_acara) + self.__init_button() + + self.show() + + def __get_data_from_db(self, data_acara, cur): + cur.execute('SELECT * FROM acara WHERE id_acara = ?', (self.__id_acara,)) + + for (_, nama_acara, + _, syarat_pendaftaran, + kuota_pendaftar, deskripsi, + waktu, harga, + link, _) in cur: + data_acara['nama_acara'] = nama_acara + data_acara['kuota_pendaftar'] = kuota_pendaftar + data_acara['waktu'] = waktu + data_acara['harga'] = harga + data_acara['deskripsi'] = deskripsi + data_acara['syarat'] = syarat_pendaftaran + data_acara['link'] = link + + cur.execute('SELECT foto FROM foto_acara WHERE id_acara = ?', + (self.__id_acara,)) + for foto in cur: + data_acara['foto'].append(foto[0]) + + cur.execute( + 'SELECT nama_kategori FROM kategori_acara WHERE id_acara = ?', + (self.__id_acara,)) + for kategori in cur: + data_acara['kategori'].append(kategori[0]) + + def __set_image(self): + if len(self.__photos) == 0: + self.image.setPixmap(QtGui.QPixmap.fromImage(self.__default_img)) + else: + self.image.setPixmap( + QtGui.QPixmap.fromImage( + self.__photos[self.__current_image_counter])) + + def __next_image(self): + try: + self.__current_image_counter += 1 + self.__current_image_counter %= len(self.__photos) + self.__set_image() + except Exception: + pass + + def __prev_image(self): + try: + self.__current_image_counter -= 1 + self.__current_image_counter %= len(self.__photos) + self.__set_image() + except Exception: + pass + + def __fill_data(self, data_acara): + ''' + Fungsi untuk mengisi form data, foto, serta kategori acara + ''' + # Ngeset foto + self.__set_image() + + # Ngeset isi form + if data_acara['nama_acara'] is not None: + self.input_nama_acara.setText(data_acara['nama_acara']) + + if data_acara['kuota_pendaftar'] is not None: + self.input_kuota.setValue(data_acara['kuota_pendaftar']) + + self.input_waktu.setMinimumDateTime(QtCore.QDateTime.currentDateTime()) + if data_acara['waktu'] is not None: + # ex: + # self.input_waktu.setDateTime( + # datetime.strptime('2100-05-12 23:59', '%Y-%m-%d %H:%M')) + # asumsi udah pasti date time + self.input_waktu.setDateTime(data_acara['waktu']) + else: + self.input_waktu.setDateTime(QtCore.QDateTime.currentDateTime()) + + if data_acara['harga'] is not None: + self.input_harga.setValue(data_acara['harga']) + + if data_acara['link'] is not None: + self.input_link.setText(data_acara['link']) + + if data_acara['deskripsi'] is not None: + self.input_deskripsi.insertPlainText(data_acara['deskripsi']) + + if data_acara['syarat'] is not None: + self.input_syarat.insertPlainText(data_acara['syarat']) + + # Ngeset kategori + if data_acara['kategori'] is not None: + # Teknologi, Motivasi, Kompetisi, Ekonomi + for kategori in data_acara['kategori']: + if kategori == 'Teknologi': + self.teknologi.setChecked(True) + elif kategori == 'Motivasi': + self.motivasi.setChecked(True) + elif kategori == 'Kompetisi': + self.kompetisi.setChecked(True) + elif kategori == 'Ekonomi': + self.ekonommi.setChecked(True) + + def __init_button(self): + ''' + Fungsi untuk menyiapkan tombol-tombol + ''' + self.button_image_next.clicked.connect(self.__next_image) + self.button_image_prev.clicked.connect(self.__prev_image) + self.button_batal.clicked.connect(self.close) + self.button_simpan.clicked.connect(self.__save_data) + self.button_add_image.clicked.connect(self.__input_image) + + def __get_checked_kategori(self): + kategs = ['motivasi', 'teknologi', 'ekonomi', 'kompetisi'] + return [x for x in kategs if getattr(self, x).isChecked()] + + def __get_form_data(self): + return dict( + id_penyelenggara=self.__id_penyelenggara, + id_acara=self.__id_acara, + foto=self.__photos, + kategori=self.__get_checked_kategori(), + nama_acara=self.input_nama_acara.text(), + kuota_pendaftar=self.input_kuota.value(), + waktu=self.input_waktu.dateTime().toPyDateTime().replace( + microsecond=0), + harga=self.input_harga.value(), + link=self.input_link.text(), + deskripsi=self.input_deskripsi.toPlainText(), + syarat=self.input_syarat.toPlainText(), + ) + + def __save_data(self): + if self.__is_form_valid(): + if tambah_acara(**self.__get_form_data(), conn=self.__conn): + self.close() # sekarang exit aja dlu + else: + self.__alert(text="Gagal menambahkan data.", + info="Silakan hubungi pembuat aplikasi.", + title="Terjadi kegagalan") + else: + self.__alert(text="Ada data yang belum diisi.", + info="Perhatikan, data dengan * merah adalah wajib\ + dan minimal sebuah kategori terpilih.", + title="Data acara kurang") + + def __input_image(self): + dg = FileInput() + files = dg.spawn(multiple=True) + for file in files: + content = b'' + with open(file, 'rb') as f: + content = f.read() + img = QtGui.QImage() + assert img.loadFromData(content) + self.__photos.append(img) + self.__set_image() + + def __is_form_valid(self): + return self.input_nama_acara is not None\ + and self.input_nama_acara.text() != ""\ + and self.input_waktu is not None\ + and self.input_harga is not None\ + and len(self.__get_checked_kategori()) != 0 + + def __alert(self, text, info, title): + msg = QtWidgets.QMessageBox() + msg.setIcon(QtWidgets.QMessageBox.Warning) + msg.setText(text) + msg.setInformativeText(info) + msg.setWindowTitle(title) + msg.setStandardButtons(QtWidgets.QMessageBox.Ok) + msg.exec_() diff --git a/src/test/linimasa_test.py b/src/test/linimasa_test.py index 6ee831c290fa41d6381d8b09022fea61f58b2d71..40c2fd4ba138f11e72204d9155b3f4646b188dbc 100644 --- a/src/test/linimasa_test.py +++ b/src/test/linimasa_test.py @@ -3,7 +3,7 @@ from mariadb._mariadb import connection from datetime import datetime from app.modules.linimasa import * -def test_linimasaPengguna_satuHasil(): +def test_linimasa_pengguna_satuHasil(): conn = MagicMock(spec=connection) now = datetime.now() @@ -15,7 +15,7 @@ def test_linimasaPengguna_satuHasil(): conn.cursor = MagicMock(return_value=cur) - res = linimasaPengguna(conn) + res = linimasa_pengguna(conn) assert len(res) == 1 res = res[0] assert res[0] == 1 @@ -27,7 +27,7 @@ def test_linimasaPengguna_satuHasil(): assert res[5][0] == 'teknologi' pass -def test_linimasaPengguna_banyakHasil(): +def test_linimasa_pengguna_banyakHasil(): conn = MagicMock(spec=connection) now = datetime.now() @@ -47,7 +47,7 @@ def test_linimasaPengguna_banyakHasil(): conn.cursor = MagicMock(return_value=cur) - res = linimasaPengguna(conn) + res = linimasa_pengguna(conn) assert len(res) == 2 assert len(res[0][5]) == 1 assert len(res[1][5]) == 1 @@ -55,7 +55,7 @@ def test_linimasaPengguna_banyakHasil(): assert res[1][0] == 2 pass -def test_linimasaPenyelenggara_satuHasil(): +def test_linimasa_penyelenggara_satuHasil(): conn = MagicMock(spec=connection) now = datetime.now() @@ -67,7 +67,7 @@ def test_linimasaPenyelenggara_satuHasil(): conn.cursor = MagicMock(return_value=cur) - res = linimasaPenyelenggara(conn) + res = linimasa_penyelenggara(conn) assert len(res) == 1 res = res[0] assert res[0] == 1 @@ -80,7 +80,7 @@ def test_linimasaPenyelenggara_satuHasil(): pass -def test_linimasaPenyelenggara_banyakHasil(): +def test_linimasa_penyelenggara_banyakHasil(): conn = MagicMock(spec=connection) now = datetime.now() @@ -100,7 +100,7 @@ def test_linimasaPenyelenggara_banyakHasil(): conn.cursor = MagicMock(return_value=cur) - res = linimasaPenyelenggara(conn) + res = linimasa_penyelenggara(conn) assert len(res) == 2 assert len(res[0][5]) == 1 assert len(res[1][5]) == 1 diff --git a/src/test/tambahAcara_test.py b/src/test/tambahAcara_test.py deleted file mode 100644 index 43c9d81bbf6e935c865213926dbb308a0cf8310f..0000000000000000000000000000000000000000 --- a/src/test/tambahAcara_test.py +++ /dev/null @@ -1,117 +0,0 @@ -''' -Modul untuk menguji tambah_acara -''' -from app.modules.tambahAcara import tambah_acara -from datetime import datetime -from app.db import init_db as init_connection - - -def test_add_acara(): - now = datetime.now() - conn = init_connection() - cur = conn.cursor() - - nama_acara = 'a' - kuota = 100 - - assert tambah_acara( - id_penyelenggara=1, - nama_acara=nama_acara, - kuota_pendaftar=100, - harga=0, - link='a', - waktu=now, - conn=conn - ) - - cur.execute( - 'SELECT nama_acara, kuota_pendaftar FROM acara WHERE nama_acara = ?', (nama_acara,)) - - res = [] - for nama, kuota in cur: - res.append((nama, kuota)) - - assert len(res) == 1 - assert res[0][0] == nama_acara - assert res[0][1] == kuota - - cur.execute('DELETE FROM acara WHERE nama_acara = ?', (nama_acara,)) - conn.commit() - - -def test_add_acara_fail(): - conn = init_connection() - assert tambah_acara( - id_penyelenggara=1, - nama_acara='a', - kuota_pendaftar='X', - waktu=datetime.now(), - harga='Y', - conn=conn - ) == False - - -def test_add_acara_fail_date_bad_string(): - conn = init_connection() - assert tambah_acara( - id_penyelenggara=1, - nama_acara='a', - kuota_pendaftar=100, - waktu='BAD STRING', - harga=0, - conn=conn - ) == False - - -def test_update_acara(): - now = datetime.now() - conn = init_connection() - cur = conn.cursor() - - nama_acara = 'a' - kuota = 100 - - # insert dlu - assert tambah_acara( - id_penyelenggara=1, - nama_acara=nama_acara, - kuota_pendaftar=100, - harga=0, - link='a', - waktu=now, - conn=conn - ) - - cur.execute('SELECT id_acara FROM acara WHERE nama_acara = ?', (nama_acara,)) - - id = 0 - for id_res in cur: - id = id_res[0] - - print(id) - - assert tambah_acara( - id_penyelenggara=1, - id_acara=id, - nama_acara=str(nama_acara + 'hadeh'), - kuota_pendaftar=100, - harga=0, - link='a', - waktu=now, - conn=conn - ) - - cur.execute('SELECT nama_acara, kuota_pendaftar FROM acara WHERE nama_acara = ?', (str( - nama_acara + 'hadeh'),)) - - res = [] - for nama, kuota in cur: - res.append((nama, kuota)) - - assert len(res) == 1 - assert res[0][0] == str(nama_acara + 'hadeh') - assert res[0][1] == kuota - - cur.execute('DELETE FROM acara WHERE nama_acara = ?', - (str(nama_acara + 'hadeh'),)) - conn.commit() diff --git a/src/test/tambah_acara_test.py b/src/test/tambah_acara_test.py new file mode 100644 index 0000000000000000000000000000000000000000..582d01b0523130c27d8af5a74a776f31bff26e13 --- /dev/null +++ b/src/test/tambah_acara_test.py @@ -0,0 +1,266 @@ +''' +Modul untuk menguji tambah_acara +''' +from app.modules.tambah_acara import tambah_acara, remove_category, remove_foto +from app.db import init_db as init_connection +from datetime import datetime + + +def test_add_acara(): + now = datetime.now().replace(microsecond=0) + conn = init_connection() + cur = conn.cursor() + + nama_acara = 'a' + kuota = 100 + + assert tambah_acara( + id_penyelenggara=1, + nama_acara=nama_acara, + kuota_pendaftar=100, + harga=0, + link='a', + kategori=['Teknologi'], + foto=[b'111'], + waktu=now, + conn=conn + ) + + cur.execute( + '''SELECT nama_acara, kuota_pendaftar, nama_kategori, foto + FROM acara JOIN + kategori_acara USING(id_acara) JOIN + foto_acara USING(id_acara) + WHERE nama_acara = ?''', (nama_acara,)) + + res = [] + for nama, kuota, kateg, foto in cur: + res.append((nama, kuota, kateg, foto)) + + assert len(res) == 1 + assert res[0][0] == nama_acara + assert res[0][1] == kuota + assert res[0][2] == 'Teknologi' + assert res[0][3] == b'111' + + cur.execute('DELETE FROM acara WHERE nama_acara = ?', (nama_acara,)) + conn.commit() + + +def test_add_acara_fail_bad_integer(): + conn = init_connection() + assert not tambah_acara( + id_penyelenggara=1, + nama_acara='a', + kuota_pendaftar='X', + waktu=datetime.now(), + harga='Y', + kategori=['Teknologi'], + conn=conn + ) + + +def test_add_acara_fail_date_bad_string(): + conn = init_connection() + assert not tambah_acara( + id_penyelenggara=1, + nama_acara='a', + kuota_pendaftar=100, + waktu='BAD STRING', + harga=0, + kategori=['Teknologi'], + conn=conn + ) + + +def test_add_acara_fail_wrong_kategori(): + conn = init_connection() + assert not tambah_acara( + id_penyelenggara=1, + nama_acara='a', + kuota_pendaftar=100, + waktu='BAD STRING', + harga=0, + kategori=['Mukbang'], + conn=conn + ) + + +def test_add_acara_fail_empty_kategori(): + conn = init_connection() + assert not tambah_acara( + id_penyelenggara=1, + nama_acara='a', + kuota_pendaftar=100, + waktu=datetime.now(), + harga=0, + kategori=[], + conn=conn + ) + + +def test_update_acara(): + now = datetime.now().replace(microsecond=0) + conn = init_connection() + cur = conn.cursor() + + nama_acara = 'a' + kuota = 100 + + # insert dlu + assert tambah_acara( + id_penyelenggara=1, + nama_acara=nama_acara, + kuota_pendaftar=100, + harga=0, + link='a', + waktu=now, + kategori=['Teknologi'], + foto=[b'111'], + conn=conn + ) + + cur.execute( + 'SELECT id_acara FROM acara WHERE nama_acara = ?', + (nama_acara,)) + + id = 0 + for id_res in cur: + id = id_res[0] + + assert tambah_acara( + id_penyelenggara=1, + id_acara=id, + nama_acara=str(nama_acara + 'hadeh'), + kuota_pendaftar=100, + harga=0, + link='a', + waktu=now, + kategori=['Teknologi', 'Motivasi'], + foto=[b'111', b'222'], + conn=conn + ) + + cur.execute( + 'SELECT nama_acara, kuota_pendaftar FROM acara WHERE id_acara = ?', + (id,)) + + res = [] + for nama, kuota in cur: + res.append((nama, kuota)) + + assert len(res) == 1 + assert res[0][0] == str(nama_acara + 'hadeh') + assert res[0][1] == kuota + + res = [] + cur.execute( + 'SELECT nama_kategori FROM kategori_acara WHERE id_acara = ?', (id,)) + for nama_kategori in cur: + res.append(nama_kategori[0]) + + assert len(res) == 2 + assert res[0] == 'Motivasi' + assert res[1] == 'Teknologi' + + res = [] + cur.execute( + 'SELECT foto FROM foto_acara WHERE id_acara = ?', (id,)) + for foto in cur: + res.append(foto[0]) + + assert len(res) == 2 + assert res[0] == b'111' + assert res[1] == b'222' + + cur.execute( + 'DELETE FROM acara WHERE nama_acara = ?', + (str(nama_acara + 'hadeh'),)) + conn.commit() + + +def test_remove_foto(): + nama_acara = 'a' + now = datetime.now().replace(microsecond=0) + conn = init_connection() + + assert tambah_acara( + id_penyelenggara=1, + nama_acara=nama_acara, + kuota_pendaftar=100, + harga=0, + link='a', + waktu=now, + kategori=['Teknologi', 'Motivasi'], + foto=[b'111', b'222'], + conn=conn + ) + + cur = conn.cursor() + cur.execute( + 'SELECT id_acara FROM acara WHERE nama_acara = ?', (nama_acara,)) + + id = 0 + for id_res in cur: + id = id_res[0] + + cur.execute( + 'SELECT id_foto FROM foto_acara WHERE id_acara = ? AND foto = ?', + (id, b'111')) + id_foto = 0 + for id_res in cur: + id_foto = id_res[0] + + assert remove_foto(id_foto=id_foto, id_acara=id, conn=conn) + + cur.execute( + 'SELECT id_foto FROM foto_acara WHERE id_acara = ? AND foto = ?', + (id, b'111')) + i = 0 + for _ in cur: + i += 1 + assert i == 0 + + cur.execute('DELETE FROM acara WHERE nama_acara = ?', (nama_acara,)) + conn.commit() + + +def test_remove_categ(): + nama_acara = 'a' + now = datetime.now().replace(microsecond=0) + conn = init_connection() + + assert tambah_acara( + id_penyelenggara=1, + nama_acara=nama_acara, + kuota_pendaftar=100, + harga=0, + link='a', + waktu=now, + kategori=['Teknologi', 'Motivasi'], + foto=[b'111', b'222'], + conn=conn + ) + + cur = conn.cursor() + cur.execute( + 'SELECT id_acara FROM acara WHERE nama_acara = ?', + (nama_acara,)) + + id = 0 + for id_res in cur: + id = id_res[0] + + assert remove_category(id_acara=id, kateg='Teknologi', conn=conn) + cur.execute( + '''SELECT id_acara + FROM kategori_acara + WHERE id_acara = ? AND nama_kategori = ?''', + (id, 'Teknologi')) + i = 0 + for _ in cur: + i += 1 + assert i == 0 + + cur.execute('DELETE FROM acara WHERE nama_acara = ?', (nama_acara,)) + conn.commit()