mirror of
https://github.com/wassname/FanFicFare.git
synced 2026-09-12 12:02:50 +08:00
Add initial version of plugin code--proof of concept stage.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'Apache License'
|
||||
__copyright__ = '2011, Fanficdownloader team'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
# The class that all Interface Action plugin wrappers must inherit from
|
||||
from calibre.customize import InterfaceActionBase
|
||||
|
||||
class InterfacePluginDemo(InterfaceActionBase):
|
||||
'''
|
||||
This class is a simple wrapper that provides information about the actual
|
||||
plugin class. The actual interface plugin class is called InterfacePlugin
|
||||
and is defined in the ui.py file, as specified in the actual_plugin field
|
||||
below.
|
||||
|
||||
The reason for having two classes is that it allows the command line
|
||||
calibre utilities to run without needing to load the GUI libraries.
|
||||
'''
|
||||
name = 'aa FanFictionDownLoader Plugin'
|
||||
description = 'UI plugin to download and maintain FanFiction from various sites.'
|
||||
supported_platforms = ['windows', 'osx', 'linux']
|
||||
author = 'Jim Miller'
|
||||
version = (1, 0, 0)
|
||||
minimum_calibre_version = (0, 7, 53)
|
||||
|
||||
#: This field defines the GUI plugin class that contains all the code
|
||||
#: that actually does something. Its format is module_path:class_name
|
||||
#: The specified class must be defined in the specified module.
|
||||
actual_plugin = 'calibre_plugins.fanfictiondownloader_plugin.ui:InterfacePlugin'
|
||||
|
||||
def is_customizable(self):
|
||||
'''
|
||||
This method must return True to enable customization via
|
||||
Preferences->Plugins
|
||||
'''
|
||||
return True
|
||||
|
||||
def config_widget(self):
|
||||
'''
|
||||
Implement this method and :meth:`save_settings` in your plugin to
|
||||
use a custom configuration dialog.
|
||||
|
||||
This method, if implemented, must return a QWidget. The widget can have
|
||||
an optional method validate() that takes no arguments and is called
|
||||
immediately after the user clicks OK. Changes are applied if and only
|
||||
if the method returns True.
|
||||
|
||||
If for some reason you cannot perform the configuration at this time,
|
||||
return a tuple of two strings (message, details), these will be
|
||||
displayed as a warning dialog to the user and the process will be
|
||||
aborted.
|
||||
|
||||
The base class implementation of this method raises NotImplementedError
|
||||
so by default no user configuration is possible.
|
||||
'''
|
||||
# It is important to put this import statement here rather than at the
|
||||
# top of the module as importing the config class will also cause the
|
||||
# GUI libraries to be loaded, which we do not want when using calibre
|
||||
# from the command line
|
||||
from calibre_plugins.fanfictiondownloader_plugin.config import ConfigWidget
|
||||
return ConfigWidget()
|
||||
|
||||
def save_settings(self, config_widget):
|
||||
'''
|
||||
Save the settings specified by the user with config_widget.
|
||||
|
||||
:param config_widget: The widget returned by :meth:`config_widget`.
|
||||
'''
|
||||
config_widget.save_settings()
|
||||
|
||||
# Apply the changes
|
||||
ac = self.actual_plugin_
|
||||
if ac is not None:
|
||||
ac.apply_settings()
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
FanFictionDownLoader Plugin Demo
|
||||
===========================
|
||||
|
||||
Created by Jim Miller, borrowing heavily from Kovid Goyal's 'The
|
||||
InterfacePlugin Demo'
|
||||
|
||||
Requires calibre >= 0.7.53
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'Apache License'
|
||||
__copyright__ = '2011, Fanficdownloader team'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from PyQt4.Qt import QWidget, QHBoxLayout, QLabel, QLineEdit
|
||||
|
||||
from calibre.utils.config import JSONConfig
|
||||
|
||||
# This is where all preferences for this plugin will be stored
|
||||
# Remember that this name (i.e. plugins/fanfictiondownloader_plugin) is also
|
||||
# in a global namespace, so make it as unique as possible.
|
||||
# You should always prefix your config file name with plugins/,
|
||||
# so as to ensure you dont accidentally clobber a calibre config file
|
||||
prefs = JSONConfig('plugins/fanfictiondownloader_plugin')
|
||||
|
||||
# Set defaults
|
||||
prefs.defaults['hello_world_msg'] = 'Hello, World!'
|
||||
|
||||
class ConfigWidget(QWidget):
|
||||
|
||||
def __init__(self):
|
||||
QWidget.__init__(self)
|
||||
self.l = QHBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
|
||||
self.label = QLabel('Hello world &message:')
|
||||
self.l.addWidget(self.label)
|
||||
|
||||
self.msg = QLineEdit(self)
|
||||
self.msg.setText(prefs['hello_world_msg'])
|
||||
self.l.addWidget(self.msg)
|
||||
self.label.setBuddy(self.msg)
|
||||
|
||||
def save_settings(self):
|
||||
prefs['hello_world_msg'] = unicode(self.msg.text())
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'Apache License'
|
||||
__copyright__ = '2011, Fanficdownloader team'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
if False:
|
||||
# This is here to keep my python error checker from complaining about
|
||||
# the builtin functions that will be defined by the plugin loading system
|
||||
# You do not need this code in your plugins
|
||||
get_icons = get_resources = None
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
from PyQt4.Qt import QDialog, QVBoxLayout, QPushButton, QMessageBox, QLabel
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
|
||||
from calibre.ebooks.metadata.epub import get_metadata
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.config import prefs
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader import adapters,writers,exceptions
|
||||
|
||||
import ConfigParser
|
||||
|
||||
class DemoDialog(QDialog):
|
||||
|
||||
def __init__(self, gui, icon, do_user_config):
|
||||
QDialog.__init__(self, gui)
|
||||
self.gui = gui
|
||||
self.do_user_config = do_user_config
|
||||
|
||||
# The current database shown in the GUI
|
||||
# db is an instance of the class LibraryDatabase2 from database.py
|
||||
# This class has many, many methods that allow you to do a lot of
|
||||
# things.
|
||||
self.db = gui.current_db
|
||||
|
||||
self.l = QVBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
|
||||
self.label = QLabel(prefs['hello_world_msg'])
|
||||
self.l.addWidget(self.label)
|
||||
|
||||
self.setWindowTitle('FanFictionDownLoader')
|
||||
self.setWindowIcon(icon)
|
||||
|
||||
self.about_button = QPushButton('About', self)
|
||||
self.about_button.clicked.connect(self.about)
|
||||
self.l.addWidget(self.about_button)
|
||||
|
||||
self.marked_button = QPushButton(
|
||||
'Show books with only one format in the calibre GUI', self)
|
||||
self.marked_button.clicked.connect(self.marked)
|
||||
self.l.addWidget(self.marked_button)
|
||||
|
||||
self.view_button = QPushButton(
|
||||
'View the most recently added book', self)
|
||||
self.view_button.clicked.connect(self.view)
|
||||
self.l.addWidget(self.view_button)
|
||||
|
||||
self.ffdl_button = QPushButton(
|
||||
'Attempt FFDL', self)
|
||||
self.ffdl_button.clicked.connect(self.ffdl)
|
||||
self.l.addWidget(self.ffdl_button)
|
||||
|
||||
self.conf_button = QPushButton(
|
||||
'Configure this plugin', self)
|
||||
self.conf_button.clicked.connect(self.config)
|
||||
self.l.addWidget(self.conf_button)
|
||||
|
||||
self.resize(self.sizeHint())
|
||||
|
||||
def about(self):
|
||||
# Get the about text from a file inside the plugin zip file
|
||||
# The get_resources function is a builtin function defined for all your
|
||||
# plugin code. It loads files from the plugin zip file. It returns
|
||||
# the bytes from the specified file.
|
||||
#
|
||||
# Note that if you are loading more than one file, for performance, you
|
||||
# should pass a list of names to get_resources. In this case,
|
||||
# get_resources will return a dictionary mapping names to bytes. Names that
|
||||
# are not found in the zip file will not be in the returned dictionary.
|
||||
text = get_resources('about.txt')
|
||||
QMessageBox.about(self, 'About the Interface Plugin Demo',
|
||||
text.decode('utf-8'))
|
||||
|
||||
def marked(self):
|
||||
fmt_idx = self.db.FIELD_MAP['formats']
|
||||
matched_ids = set()
|
||||
for record in self.db.data.iterall():
|
||||
# Iterate over all records
|
||||
fmts = record[fmt_idx]
|
||||
# fmts is either None or a comma separated list of formats
|
||||
if fmts and ',' not in fmts:
|
||||
matched_ids.add(record[0])
|
||||
# Mark the records with the matching ids
|
||||
self.db.set_marked_ids(matched_ids)
|
||||
|
||||
# Tell the GUI to search for all marked records
|
||||
self.gui.search.setEditText('marked:true')
|
||||
self.gui.search.do_search()
|
||||
|
||||
def ffdl(self):
|
||||
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.readfp(StringIO(get_resources("defaults.ini")))
|
||||
adapter = adapters.getAdapter(config,"http://test1.com?sid=6646") # http://www.fanfiction.net/s/6439390/1/All_Hallows_Eve") #
|
||||
|
||||
writer = writers.getWriter("epub",config,adapter)
|
||||
tmp = PersistentTemporaryFile(".epub")
|
||||
writer.writeStory(tmp)
|
||||
print("tmp: "+tmp.name)
|
||||
mi = get_metadata(tmp,extract_cover=False)
|
||||
self.db.add_books([tmp],["EPUB"],[mi])
|
||||
QMessageBox.about(self, 'FFDL Metadata',
|
||||
str(adapter.getStoryMetadataOnly()).decode('utf-8'))
|
||||
|
||||
def view(self):
|
||||
most_recent = most_recent_id = None
|
||||
timestamp_idx = self.db.FIELD_MAP['timestamp']
|
||||
|
||||
for record in self.db.data:
|
||||
# Iterate over all currently showing records
|
||||
timestamp = record[timestamp_idx]
|
||||
if most_recent is None or timestamp > most_recent:
|
||||
most_recent = timestamp
|
||||
most_recent_id = record[0]
|
||||
|
||||
if most_recent_id is not None:
|
||||
# Get the row number of the id as shown in the GUI
|
||||
row_number = self.db.row(most_recent_id)
|
||||
# Get a reference to the View plugin
|
||||
view_plugin = self.gui.iactions['View']
|
||||
# Ask the view plugin to launch the viewer for row_number
|
||||
view_plugin._view_books([row_number])
|
||||
|
||||
def config(self):
|
||||
self.do_user_config(parent=self)
|
||||
# Apply the changes
|
||||
self.label.setText(prefs['hello_world_msg'])
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'Apache License'
|
||||
__copyright__ = '2011, Fanficdownloader team'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
if False:
|
||||
# This is here to keep my python error checker from complaining about
|
||||
# the builtin functions that will be defined by the plugin loading system
|
||||
# You do not need this code in your plugins
|
||||
get_icons = get_resources = None
|
||||
|
||||
# The class that all interface action plugins must inherit from
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre_plugins.fanfictiondownloader_plugin.plugin import DemoDialog
|
||||
|
||||
class InterfacePlugin(InterfaceAction):
|
||||
|
||||
name = 'FanFictionDownLoader'
|
||||
|
||||
# Declare the main action associated with this plugin
|
||||
# The keyboard shortcut can be None if you dont want to use a keyboard
|
||||
# shortcut. Remember that currently calibre has no central management for
|
||||
# keyboard shortcuts, so try to use an unusual/unused shortcut.
|
||||
action_spec = ('FanFictionDownLoader', None,
|
||||
'Run the FanFictionDownLoader Plugin', None)
|
||||
|
||||
def genesis(self):
|
||||
# This method is called once per plugin, do initial setup here
|
||||
|
||||
# Set the icon for this interface action
|
||||
# The get_icons function is a builtin function defined for all your
|
||||
# plugin code. It loads icons from the plugin zip file. It returns
|
||||
# QIcon objects, if you want the actual data, use the analogous
|
||||
# get_resources builtin function.
|
||||
#
|
||||
# Note that if you are loading more than one icon, for performance, you
|
||||
# should pass a list of names to get_icons. In this case, get_icons
|
||||
# will return a dictionary mapping names to QIcons. Names that
|
||||
# are not found in the zip file will result in null QIcons.
|
||||
icon = get_icons('images/icon.png')
|
||||
|
||||
# The qaction is automatically created from the action_spec defined
|
||||
# above
|
||||
self.qaction.setIcon(icon)
|
||||
self.qaction.triggered.connect(self.show_dialog)
|
||||
|
||||
def show_dialog(self):
|
||||
# The base plugin object defined in __init__.py
|
||||
base_plugin_object = self.interface_action_base_plugin
|
||||
# Show the config dialog
|
||||
# The config dialog can also be shown from within
|
||||
# Preferences->Plugins, which is why the do_user_config
|
||||
# method is defined on the base plugin class
|
||||
do_user_config = base_plugin_object.do_user_config
|
||||
|
||||
# self.gui is the main calibre GUI. It acts as the gateway to access
|
||||
# all the elements of the calibre user interface, it should also be the
|
||||
# parent of the dialog
|
||||
d = DemoDialog(self.gui, self.qaction.icon(), do_user_config)
|
||||
d.show()
|
||||
|
||||
def apply_settings(self):
|
||||
from calibre_plugins.fanfictiondownloader_plugin.config import prefs
|
||||
# In an actual non trivial plugin, you would probably need to
|
||||
# do something based on the settings in prefs
|
||||
prefs
|
||||
|
||||
Reference in New Issue
Block a user