comparison browser_side/panels.py @ 365:a74a2dfbe4f5

browser_side: groupblog: handle main items with no associated comments node + do not mix up attributes names between the item own service/node and the comments service/node
author souliane <souliane@mailoo.org>
date Thu, 20 Feb 2014 19:33:31 +0100
parents 019e1e706e74
children 39ae5bf92786
comparison
equal deleted inserted replaced
364:4cf735b40304 365:a74a2dfbe4f5
364 self.title_xhtml = data.get('title_xhtml', '') 364 self.title_xhtml = data.get('title_xhtml', '')
365 self.content = data.get('content', '') 365 self.content = data.get('content', '')
366 self.content_xhtml = data.get('content_xhtml', '') 366 self.content_xhtml = data.get('content_xhtml', '')
367 self.author = data['author'] 367 self.author = data['author']
368 self.updated = float(data.get('updated', 0)) # XXX: int doesn't work here 368 self.updated = float(data.get('updated', 0)) # XXX: int doesn't work here
369 try: 369 self.published = float(data.get('published', self.updated)) # XXX: int doesn't work here
370 self.published = float(data['published']) # XXX: int doesn't work here 370 self.service = data.get('service', '')
371 except KeyError: 371 self.node = data.get('node', '')
372 self.published = self.updated
373 self.comments = data.get('comments', False) 372 self.comments = data.get('comments', False)
374 if self.empty and self.type == 'main_item': 373 self.comments_service = data.get('comments_service', '')
375 self.service = self.node = None 374 self.comments_node = data.get('comments_node', '')
376 self.hash = (self.service, self.node)
377 else:
378 try:
379 self.service = data['comments_service'] if self.comments else data['service']
380 self.node = data['comments_node'] if self.comments else data['node']
381 self.hash = (self.service, self.node)
382 except KeyError:
383 print "Warning: can't manage item [%s] some keys are missing in microblog data (%s)" % (self.id, str(data))
384 self.comments = False
385 375
386 376
387 class MicroblogEntry(SimplePanel, ClickHandler, FocusHandler, KeyboardHandler): 377 class MicroblogEntry(SimplePanel, ClickHandler, FocusHandler, KeyboardHandler):
388 378
389 def __init__(self, blog_panel, data): 379 def __init__(self, blog_panel, data):
391 @param blog_panel: the parent panel 381 @param blog_panel: the parent panel
392 @param data: dict containing the blog item data, or a MicroblogItem instance. 382 @param data: dict containing the blog item data, or a MicroblogItem instance.
393 """ 383 """
394 self._base_item = data if isinstance(data, MicroblogItem) else MicroblogItem(data) 384 self._base_item = data if isinstance(data, MicroblogItem) else MicroblogItem(data)
395 for attr in ['id', 'type', 'empty', 'title', 'title_xhtml', 'content', 'content_xhtml', 385 for attr in ['id', 'type', 'empty', 'title', 'title_xhtml', 'content', 'content_xhtml',
396 'author', 'updated', 'published', 'comments', 'service', 'node', 'hash']: 386 'author', 'updated', 'published', 'comments', 'service', 'node',
387 'comments_service', 'comments_node']:
397 getter = lambda attr: lambda inst: getattr(inst._base_item, attr) 388 getter = lambda attr: lambda inst: getattr(inst._base_item, attr)
398 setattr(MicroblogEntry, attr, property(getter(attr))) 389 setattr(MicroblogEntry, attr, property(getter(attr)))
399 390
400 SimplePanel.__init__(self) 391 SimplePanel.__init__(self)
401 self._blog_panel = blog_panel 392 self._blog_panel = blog_panel
422 413
423 self.add(self.panel) 414 self.add(self.panel)
424 ClickHandler.__init__(self) 415 ClickHandler.__init__(self)
425 self.addClickListener(self) 416 self.addClickListener(self)
426 417
427 self.pub_data = (self.hash[0], self.hash[1], self.id) 418 self.__pub_data = (self.service, self.node, self.id)
428 self.__setContent() 419 self.__setContent()
429 420
430 def __setContent(self): 421 def __setContent(self):
431 """Actually set the entry content (header, icons, bubble...)""" 422 """Actually set the entry content (header, icons, bubble...)"""
432 self.delete_label = self.update_label = self.comment_label = None 423 self.delete_label = self.update_label = self.comment_label = None
499 if self.type == 'main_item': 490 if self.type == 'main_item':
500 self._blog_panel.host.bridge.call('sendMblog', None, None, self._blog_panel.accepted_groups, content['text'], extra) 491 self._blog_panel.host.bridge.call('sendMblog', None, None, self._blog_panel.accepted_groups, content['text'], extra)
501 else: 492 else:
502 self._blog_panel.host.bridge.call('sendMblogComment', None, self._parent_entry.comments, content['text'], extra) 493 self._blog_panel.host.bridge.call('sendMblogComment', None, self._parent_entry.comments, content['text'], extra)
503 else: 494 else:
504 self._blog_panel.host.bridge.call('updateMblog', None, self.pub_data, self.comments, content['text'], extra) 495 self._blog_panel.host.bridge.call('updateMblog', None, self.__pub_data, self.comments, content['text'], extra)
505 return True 496 return True
506 497
507 def __afterEditCb(self, content): 498 def __afterEditCb(self, content):
508 """Remove the entry if it was an empty one (used for creating a new blog post). 499 """Remove the entry if it was an empty one (used for creating a new blog post).
509 Data for the actual new blog post will be received from the bridge""" 500 Data for the actual new blog post will be received from the bridge"""
541 def _delete(self, empty=False): 532 def _delete(self, empty=False):
542 """Ask confirmation for deletion. 533 """Ask confirmation for deletion.
543 @return: False if the deletion has been cancelled.""" 534 @return: False if the deletion has been cancelled."""
544 def confirm_cb(answer): 535 def confirm_cb(answer):
545 if answer: 536 if answer:
546 self._blog_panel.host.bridge.call('deleteMblog', None, self.pub_data, self.comments) 537 self._blog_panel.host.bridge.call('deleteMblog', None, self.__pub_data, self.comments)
547 else: # restore the text if it has been emptied during the edition 538 else: # restore the text if it has been emptied during the edition
548 self.bubble.setContent(self.bubble._original_content) 539 self.bubble.setContent(self.bubble._original_content)
549 540
550 if self.empty: 541 if self.empty:
551 text = _("New ") + (_("message") if self.comments else _("comment")) + _(" without body has been cancelled.") 542 text = _("New ") + (_("message") if self.comments else _("comment")) + _(" without body has been cancelled.")
565 return 556 return
566 data = {'id': str(time()), 557 data = {'id': str(time()),
567 'new': True, 558 'new': True,
568 'type': 'comment', 559 'type': 'comment',
569 'author': self._blog_panel.host.whoami.bare, 560 'author': self._blog_panel.host.whoami.bare,
570 'service': self.service, 561 'service': self.comments_service,
571 'node': self.node 562 'node': self.comments_node
572 } 563 }
573 entry = self._blog_panel.addEntry(data) 564 entry = self._blog_panel.addEntry(data)
565 if entry is None:
566 print "The entry of id %s can not be commented" % self.id
567 return
574 entry._parent_entry = self 568 entry._parent_entry = self
575 self._current_comment = entry 569 self._current_comment = entry
576 entry.bubble.edit(True) 570 entry.bubble.edit(True)
577 571
578 572
676 return ("GROUP", self.warning_msg_group % self._accepted_groups[0]) 670 return ("GROUP", self.warning_msg_group % self._accepted_groups[0])
677 671
678 def onTextEntered(self, text): 672 def onTextEntered(self, text):
679 if self.selected_entry: 673 if self.selected_entry:
680 # we are entering a comment 674 # we are entering a comment
681 comments_node = self.selected_entry.comments 675 comments_url = self.selected_entry.comments
682 if not comments_node: 676 if not comments_url:
683 raise Exception("ERROR: comments node is empty") 677 raise Exception("ERROR: the comments URL is empty")
684 target = ("COMMENT", comments_node) 678 target = ("COMMENT", comments_url)
685 elif not self._accepted_groups: 679 elif not self._accepted_groups:
686 # we are entering a public microblog 680 # we are entering a public microblog
687 target = ("PUBLIC", None) 681 target = ("PUBLIC", None)
688 else: 682 else:
689 # we are entering a microblog restricted to a group 683 # we are entering a microblog restricted to a group
752 @param data: dict containing the item data 746 @param data: dict containing the item data
753 @return: the added entry, or None 747 @return: the added entry, or None
754 """ 748 """
755 _entry = MicroblogEntry(self, data) 749 _entry = MicroblogEntry(self, data)
756 if _entry.type == "comment": 750 if _entry.type == "comment":
757 if not _entry.hash in self.comments: 751 comments_hash = (_entry.service, _entry.node)
752 if not comments_hash in self.comments:
758 # The comments node is not known in this panel 753 # The comments node is not known in this panel
759 return None 754 return None
760 parent = self.comments[_entry.hash] 755 parent = self.comments[comments_hash]
761 parent_idx = self.vpanel.getWidgetIndex(parent) 756 parent_idx = self.vpanel.getWidgetIndex(parent)
762 # we find or create the panel where the comment must be inserted 757 # we find or create the panel where the comment must be inserted
763 try: 758 try:
764 sub_panel = self.vpanel.getWidget(parent_idx + 1) 759 sub_panel = self.vpanel.getWidget(parent_idx + 1)
765 except IndexError: 760 except IndexError:
769 sub_panel.setStyleName('microblogPanel') 764 sub_panel.setStyleName('microblogPanel')
770 sub_panel.addStyleName('subPanel') 765 sub_panel.addStyleName('subPanel')
771 self.vpanel.insert(sub_panel, parent_idx + 1) 766 self.vpanel.insert(sub_panel, parent_idx + 1)
772 for idx in xrange(0, len(sub_panel.getChildren())): 767 for idx in xrange(0, len(sub_panel.getChildren())):
773 comment = sub_panel.getIndexedChild(idx) 768 comment = sub_panel.getIndexedChild(idx)
774 if comment.pub_data[2] == _entry.id: 769 if comment.id == _entry.id:
775 # update an existing comment 770 # update an existing comment
776 sub_panel.remove(comment) 771 sub_panel.remove(comment)
777 sub_panel.insert(_entry, idx) 772 sub_panel.insert(_entry, idx)
778 return _entry 773 return _entry
779 # we want comments to be inserted in chronological order 774 # we want comments to be inserted in chronological order
787 else: # new entry 782 else: # new entry
788 self._chronoInsert(self.vpanel, _entry) 783 self._chronoInsert(self.vpanel, _entry)
789 self.entries[_entry.id] = _entry 784 self.entries[_entry.id] = _entry
790 785
791 if _entry.comments: 786 if _entry.comments:
792 # entry has comments, we keep the comment node as a reference 787 # entry has comments, we keep the comments service/node as a reference
793 self.comments[_entry.hash] = _entry 788 comments_hash = (_entry.comments_service, _entry.comments_node)
794 self.host.bridge.call('getMblogComments', self.mblogsInsert, _entry.service, _entry.node) 789 self.comments[comments_hash] = _entry
790 self.host.bridge.call('getMblogComments', self.mblogsInsert, _entry.comments_service, _entry.comments_node)
795 791
796 return _entry 792 return _entry
797 793
798 def removeEntry(self, type_, id_): 794 def removeEntry(self, type_, id_):
799 """Remove an entry from the panel 795 """Remove an entry from the panel
800 @param type_: entry type ('main_item' or 'comment') 796 @param type_: entry type ('main_item' or 'comment')
801 @param id_: entry id 797 @param id_: entry id
802 """ 798 """
803 for child in self.vpanel.getChildren(): 799 for child in self.vpanel.getChildren():
804 if isinstance(child, MicroblogEntry) and type_ == 'main_item': 800 if isinstance(child, MicroblogEntry) and type_ == 'main_item':
805 if child.pub_data[2] == id_: 801 if child.id == id_:
806 main_idx = self.vpanel.getWidgetIndex(child) 802 main_idx = self.vpanel.getWidgetIndex(child)
807 try: 803 try:
808 sub_panel = self.vpanel.getWidget(main_idx + 1) 804 sub_panel = self.vpanel.getWidget(main_idx + 1)
809 if isinstance(sub_panel, VerticalPanel): 805 if isinstance(sub_panel, VerticalPanel):
810 sub_panel.removeFromParent() 806 sub_panel.removeFromParent()
813 child.removeFromParent() 809 child.removeFromParent()
814 self.selected_entry = None 810 self.selected_entry = None
815 break 811 break
816 elif isinstance(child, VerticalPanel) and type_ == 'comment': 812 elif isinstance(child, VerticalPanel) and type_ == 'comment':
817 for comment in child.getChildren(): 813 for comment in child.getChildren():
818 if comment.pub_data[2] == id_: 814 if comment.id == id_:
819 comment.removeFromParent() 815 comment.removeFromParent()
820 self.selected_entry = None 816 self.selected_entry = None
821 break 817 break
822 818
823 def setSelectedEntry(self, entry): 819 def setSelectedEntry(self, entry):