Add a utility to generate python API docs using epydoc
This commit is contained in:
parent
fb33ba4cce
commit
0ce8f99494
@ -308,6 +308,7 @@ add_subdirectory(tests)
|
|||||||
add_subdirectory(dist)
|
add_subdirectory(dist)
|
||||||
add_subdirectory(tools/ultimate_lyrics_parser)
|
add_subdirectory(tools/ultimate_lyrics_parser)
|
||||||
add_subdirectory(scripts)
|
add_subdirectory(scripts)
|
||||||
|
add_subdirectory(doc/python)
|
||||||
|
|
||||||
option(WITH_DEBIAN OFF)
|
option(WITH_DEBIAN OFF)
|
||||||
if(WITH_DEBIAN)
|
if(WITH_DEBIAN)
|
||||||
|
24
doc/python/CMakeLists.txt
Normal file
24
doc/python/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
include_directories(${LIBGPOD_INCLUDE_DIRS})
|
||||||
|
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src)
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../src)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
generate_python_docs.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(RESOURCES
|
||||||
|
generate_python_docs.qrc
|
||||||
|
)
|
||||||
|
|
||||||
|
qt4_add_resources(QRC ${RESOURCES})
|
||||||
|
|
||||||
|
add_executable(generate_python_docs EXCLUDE_FROM_ALL ${SOURCES} ${QRC})
|
||||||
|
target_link_libraries(generate_python_docs clementine_lib)
|
||||||
|
|
||||||
|
add_custom_target(pythondocs
|
||||||
|
generate_python_docs
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
57
doc/python/generate_python_docs.cpp
Normal file
57
doc/python/generate_python_docs.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* This file is part of Clementine.
|
||||||
|
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
|
|
||||||
|
Clementine is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Clementine is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
#include "playlist/playlistitem.h"
|
||||||
|
#include "scripting/scriptmanager.h"
|
||||||
|
#include "scripting/python/pythonengine.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
// Register some meta types required by the exposed classes
|
||||||
|
qRegisterMetaType<PlaylistItemPtr>("PlaylistItemPtr");
|
||||||
|
|
||||||
|
// Create the python engine
|
||||||
|
ScriptManager manager;
|
||||||
|
LanguageEngine* language_engine =
|
||||||
|
manager.EngineForLanguage(ScriptInfo::Language_Python);
|
||||||
|
PythonEngine* python_engine = qobject_cast<PythonEngine*>(language_engine);
|
||||||
|
|
||||||
|
// Initialise python
|
||||||
|
if (!python_engine->EnsureInitialised()) {
|
||||||
|
qFatal("Failed to initialise Python engine");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the python script
|
||||||
|
QFile script(":/doc/python/generate_python_docs.py");
|
||||||
|
script.open(QIODevice::ReadOnly);
|
||||||
|
QByteArray script_data = script.readAll();
|
||||||
|
|
||||||
|
// Run it
|
||||||
|
PyEval_AcquireLock();
|
||||||
|
if (PyRun_SimpleString(script_data.constData()) != 0) {
|
||||||
|
qFatal("Could not execute generate_python_docs.py");
|
||||||
|
}
|
||||||
|
PyEval_ReleaseLock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
17
doc/python/generate_python_docs.py
Normal file
17
doc/python/generate_python_docs.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import clementine
|
||||||
|
import epydoc.cli
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.argv = [
|
||||||
|
"epydoc",
|
||||||
|
"--html",
|
||||||
|
"-o", "output",
|
||||||
|
"--introspect-only",
|
||||||
|
"-v",
|
||||||
|
"--name", "clementine",
|
||||||
|
"--url", "http://www.clementine-player.org",
|
||||||
|
"clementine",
|
||||||
|
]
|
||||||
|
|
||||||
|
print "Running '%s'" % ' '.join(sys.argv)
|
||||||
|
epydoc.cli.cli()
|
5
doc/python/generate_python_docs.qrc
Normal file
5
doc/python/generate_python_docs.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/doc/python">
|
||||||
|
<file>generate_python_docs.py</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -45,7 +45,12 @@ signals:
|
|||||||
void PlaylistFinished();
|
void PlaylistFinished();
|
||||||
void VolumeChanged(int volume);
|
void VolumeChanged(int volume);
|
||||||
void Error(const QString& message);
|
void Error(const QString& message);
|
||||||
void TrackSkipped(PlaylistItemPtr old_track);
|
|
||||||
|
// Disabled for now because it causes:
|
||||||
|
// TypeError: C++ type 'PlaylistItemPtr' is not supported as a native Qt signal type
|
||||||
|
// void TrackSkipped(PlaylistItemPtr old_track);
|
||||||
|
|
||||||
|
void Seeked(qlonglong microseconds);
|
||||||
|
|
||||||
void ForceShowOSD(Song);
|
void ForceShowOSD(Song);
|
||||||
|
|
||||||
|
@ -93,73 +93,81 @@ const sipAPIDef* PythonEngine::GetSIPApi() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Script* PythonEngine::CreateScript(const ScriptInfo& info) {
|
bool PythonEngine::EnsureInitialised() {
|
||||||
// Initialise Python if it hasn't been done yet
|
if (initialised_)
|
||||||
if (!initialised_) {
|
return true;
|
||||||
AddLogLine("Initialising python...", false);
|
|
||||||
|
AddLogLine("Initialising python...", false);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
// On Windows we statically link against SIP and PyQt, so add those modules
|
// On Windows we statically link against SIP and PyQt, so add those modules
|
||||||
// to Python's inittab here.
|
// to Python's inittab here.
|
||||||
PyImport_AppendInittab(const_cast<char*>("sip"), initsip);
|
PyImport_AppendInittab(const_cast<char*>("sip"), initsip);
|
||||||
PyImport_AppendInittab(const_cast<char*>("PyQt4.Qt"), initQt);
|
PyImport_AppendInittab(const_cast<char*>("PyQt4.Qt"), initQt);
|
||||||
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtCore"), initQtCore);
|
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtCore"), initQtCore);
|
||||||
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtGui"), initQtGui);
|
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtGui"), initQtGui);
|
||||||
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtNetwork"), initQtNetwork);
|
PyImport_AppendInittab(const_cast<char*>("PyQt4.QtNetwork"), initQtNetwork);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add the Clementine builtin module
|
// Add the Clementine builtin module
|
||||||
PyImport_AppendInittab(const_cast<char*>("clementine"), initclementine);
|
PyImport_AppendInittab(const_cast<char*>("clementine"), initclementine);
|
||||||
|
|
||||||
// Initialise python
|
// Initialise python
|
||||||
Py_SetProgramName(const_cast<char*>("clementine"));
|
Py_SetProgramName(const_cast<char*>("clementine"));
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
Py_InitializeEx(0);
|
Py_InitializeEx(0);
|
||||||
|
|
||||||
// Get the clementine module so we can put stuff in it
|
// Get the clementine module so we can put stuff in it
|
||||||
clementine_module_ = PyImport_ImportModule("clementine");
|
clementine_module_ = PyImport_ImportModule("clementine");
|
||||||
if (!clementine_module_) {
|
if (!clementine_module_) {
|
||||||
AddLogLine("Failed to import the clementine module", true);
|
AddLogLine("Failed to import the clementine module", true);
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
}
|
|
||||||
Py_Finalize();
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
sip_api_ = GetSIPApi();
|
Py_Finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sip_api_ = GetSIPApi();
|
||||||
|
|
||||||
// Add objects to the module
|
// Add objects to the module
|
||||||
if (manager()->data().valid_) {
|
if (manager()->data().valid_) {
|
||||||
AddObject(manager()->data().library_->backend(), sipType_LibraryBackend, "library");
|
AddObject(manager()->data().library_->backend(), sipType_LibraryBackend, "library");
|
||||||
AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view");
|
AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view");
|
||||||
AddObject(manager()->data().player_, sipType_PlayerInterface, "player");
|
AddObject(manager()->data().player_, sipType_PlayerInterface, "player");
|
||||||
AddObject(manager()->data().playlists_, sipType_PlaylistManagerInterface, "playlists");
|
AddObject(manager()->data().playlists_, sipType_PlaylistManagerInterface, "playlists");
|
||||||
AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model");
|
AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model");
|
||||||
AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog");
|
AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog");
|
||||||
AddObject(manager()->data().task_manager_, sipType_TaskManager, "task_manager");
|
AddObject(manager()->data().task_manager_, sipType_TaskManager, "task_manager");
|
||||||
}
|
}
|
||||||
|
|
||||||
AddObject(manager()->ui(), sipType_UIInterface, "ui");
|
AddObject(manager()->ui(), sipType_UIInterface, "ui");
|
||||||
AddObject(this, sipType_PythonEngine, "pythonengine");
|
AddObject(this, sipType_PythonEngine, "pythonengine");
|
||||||
|
|
||||||
// Create a module for scripts
|
// Create a module for scripts
|
||||||
PyImport_AddModule(kModulePrefix);
|
PyImport_AddModule(kModulePrefix);
|
||||||
|
|
||||||
// Run the startup script - this redirects sys.stdout and sys.stderr to our
|
// Run the startup script - this redirects sys.stdout and sys.stderr to our
|
||||||
// log handler.
|
// log handler.
|
||||||
QFile python_startup(":pythonstartup.py");
|
QFile python_startup(":pythonstartup.py");
|
||||||
python_startup.open(QIODevice::ReadOnly);
|
python_startup.open(QIODevice::ReadOnly);
|
||||||
QByteArray python_startup_script = python_startup.readAll();
|
QByteArray python_startup_script = python_startup.readAll();
|
||||||
|
|
||||||
if (PyRun_SimpleString(python_startup_script.constData()) != 0) {
|
if (PyRun_SimpleString(python_startup_script.constData()) != 0) {
|
||||||
AddLogLine("Could not execute startup code", true);
|
AddLogLine("Could not execute startup code", true);
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyEval_ReleaseLock();
|
PyEval_ReleaseLock();
|
||||||
|
|
||||||
initialised_ = true;
|
initialised_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Script* PythonEngine::CreateScript(const ScriptInfo& info) {
|
||||||
|
// Initialise Python if it hasn't been done yet
|
||||||
|
if (!EnsureInitialised()) {
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Script* ret = new PythonScript(this, info);
|
Script* ret = new PythonScript(this, info);
|
||||||
|
@ -38,6 +38,8 @@ public:
|
|||||||
ScriptInfo::Language language() const { return ScriptInfo::Language_Python; }
|
ScriptInfo::Language language() const { return ScriptInfo::Language_Python; }
|
||||||
QString name() const { return "python"; }
|
QString name() const { return "python"; }
|
||||||
|
|
||||||
|
bool EnsureInitialised();
|
||||||
|
|
||||||
Script* CreateScript(const ScriptInfo& info);
|
Script* CreateScript(const ScriptInfo& info);
|
||||||
void DestroyScript(Script* script);
|
void DestroyScript(Script* script);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user