home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1442 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  16.2 KB  |  446 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL v3'
  6. __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
  7. __docformat__ = 'restructuredtext en'
  8. import os
  9. import copy
  10. from PyQt4.Qt import QAbstractItemModel, QVariant, Qt, QColor, QFont, QIcon, QModelIndex, SIGNAL, QMetaObject, pyqtSlot
  11. from calibre.utils.search_query_parser import SearchQueryParser
  12. from calibre.gui2 import NONE
  13. from calibre.utils.localization import get_language
  14. from calibre.web.feeds.recipes.collection import get_builtin_recipe_collection, get_custom_recipe_collection, SchedulerConfig, download_builtin_recipe
  15. from calibre.utils.pyparsing import ParseException
  16.  
  17. class NewsTreeItem(object):
  18.     
  19.     def __init__(self, builtin, custom, scheduler_config, parent = None):
  20.         self.builtin = builtin
  21.         self.custom = custom
  22.         self.scheduler_config = scheduler_config
  23.         self.parent = parent
  24.         if self.parent is not None:
  25.             self.parent.append(self)
  26.         
  27.         self.children = []
  28.  
  29.     
  30.     def row(self):
  31.         if self.parent is not None:
  32.             return self.parent.children.index(self)
  33.         return 0
  34.  
  35.     
  36.     def append(self, child):
  37.         child.parent = self
  38.         self.children.append(child)
  39.  
  40.     
  41.     def data(self, role):
  42.         return NONE
  43.  
  44.     
  45.     def flags(self):
  46.         return Qt.ItemIsEnabled | Qt.ItemIsSelectable
  47.  
  48.     
  49.     def sort(self):
  50.         self.children.sort()
  51.         for child in self.children:
  52.             child.sort()
  53.         
  54.  
  55.     
  56.     def prune(self):
  57.         for child in list(self.children):
  58.             if len(child.children) == 0:
  59.                 self.children.remove(child)
  60.                 child.parent = None
  61.                 continue
  62.         
  63.  
  64.  
  65.  
  66. class NewsCategory(NewsTreeItem):
  67.     
  68.     def __init__(self, category, builtin, custom, scheduler_config, parent):
  69.         NewsTreeItem.__init__(self, builtin, custom, scheduler_config, parent)
  70.         self.category = category
  71.         self.cdata = get_language(self.category)
  72.         self.bold_font = QFont()
  73.         self.bold_font.setBold(True)
  74.         self.bold_font = QVariant(self.bold_font)
  75.  
  76.     
  77.     def data(self, role):
  78.         if role == Qt.DisplayRole:
  79.             return QVariant(self.cdata + ' [%d]' % len(self.children))
  80.         if role == Qt.FontRole:
  81.             return self.bold_font
  82.         if role == Qt.ForegroundRole and self.category == _('Scheduled'):
  83.             return QVariant(QColor(0, 255, 0))
  84.         return NONE
  85.  
  86.     
  87.     def flags(self):
  88.         return Qt.ItemIsEnabled
  89.  
  90.     
  91.     def __cmp__(self, other):
  92.         
  93.         def decorate(x):
  94.             if x == _('Scheduled'):
  95.                 x = '0' + x
  96.             elif x == _('Custom'):
  97.                 x = '1' + x
  98.             else:
  99.                 x = '2' + x
  100.             return x
  101.  
  102.         return cmp(decorate(self.cdata), decorate(getattr(other, 'cdata', '')))
  103.  
  104.  
  105.  
  106. class NewsItem(NewsTreeItem):
  107.     
  108.     def __init__(self, urn, title, default_icon, custom_icon, builtin, custom, scheduler_config, parent):
  109.         NewsTreeItem.__init__(self, builtin, custom, scheduler_config, parent)
  110.         self.urn = urn
  111.         self.title = title
  112.         self.icon = None
  113.         self.default_icon = None
  114.         self.default_icon = default_icon
  115.         if 'custom:' in self.urn:
  116.             self.icon = custom_icon
  117.         
  118.  
  119.     
  120.     def data(self, role):
  121.         if role == Qt.DisplayRole:
  122.             return QVariant(self.title)
  123.         if role == Qt.DecorationRole:
  124.             if self.icon is None:
  125.                 icon = I('news/%s.png' % self.urn[8:])
  126.                 if os.path.exists(icon):
  127.                     self.icon = QVariant(QIcon(icon))
  128.                 else:
  129.                     self.icon = self.default_icon
  130.             
  131.             return self.icon
  132.         return NONE
  133.  
  134.     
  135.     def __cmp__(self, other):
  136.         return cmp(self.title.lower(), getattr(other, 'title', '').lower())
  137.  
  138.  
  139.  
  140. class RecipeModel(QAbstractItemModel, SearchQueryParser):
  141.     LOCATIONS = [
  142.         'all']
  143.     
  144.     def __init__(self, db, *args):
  145.         QAbstractItemModel.__init__(self, *args)
  146.         SearchQueryParser.__init__(self, locations = [
  147.             'all'])
  148.         self.db = db
  149.         self.default_icon = QVariant(QIcon(I('news.svg')))
  150.         self.custom_icon = QVariant(QIcon(I('user_profile.svg')))
  151.         self.builtin_recipe_collection = get_builtin_recipe_collection()
  152.         self.scheduler_config = SchedulerConfig()
  153.         self.do_refresh()
  154.  
  155.     
  156.     def do_database_change(self):
  157.         self.db = self.newdb
  158.         self.newdb = None
  159.         self.do_refresh()
  160.  
  161.     do_database_change = pyqtSlot()(do_database_change)
  162.     
  163.     def database_changed(self, db):
  164.         self.newdb = db
  165.         QMetaObject.invokeMethod(self, 'do_database_change', Qt.QueuedConnection)
  166.  
  167.     
  168.     def get_builtin_recipe(self, urn, download = True):
  169.         if download:
  170.             
  171.             try:
  172.                 return download_builtin_recipe(urn)
  173.             import traceback
  174.             traceback.print_exc()
  175.  
  176.         
  177.         return P('recipes/%s.recipe' % urn, data = True)
  178.  
  179.     
  180.     def get_recipe(self, urn, download = True):
  181.         coll = None if urn.startswith('custom:') else self.builtin_recipe_collection
  182.         for recipe in coll:
  183.             if recipe.get('id', False) == urn:
  184.                 if coll is self.builtin_recipe_collection:
  185.                     return self.get_builtin_recipe(urn[8:], download = download)
  186.                 return self.db.get_feed(int(urn[len('custom:'):]))
  187.         
  188.  
  189.     
  190.     def update_custom_recipe(self, urn, title, script):
  191.         self.db.update_feed(int(urn[len('custom:'):]), script, title)
  192.         self.custom_recipe_collection = get_custom_recipe_collection(self.db)
  193.  
  194.     
  195.     def add_custom_recipe(self, title, script):
  196.         self.db.add_feed(title, script)
  197.         self.custom_recipe_collection = get_custom_recipe_collection(self.db)
  198.  
  199.     
  200.     def remove_custom_recipes(self, urns):
  201.         ids = [ int(x[len('custom:'):]) for x in urns ]
  202.         self.db.remove_feeds(ids)
  203.         self.custom_recipe_collection = get_custom_recipe_collection(self.db)
  204.  
  205.     
  206.     def do_refresh(self, restrict_to_urns = set([])):
  207.         self.custom_recipe_collection = get_custom_recipe_collection(self.db)
  208.         
  209.         def factory(cls, parent, *args):
  210.             args = list(args)
  211.             if cls is NewsItem:
  212.                 args.extend([
  213.                     self.default_icon,
  214.                     self.custom_icon])
  215.             
  216.             args += [
  217.                 self.builtin_recipe_collection,
  218.                 self.custom_recipe_collection,
  219.                 self.scheduler_config,
  220.                 parent]
  221.             return cls(*args)
  222.  
  223.         
  224.         def ok(urn):
  225.             if restrict_to_urns is None:
  226.                 return False
  227.             if not not restrict_to_urns:
  228.                 pass
  229.             return urn in restrict_to_urns
  230.  
  231.         new_root = factory(NewsTreeItem, None)
  232.         scheduled = factory(NewsCategory, new_root, _('Scheduled'))
  233.         custom = factory(NewsCategory, new_root, _('Custom'))
  234.         lang_map = { }
  235.         self.all_urns = set([])
  236.         self.showing_count = 0
  237.         for x in self.custom_recipe_collection:
  238.             urn = x.get('id')
  239.             self.all_urns.add(urn)
  240.             if ok(urn):
  241.                 factory(NewsItem, custom, urn, x.get('title'))
  242.                 self.showing_count += 1
  243.                 continue
  244.             self
  245.         
  246.         for x in self.builtin_recipe_collection:
  247.             urn = x.get('id')
  248.             self.all_urns.add(urn)
  249.             if ok(urn):
  250.                 lang = x.get('language', 'und')
  251.                 if lang not in lang_map:
  252.                     lang_map[lang] = factory(NewsCategory, new_root, lang)
  253.                 
  254.                 factory(NewsItem, lang_map[lang], urn, x.get('title'))
  255.                 self.showing_count += 1
  256.                 continue
  257.             self
  258.         
  259.         for x in self.scheduler_config.iter_recipes():
  260.             urn = x.get('id')
  261.             if urn not in self.all_urns:
  262.                 self.scheduler_config.un_schedule_recipe(urn)
  263.                 continue
  264.             
  265.             if ok(urn):
  266.                 factory(NewsItem, scheduled, urn, x.get('title'))
  267.                 continue
  268.         
  269.         new_root.prune()
  270.         new_root.sort()
  271.         self.root = new_root
  272.         self.reset()
  273.  
  274.     
  275.     def recipe_from_urn(self, urn):
  276.         coll = None if 'custom:' in urn else self.builtin_recipe_collection
  277.         for x in coll:
  278.             if x.get('id', None) == urn:
  279.                 return copy.deepcopy(x)
  280.         
  281.  
  282.     
  283.     def schedule_info_from_urn(self, urn):
  284.         return self.scheduler_config.get_schedule_info(urn)
  285.  
  286.     
  287.     def account_info_from_urn(self, urn):
  288.         return self.scheduler_config.get_account_info(urn)
  289.  
  290.     
  291.     def universal_set(self):
  292.         return self.all_urns
  293.  
  294.     
  295.     def get_customize_info(self, urn):
  296.         return self.scheduler_config.get_customize_info(urn)
  297.  
  298.     
  299.     def get_matches(self, location, query):
  300.         query = query.strip().lower()
  301.         if not query:
  302.             return self.universal_set()
  303.         results = set([])
  304.         for urn in self.universal_set():
  305.             recipe = self.recipe_from_urn(urn)
  306.             if query in recipe.get('title', '').lower() or query in recipe.get('description', '').lower():
  307.                 results.add(urn)
  308.                 continue
  309.             query
  310.         
  311.         return results
  312.  
  313.     
  314.     def search(self, query):
  315.         
  316.         try:
  317.             results = self.parse(unicode(query))
  318.             if not results:
  319.                 results = None
  320.         except ParseException:
  321.             results = []
  322.  
  323.         self.do_refresh(restrict_to_urns = results)
  324.         self.emit(SIGNAL('searched(PyQt_PyObject)'), True)
  325.  
  326.     
  327.     def columnCount(self, parent):
  328.         return 1
  329.  
  330.     
  331.     def data(self, index, role):
  332.         if not index.isValid():
  333.             return NONE
  334.         item = index.internalPointer()
  335.         return item.data(role)
  336.  
  337.     
  338.     def headerData(self, *args):
  339.         return NONE
  340.  
  341.     
  342.     def flags(self, index):
  343.         if not index.isValid():
  344.             return Qt.ItemIsEnabled | Qt.ItemIsSelectable
  345.         item = index.internalPointer()
  346.         return item.flags()
  347.  
  348.     
  349.     def resort(self):
  350.         self.do_refresh()
  351.  
  352.     
  353.     def index(self, row, column, parent):
  354.         if not self.hasIndex(row, column, parent):
  355.             return QModelIndex()
  356.         if not parent.isValid():
  357.             parent_item = self.root
  358.         else:
  359.             parent_item = parent.internalPointer()
  360.         
  361.         try:
  362.             child_item = parent_item.children[row]
  363.         except IndexError:
  364.             return QModelIndex()
  365.  
  366.         ans = self.createIndex(row, column, child_item)
  367.         return ans
  368.  
  369.     
  370.     def parent(self, index):
  371.         if not index.isValid():
  372.             return QModelIndex()
  373.         child_item = index.internalPointer()
  374.         parent_item = child_item.parent
  375.         if parent_item is self.root or parent_item is None:
  376.             return QModelIndex()
  377.         ans = self.createIndex(parent_item.row(), 0, parent_item)
  378.         return ans
  379.  
  380.     
  381.     def rowCount(self, parent):
  382.         if parent.column() > 0:
  383.             return 0
  384.         if not parent.isValid():
  385.             parent_item = self.root
  386.         else:
  387.             parent_item = parent.internalPointer()
  388.         return len(parent_item.children)
  389.  
  390.     
  391.     def update_recipe_schedule(self, urn, schedule_type, schedule, add_title_tag = True, custom_tags = []):
  392.         recipe = self.recipe_from_urn(urn)
  393.         self.scheduler_config.schedule_recipe(recipe, schedule_type, schedule, add_title_tag = add_title_tag, custom_tags = custom_tags)
  394.  
  395.     
  396.     def update_last_downloaded(self, urn):
  397.         self.scheduler_config.update_last_downloaded(urn)
  398.  
  399.     
  400.     def set_account_info(self, urn, un, pw):
  401.         self.scheduler_config.set_account_info(urn, un, pw)
  402.  
  403.     
  404.     def get_account_info(self, urn):
  405.         return self.scheduler_config.get_account_info(urn)
  406.  
  407.     
  408.     def get_schedule_info(self, urn):
  409.         return self.scheduler_config.get_schedule_info(urn)
  410.  
  411.     
  412.     def un_schedule_recipe(self, urn):
  413.         self.scheduler_config.un_schedule_recipe(urn)
  414.  
  415.     
  416.     def schedule_recipe(self, urn, sched_type, schedule):
  417.         self.scheduler_config.schedule_recipe(self.recipe_from_urn(urn), sched_type, schedule)
  418.  
  419.     
  420.     def customize_recipe(self, urn, add_title_tag, custom_tags):
  421.         self.scheduler_config.customize_recipe(urn, add_title_tag, custom_tags)
  422.  
  423.     
  424.     def get_to_be_downloaded_recipes(self):
  425.         ans = self.scheduler_config.get_to_be_downloaded_recipes()
  426.         ans2 = _[1]
  427.         for x in set(ans) - set(ans2):
  428.             self.un_schedule_recipe(x)
  429.         
  430.         return ans2
  431.  
  432.     
  433.     def scheduled_urns(self):
  434.         ans = []
  435.         self.scheduler_config.lock.__enter__()
  436.         
  437.         try:
  438.             for recipe in self.scheduler_config.iter_recipes():
  439.                 ans.append(recipe.get('id'))
  440.         finally:
  441.             pass
  442.  
  443.         return ans
  444.  
  445.  
  446.