diff --git a/src/calibre/gui2/dialogs/config/__init__.py b/src/calibre/gui2/dialogs/config/__init__.py
index 5d855b5263..b9c57b27ab 100644
--- a/src/calibre/gui2/dialogs/config/__init__.py
+++ b/src/calibre/gui2/dialogs/config/__init__.py
@@ -445,6 +445,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
self.username.setText(opts.username)
self.password.setText(opts.password if opts.password else '')
self.opt_max_opds_items.setValue(opts.max_opds_items)
+ self.opt_max_opds_ungrouped_items.setValue(opts.max_opds_ungrouped_items)
self.auto_launch.setChecked(config['autolaunch_server'])
self.systray_icon.setChecked(config['systray_icon'])
self.sync_news.setChecked(config['upload_news_to_device'])
@@ -848,6 +849,8 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
sc.set('port', self.port.value())
sc.set('max_cover', mcs)
sc.set('max_opds_items', self.opt_max_opds_items.value())
+ sc.set('max_opds_ungrouped_items',
+ self.opt_max_opds_ungrouped_items.value())
config['delete_news_from_library_on_upload'] = self.delete_news.isChecked()
config['upload_news_to_device'] = self.sync_news.isChecked()
config['search_as_you_type'] = self.search_as_you_type.isChecked()
diff --git a/src/calibre/gui2/dialogs/config/config.ui b/src/calibre/gui2/dialogs/config/config.ui
index db748dae7e..917333a989 100644
--- a/src/calibre/gui2/dialogs/config/config.ui
+++ b/src/calibre/gui2/dialogs/config/config.ui
@@ -892,6 +892,26 @@
+ -
+
+
+ 25
+
+
+ 1000000
+
+
+
+ -
+
+
+ Max. OPDS &ungrouped items:
+
+
+ opt_max_opds_ungrouped_items
+
+
+
-
diff --git a/src/calibre/library/server/__init__.py b/src/calibre/library/server/__init__.py
index 441aee9b60..5050dfaa99 100644
--- a/src/calibre/library/server/__init__.py
+++ b/src/calibre/library/server/__init__.py
@@ -38,6 +38,12 @@ def server_config(defaults=None):
c.add_opt('max_opds_items', ['--max-opds-items'], default=30,
help=_('The maximum number of matches to return per OPDS query. '
'This affects Stanza, WordPlayer, etc. integration.'))
+ c.add_opt('max_opds_ungrouped_items', ['--max-opds-ungrouped-items'],
+ default=100,
+ help=_('Group items in categories such as author/tags '
+ 'by first letter when there are more than this number '
+ 'of items. Default: %default. Set to a large number '
+ 'to disable grouping.'))
return c
def main():
diff --git a/src/calibre/library/server/opds.py b/src/calibre/library/server/opds.py
index f32f60a6dd..d396d73af2 100644
--- a/src/calibre/library/server/opds.py
+++ b/src/calibre/library/server/opds.py
@@ -445,7 +445,7 @@ class OPDSServer(object):
id_ = 'calibre-category-feed:'+which
- MAX_ITEMS = 50
+ MAX_ITEMS = self.opts.max_opds_ungrouped_items
if len(items) <= MAX_ITEMS:
max_items = self.opts.max_opds_items
@@ -459,8 +459,6 @@ class OPDSServer(object):
self.text, self.count = text, count
starts = set([x.name[0] for x in items])
- if len(starts) > MAX_ITEMS:
- starts = set([x.name[:2] for x in items])
category_groups = OrderedDict()
for x in sorted(starts, cmp=lambda x,y:cmp(x.lower(), y.lower())):
category_groups[x] = len([y for y in items if