Mercurial > libervia-web
comparison src/browser/libervia_main.py @ 716:3b91225b457a
server + browser side: blogging refactoring (draft), huge commit sorry:
/!\ everything is not working yet, group blog is not working for now
- adaptation to backend changes
- frontend commons part of blog have been moved to QuickFrontend
- (editors) button "WYSIWYG edition" renamed to "preview"
- (editors) Shift + [ENTER] is now used to send a text message, [ENTER] to finish a ligne normally
- (editors) fixed modifiers handling
- global simplification, resulting of the refactoring
- with backend refactoring, we are now using PEP again, XEP-0277 compatibility is restored \o/
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 16 Aug 2015 01:51:12 +0200 |
parents | 03e9fe91081c |
children | 5745b5e6586a |
comparison
equal
deleted
inserted
replaced
715:b2465423c76e | 716:3b91225b457a |
---|---|
36 from sat_frontends.tools import jid | 36 from sat_frontends.tools import jid |
37 from sat_frontends.tools import host_listener | 37 from sat_frontends.tools import host_listener |
38 from sat.core.i18n import _ | 38 from sat.core.i18n import _ |
39 | 39 |
40 from pyjamas.ui.RootPanel import RootPanel | 40 from pyjamas.ui.RootPanel import RootPanel |
41 from pyjamas.ui.HTML import HTML | 41 # from pyjamas.ui.HTML import HTML |
42 from pyjamas.ui.KeyboardListener import KEY_ESCAPE | 42 from pyjamas.ui.KeyboardListener import KEY_ESCAPE |
43 from pyjamas.Timer import Timer | 43 from pyjamas.Timer import Timer |
44 from pyjamas import Window, DOM | 44 from pyjamas import Window, DOM |
45 | 45 |
46 from sat_browser import json | 46 from sat_browser import json |
67 | 67 |
68 | 68 |
69 unicode = str # FIXME: pyjamas workaround | 69 unicode = str # FIXME: pyjamas workaround |
70 | 70 |
71 | 71 |
72 MAX_MBLOG_CACHE = 500 # Max microblog entries kept in memories | 72 # MAX_MBLOG_CACHE = 500 # Max microblog entries kept in memories # FIXME |
73 | 73 |
74 | 74 |
75 class SatWebFrontend(InputHistory, QuickApp): | 75 class SatWebFrontend(InputHistory, QuickApp): |
76 def onModuleLoad(self): | 76 def onModuleLoad(self): |
77 log.info("============ onModuleLoad ==============") | 77 log.info("============ onModuleLoad ==============") |
355 self.plug_profiles([C.PROF_KEY_NONE]) # XXX: None was used intitially, but pyjamas bug when using variable arguments and None is the only arg. | 355 self.plug_profiles([C.PROF_KEY_NONE]) # XXX: None was used intitially, but pyjamas bug when using variable arguments and None is the only arg. |
356 | 356 |
357 def profilePlugged(self, dummy): | 357 def profilePlugged(self, dummy): |
358 self._profile_plugged = True | 358 self._profile_plugged = True |
359 QuickApp.profilePlugged(self, C.PROF_KEY_NONE) | 359 QuickApp.profilePlugged(self, C.PROF_KEY_NONE) |
360 | 360 # XXX: as contact_list.update() is slow and it's called a lot of time |
361 microblog_widget = self.displayWidget(blog.MicroblogPanel, ()) | 361 # during profile plugging, we prevent it before it's plugged |
362 self.setSelected(microblog_widget) | 362 # and do all at once now |
363 contact_list = self.contact_list | |
364 contact_list.update() | |
365 | |
366 | |
367 blog_widget = self.displayWidget(blog.Blog, ()) | |
368 self.setSelected(blog_widget) | |
363 | 369 |
364 # we fill the panels already here | 370 # we fill the panels already here |
365 for wid in self.widgets.getWidgets(blog.MicroblogPanel): | 371 # for wid in self.widgets.getWidgets(blog.MicroblogPanel): |
366 if wid.accept_all(): | 372 # if wid.accept_all(): |
367 self.bridge.getMassiveMblogs('ALL', (), None, profile=C.PROF_KEY_NONE, callback=wid.massiveInsert) | 373 # self.bridge.getMassiveMblogs('ALL', (), None, profile=C.PROF_KEY_NONE, callback=wid.massiveInsert) |
368 else: | 374 # else: |
369 self.bridge.getMassiveMblogs('GROUP', list(wid.accepted_groups), None, profile=C.PROF_KEY_NONE, callback=wid.massiveInsert) | 375 # self.bridge.getMassiveMblogs('GROUP', list(wid.accepted_groups), None, profile=C.PROF_KEY_NONE, callback=wid.massiveInsert) |
370 | 376 |
371 #we ask for our own microblogs: | 377 #we ask for our own microblogs: |
372 self.loadOurMainEntries() | 378 # self.loadOurMainEntries() |
373 | 379 |
374 def gotDefaultMUC(default_muc): | 380 def gotDefaultMUC(default_muc): |
375 self.default_muc = default_muc | 381 self.default_muc = default_muc |
376 self.bridge.getDefaultMUC(profile=None, callback=gotDefaultMUC) | 382 self.bridge.getDefaultMUC(profile=None, callback=gotDefaultMUC) |
377 | 383 |
436 pass | 442 pass |
437 elif "xmlui" in data: | 443 elif "xmlui" in data: |
438 ui = xmlui.create(self, xml_data=data['xmlui']) | 444 ui = xmlui.create(self, xml_data=data['xmlui']) |
439 ui.show() | 445 ui.show() |
440 elif "public_blog" in data: | 446 elif "public_blog" in data: |
447 # FIXME: remove this, this is not generic ! | |
441 # TODO: use the bare instead of node when all blogs can be retrieved | 448 # TODO: use the bare instead of node when all blogs can be retrieved |
442 node = jid.JID(data['public_blog']).node | 449 node = jid.JID(data['public_blog']).node |
443 # FIXME: "/blog/{}" won't work with unicode nodes | 450 # FIXME: "/blog/{}" won't work with unicode nodes |
444 self.displayWidget(widget.WebWidget, "/blog/{}".format(node), show_url=False, new_tab=_(u"{}'s blog").format(unicode(node))) | 451 self.displayWidget(widget.WebWidget, "/blog/{}".format(node), show_url=False, new_tab=_(u"{}'s blog").format(unicode(node))) |
445 else: | 452 else: |
459 """ | 466 """ |
460 if data is None: | 467 if data is None: |
461 data = {} | 468 data = {} |
462 self.bridge.launchAction(callback_id, data, profile=profile, callback=self._actionCb, errback=self._actionEb) | 469 self.bridge.launchAction(callback_id, data, profile=profile, callback=self._actionCb, errback=self._actionEb) |
463 | 470 |
464 def _ownBlogsFills(self, mblogs, mblog_panel=None): | 471 # def _ownBlogsFills(self, mblogs, mblog_panel=None): |
465 """Put our own microblogs in cache, then fill the panels with them. | 472 # """Put our own microblogs in cache, then fill the panels with them. |
466 | 473 |
467 @param mblogs (dict): dictionary mapping a publisher JID to blogs data. | 474 # @param mblogs (dict): dictionary mapping a publisher JID to blogs data. |
468 @param mblog_panel (MicroblogPanel): the panel to fill, or all if None. | 475 # @param mblog_panel (MicroblogPanel): the panel to fill, or all if None. |
469 """ | 476 # """ |
470 cache = [] | 477 # cache = [] |
471 for publisher in mblogs: | 478 # for publisher in mblogs: |
472 for mblog in mblogs[publisher][0]: | 479 # for mblog in mblogs[publisher][0]: |
473 if 'content' not in mblog: | 480 # if 'content' not in mblog: |
474 log.warning(u"No content found in microblog [%s]" % mblog) | 481 # log.warning(u"No content found in microblog [%s]" % mblog) |
475 continue | 482 # continue |
476 if 'groups' in mblog: | 483 # if 'groups' in mblog: |
477 _groups = set(mblog['groups'].split() if mblog['groups'] else []) | 484 # _groups = set(mblog['groups'].split() if mblog['groups'] else []) |
478 else: | 485 # else: |
479 _groups = None | 486 # _groups = None |
480 mblog_entry = blog.MicroblogItem(mblog) | 487 # mblog_entry = blog.MicroblogItem(mblog) |
481 cache.append((_groups, mblog_entry)) | 488 # cache.append((_groups, mblog_entry)) |
482 | 489 |
483 self.mblog_cache.extend(cache) | 490 # self.mblog_cache.extend(cache) |
484 if len(self.mblog_cache) > MAX_MBLOG_CACHE: | 491 # if len(self.mblog_cache) > MAX_MBLOG_CACHE: |
485 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)] | 492 # del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)] |
486 | 493 |
487 widget_list = [mblog_panel] if mblog_panel else self.widgets.getWidgets(blog.MicroblogPanel) | 494 # widget_list = [mblog_panel] if mblog_panel else self.widgets.getWidgets(blog.MicroblogPanel) |
488 | 495 |
489 for wid in widget_list: | 496 # for wid in widget_list: |
490 self.fillMicroblogPanel(wid, cache) | 497 # self.fillMicroblogPanel(wid, cache) |
491 | 498 |
492 # FIXME | 499 # # FIXME |
493 | 500 |
494 if self.initialised: | 501 # if self.initialised: |
495 return | 502 # return |
496 self.initialised = True # initialisation phase is finished here | 503 # self.initialised = True # initialisation phase is finished here |
497 for event_data in self.init_cache: # so we have to send all the cached events | 504 # for event_data in self.init_cache: # so we have to send all the cached events |
498 self.personalEventHandler(*event_data) | 505 # self.personalEventHandler(*event_data) |
499 del self.init_cache | 506 # del self.init_cache |
500 | 507 |
501 def loadOurMainEntries(self, index=0, mblog_panel=None): | 508 # def loadOurMainEntries(self, index=0, mblog_panel=None): |
502 """Load a page of our own blogs from the cache or ask them to the | 509 # """Load a page of our own blogs from the cache or ask them to the |
503 backend. Then fill the panels with them. | 510 # backend. Then fill the panels with them. |
504 | 511 |
505 @param index (int): starting index of the blog page to retrieve. | 512 # @param index (int): starting index of the blog page to retrieve. |
506 @param mblog_panel (MicroblogPanel): the panel to fill, or all if None. | 513 # @param mblog_panel (MicroblogPanel): the panel to fill, or all if None. |
507 """ | 514 # """ |
508 delta = index - self.next_rsm_index | 515 # delta = index - self.next_rsm_index |
509 if delta < 0: | 516 # if delta < 0: |
510 assert mblog_panel is not None | 517 # assert mblog_panel is not None |
511 self.fillMicroblogPanel(mblog_panel, self.mblog_cache[index:index + C.RSM_MAX_ITEMS]) | 518 # self.fillMicroblogPanel(mblog_panel, self.mblog_cache[index:index + C.RSM_MAX_ITEMS]) |
512 return | 519 # return |
513 | 520 |
514 def cb(result): | 521 # def cb(result): |
515 self._ownBlogsFills(result, mblog_panel) | 522 # self._ownBlogsFills(result, mblog_panel) |
516 | 523 |
517 rsm = {'max_': str(delta + C.RSM_MAX_ITEMS), 'index': str(self.next_rsm_index)} | 524 # rsm = {'max_': str(delta + C.RSM_MAX_ITEMS), 'index': str(self.next_rsm_index)} |
518 self.bridge.getMassiveMblogs('JID', [unicode(self.whoami.bare)], rsm, callback=cb, profile=C.PROF_KEY_NONE) | 525 # self.bridge.getMassiveMblogs('JID', [unicode(self.whoami.bare)], rsm, callback=cb, profile=C.PROF_KEY_NONE) |
519 self.next_rsm_index = index + C.RSM_MAX_ITEMS | 526 # self.next_rsm_index = index + C.RSM_MAX_ITEMS |
520 | 527 |
521 ## Signals callbacks ## | 528 ## Signals callbacks ## |
522 | 529 |
523 def personalEventHandler(self, sender, event_type, data): | 530 # def personalEventHandler(self, sender, event_type, data): |
524 # FIXME: move some code from here to QuickApp | 531 # elif event_type == 'MICROBLOG_DELETE': |
525 if not self.initialised: | 532 # for wid in self.widgets.getWidgets(blog.MicroblogPanel): |
526 self.init_cache.append((sender, event_type, data)) | 533 # wid.removeEntry(data['type'], data['id']) |
527 return | 534 |
528 sender = jid.JID(sender).bare | 535 # if sender == self.whoami.bare and data['type'] == 'main_item': |
529 if event_type == "MICROBLOG": | 536 # for index in xrange(0, len(self.mblog_cache)): |
530 if not 'content' in data: | 537 # entry = self.mblog_cache[index] |
531 log.warning("No content found in microblog data") | 538 # if entry[1].id == data['id']: |
532 return | 539 # self.mblog_cache.remove(entry) |
533 if 'groups' in data: | 540 # break |
534 _groups = set(data['groups'].split() if data['groups'] else []) | 541 |
535 else: | 542 # def fillMicroblogPanel(self, mblog_panel, mblogs): |
536 _groups = None | 543 # """Fill a microblog panel with entries in cache |
537 mblog_entry = blog.MicroblogItem(data) | 544 |
538 | 545 # @param mblog_panel: MicroblogPanel instance |
539 for wid in self.widgets.getWidgets(blog.MicroblogPanel): | 546 # """ |
540 wid.addEntryIfAccepted(sender, _groups, mblog_entry) | 547 # #XXX: only our own entries are cached |
541 | 548 # for cache_entry in mblogs: |
542 if sender == self.whoami.bare: | 549 # _groups, mblog_entry = cache_entry |
543 found = False | 550 # mblog_panel.addEntryIfAccepted(self.whoami.bare, *cache_entry) |
544 for index in xrange(0, len(self.mblog_cache)): | 551 |
545 entry = self.mblog_cache[index] | 552 # def getEntityMBlog(self, entity): |
546 if entry[1].id == mblog_entry.id: | 553 # # FIXME: call this after a contact has been added to roster |
547 # replace existing entry | 554 # log.info(u"geting mblog for entity [%s]" % (entity,)) |
548 self.mblog_cache.remove(entry) | 555 # for lib_wid in self.libervia_widgets: |
549 self.mblog_cache.insert(index, (_groups, mblog_entry)) | 556 # if isinstance(lib_wid, blog.MicroblogPanel): |
550 found = True | 557 # if lib_wid.isJidAccepted(entity): |
551 break | 558 # self.bridge.call('getMassiveMblogs', lib_wid.massiveInsert, 'JID', [unicode(entity)]) |
552 if not found: | |
553 self.mblog_cache.append((_groups, mblog_entry)) | |
554 if len(self.mblog_cache) > MAX_MBLOG_CACHE: | |
555 del self.mblog_cache[0:len(self.mblog_cache - MAX_MBLOG_CACHE)] | |
556 elif event_type == 'MICROBLOG_DELETE': | |
557 for wid in self.widgets.getWidgets(blog.MicroblogPanel): | |
558 wid.removeEntry(data['type'], data['id']) | |
559 | |
560 if sender == self.whoami.bare and data['type'] == 'main_item': | |
561 for index in xrange(0, len(self.mblog_cache)): | |
562 entry = self.mblog_cache[index] | |
563 if entry[1].id == data['id']: | |
564 self.mblog_cache.remove(entry) | |
565 break | |
566 | |
567 def fillMicroblogPanel(self, mblog_panel, mblogs): | |
568 """Fill a microblog panel with entries in cache | |
569 | |
570 @param mblog_panel: MicroblogPanel instance | |
571 """ | |
572 #XXX: only our own entries are cached | |
573 for cache_entry in mblogs: | |
574 _groups, mblog_entry = cache_entry | |
575 mblog_panel.addEntryIfAccepted(self.whoami.bare, *cache_entry) | |
576 | |
577 def getEntityMBlog(self, entity): | |
578 # FIXME: call this after a contact has been added to roster | |
579 log.info(u"geting mblog for entity [%s]" % (entity,)) | |
580 for lib_wid in self.libervia_widgets: | |
581 if isinstance(lib_wid, blog.MicroblogPanel): | |
582 if lib_wid.isJidAccepted(entity): | |
583 self.bridge.call('getMassiveMblogs', lib_wid.massiveInsert, 'JID', [unicode(entity)]) | |
584 | 559 |
585 def displayWidget(self, class_, target, dropped=False, new_tab=None, *args, **kwargs): | 560 def displayWidget(self, class_, target, dropped=False, new_tab=None, *args, **kwargs): |
586 """Get or create a LiberviaWidget and select it. When the user dropped | 561 """Get or create a LiberviaWidget and select it. When the user dropped |
587 something, a new widget is always created, otherwise we look for an | 562 something, a new widget is always created, otherwise we look for an |
588 existing widget and re-use it if it's in the current tab. | 563 existing widget and re-use it if it's in the current tab. |