Commit e9801c94 authored by Ivan Tyagov's avatar Ivan Tyagov

Allow a gadget to modify its main title.

Refactor Feed reader use mentioned above feature.
Use JSON dump whenever possible.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@41395 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3e394fdd
import feedparser, md5, urllib2, socket import feedparser, md5, urllib2, socket
def getRssDataAsDict(self, url, username=None, password=None): def getRssDataAsDict(self, url, username=None, password=None):
result = {} result = {}
translate = self.Base_translateString translate = self.Base_translateString
# no url, no feed to read # no url, no feed to read
if url in ('', None, 'None',): if url in ('', None, 'None',):
return {'title':translate('Please enter a valid Rss or Atom url in the preference form.')} # no URL
return {'status':-1}
# use authentication or not? # use authentication or not?
handlers = [] handlers = []
...@@ -20,16 +21,19 @@ def getRssDataAsDict(self, url, username=None, password=None): ...@@ -20,16 +21,19 @@ def getRssDataAsDict(self, url, username=None, password=None):
socket.setdefaulttimeout(10.0) socket.setdefaulttimeout(10.0)
d = feedparser.parse(url, handlers=handlers) d = feedparser.parse(url, handlers=handlers)
socket.setdefaulttimeout(default_timeout) socket.setdefaulttimeout(default_timeout)
if d.bozo and isinstance(d.bozo_exception, urllib2.URLError): if d.bozo and isinstance(d.bozo_exception, urllib2.URLError):
# we have an URL error # we have an URL error
return {'title':translate('Wrong Rss or Atom url or service temporary down.')} return {'status':-2}
elif d.bozo:
# http status code checks print d.bozo, d.bozo_exception
return {'status': -5}
if d.status == 401: if d.status == 401:
return {'title': translate('Unauthorized, verify your authentication.')} return {'status':-3}
elif d.status == 404: elif d.status == 404:
return {'title': translate('Page not found.')} return {'status':-4}
result['items'] = [] result['items'] = []
# some feeds may not provide logo # some feeds may not provide logo
...@@ -51,4 +55,5 @@ def getRssDataAsDict(self, url, username=None, password=None): ...@@ -51,4 +55,5 @@ def getRssDataAsDict(self, url, username=None, password=None):
# sort by date # sort by date
result['items'] = sorted(result['items'], key=lambda k: k['updated_parsed']) result['items'] = sorted(result['items'], key=lambda k: k['updated_parsed'])
result['items'].reverse() result['items'].reverse()
result['status'] = 0
return result return result
\ No newline at end of file
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<tuple> <global name="Gadget" module="Products.ERP5.Document.Gadget"/>
<global name="Gadget" module="Products.ERP5.Document.Gadget"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -162,7 +159,7 @@ ...@@ -162,7 +159,7 @@
</item> </item>
<item> <item>
<key> <string>view_form_id</string> </key> <key> <string>view_form_id</string> </key>
<value> <string>ERP5Site_viewRssGadget</string> </value> <value> <string>ERP5Site_viewRssGadgetAsJSON</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
...@@ -175,7 +172,7 @@ ...@@ -175,7 +172,7 @@
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="OOBTree" module="BTrees._OOBTree"/> <global name="OOBTree" module="BTrees.OOBTree"/>
</pickle> </pickle>
<pickle> <pickle>
<none/> <none/>
...@@ -183,7 +180,7 @@ ...@@ -183,7 +180,7 @@
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="OOBTree" module="BTrees._OOBTree"/> <global name="OOBTree" module="BTrees.OOBTree"/>
</pickle> </pickle>
<pickle> <pickle>
<none/> <none/>
......
...@@ -50,16 +50,21 @@ ...@@ -50,16 +50,21 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Document import newTempBase\n <value> <string encoding="cdata"><![CDATA[
from Products.ERP5Type.Document import newTempBase\n
\n
box_relative_url = kw.get(\'box_relative_url\')\n box_relative_url = kw.get(\'box_relative_url\')\n
selection_name = kw.get(\'list_selection_name\')\n selection_name = kw.get(\'list_selection_name\')\n
portal_selection = getattr(context,\'portal_selections\')\n portal_selection = getattr(context,\'portal_selections\')\n
selection = portal_selection.getSelectionFor(selection_name)\n selection = portal_selection.getSelectionFor(selection_name)\n
\n \n
# XXX: This test has been added because currently the "Asynchronous" mode is\n error_mapping_dict = {-1: \'Please enter a valid Rss or Atom url in the preference form.\',\n
# the only one supported by gadgets which uses the page templates\n -2: \'Wrong Rss or Atom url or service temporary down.\',\n
# ListBox_asListStyleHTML.\n -3: \'Unauthorized, verify your authentication.\',\n
# More investigation are required to fix this bug\n -4: \'Page not found.\',\n
-5: \'Mismatched RSS feed.\'}\n
\n
if box_relative_url:\n if box_relative_url:\n
box = context.restrictedTraverse(box_relative_url)\n box = context.restrictedTraverse(box_relative_url)\n
preferences = box.KnowledgeBox_getDefaultPreferencesDict()\n preferences = box.KnowledgeBox_getDefaultPreferencesDict()\n
...@@ -70,24 +75,27 @@ feed_url = str(preferences.get(\'preferred_rss_feed\',\'\'))\n ...@@ -70,24 +75,27 @@ feed_url = str(preferences.get(\'preferred_rss_feed\',\'\'))\n
username = str(preferences.get(\'preferred_username\',\'\'))\n username = str(preferences.get(\'preferred_username\',\'\'))\n
password = str(preferences.get(\'preferred_password\',\'\'))\n password = str(preferences.get(\'preferred_password\',\'\'))\n
results = context.Base_getRssDataAsDict(context, url = feed_url, username = username, password = password)\n results = context.Base_getRssDataAsDict(context, url = feed_url, username = username, password = password)\n
readItemList = {}\n \n
md5_list = []\n md5_list = []\n
message_list = []\n message_list = []\n
items = results.get(\'items\',None)\n items = results.get(\'items\', [])\n
\n status = results.get(\'status\', 0)\n
rss_title = results.get(\'title\',\'No title for this feed\')\n
if items is not None:\n
rss_title = \'%s (%s)\' %(rss_title, len(items))\n
\n \n
rss_logo = results.get(\'logo\', None)\n context.REQUEST.set(\'rss_status\', status)\n
if rss_logo not in (\'\', None):\n if status < 0:\n
context.REQUEST.set(\'rss_logo\',rss_logo)\n # some error occured show message to user\n
\n context.REQUEST.set(\'rss_title\', context.Base_translateString(error_mapping_dict[status]))\n
context.REQUEST.set(\'rss_title\', rss_title)\n
context.REQUEST.set(\'rss_link\',results.get(\'link\',None))\n
\n
if items is None:\n
return []\n return []\n
else:\n
# all good\n
rss_title = results.get(\'title\',\'No title for this feed\')\n
rss_logo = results.get(\'logo\', None)\n
if items is not None:\n
rss_title = \'%s (%s)\' %(rss_title, len(items))\n
if rss_logo not in (\'\', None):\n
context.REQUEST.set(\'rss_logo\',rss_logo)\n
context.REQUEST.set(\'rss_link\',results.get(\'link\',None))\n
context.REQUEST.set(\'rss_gadget_title\', rss_title)\n
\n \n
for result in items:\n for result in items:\n
md5_list.append(result[\'md5\'])\n md5_list.append(result[\'md5\'])\n
...@@ -106,7 +114,9 @@ for result in items:\n ...@@ -106,7 +114,9 @@ for result in items:\n
context.REQUEST.set(\'rss_documents_count\', len(message_list))\n context.REQUEST.set(\'rss_documents_count\', len(message_list))\n
\n \n
return message_list\n return message_list\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_code</string> </key> <key> <string>_code</string> </key>
...@@ -152,6 +162,7 @@ return message_list\n ...@@ -152,6 +162,7 @@ return message_list\n
<string>context</string> <string>context</string>
<string>portal_selection</string> <string>portal_selection</string>
<string>selection</string> <string>selection</string>
<string>error_mapping_dict</string>
<string>box</string> <string>box</string>
<string>preferences</string> <string>preferences</string>
<string>str</string> <string>str</string>
...@@ -159,17 +170,17 @@ return message_list\n ...@@ -159,17 +170,17 @@ return message_list\n
<string>username</string> <string>username</string>
<string>password</string> <string>password</string>
<string>results</string> <string>results</string>
<string>readItemList</string>
<string>md5_list</string> <string>md5_list</string>
<string>message_list</string> <string>message_list</string>
<string>None</string>
<string>items</string> <string>items</string>
<string>status</string>
<string>_getitem_</string>
<string>rss_title</string> <string>rss_title</string>
<string>len</string> <string>None</string>
<string>rss_logo</string> <string>rss_logo</string>
<string>len</string>
<string>_getiter_</string> <string>_getiter_</string>
<string>result</string> <string>result</string>
<string>_getitem_</string>
<string>date</string> <string>date</string>
<string>message</string> <string>message</string>
</tuple> </tuple>
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
<list> <list>
<string>listbox</string> <string>listbox</string>
<string>logo</string> <string>logo</string>
<string>message</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
<string>search_columns</string> <string>search_columns</string>
<string>sort</string> <string>sort</string>
<string>sort_columns</string> <string>sort_columns</string>
<string>title</string>
<string>url_columns</string> <string>url_columns</string>
</list> </list>
</value> </value>
...@@ -112,12 +111,6 @@ ...@@ -112,12 +111,6 @@
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -170,7 +163,7 @@ ...@@ -170,7 +163,7 @@
<item> <item>
<key> <string>list_method</string> </key> <key> <string>list_method</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
...@@ -229,10 +222,6 @@ ...@@ -229,10 +222,6 @@
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value> <string>Rss reader</string> </value>
</item>
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
<value> <value>
...@@ -264,19 +253,6 @@ ...@@ -264,19 +253,6 @@
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: request.get(\'rss_title\', \'Rss Title Error\').encode(\'utf-8\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="Method" module="Products.Formulator.MethodField"/> <global name="Method" module="Products.Formulator.MethodField"/>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.JSON import dumps\n
\n
request = context.REQUEST\n
\n
# render real gadget content as HTML\n
html = context.ERP5Site_viewRssGadget()\n
box_relative_url = request.get(\'box_relative_url\', None)\n
box = context.restrictedTraverse(box_relative_url)\n
\n
box_dom_id = box.getRelativeUrl().replace(\'/\', \'_\')\n
gadget_title_dom_id = \'%s_gadget_title\' %box_dom_id\n
\n
# return some JavaScript which will update respective page\n
gadget_title = request.get(\'rss_gadget_title\', box.getSpecialiseValue().getTitle())\n
gadget_title = unicode(gadget_title).encode(\'utf-8\')[:40]\n
javascript = \'getElement("%s").innerHTML="%s";\' %(gadget_title_dom_id, gadget_title)\n
\n
request.RESPONSE.setHeader("Content-Type", "application/json;; charset=utf-8")\n
result = {"body": html,\n
"javascript": javascript}\n
return dumps(result)\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>Products.ERP5Type.JSON</string>
<string>dumps</string>
<string>_getattr_</string>
<string>context</string>
<string>request</string>
<string>html</string>
<string>None</string>
<string>box_relative_url</string>
<string>box</string>
<string>box_dom_id</string>
<string>gadget_title_dom_id</string>
<string>gadget_title</string>
<string>_getitem_</string>
<string>unicode</string>
<string>javascript</string>
<string>result</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_viewRssGadgetAsJSON</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -6,6 +6,14 @@ ...@@ -6,6 +6,14 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>enabled</string>
</list>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>my_listbox_selection_list_lines</string> </value> <value> <string>my_listbox_selection_list_lines</string> </value>
...@@ -63,6 +71,10 @@ ...@@ -63,6 +71,10 @@
<key> <string>values</string> </key> <key> <string>values</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_listbox_selection_list_lines</string> </value> <value> <string>my_listbox_selection_list_lines</string> </value>
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
box_dom_id python: \'%s\' %box.getRelativeUrl().replace(\'/\', \'_\');\n box_dom_id python: \'%s\' %box.getRelativeUrl().replace(\'/\', \'_\');\n
view_form_dom_id python: \'%s_content\' %box_dom_id;\n view_form_dom_id python: \'%s_content\' %box_dom_id;\n
edit_form_dom_id python: \'%s_edit_form\' %box_dom_id;\n edit_form_dom_id python: \'%s_edit_form\' %box_dom_id;\n
gadget_title_dom_id python: \'%s_gadget_title\' %box_dom_id;\n
gadget python: box.getSpecialiseValue();\n gadget python: box.getSpecialiseValue();\n
gadget_state python: gadget.getValidationState();\n gadget_state python: gadget.getValidationState();\n
dummy python: request.set(\'is_gadget_mode\', \'1\');\n dummy python: request.set(\'is_gadget_mode\', \'1\');\n
...@@ -105,7 +106,8 @@ ...@@ -105,7 +106,8 @@
title="Minimize"></a>\n title="Minimize"></a>\n
</tal:block>\n </tal:block>\n
<span class="gadget_title" \n <span class="gadget_title" \n
tal:content="python: here.Base_translateString(box.getProperty(\'preferred_header_title\', None) or gadget.getTitle())"/>\n tal:content="python: here.Base_translateString(box.getProperty(\'preferred_header_title\', None) or gadget.getTitle())"\n
tal:attributes="id gadget_title_dom_id"/>\n
</span>\n </span>\n
</h3>\n </h3>\n
\n \n
......
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
Render an entire Pad and needed JavaScript code.\n Render an entire Pad and needed JavaScript code.\n
Used to make instant Pad switching.\n Used to make instant Pad switching.\n
"""\n """\n
from Products.ERP5Type.JSON import dumps\n
\n
pad = context.restrictedTraverse(pad_relative_url)\n pad = context.restrictedTraverse(pad_relative_url)\n
\n \n
# render Pad\'s html\n # render Pad\'s html\n
...@@ -81,7 +83,7 @@ javascript = \'\'.join(javascript_list)\n ...@@ -81,7 +83,7 @@ javascript = \'\'.join(javascript_list)\n
# return JSON\n # return JSON\n
result = {\'body\': body,\n result = {\'body\': body,\n
\'javascript\': javascript}\n \'javascript\': javascript}\n
return result\n return dumps(result)\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
...@@ -120,6 +122,8 @@ return result\n ...@@ -120,6 +122,8 @@ return result\n
<tuple> <tuple>
<string>pad_relative_url</string> <string>pad_relative_url</string>
<string>mode</string> <string>mode</string>
<string>Products.ERP5Type.JSON</string>
<string>dumps</string>
<string>_getattr_</string> <string>_getattr_</string>
<string>context</string> <string>context</string>
<string>pad</string> <string>pad</string>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts91384188.54</string> </value> <value> <string>ts92251979.92</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -452,9 +452,16 @@ div.document-gadget-quick-preview a.document-link{\n ...@@ -452,9 +452,16 @@ div.document-gadget-quick-preview a.document-link{\n
show number of records or show \'No results\' as listbox title is used for this */\n show number of records or show \'No results\' as listbox title is used for this */\n
div.gadget-rss-reader table.listbox thead,\n div.gadget-rss-reader table.listbox thead,\n
div.gadget-rss-reader div.listbox-number-of-records,\n div.gadget-rss-reader div.listbox-number-of-records,\n
div.gadget-rss-reader table.listbox td.listbox-table-no-result-row{\n div.gadget-rss-reader table.listbox td.listbox-table-no-result-row,\n
div.gadget-rss-reader div.listbox-title{\n
display: none;\n display: none;\n
}\n }\n
div.gadget-rss-reader-message{\n
font-weight:bold;\n
}\n
div.gadget-rss-reader .listbox-head-content{\n
height:auto;\n
}\n
div.gadget-rss-reader .listbox-body,\n div.gadget-rss-reader .listbox-body,\n
div.gadget-rss-reader .listbox-head{\n div.gadget-rss-reader .listbox-head{\n
margin-left:4px;\n margin-left:4px;\n
...@@ -513,7 +520,7 @@ div.gadget-rss-reader .body {\n ...@@ -513,7 +520,7 @@ div.gadget-rss-reader .body {\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>8519</int> </value> <value> <int>8675</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts91990881.97</string> </value> <value> <string>ts92251348.76</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -107,8 +107,22 @@ function updater(url, box_relative_url, dom_id, \n ...@@ -107,8 +107,22 @@ function updater(url, box_relative_url, dom_id, \n
d = MochiKit.Async.doSimpleXMLHttpRequest(url, request_params);\n d = MochiKit.Async.doSimpleXMLHttpRequest(url, request_params);\n
d.addCallbacks(handleServerSuccess, handleServerError);\n d.addCallbacks(handleServerSuccess, handleServerError);\n
function handleServerSuccess(res){\n function handleServerSuccess(res){\n
getElement(dom_id).innerHTML = res.responseText;\n content_type = res.getResponseHeader(\'Content-Type\');\n
if(content_type.search("application/json")!=-1){\n
/* server returned JSON which may contain HTML & JavaScript */\n
text = res.responseText \n
json_dict = evalJSON(text);\n
html = json_dict[\'body\'];\n
eval(json_dict[\'javascript\']);\n
}\n
else{\n
/* server returned HTML */\n
html = res.responseText;\n
}\n
/* set HTML as returned from server */\n
getElement(dom_id).innerHTML = html;\n
getElement(dom_id).style.opacity = 1.0;};\n getElement(dom_id).style.opacity = 1.0;};\n
\n
function handleServerError(res){\n function handleServerError(res){\n
getElement(dom_id).innerHTML = \'Server side error.\';\n getElement(dom_id).innerHTML = \'Server side error.\';\n
getElement(dom_id).style.opacity = 1.0;};\n getElement(dom_id).style.opacity = 1.0;};\n
...@@ -507,7 +521,7 @@ MochiKit.DOM.addLoadEvent(initialize);\n ...@@ -507,7 +521,7 @@ MochiKit.DOM.addLoadEvent(initialize);\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>19090</int> </value> <value> <int>19554</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
648 650
\ No newline at end of file \ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment