Is it possible to include the following statistics window after Picard has finished?
UPDATE
It would be good if Picard remembered the previous result (saved in some little file) and gave the current one next to him.
Iām going to write a plugin that will output the above image.
I just need variables that are assigned to these icons below (in the right panel of Picard).
That would speed up writing the plugin.
I think I can handle the rest of the code, the āforā and āifā statements myself.
I used Total Commander to search for the words āmodifiedā in the Picard source files.
He found 11 *.py files with this word.
Is this a good lead?
I need help with Python code.
I want to include the code for the āRemove Perfect Albumsā plugin to include the āCalculatorā popup code somewhere in the place marked by my comment.
PLUGIN_NAME = 'Remove Perfect Albums'
PLUGIN_AUTHOR = 'ichneumon, hrglgrmpf'
PLUGIN_DESCRIPTION = '''Remove all perfectly matched albums from the selection.'''
PLUGIN_VERSION = '0.3'
PLUGIN_API_VERSIONS = ['2.0', '2.1', '2.2', '2.3']
PLUGIN_LICENSE = "GPL-2.0"
PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html"
from PyQt5.QtCore import QCoreApplication
from picard.album import Album
from picard.ui.itemviews import BaseAction, register_album_action
class RemovePerfectAlbums(BaseAction):
NAME = 'Remove perfect albums'
def callback(self, objs):
for album in objs:
if (isinstance(album, Album) and album.loaded
and album.is_complete() and album.get_num_unsaved_files() == 0):
self.tagger.remove_album(album)
QCoreApplication.processEvents()
##### SOMEWHERE HERE
register_album_action(RemovePerfectAlbums())
Kalkulator:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QApplication, QWidget
class Kalkulator(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.interfejs()
def interfejs(self):
self.resize(300, 100)
self.setWindowTitle("Prosty kalkulator")
self.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
okno = Kalkulator()
sys.exit(app.exec_())
I will include any help in the PLUGIN_AUTHOR field.
This is a bit tricky, as Picard does not offer an explicit plugin hook to run something on exit.
However, as everything is Python and plugins have full access to all of Picard you can do essentially anything. Itās just that none of the existing plugins explicitly runs on exit.
So first you want to have something that runs on exit. There is the (currently undocumented) ui_init
extension point. You can use it to get access to run something on start and get access to an instance of picard.Tagger
(see picard.tagger.py
). This allows you to register a function to run on exit:
from picard.ui.mainwindow import register_ui_init
from PyQt5.QtCore import QCoreApplication
def ui_init(mainwindow):
# Get the main application instance, an instance of picard.Tagger.
tagger = QCoreApplication.instance()
# Register a function to run on exit
tagger.register_cleanup(on_exit)
def on_exit():
tagger = QCoreApplication.instance()
albums = tagger.albums
# Iterate over the albums, check album state with album.is_complete()
# and album.is_modified()
# Then show a QDialog with the results (your code above was on the right track)
register_ui_init(ui_init)
The albums are of type picard.Album
, see picard/album.py
. Check this class for more details. The code you found in itemviews.py
is the correct code that decides the icons. It uses Album.is_complete()
and album.is_modified()
to decide on the proper icon.
I havenāt tested the above code, but this should get you started.
Just a few notes: Because the plugin registers the exit callback with ui_init
this means the plugin will need to be installed and active when Picard starts. Which means if this gets installed it needs a restart before the exit callback will work.
Also if Picard gets started with the plugin enabled the exit hook will run, no matter whether the user disables or uninstalls the plugin.
A bit difficult, but Iām not going to ask you 10 questions a day.
Maybe once a week.
Only one thing today.
I added your lines and mine to the code:
A=A+1 perfect albums counter
print(A)
class RemovePerfectAlbums(BaseAction):
NAME = 'Stat'
def callback(self, objs):
for album in objs:
if (isinstance(album, Album) and album.loaded
and album.is_complete() and album.get_num_unsaved_files() == 0):
self.tagger.remove_album(album)
A=A+1
QCoreApplication.processEvents()
print(A)
However, when I run the plugin, Picard shuts down.
I just want to check if the counting and quick display works.
Iām new to Python, but I know Pascal and C++.
Thatās likely because some part of the code is raising an exception.
Try running picard (or picard.exe on Windows) from a command prompt. It should show you more information why it crashed. For any development it is always best to run Picard that way.
Yes, on Windows there are a few ways to crash that unfortunately donāt show up anywhere. If you share the full plugin as you currently have it Iāll take a look and try to run it here.
PLUGIN_NAME = 'Stat'
PLUGIN_AUTHOR = 'ichneumon, hrglgrmpf'
PLUGIN_DESCRIPTION = '''Remove all perfectly matched albums from the selection.'''
PLUGIN_VERSION = '0.3'
PLUGIN_API_VERSIONS = ['2.0', '2.1', '2.2', '2.3']
PLUGIN_LICENSE = "GPL-2.0"
PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html"
from PyQt5.QtCore import QCoreApplication
from picard.album import Album
from picard.ui.itemviews import BaseAction, register_album_action
from picard.ui.mainwindow import register_ui_init
def ui_init(mainwindow):
# Get the main application instance, an instance of picard.Tagger.
tagger = QCoreApplication.instance()
# Register a function to run on exit
tagger.register_cleanup(on_exit)
def on_exit():
tagger = QCoreApplication.instance()
albums = tagger.albums
# Iterate over the albums, check album state with album.is_complete()
# and album.is_modified()
# Then show a QDialog with the results (your code above was on the right track)
class RemovePerfectAlbums(BaseAction):
NAME = 'Stat'
def callback(self, objs):
for album in objs:
if (isinstance(album, Album) and album.loaded
and album.is_complete() and album.get_num_unsaved_files() == 0):
self.tagger.remove_album(album)
A=A+1
QCoreApplication.processEvents()
print(A)
register_album_action(RemovePerfectAlbums())
register_ui_init(ui_init)
'''
from picard.ui.mainwindow import register_ui_init
from PyQt5.QtCore import QCoreApplication
def ui_init(mainwindow):
# Get the main application instance, an instance of picard.Tagger.
tagger = QCoreApplication.instance()
# Register a function to run on exit
tagger.register_cleanup(on_exit)
def on_exit():
tagger = QCoreApplication.instance()
albums = tagger.albums
# Iterate over the albums, check album state with album.is_complete()
# and album.is_modified()
# Then show a QDialog with the results (your code above was on the right track)
register_ui_init(ui_init)
'''
The problem is that on in the callback the variable A
was not initialized.
Do something like this:
A = 1
def callback(self, objs):
for album in objs:
...
That there was no output at all when running from command prompt likely was because Picard was already running. If it is then by default picard just passes arguments to the running instance. So either make sure Picard is stopped or run picard.exe --stand-alone-instance
(or short picard.exe -s
) to explicitly launch a new instance.
Additional question and itās not a problem.
Do I need to install a new version of the plugin or just copy the ZIP and reload the plugin list?
Only thing needed is to put the plugin code into a file with a unique name (e.g. stat.py
) into the plugin directory. Then restart Picard. The plugin will show up in the plugin list where you can enable it.
I know all this.
I can turn on plug-ins.
I wanted a faster method (less clicking) to update the plugin.