Skip to content
Permalink
Browse files

Added new, much faster way to open songs via osu!'s internal database…

…. You can still choose to open using your songs folder. Detailed changes below:

gui:
  - Settings: Added fields for new values in Startup dialog
  - Startup: Revamped startup dialog to fit new startup workflow

gui_controller:
  - Addsongs: Changed import for Songs
  - Loading: Added option to load using new osu!.db parser instead of Songs directory.
  - LoadingApi: Changed imports for Difficulty2 and Song
  - Main: Changed imports for models. Made changes for new startup dialog
  - Settings: Added fields for new values in Startup dialog
  - Startup: Load using osu!.db by default, but give option to load using Song directory. Auto-hide unneeded gui parts.

tests:
  - CollectionBeatmapMatcherTest: Changed imports for models
  - OsuParserTest: Changed imports for models
  - OsudbParserTest: A test to check if the OsuDB parser is working correctly

ui_designs: Updated settings and startup UI.

util:
  - CollectionsParser: Moved all models to oce_models.py, and osu binary types and conversion functions to osudb_format.py
  - OceModels: Collected all models used by OCE in one place.
  - OsuParser: Moved all models to oce_models.py
  - OsudbFormat: Collected all functions and fields related to the osu.db format in one place
  - OsudbParser: This is the new parser for the osu!.db file.

settings.py: Added default values for the new settings
  • Loading branch information...
Kurocon committed Apr 25, 2016
1 parent c2d7b4a commit 85eb5d08a4df304f3b5fe98ce0bd7589d22bb315
@@ -11,7 +11,7 @@
class Ui_SettingsDialog(object):
def setupUi(self, SettingsDialog):
SettingsDialog.setObjectName("SettingsDialog")
SettingsDialog.resize(624, 423)
SettingsDialog.resize(624, 488)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("icons/oce.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
SettingsDialog.setWindowIcon(icon)
@@ -56,12 +56,20 @@ def setupUi(self, SettingsDialog):
self.default_folders_box.setObjectName("default_folders_box")
self.formLayout_2 = QtWidgets.QFormLayout(self.default_folders_box)
self.formLayout_2.setObjectName("formLayout_2")
self.loadfrom_label = QtWidgets.QLabel(self.default_folders_box)
self.loadfrom_label.setObjectName("loadfrom_label")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.loadfrom_label)
self.loadfrom_dropdown = QtWidgets.QComboBox(self.default_folders_box)
self.loadfrom_dropdown.setObjectName("loadfrom_dropdown")
self.loadfrom_dropdown.addItem("")
self.loadfrom_dropdown.addItem("")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.loadfrom_dropdown)
self.default_osudb_label = QtWidgets.QLabel(self.default_folders_box)
self.default_osudb_label.setObjectName("default_osudb_label")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.default_osudb_label)
self.default_songs_label = QtWidgets.QLabel(self.default_folders_box)
self.default_songs_label.setObjectName("default_songs_label")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.default_songs_label)
self.default_collection_label = QtWidgets.QLabel(self.default_folders_box)
self.default_collection_label.setObjectName("default_collection_label")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.default_collection_label)
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.default_songs_label)
self.default_songs_layout = QtWidgets.QHBoxLayout()
self.default_songs_layout.setObjectName("default_songs_layout")
self.default_songs_line = QtWidgets.QLineEdit(self.default_folders_box)
@@ -70,7 +78,10 @@ def setupUi(self, SettingsDialog):
self.default_songs_button = QtWidgets.QPushButton(self.default_folders_box)
self.default_songs_button.setObjectName("default_songs_button")
self.default_songs_layout.addWidget(self.default_songs_button)
self.formLayout_2.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.default_songs_layout)
self.formLayout_2.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.default_songs_layout)
self.default_collection_label = QtWidgets.QLabel(self.default_folders_box)
self.default_collection_label.setObjectName("default_collection_label")
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.default_collection_label)
self.default_collection_layout = QtWidgets.QHBoxLayout()
self.default_collection_layout.setObjectName("default_collection_layout")
self.default_collection_line = QtWidgets.QLineEdit(self.default_folders_box)
@@ -79,7 +90,16 @@ def setupUi(self, SettingsDialog):
self.default_collection_button = QtWidgets.QPushButton(self.default_folders_box)
self.default_collection_button.setObjectName("default_collection_button")
self.default_collection_layout.addWidget(self.default_collection_button)
self.formLayout_2.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.default_collection_layout)
self.formLayout_2.setLayout(3, QtWidgets.QFormLayout.FieldRole, self.default_collection_layout)
self.default_osudb_layout = QtWidgets.QHBoxLayout()
self.default_osudb_layout.setObjectName("default_osudb_layout")
self.default_osudb_line = QtWidgets.QLineEdit(self.default_folders_box)
self.default_osudb_line.setObjectName("default_osudb_line")
self.default_osudb_layout.addWidget(self.default_osudb_line)
self.default_osudb_button = QtWidgets.QPushButton(self.default_folders_box)
self.default_osudb_button.setObjectName("default_osudb_button")
self.default_osudb_layout.addWidget(self.default_osudb_button)
self.formLayout_2.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.default_osudb_layout)
self.settings_layout.addWidget(self.default_folders_box)
self.dialog_settings_box = QtWidgets.QGroupBox(SettingsDialog)
self.dialog_settings_box.setObjectName("dialog_settings_box")
@@ -129,10 +149,15 @@ def retranslateUi(self, SettingsDialog):
self.download_api_combobox.setItemText(2, _translate("SettingsDialog", "Never"))
self.default_folders_box.setToolTip(_translate("SettingsDialog", "These values will be the default values if you open a new collection."))
self.default_folders_box.setTitle(_translate("SettingsDialog", "Default Folders"))
self.loadfrom_label.setText(_translate("SettingsDialog", "Load from"))
self.loadfrom_dropdown.setItemText(0, _translate("SettingsDialog", "osu!.db file"))
self.loadfrom_dropdown.setItemText(1, _translate("SettingsDialog", "Songs folder"))
self.default_osudb_label.setText(_translate("SettingsDialog", "Default osu!.db"))
self.default_songs_label.setText(_translate("SettingsDialog", "Default Songs folder"))
self.default_collection_label.setText(_translate("SettingsDialog", "Default collection.db"))
self.default_songs_button.setText(_translate("SettingsDialog", "Browse"))
self.default_collection_label.setText(_translate("SettingsDialog", "Default collection.db"))
self.default_collection_button.setText(_translate("SettingsDialog", "Browse"))
self.default_osudb_button.setText(_translate("SettingsDialog", "Browse"))
self.dialog_settings_box.setToolTip(_translate("SettingsDialog", "These settings can disable confirmation dialogs across the application."))
self.dialog_settings_box.setTitle(_translate("SettingsDialog", "Dialog Settings"))
self.shutdown_dialog_checkbox.setText(_translate("SettingsDialog", "Show shutdown dialog when I exit the program."))
@@ -11,44 +11,71 @@
class Ui_LoadDialog(object):
def setupUi(self, LoadDialog):
LoadDialog.setObjectName("LoadDialog")
LoadDialog.resize(599, 160)
LoadDialog.resize(646, 244)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("icons/oce.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
LoadDialog.setWindowIcon(icon)
self.verticalLayout = QtWidgets.QVBoxLayout(LoadDialog)
self.verticalLayout.setObjectName("verticalLayout")
self.grid_layout = QtWidgets.QGridLayout()
self.grid_layout.setObjectName("grid_layout")
self.songdir_label = QtWidgets.QLabel(LoadDialog)
self.songdir_label.setObjectName("songdir_label")
self.grid_layout.addWidget(self.songdir_label, 1, 0, 1, 1)
self.collection_label = QtWidgets.QLabel(LoadDialog)
self.collection_label.setObjectName("collection_label")
self.grid_layout.addWidget(self.collection_label, 2, 0, 1, 1)
self.songdir_edit = QtWidgets.QLineEdit(LoadDialog)
self.songdir_edit.setObjectName("songdir_edit")
self.grid_layout.addWidget(self.songdir_edit, 1, 1, 1, 1)
self.collectionfile_edit = QtWidgets.QLineEdit(LoadDialog)
self.collectionfile_edit.setObjectName("collectionfile_edit")
self.grid_layout.addWidget(self.collectionfile_edit, 2, 1, 1, 1)
self.songdir_button = QtWidgets.QPushButton(LoadDialog)
self.songdir_button.setStatusTip("")
self.songdir_button.setObjectName("songdir_button")
self.grid_layout.addWidget(self.songdir_button, 1, 2, 1, 1)
self.collectionfile_button = QtWidgets.QPushButton(LoadDialog)
self.collectionfile_button.setStatusTip("")
self.collectionfile_button.setObjectName("collectionfile_button")
self.grid_layout.addWidget(self.collectionfile_button, 2, 2, 1, 1)
self.container = QtWidgets.QVBoxLayout()
self.container.setObjectName("container")
self.help_label = QtWidgets.QLabel(LoadDialog)
self.help_label.setTextFormat(QtCore.Qt.PlainText)
self.help_label.setScaledContents(False)
self.help_label.setAlignment(QtCore.Qt.AlignCenter)
self.help_label.setWordWrap(True)
self.help_label.setObjectName("help_label")
self.grid_layout.addWidget(self.help_label, 0, 0, 1, 3)
self.verticalLayout.addLayout(self.grid_layout)
self.container.addWidget(self.help_label)
self.form_layout = QtWidgets.QFormLayout()
self.form_layout.setHorizontalSpacing(6)
self.form_layout.setVerticalSpacing(0)
self.form_layout.setObjectName("form_layout")
self.loadfrom_label = QtWidgets.QLabel(LoadDialog)
self.loadfrom_label.setObjectName("loadfrom_label")
self.form_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.loadfrom_label)
self.loadfrom_dropdown = QtWidgets.QComboBox(LoadDialog)
self.loadfrom_dropdown.setObjectName("loadfrom_dropdown")
self.loadfrom_dropdown.addItem("")
self.loadfrom_dropdown.addItem("")
self.form_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.loadfrom_dropdown)
self.osudb_label = QtWidgets.QLabel(LoadDialog)
self.osudb_label.setObjectName("osudb_label")
self.form_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.osudb_label)
self.osudb_fields = QtWidgets.QHBoxLayout()
self.osudb_fields.setSpacing(0)
self.osudb_fields.setObjectName("osudb_fields")
self.osudb_edit = QtWidgets.QLineEdit(LoadDialog)
self.osudb_edit.setObjectName("osudb_edit")
self.osudb_fields.addWidget(self.osudb_edit)
self.osudb_button = QtWidgets.QPushButton(LoadDialog)
self.osudb_button.setObjectName("osudb_button")
self.osudb_fields.addWidget(self.osudb_button)
self.form_layout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.osudb_fields)
self.songsfolder_label = QtWidgets.QLabel(LoadDialog)
self.songsfolder_label.setObjectName("songsfolder_label")
self.form_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.songsfolder_label)
self.songfolder_fields = QtWidgets.QHBoxLayout()
self.songfolder_fields.setSpacing(0)
self.songfolder_fields.setObjectName("songfolder_fields")
self.songfolder_edit = QtWidgets.QLineEdit(LoadDialog)
self.songfolder_edit.setObjectName("songfolder_edit")
self.songfolder_fields.addWidget(self.songfolder_edit)
self.songfolder_button = QtWidgets.QPushButton(LoadDialog)
self.songfolder_button.setObjectName("songfolder_button")
self.songfolder_fields.addWidget(self.songfolder_button)
self.form_layout.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.songfolder_fields)
self.collectiondb_label = QtWidgets.QLabel(LoadDialog)
self.collectiondb_label.setObjectName("collectiondb_label")
self.form_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.collectiondb_label)
self.collectiondb_fields = QtWidgets.QHBoxLayout()
self.collectiondb_fields.setSpacing(0)
self.collectiondb_fields.setObjectName("collectiondb_fields")
self.collectiondb_edit = QtWidgets.QLineEdit(LoadDialog)
self.collectiondb_edit.setObjectName("collectiondb_edit")
self.collectiondb_fields.addWidget(self.collectiondb_edit)
self.collectiondb_button = QtWidgets.QPushButton(LoadDialog)
self.collectiondb_button.setObjectName("collectiondb_button")
self.collectiondb_fields.addWidget(self.collectiondb_button)
self.form_layout.setLayout(3, QtWidgets.QFormLayout.FieldRole, self.collectiondb_fields)
self.container.addLayout(self.form_layout)
self.verticalLayout.addLayout(self.container)
self.button_box = QtWidgets.QDialogButtonBox(LoadDialog)
self.button_box.setStatusTip("")
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.button_box.setObjectName("button_box")
@@ -62,9 +89,18 @@ def setupUi(self, LoadDialog):
def retranslateUi(self, LoadDialog):
_translate = QtCore.QCoreApplication.translate
LoadDialog.setWindowTitle(_translate("LoadDialog", "Open collection"))
self.songdir_label.setText(_translate("LoadDialog", "Songs directory"))
self.collection_label.setText(_translate("LoadDialog", "collection.db"))
self.songdir_button.setText(_translate("LoadDialog", "Browse"))
self.collectionfile_button.setText(_translate("LoadDialog", "Browse"))
self.help_label.setText(_translate("LoadDialog", "Please locate your osu! Songs directory and the collection.db file you wish to edit."))
self.help_label.setText(_translate("LoadDialog", "Osu Collections Editor can load your songs from two different places. You can load from the\n"
"osu!.db file which osu! itself also uses, or you can load directly from your Songs folder.\n"
"\n"
"Loading from the osu! database will be much faster, but loading directly from your Songs folder \n"
"can be handy if you do not have an osu!.db at the ready."))
self.loadfrom_label.setText(_translate("LoadDialog", "Load from"))
self.loadfrom_dropdown.setItemText(0, _translate("LoadDialog", "osu!.db file"))
self.loadfrom_dropdown.setItemText(1, _translate("LoadDialog", "Songs folder"))
self.osudb_label.setText(_translate("LoadDialog", "osu!.db"))
self.osudb_button.setText(_translate("LoadDialog", "Browse"))
self.songsfolder_label.setText(_translate("LoadDialog", "Songs folder"))
self.songfolder_button.setText(_translate("LoadDialog", "Browse"))
self.collectiondb_label.setText(_translate("LoadDialog", "collection.db"))
self.collectiondb_button.setText(_translate("LoadDialog", "Browse"))

@@ -6,12 +6,14 @@
import settings
from gui_controller.beatmapitem import BeatmapItem

from util.oce_models import Songs


class AddSongs(QtWidgets.QDialog):
def __init__(self, collectionname, songs, loading_dialog):
"""
:type collectionname: str
:type songs: util.osu_parser.Songs
:type songs: Songs
:type loading_dialog: Loading dialog for this dialog.
"""
super(AddSongs, self).__init__()
@@ -2,8 +2,10 @@
from PyQt5 import QtWidgets, QtCore, QtGui
import gui.loading
import settings
import os
import util.collections_parser as cp
import util.osu_parser as op
import util.osudb_parser as odp


class Loading(QtWidgets.QDialog):
@@ -12,7 +14,7 @@ class Loading(QtWidgets.QDialog):
text = QtCore.pyqtSignal(str)
done = QtCore.pyqtSignal()

def __init__(self, collectionfile, songdir):
def __init__(self, collectionfile, songdb):
super(Loading, self).__init__()
self.log = logging.getLogger(__name__)

@@ -26,7 +28,8 @@ def __init__(self, collectionfile, songdir):
self.collections = None
self.songs = None
self.collection_file = collectionfile
self.song_directory = songdir
self.song_db = songdb
self.db_is_directory = os.path.isdir(self.song_db)

self.progress.connect(self.update_precentage)
self.current.connect(self.update_current)
@@ -56,7 +59,7 @@ def update_current(self, text):
self.ui.loading_current_label.setText(text)

def exec_(self):
w = LoadTask(self.collection_file, self.song_directory, self)
w = LoadTask(self.collection_file, self.song_db, self.db_is_directory, self)
w.moveToThread(self.thread)
self.thread.started.connect(w.work)
self.thread.start()
@@ -67,10 +70,11 @@ def dismiss(self):


class LoadTask(QtCore.QObject):
def __init__(self, cf, sd, dialog):
def __init__(self, cf, sd, sd_isdir, dialog):
super(LoadTask, self).__init__()
self.collection_file = cf
self.song_directory = sd
self.song_db = sd
self.db_is_directory = sd_isdir
self.dialog = dialog
self.settings = settings.Settings.get_instance()
self.log = logging.getLogger(__name__)
@@ -84,7 +88,10 @@ def work(self):
# Load songs from dir
self.log.debug("Loading songs...")
self.dialog.text.emit("Loading songs...")
self.dialog.songs = op.load_songs_from_dir_gui(self.song_directory, self.dialog)
if self.db_is_directory:
self.dialog.songs = op.load_songs_from_dir_gui(self.song_db, self.dialog)
else:
self.dialog.songs = odp.load_osudb_gui(self.song_db, self.dialog)

# Notify we're done.
self.dialog.done.emit()
@@ -2,9 +2,10 @@
from PyQt5 import QtWidgets, QtCore, QtGui
import gui.loading
import settings
import util.osu_parser as op
import util.osu_api as oa

from util.oce_models import Difficulty2, Song


class LoadingApi(QtWidgets.QDialog):
progress = QtCore.pyqtSignal(int)
@@ -99,7 +100,7 @@ def work(self):
if res:
details = res[0]
# Create a difficulty for the map
diff = op.Difficulty2("api")
diff = Difficulty2("api")
diff.name = details['title']
diff.artist = details['artist']
diff.mapper = details['creator']
@@ -127,7 +128,7 @@ def work(self):
break
# If the for loop ended without breaking, create a mapset for this map
else:
umap.mapset = op.Song()
umap.mapset = Song()
umap.mapset.add_difficulty(diff)
umap.mapset.beatmapset_id = int(details['beatmapset_id'])
self.log.debug("Created new mapset for beatpam {} - {} [{}] (beatmapset_id {})".format(diff.artist, diff.name, diff.difficulty, umap.mapset.beatmapset_id))

0 comments on commit 85eb5d0

Please sign in to comment.
You can’t perform that action at this time.