Exemplo n.º 1
0
    def __init__(self, track):
        hippo.CanvasWindow.__init__(self, gtk.WINDOW_POPUP)
        DataBoundItem.__init__(self, track)

        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xffff,0xffff,0xffff))

        root = CanvasHBox(border=1, border_color=0x000000ff)
        self.set_root(root)
        
        box = CanvasHBox(border=5)
        root.append(box)
        
        image = CanvasMugshotURLImage(box_width=track.imageWidth, box_height=track.imageHeight)
        image.set_url(track.imageUrl)
        box.append(image)
        
        details = CanvasVBox(border_left=6)
        box.append(details)

        artist_text = hippo.CanvasText(text=track.artist,
                                       font="13px",
                                       xalign=hippo.ALIGNMENT_START)
        details.append(artist_text)

        title_text = hippo.CanvasText(text=track.name,
                                      font="13px",
                                      xalign=hippo.ALIGNMENT_START)
        details.append(title_text)
Exemplo n.º 2
0
    def __init__(self, app=None, **kwargs):
        PhotoContentItem.__init__(self, border_right=6, **kwargs)
        self.__app = None 

        self.__description_mode = False
            
        self._logger = logging.getLogger('bigboard.AppDisplay')                
                
        self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30)
        self.set_photo(self.__photo)
        self.__box = CanvasVBox(spacing=2, border_right=4)
        sub_kwargs = {}
        if kwargs.has_key('color'): 
            sub_kwargs['color'] = kwargs['color']

        self.__title = ActionLink(font="14px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END, **sub_kwargs)
        self.__title.connect("activated", lambda t: self.emit("title-clicked"))
        self.__subtitle = hippo.CanvasText(font="10px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)

        attrs = pango.AttrList()
        attrs.insert(pango.AttrForeground(0x6666, 0x6666, 0x6666, 0, 0xFFFF))
        self.__subtitle.set_property("attributes", attrs)        
        self.__box.append(self.__title)
        self.__box.append(self.__subtitle)        
        self.set_child(self.__box)

        self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs)
        self.__box.append(self.__description)
        
        if app:
            self.set_app(app)
Exemplo n.º 3
0
    def __init__(self, profiles, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        kwargs['border'] = 1
        kwargs['border-color'] = 0x0000000ff
        hippo.CanvasBox.__init__(self, **kwargs)

        self.__profiles = profiles
        self.__entity = None

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)
        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__online = hippo.CanvasText(text='Offline')
        self.append(self.__online)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=2)
        self.append(self.__ribbon_bar)
Exemplo n.º 4
0
 def __init__(self, acct):
     super(ExternalAccountIcon, self).__init__(box_width=16, box_height=16)
     self.__acct = None
     self.__img = CanvasMugshotURLImage()
     self.append(self.__img)
     self.connect("activated", lambda s2: self.__launch_browser())
     self.set_clickable(True)
     self.set_acct(acct)
Exemplo n.º 5
0
class ExternalAccountIcon(CanvasHBox):
    def __init__(self, acct):
        super(ExternalAccountIcon, self).__init__(box_width=16, box_height=16)
        self.__acct = None
        self.__img = CanvasMugshotURLImage()
        self.append(self.__img)
        self.connect("activated", lambda s2: self.__launch_browser())
        self.set_clickable(True)
        self.set_acct(acct)
        
    def set_acct(self, acct):
        if self.__acct:
            self.__acct.disconnect(self.__sync)
        self.__acct = acct
        self.__acct.connect(self.__sync)
        self.__sync()
         
    def __sync(self):
        self.__img.set_url(self.__acct.iconUrl)
        
    def __launch_browser(self):
        libbig.show_url(self.__acct.link)
Exemplo n.º 6
0
    def __init__(self, app_location, app=None, **kwargs):
        if app_location == AppLocation.STOCK:
            kwargs['enable_theme'] = True
        PhotoContentItem.__init__(self, border_right=6, **kwargs)
        self.__app = None 
 
        self.__description_mode = False
            
        self._logger = logging.getLogger('bigboard.AppDisplay')                
                
        self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30)
        self.set_photo(self.__photo)
        self.__box = CanvasVBox(spacing=2, border_right=4)
        sub_kwargs = {}
        if kwargs.has_key('color'): 
            sub_kwargs['color'] = kwargs['color']

        title_kwargs = dict(sub_kwargs)
        title_kwargs.update({'font': '14px',
                             'xalign': hippo.ALIGNMENT_START, 
                             'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END
                           })
        if app_location == AppLocation.STOCK:
            self.__title = ThemedLink(**title_kwargs)
        else:
            self.__title = ActionLink(**title_kwargs)
        self.__title.connect("activated", lambda t: self.emit("title-clicked"))
        subtitle_kwargs = {'font': '10px',
                           'xalign': hippo.ALIGNMENT_START, 
                           'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END                           
                           }
        if app_location == AppLocation.STOCK:
            self.__subtitle = ThemedText(theme_hints=['subforeground'], **subtitle_kwargs)
        else:
            self.__subtitle = hippo.CanvasText(**subtitle_kwargs)
      
        self.__box.append(self.__title)
        self.__box.append(self.__subtitle)        
        self.set_child(self.__box)

        self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs)
        self.__box.append(self.__description)
        
        self.__photo.set_clickable(True)
        self.__box.set_clickable(True)
        self.__app_location = app_location         
        if app:
            self.set_app(app)
Exemplo n.º 7
0
    def __init__(self, **kwargs):
        PhotoContentItem.__init__(self, **kwargs)
        
        self.__entity = None

        self.__photo = CanvasMugshotURLImage(scale_width=30,
                                            scale_height=30,
                                            border=1,
                                            border_color=0x000000ff)

        self.set_photo(self.__photo)

        self.__name = hippo.CanvasText(xalign=hippo.ALIGNMENT_FILL, yalign=hippo.ALIGNMENT_START,
                                      size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.set_child(self.__name)

        self.connect('button-press-event', self.__handle_button_press)
        self.connect('button-release-event', self.__handle_button_release)
        self.__pressed = False
Exemplo n.º 8
0
class PhotosStock(AbstractMugshotStock):
    SLIDE_TIMEOUT_SEC = 1 * 60  # 1 minute

    MAX_PREV_IMAGES = 5

    """Cycles between photos from friends in Mugshot network"""

    def __init__(self, *args, **kwargs):
        super(PhotosStock, self).__init__(*args, **kwargs)

        self.__images = None
        self.__images_reverse = []
        self.__images_forward = []
        self.__current_image = None

        self.__box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL, spacing=4)

        self.__successive_load_failures = 0

        self.__photosize = 120

        self.__idle_display_id = 0
        self.__text = hippo.CanvasText(text="No thumbnails found")

        self.__displaymode = "uninitialized"  # "none", "photo"

        self.__displaybox = CanvasVBox(spacing=4)

        self.__photo_header = CanvasHBox(spacing=4)
        self.__favicon = CanvasMugshotURLImage()
        self.__title = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__title.connect("button-press-event", lambda photo, event: self.__visit_photo())
        self.__photo_header.append(self.__favicon)
        self.__photo_header.append(self.__title)

        self.__displaybox.append(self.__photo_header)

        self.__photobox = CanvasHBox(spacing=6)
        self.__photo = TransitioningURLImage(dimension=self.__photosize)
        self.__photo.connect("loaded", lambda photo, loaded: self.__on_image_load(loaded))
        self.__photo.connect("button-press-event", lambda photo, event: self.__visit_photo())
        self.__metabox = CanvasVBox()
        self.__metabox.append(hippo.CanvasText(text="from"))
        self.__fromphoto = CanvasMugshotURLImage()
        self.__fromphoto.set_clickable(True)
        self.__fromphoto.connect("button-press-event", lambda photo, event: self.__visit_person())
        self.__metabox.append(self.__fromphoto)
        self.__fromname = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__fromname.connect("button-press-event", lambda photo, event: self.__visit_person())
        self.__metabox.append(self.__fromname)
        self.__photobox.append(self.__photo)
        self.__photobox.append(self.__metabox)

        self.__displaybox.append(self.__photobox)

        self.__controlbox = CanvasHBox()
        prev_link = ActionLink(text=u"\u00ab Prev", xalign=hippo.ALIGNMENT_START)
        prev_link.connect("button-press-event", lambda b, e: self.__do_prev())
        self.__controlbox.append(prev_link)
        next_link = ActionLink(text=u"Next \u00bb", xalign=hippo.ALIGNMENT_END)
        next_link.connect("button-press-event", lambda b, e: self.__do_next())
        self.__controlbox.append(next_link, hippo.PACK_EXPAND)
        self.__displaybox.append(self.__controlbox)

        self.__person_accts_len = {}  # <Person,int>

        self.__bearbox = CanvasVBox()
        self.__bearphoto = TransitioningURLImage(dimension=self.SIZE_BEAR_CONTENT_PX - 6)
        self.__bearphoto.connect("button-press-event", lambda photo, event: self.__visit_photo())
        self.__bearbox.append(self.__bearphoto)

    def _on_ready(self):
        if self._model.self_resource != None:
            query = self._model.query_resource(
                self._model.self_resource, "contacts user [+;lovedAccounts [+;thumbnails +]]"
            )
            query.add_handler(self.__on_got_self)
            query.execute()

    def __on_got_self(self, myself):
        self.__reset()

    def get_authed_content(self, size):
        return size == self.SIZE_BULL and self.__box or self.__bearbox

    def __visit_photo(self):
        _logger.debug("visiting photo for %s", self.__current_image)
        if not self.__current_image:
            return
        libbig.show_url(self.__current_image[2].get_href())

    def __visit_person(self):
        _logger.debug("visiting person for %s", self.__current_image)
        if not self.__current_image:
            return
        libbig.show_url(urlparse.urljoin(globals.get_baseurl(), self.__current_image[0].get_home_url()))

    def __thumbnails_generator(self):
        """The infinite photos function.  Cool."""
        while True:
            found_one = False
            # Iterate through all thumbnails for all "loved accounts" for all contacts.
            # We don't handle change notification ... if something changes we'll pick
            # it up next time around. Note the use of temporary copies of lists to avoid
            # problems if a list is mutated by a change notification while we are iterating it.
            if self._model.self_resource:
                for contact in list(getattr(self._model.self_resource, "contacts", [])):
                    user = getattr(contact, "user", None)
                    if user != None:
                        lovedAccounts = getattr(user, "lovedAccounts", None)
                        if lovedAccounts:
                            for externalAccount in lovedAccounts:
                                thumbnails = getattr(externalAccount, "thumbnails", None)
                                if thumbnails:
                                    for thumbnail in thumbnails:
                                        yield (user, externalAccount, thumbnail)

            # If we didn't find any photos, we go into a "no photos" state; we'll keep on trying
            # to restart the iterator in the timeout, so when things appear we'll display them
            if not found_one:
                return

    def __next_image(self):
        if self.__current_image:
            self.__images_reverse.append(self.__current_image)
            if len(self.__images_reverse) > self.MAX_PREV_IMAGES:
                self.__images_reverse.pop(0)
        if self.__images_forward:
            return self.__images_forward.pop()
        else:
            return self.__images.next()

    def __prev_image(self):
        if self.__current_image:
            self.__images_forward.append(self.__current_image)
        return self.__images_reverse.pop()

    def __set_image(self, imageinfo):
        self.__current_image = imageinfo
        (user, account, thumbnail) = imageinfo

        _logger.debug("starting load of url %s" % (thumbnail.src,))
        self.__photo.set_url(thumbnail.src)
        self.__bearphoto.set_url(thumbnail.src)

    def __on_image_load(self, success):
        if self.__current_image is None:
            _logger.debug("image load complete, but no current image")
            return
        if not success:
            self.__successive_load_failures = max(self.__successive_load_failures + 1, 17)
            _logger.debug("image load failed, queueing skip to next")
            gobject.timeout_add(8000 + (2 ** self.__successive_load_failures) * 1000, self.__do_next)
        else:
            self.__successive_load_failures = 0

        _logger.debug("image load success, syncing metadata")
        (user, account, thumbnail) = self.__current_image

        self.__favicon.set_url(account.iconUrl)

        title = getattr(thumbnail, "title", None)
        if not title:
            title = "(untitled)"
        self.__title.set_property("text", title)

        self.__fromname.set_property("text", user.name)
        self.__fromphoto.set_url(user.photoUrl)

    def __idle_display_image(self):
        _logger.debug("in idle, doing next image")
        self.__idle_display_id = 0
        self.__do_next()
        return False

    def __do_direction(self, is_next):
        _logger.debug("skipping to %s" % (is_next and "next" or "prev",))
        try:
            self.__set_image(is_next and self.__next_image() or self.__prev_image())
            if self.__displaymode == "text":
                self.__box.remove(self.__text)
            if self.__displaymode != "photo":
                self.__box.append(self.__displaybox)
            self.__displaymode = "photo"
        except StopIteration:
            _logger.debug("caught StopIteration, displaying no photos text")
            if self.__displaymode == "photo":
                self.__box.remove(self.__displaybox)
            if self.__displaymode != "text":
                self.__box.append(self.__text)
            self.__displaymode = "text"
        if self.__idle_display_id > 0:
            gobject.source_remove(self.__idle_display_id)
        self.__idle_display_id = gobject.timeout_add(self.SLIDE_TIMEOUT_SEC * 1000, self.__idle_display_image)

    def __do_next(self):
        self.__do_direction(True)

    def __do_prev(self):
        self.__do_direction(False)

    def __reset(self):
        _logger.debug("resetting")
        self.__images = self.__thumbnails_generator()
        self.__images_reverse = []
        self.__box.remove_all()
        self.__displaymode = "uninitialized"
        self.__do_next()
Exemplo n.º 9
0
    def __init__(self, person, themed=False, **kwargs):
        PhotoContentItem.__init__(self, **kwargs)
        self.person = person
        
        self.__themed = themed
        if themed:
            self.set_themed()
        
        model = DataModel(bigboard.globals.server_name)

        self.set_clickable(True)
        
        self.__photo = CanvasMugshotURLImage(scale_width=45,
                                            scale_height=45,
                                            border=1,
                                            border_color=0x000000ff)

        self.set_photo(self.__photo)

        self.__details_box = CanvasVBox()
        self.set_child(self.__details_box)

        nameklass = themed and ThemedText or hippo.CanvasText
        self.__name = nameklass(xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START,
                                size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__details_box.append(self.__name)

        self.__presence_box = CanvasHBox(spacing=4)
        self.__details_box.append(self.__presence_box)
        
        self.__statuses = []
        self.__status_box = CanvasHBox()
        self.__details_box.append(self.__status_box)

        self.connect('button-press-event', self.__handle_button_press)
        self.connect('button-release-event', self.__handle_button_release)
        self.__pressed = False

        self.__aim_icon = None
        self.__xmpp_icon = None

        self.__current_track = None
        self.__current_track_timeout = None

        if self.person.is_contact:
            try:
                user = self.person.resource.user
            except AttributeError:
                user = None

            if user:
                query = model.query_resource(user, "currentTrack +;currentTrackPlayTime")
                query.execute()

                user.connect(self.__update_current_track, 'currentTrack')
                user.connect(self.__update_current_track, 'currentTrackPlayTime')
                self.__update_current_track(user)
            
        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        
        self.person.connect('aim-buddy-changed', self.__update_aim_buddy)
        self.person.connect('xmpp-buddy-changed', self.__update_xmpp_buddy)
        
        self.__update(self.person)
        self.__update_aim_buddy(self.person)
        self.__update_xmpp_buddy(self.person)
Exemplo n.º 10
0
class PersonItem(PhotoContentItem):
    def __init__(self, person, themed=False, **kwargs):
        PhotoContentItem.__init__(self, **kwargs)
        self.person = person
        
        self.__themed = themed
        if themed:
            self.set_themed()
        
        model = DataModel(bigboard.globals.server_name)

        self.set_clickable(True)
        
        self.__photo = CanvasMugshotURLImage(scale_width=45,
                                            scale_height=45,
                                            border=1,
                                            border_color=0x000000ff)

        self.set_photo(self.__photo)

        self.__details_box = CanvasVBox()
        self.set_child(self.__details_box)

        nameklass = themed and ThemedText or hippo.CanvasText
        self.__name = nameklass(xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START,
                                size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__details_box.append(self.__name)

        self.__presence_box = CanvasHBox(spacing=4)
        self.__details_box.append(self.__presence_box)
        
        self.__statuses = []
        self.__status_box = CanvasHBox()
        self.__details_box.append(self.__status_box)

        self.connect('button-press-event', self.__handle_button_press)
        self.connect('button-release-event', self.__handle_button_release)
        self.__pressed = False

        self.__aim_icon = None
        self.__xmpp_icon = None

        self.__current_track = None
        self.__current_track_timeout = None

        if self.person.is_contact:
            try:
                user = self.person.resource.user
            except AttributeError:
                user = None

            if user:
                query = model.query_resource(user, "currentTrack +;currentTrackPlayTime")
                query.execute()

                user.connect(self.__update_current_track, 'currentTrack')
                user.connect(self.__update_current_track, 'currentTrackPlayTime')
                self.__update_current_track(user)
            
        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        
        self.person.connect('aim-buddy-changed', self.__update_aim_buddy)
        self.person.connect('xmpp-buddy-changed', self.__update_xmpp_buddy)
        
        self.__update(self.person)
        self.__update_aim_buddy(self.person)
        self.__update_xmpp_buddy(self.person)

    def __update_color(self):
        if self.__pressed:
            self.set_property('background-color', 0x00000088)
        else:
            self.sync_prelight_color()

    def __handle_button_press(self, self2, event):
        if event.button != 1 or event.count != 1:
            return False
        
        self.__pressed = True
        self.__update_color()

        return False

    def __handle_button_release(self, self2, event):
        if event.button != 1:
            return False

        self.__pressed = False
        self.__update_color()

        return False

    def get_person(self):
        return self.person

    def set_size(self, size):
        if size == bigboard.stock.SIZE_BULL:
            self.set_child_visible(self.__details_box, True)
            self.__photo.set_property('xalign', hippo.ALIGNMENT_START)
            self.__photo.set_property('yalign', hippo.ALIGNMENT_START)
        else:
            self.set_child_visible(self.__details_box, False)
            self.__photo.set_property('xalign', hippo.ALIGNMENT_CENTER)
            self.__photo.set_property('yalign', hippo.ALIGNMENT_CENTER)

    def __update(self, person):
        self.__name.set_property("text", self.person.display_name) #+ " " + str(self.person._debug_rank))
        self.__photo.set_url(self.person.icon_url)

    def __reset_im_status(self):
        buddies = self.person.aim_buddies + self.person.xmpp_buddies
        if len(buddies) > 0:
            sm = StatusMessage(themed=self.__themed)
            sm.set_buddies(buddies)
            self.__set_status(STATUS_IM, sm)

    def __update_aim_buddy(self, person):
        if person.aim_buddy:
            if not self.__aim_icon:
                self.__aim_icon = AimIcon(person.aim_buddy, theme_hints=(not self.__themed and 'notheme' or []))
                self.__presence_box.append(self.__aim_icon)
        else:
            if self.__aim_icon:
                self.__aim_icon.destroy()
                self.__aim_icon = None        

        self.__reset_im_status()

    def __update_xmpp_buddy(self, person):
        if person.xmpp_buddy:
            if not self.__xmpp_icon:
                self.__xmpp_icon = XMPPIcon(person.xmpp_buddy, theme_hints=(not self.__themed and 'notheme' or []))
                self.__presence_box.append(self.__xmpp_icon)
        else:
            if self.__xmpp_icon:
                self.__xmpp_icon.destroy()
                self.__xmpp_icon = None

        self.__reset_im_status()

    def __timeout_track(self):
        self.__current_track_timeout = None
        self.__update_current_track(self.person.resource.user)
        return False

    def __update_current_track(self, user):
        try:
            current_track = user.currentTrack
            current_track_play_time = user.currentTrackPlayTime / 1000.
        except AttributeError:
            current_track = None
            current_track_play_time = -1

        _logger.debug("current track %s" % str(current_track))

        # current_track_play_time < 0, current_track != None might indicate stale
        # current_track data
        if current_track_play_time < 0:
            current_track = None

        if current_track != None:
            now = time.time()
            if current_track.duration < 0:
                endTime = current_track_play_time + 30 * 60   # Half hour
            else:
                endTime = current_track_play_time + current_track.duration / 1000. # msec => sec

            if now >= endTime:
               current_track = None

        if current_track != self.__current_track:
            self.__current_track = current_track
            
            if self.__current_track_timeout:
                gobject.source_remove(self.__current_track_timeout)

            if current_track != None:
                # We give 30 seconds of lee-way, so that the track is pretty reliably really stopped
                self.__current_track_timeout = gobject.timeout_add(int((endTime + 30 - now) * 1000), self.__timeout_track)

            if current_track != None:
                self.__set_status(STATUS_MUSIC, TrackItem(current_track))
            else:
                self.__set_status(STATUS_MUSIC, None)
            
    def __set_status(self, type, contents):
        if len(self.__statuses) > 0:
            old_contents = self.__statuses[0][1]
        else:
            old_contents = None
        
        for i in range(0,len(self.__statuses)):
            (i_type,i_contents) = self.__statuses[i]
            if i_type == type:
                i_contents.destroy()
                del self.__statuses[i]
                if i == 0:
                    old_contents = None
                break

        if old_contents != None:
            old_contents.set_visible(False)
        
        if contents != None:
            self.__statuses.insert(0, (type, contents))
            self.__status_box.append(contents)
            
        if len(self.__statuses) > 0:
            new_contents = self.__statuses[0][1]
            new_contents.set_visible(True)

    def get_screen_coords(self):
        return self.get_context().translate_to_screen(self)
Exemplo n.º 11
0
    def __init__(self, person, themed=False, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        hippo.CanvasBox.__init__(self, **kwargs)
        self.person = person

        self.__themed = themed
        if themed:
            self.__header = Header(topborder=False)
        else:
            self.__header = hippo.CanvasGradient(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                 start_color=0xf2f2f2f2,
                                                 end_color=0xc8c8c8ff)            

        self.append(self.__header)
        
        textklass = themed and ThemedText or hippo.CanvasText
        linkklass = themed and ThemedLink or ActionLink

        name_vbox = hippo.CanvasBox(padding=6)
        self.__name = textklass(font="22px")
        name_vbox.append(self.__name)
        rename_link = linkklass(text='rename', font="10px", xalign=hippo.ALIGNMENT_END)
        name_vbox.append(rename_link)

        rename_link.connect('activated', self.__on_rename_activated)

        self.__header.append(name_vbox)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                mugshot_link = linkklass(text="Mugshot", padding=6)
                self.__header.append(mugshot_link, flags=hippo.PACK_END)
                mugshot_link.connect("activated", self.__on_activate_web)

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                self.__photo.set_clickable(True)
                self.__photo.connect("activated", self.__on_activate_web)

        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__contact_status_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                    spacing=4, border=4)
        self.append(self.__contact_status_box)

        if person.is_contact:
            self.__add_link = None
            self.__remove_link = linkklass()
            self.__remove_link.connect('activated', self.__remove_from_network_clicked)
            self.append(self.__remove_link)
        else:
            self.__remove_link = None
            self.__add_link = linkklass(text=('Add %s to network' % self.person.display_name))
            self.__add_link.connect('activated', self.__add_to_network_clicked)
            self.append(self.__add_link)
        
#        self.__online = hippo.CanvasText(text='Offline')
#        self.append(self.__online)

        separator = hippo.CanvasBox(box_height=1, background_color=0xAAAAAAFF)
        self.append(separator)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=4)
        self.append(self.__ribbon_bar)

        self.__link_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                          spacing=2, border=4)
        self.append(self.__link_box)
        
        self.__local_files_link = None

        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        self.person.connect('aim-changed', self.__update)
        self.person.connect('local-buddy-changed', self.__update_local_buddy)
        self.person.connect('xmpp-changed', self.__update)
        if person.is_contact:
            self.person.resource.connect(lambda *args: self.__update(self.person), 'emails')
            self.person.resource.connect(self.__update_contact_status, "status")
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                user.connect(self.__update_loved_accounts, "lovedAccounts")
        
        query = DataModel(bigboard.globals.server_name).query_resource(self.person.resource, "lovedAccounts +")
        query.add_handler(self.__update_loved_accounts)
        query.execute()

        self.__update(self.person)
        self.__update_local_buddy(self.person)
        
        if self.person.is_contact:
            self.__update_contact_status(self.person.resource)

            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                self.__update_loved_accounts(user)
Exemplo n.º 12
0
class ProfileItem(hippo.CanvasBox):
    __gsignals__ = {
        "close": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (bool,))
       }
        
    def __init__(self, person, themed=False, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        hippo.CanvasBox.__init__(self, **kwargs)
        self.person = person

        self.__themed = themed
        if themed:
            self.__header = Header(topborder=False)
        else:
            self.__header = hippo.CanvasGradient(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                 start_color=0xf2f2f2f2,
                                                 end_color=0xc8c8c8ff)            

        self.append(self.__header)
        
        textklass = themed and ThemedText or hippo.CanvasText
        linkklass = themed and ThemedLink or ActionLink

        name_vbox = hippo.CanvasBox(padding=6)
        self.__name = textklass(font="22px")
        name_vbox.append(self.__name)
        rename_link = linkklass(text='rename', font="10px", xalign=hippo.ALIGNMENT_END)
        name_vbox.append(rename_link)

        rename_link.connect('activated', self.__on_rename_activated)

        self.__header.append(name_vbox)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                mugshot_link = linkklass(text="Mugshot", padding=6)
                self.__header.append(mugshot_link, flags=hippo.PACK_END)
                mugshot_link.connect("activated", self.__on_activate_web)

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                self.__photo.set_clickable(True)
                self.__photo.connect("activated", self.__on_activate_web)

        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__contact_status_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                    spacing=4, border=4)
        self.append(self.__contact_status_box)

        if person.is_contact:
            self.__add_link = None
            self.__remove_link = linkklass()
            self.__remove_link.connect('activated', self.__remove_from_network_clicked)
            self.append(self.__remove_link)
        else:
            self.__remove_link = None
            self.__add_link = linkklass(text=('Add %s to network' % self.person.display_name))
            self.__add_link.connect('activated', self.__add_to_network_clicked)
            self.append(self.__add_link)
        
#        self.__online = hippo.CanvasText(text='Offline')
#        self.append(self.__online)

        separator = hippo.CanvasBox(box_height=1, background_color=0xAAAAAAFF)
        self.append(separator)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=4)
        self.append(self.__ribbon_bar)

        self.__link_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                          spacing=2, border=4)
        self.append(self.__link_box)
        
        self.__local_files_link = None

        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        self.person.connect('aim-changed', self.__update)
        self.person.connect('local-buddy-changed', self.__update_local_buddy)
        self.person.connect('xmpp-changed', self.__update)
        if person.is_contact:
            self.person.resource.connect(lambda *args: self.__update(self.person), 'emails')
            self.person.resource.connect(self.__update_contact_status, "status")
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                user.connect(self.__update_loved_accounts, "lovedAccounts")
        
        query = DataModel(bigboard.globals.server_name).query_resource(self.person.resource, "lovedAccounts +")
        query.add_handler(self.__update_loved_accounts)
        query.execute()

        self.__update(self.person)
        self.__update_local_buddy(self.person)
        
        if self.person.is_contact:
            self.__update_contact_status(self.person.resource)

            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                self.__update_loved_accounts(user)

    def __add_status_link(self, text, current_status, new_status):
        textklass = self.__themed and ThemedText or hippo.CanvasText        
        linkklass = self.__themed and ThemedLink or ActionLink        
        if current_status == new_status:
            link = textklass(text=text)
        else:
            def set_new_status(object):
                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "setContactStatus"),
                                     contact=self.person.resource,
                                     status=new_status)
                query.execute()
        
            link = linkklass(text=text)
            link.connect("activated", set_new_status)
        
        self.__contact_status_box.append(link)

    def __remove_from_network_clicked(self, link):

        dialog = gtk.MessageDialog(type=gtk.MESSAGE_QUESTION)
        dialog.set_markup("<b>Remove %s from your network?</b>" % (self.person.display_name))
        dialog.format_secondary_text("This will delete %s's contact information and remove %s from your sidebar" % (self.person.display_name, self.person.display_name))
        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Remove", gtk.RESPONSE_ACCEPT)

        def remove_from_network_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("removing from network")

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "deleteContact"),
                                     contact=person.resource)
                query.execute()

            else:
                _logger.debug("not removing from network")

        dialog.connect("response", lambda dialog, response_id: remove_from_network_response(dialog, response_id, self.person))                

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()

    def __on_rename_activated(self, link):
        dialog = gtk.Dialog(title="Rename a contact")
        
        entry = gtk.Entry()
        entry.set_text(self.person.display_name)
        entry.set_activates_default(True)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Name:'), False, False)
        hbox.pack_end(entry, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Rename", gtk.RESPONSE_ACCEPT)
        dialog.set_default_response(gtk.RESPONSE_ACCEPT)

        def rename_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("renaming this person")

                name = entry.get_text()

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "setContactName"),
                                     contact=person.resource, name=name)
                query.execute()

            else:
                _logger.debug("not renaming")

        dialog.connect("response", lambda dialog, response_id: rename_response(dialog, response_id, self.person))                

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()

    def __create_contact(self, addressType, address):
        _logger.debug("creating contact %s %s" % (addressType, address))
        
        model = globals.get_data_model()
        query = model.update(("http://mugshot.org/p/contacts", "createContact"),
                             addressType=addressType,
                             address=address)
        query.execute()

    def __create_user_contact(self, user_resource):
        _logger.debug("creating contact %s" % (str(user_resource)))
        
        model = globals.get_data_model()
        query = model.update(("http://mugshot.org/p/contacts", "createUserContact"),
                             user=user_resource);
        query.execute()

    def __add_to_network_clicked(self, link):
        if self.person.aim:
            self.__create_contact('aim', self.person.aim)
        elif self.person.xmpp:
            self.__create_contact('xmpp', self.person.xmpp)
        elif self.person.local_buddy:
            self.__create_user_contact(self.person.local_buddy.user)

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

    def __update_contact_status(self, person):
        self.__contact_status_box.remove_all()
        try:
            status = self.person.resource.status
        except AttributeError:
            status = 0

        if status == 0:
            status = 3 

        textklass = self.__themed and ThemedText or hippo.CanvasText
        self.__contact_status_box.append(textklass(text="In sidebar: "))
        
        self.__add_status_link("Top", status, 4)
        self.__add_status_link("Middle", status, 3)
        self.__add_status_link("Bottom", status, 2)

    def __update_loved_accounts(self, person):
        try:
            accounts = self.person.resource.lovedAccounts
        except AttributeError:
            accounts = []
        
        self.__ribbon_bar.clear()
        for a in accounts:
            icon = ExternalAccountIcon(a)
            self.__ribbon_bar.append(icon)

    def __update_local_buddy(self, person):
        if self.__local_files_link:
            self.__local_files_link.destroy()
            self.__local_files_link = None

        try:
            buddy = person.local_buddy
        except AttributeError:
            return

        if buddy != None:
            self.__local_files_link = LocalFilesLink(buddy)
            self.__link_box.append(self.__local_files_link)

    def __update(self, person):
        textklass = self.__themed and ThemedText or hippo.CanvasText
        linkklass = self.__themed and ThemedLink or ActionLink
                
        self.__name.set_property('text', self.person.display_name)
        self.__photo.set_url(self.person.icon_url)

        self.__address_box.remove_all()

        if self.__remove_link:
            self.__remove_link.set_property('text', 
                                            "Remove %s from network" % self.person.display_name)

        emails = None
        if person.is_contact:
            try:
                emails = self.person.resource.emails
            except AttributeError:
                pass
         
        if emails != None and len(emails) > 0:
            email = linkklass(text=emails[0], xalign=hippo.ALIGNMENT_START)
            email.connect('activated', self.__on_activate_email)
            self.__address_box.append(email)

        if person.aim != None:
            aim = linkklass(text=person.aim, xalign=hippo.ALIGNMENT_START)
            aim.connect('activated', self.__on_activate_aim)
            self.__address_box.append(aim)

        if person.xmpp != None:
            xmpp = linkklass(text=person.aim, xalign=hippo.ALIGNMENT_START)
            xmpp.connect('activated', self.__on_activate_xmpp)
            self.__address_box.append(xmpp)

        add = linkklass(text='add address', xalign=hippo.ALIGNMENT_END, font_scale=0.8)
        add.connect('activated', self.__on_activate_add_address)
        self.__address_box.append(add)

    def __on_activate_web(self, canvas_item):
        self.emit("close", True)
        libbig.show_url(self.person.resource.user.homeUrl)

    def __on_activate_email(self, canvas_item):
        self.emit("close", True)
        # email should probably cgi.escape except it breaks if you escape the @
        os.spawnlp(os.P_NOWAIT, 'gnome-open', 'gnome-open', 'mailto:' + self.person.resource.email)

    def __on_activate_aim(self, canvas_item):
        self.emit("close", True)
        _open_aim(self.person.aim)
        
    def __on_activate_xmpp(self, canvas_item):
        self.emit("close", True)
        _open_xmpp(self.person.xmpp)

    def __on_activate_add_address(self, canvas_item):
        dialog = gtk.Dialog(title=("Add an address for %s" % self.person.display_name))
        
        entry = gtk.Entry()
        entry.set_activates_default(True)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Address:'), False, False)
        hbox.pack_end(entry, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        type_combo = gtk.combo_box_new_text()
        type_combo.append_text('AIM')
        type_combo.append_text('Email')
        type_combo.append_text('GTalk/XMPP')
        type_combo.set_active(0)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Type:'), False, False)
        hbox.pack_end(type_combo, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Add", gtk.RESPONSE_ACCEPT)
        dialog.set_default_response(gtk.RESPONSE_ACCEPT)


        def combo_get_address_type(combo):
            visible_type = type_combo.get_active_text()
            addressType = None
            if visible_type == 'Email':
                addressType = 'email'
            elif visible_type == 'AIM':
                addressType = 'aim'
            elif visible_type == 'GTalk/XMPP':
                addressType = xmpp
            else:
                _logger.warn('Bug: unknown combox box text for address type')
                if '@' in entry.get_text():
                    addressType = 'email'
                else:
                    addressType = 'aim'

            return addressType

        def address_entry_changed(entry):
            address = entry.get_text()
            type = combo_get_address_type(type_combo)
            
            if '@' in address and type == 'aim':
                type_combo.set_active(1) ## set to email if an @ is typed
            elif '@' not in address and type == 'email':
                type_combo.set_active(0) ## set to AIM if no @ is found

            ## remember that @ can mean either email or xmpp

        entry.connect('changed', address_entry_changed)

        def add_address_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("adding address for this person")

                address = entry.get_text()
                addressType = combo_get_address_type(type_combo)

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "addContactAddress"),
                                     contact=person.resource, addressType=addressType, address=address)
                query.execute()

            else:
                _logger.debug("not adding_address")

        dialog.connect("response", lambda dialog, response_id: add_address_response(dialog, response_id, self.person))

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()
Exemplo n.º 13
0
class AppDisplay(PhotoContentItem):
    __gsignals__ = {
        "title-clicked" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }
    def __init__(self, app=None, **kwargs):
        PhotoContentItem.__init__(self, border_right=6, **kwargs)
        self.__app = None 

        self.__description_mode = False
            
        self._logger = logging.getLogger('bigboard.AppDisplay')                
                
        self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30)
        self.set_photo(self.__photo)
        self.__box = CanvasVBox(spacing=2, border_right=4)
        sub_kwargs = {}
        if kwargs.has_key('color'): 
            sub_kwargs['color'] = kwargs['color']

        self.__title = ActionLink(font="14px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END, **sub_kwargs)
        self.__title.connect("activated", lambda t: self.emit("title-clicked"))
        self.__subtitle = hippo.CanvasText(font="10px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)

        attrs = pango.AttrList()
        attrs.insert(pango.AttrForeground(0x6666, 0x6666, 0x6666, 0, 0xFFFF))
        self.__subtitle.set_property("attributes", attrs)        
        self.__box.append(self.__title)
        self.__box.append(self.__subtitle)        
        self.set_child(self.__box)

        self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs)
        self.__box.append(self.__description)
        
        if app:
            self.set_app(app)

    def set_description_mode(self, mode):
        self.__description_mode = mode
        self.__app_display_sync()
        
    def get_app(self):
        return self.__app
        
    def set_app(self, app):
        self.__app = app
        self.__app.connect("changed", lambda app: self.__app_display_sync())
        self.__app_display_sync()
    
    def __get_name(self):
        if self.__app is None:
            return "unknown"
        return self.__app.get_name()
    
    def __str__(self):
        return '<AppDisplay name="%s">' % (self.__get_name())
        
    # override
    def do_prelight(self):
        return self.__app.is_installed()
    
    def __app_display_sync(self):
        if not self.__app:
            return

        self.__box.set_child_visible(self.__subtitle, not self.__description_mode)
        self.__box.set_child_visible(self.__description, self.__description_mode)

        self.__photo.set_clickable(self.__app.is_installed())
        self.__box.set_clickable(self.__app.is_installed())  
        self.__title.set_property("text", self.__app.get_name())
        self.__subtitle.set_property("text", self.__app.get_generic_name() or self.__app.get_tooltip() or self.__app.get_comment())

        self.__description.set_property("text", self.__app.get_description())

        if self.__app.get_mugshot_app():
            self.__photo.set_url(self.__app.get_mugshot_app().get_icon_url())
        else:
            pixbuf = self.__app.get_local_pixbuf()
            if pixbuf:
                self.__photo.set_property("image", hippo.cairo_surface_from_gdk_pixbuf(pixbuf))
        
    def launch(self):
        self._logger.debug("launching app %s", self)
        self.__app.launch()
Exemplo n.º 14
0
class AppDisplay(PhotoContentItem):
    __gsignals__ = {
        "title-clicked" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }
    def __init__(self, app_location, app=None, **kwargs):
        if app_location == AppLocation.STOCK:
            kwargs['enable_theme'] = True
        PhotoContentItem.__init__(self, border_right=6, **kwargs)
        self.__app = None 
 
        self.__description_mode = False
            
        self._logger = logging.getLogger('bigboard.AppDisplay')                
                
        self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30)
        self.set_photo(self.__photo)
        self.__box = CanvasVBox(spacing=2, border_right=4)
        sub_kwargs = {}
        if kwargs.has_key('color'): 
            sub_kwargs['color'] = kwargs['color']

        title_kwargs = dict(sub_kwargs)
        title_kwargs.update({'font': '14px',
                             'xalign': hippo.ALIGNMENT_START, 
                             'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END
                           })
        if app_location == AppLocation.STOCK:
            self.__title = ThemedLink(**title_kwargs)
        else:
            self.__title = ActionLink(**title_kwargs)
        self.__title.connect("activated", lambda t: self.emit("title-clicked"))
        subtitle_kwargs = {'font': '10px',
                           'xalign': hippo.ALIGNMENT_START, 
                           'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END                           
                           }
        if app_location == AppLocation.STOCK:
            self.__subtitle = ThemedText(theme_hints=['subforeground'], **subtitle_kwargs)
        else:
            self.__subtitle = hippo.CanvasText(**subtitle_kwargs)
      
        self.__box.append(self.__title)
        self.__box.append(self.__subtitle)        
        self.set_child(self.__box)

        self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs)
        self.__box.append(self.__description)
        
        self.__photo.set_clickable(True)
        self.__box.set_clickable(True)
        self.__app_location = app_location         
        if app:
            self.set_app(app)

    def set_description_mode(self, mode):
        self.__description_mode = mode
        self.__app_display_sync()
        
    def get_app(self):
        return self.__app
        
    def set_app(self, app):
        self.__app = app
        self.__app_display_sync()
    
    def __get_name(self):
        if self.__app is None:
            return "unknown"
        return self.__app.get_name()
    
    def __str__(self):
        return '<AppDisplay name="%s">' % (self.__get_name())
    
    def __app_display_sync(self):
        if not self.__app:
            return

        self.__box.set_child_visible(self.__subtitle, not self.__description_mode)
        self.__box.set_child_visible(self.__description, self.__description_mode)
 
        self.__title.set_property("text", self.__app.get_name())
        if self.__app.is_installed() or self.__app_location == AppLocation.DESCRIPTION_HEADER:
            self.__subtitle.set_property("text", self.__app.get_generic_name() or self.__app.get_tooltip() or self.__app.get_comment())
        ## for now, install won't work if not connected
        elif self.__app_location == AppLocation.STOCK and globals.get_data_model().ready and globals.get_data_model().global_resource.online:
            self.__subtitle.set_property('text', "(Click to Install)")
        else:
            self.__subtitle.set_property('text', "(Not Installed)")
 
        self.__description.set_property("text", self.__app.get_description())

        if self.__app.get_icon_url():
            self.__photo.set_url(self.__app.get_icon_url())
        else:
            pixbuf = self.__app.get_local_pixbuf()
            if pixbuf:
                self.__photo.set_property("image", hippo.cairo_surface_from_gdk_pixbuf(pixbuf))
        
    def launch(self):
        self._logger.debug("launching app %s", self)
        self.__app.launch()
Exemplo n.º 15
0
class ProfileItem(hippo.CanvasBox):
    def __init__(self, profiles, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        kwargs['border'] = 1
        kwargs['border-color'] = 0x0000000ff
        hippo.CanvasBox.__init__(self, **kwargs)

        self.__profiles = profiles
        self.__entity = None

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)
        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__online = hippo.CanvasText(text='Offline')
        self.append(self.__online)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=2)
        self.append(self.__ribbon_bar)

    def set_entity(self, entity):
        if self.__entity == entity:
            return
        self.__entity = entity    

        if self.__entity:

            if self.__entity.get_photo_url():
                self.__photo.set_url(self.__entity.get_photo_url())

            self.__profiles.fetch_profile(self.__entity.get_guid(), self.__on_profile_fetched)

    def __on_activate_email(self, canvas_item, profile):
        # email should probably cgi.escape except it breaks if you escape the @
        os.spawnlp(os.P_NOWAIT, 'gnome-open', 'gnome-open', 'mailto:' + profile.get_email())

    def __on_activate_aim(self, canvas_item, profile):
        os.spawnlp(os.P_NOWAIT, 'gnome-open', 'gnome-open', 'aim:GoIM?screenname=' + cgi.escape(profile.get_aim()))

    def __on_profile_fetched(self, profile):
        if not profile:
            print "failed to fetch profile"
            return
        
        #print str(profile)

        if profile.get_online():
            self.__online.set_property('text', 'Online')
        else:
            self.__online.set_property('text', 'Offline')

        self.__ribbon_bar.remove_all()
        for a in profile.get_accounts():
            badge = CanvasMugshotURLImageButton(scale_width=16, scale_height=16)
            badge.set_url(a['icon'])
            badge.set_property('tooltip', a['linkText']) # doesn't work...
            self.__ribbon_bar.append(badge)

        self.__address_box.remove_all()
        if profile.get_email():
            email = hippo.CanvasLink(text=profile.get_email(), xalign=hippo.ALIGNMENT_START)
            email.connect('activated', self.__on_activate_email, profile)
            self.__address_box.append(email)

        if profile.get_aim():
            aim = hippo.CanvasLink(text=profile.get_aim(), xalign=hippo.ALIGNMENT_START)
            aim.connect('activated', self.__on_activate_aim, profile)
            self.__address_box.append(aim)
Exemplo n.º 16
0
class PhotosStock(AbstractMugshotStock):
    SLIDE_TIMEOUT_SEC = 1 * 60  # 1 minute
    
    MAX_PREV_IMAGES = 5

    """Cycles between photos from friends in Mugshot network"""
    def __init__(self, *args, **kwargs):
        super(PhotosStock,self).__init__(*args, **kwargs)

        self.__images = None
        self.__images_reverse = []
        self.__images_forward = []
        self.__current_image = None

        self.__box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL, spacing=4)

        self.__successive_load_failures = 0
        
        self.__photosize = 120

        self.__idle_display_id = 0
        self.__text = hippo.CanvasText(text="No thumbnails found")

        self.__displaymode = "uninitialized" # "none", "photo"
        
        self.__displaybox = CanvasVBox(spacing=4)
        
        self.__photo_header = CanvasHBox(spacing=4)
        self.__favicon = CanvasMugshotURLImage()
        self.__title = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__title.connect("button-press-event", lambda photo, event: self.__visit_photo())        
        self.__photo_header.append(self.__favicon)
        self.__photo_header.append(self.__title)
        
        self.__displaybox.append(self.__photo_header)
        
        self.__photobox = CanvasHBox(spacing=6)
        self.__photo = TransitioningURLImage(self._logger, dimension=self.__photosize)
        self.__photo.connect("loaded", lambda photo, loaded: self.__on_image_load(loaded))
        self.__photo.connect("button-press-event", lambda photo, event: self.__visit_photo())
        self.__metabox = CanvasVBox()
        self.__metabox.append(hippo.CanvasText(text="from"))
        self.__fromphoto = CanvasMugshotURLImage()
        self.__fromphoto.set_clickable(True)
        self.__fromphoto.connect("button-press-event", lambda photo, event: self.__visit_person())           
        self.__metabox.append(self.__fromphoto)
        self.__fromname = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__fromname.connect("button-press-event", lambda photo, event: self.__visit_person())              
        self.__metabox.append(self.__fromname)
        self.__photobox.append(self.__photo)
        self.__photobox.append(self.__metabox)

        self.__displaybox.append(self.__photobox)        

        self.__controlbox = CanvasHBox()
        prev_link = ActionLink(text=u"\u00ab Prev", xalign=hippo.ALIGNMENT_START)
        prev_link.connect("button-press-event", lambda b,e: self.__do_prev())
        self.__controlbox.append(prev_link)
        next_link = ActionLink(text=u"Next \u00bb", xalign=hippo.ALIGNMENT_END)
        next_link.connect("button-press-event", lambda b,e: self.__do_next())
        self.__controlbox.append(next_link, hippo.PACK_EXPAND)
        self.__displaybox.append(self.__controlbox)        
        
        self.__person_accts_len = {} # <Person,int>
        
        self.__bearbox = CanvasVBox()
        self.__bearphoto = TransitioningURLImage(self._logger, dimension=self.SIZE_BEAR_CONTENT_PX-6)
        self.__bearphoto.connect("button-press-event", lambda photo, event: self.__visit_photo())        
        self.__bearbox.append(self.__bearphoto)
        
        self._mugshot.connect("network-changed", lambda mugshot: self.__handle_network_change())  
        
    def _on_mugshot_ready(self):
        super(PhotosStock, self)._on_mugshot_ready()       
        self._mugshot.get_network()
        
    def get_authed_content(self, size):
        return size == self.SIZE_BULL and self.__box or self.__bearbox
    
    def __visit_photo(self):
        self._logger.debug("visiting photo for %s", self.__current_image)
        if not self.__current_image:
            return
        libbig.show_url(self.__current_image[2].get_href())
        
    def __visit_person(self):
        self._logger.debug("visiting person for %s", self.__current_image)
        if not self.__current_image:
            return
        libbig.show_url(mugshot.get_mugshot().get_baseurl() + self.__current_image[0].get_home_url())    

    def __thumbnails_generator(self):
        """The infinite photos function.  Cool."""
        found_one = False
        while True:
            for entity in self._mugshot.get_network():
                accts = entity.get_external_accounts()
                if not accts:
                    continue
                for acct in accts:
                    if acct.get_thumbnails():
                        for thumbnail in acct.get_thumbnails():
                            found_one = True
                            yield (entity, acct, thumbnail)
            if not found_one:
                return
            
    def __next_image(self):
        if self.__current_image:
            self.__images_reverse.append(self.__current_image)
            if len(self.__images_reverse) > self.MAX_PREV_IMAGES:
                self.__images_reverse.pop(0)
        if self.__images_forward:
            return self.__images_forward.pop()
        else:
            return self.__images.next()

    def __prev_image(self):
        if self.__current_image:
            self.__images_forward.append(self.__current_image)
        return self.__images_reverse.pop()
    
    def __set_image(self, imageinfo):
        self.__current_image = imageinfo
        (entity, acct, thumbnail) = imageinfo
        
        self._logger.debug("starting load of url %s" % (thumbnail.get_src(),))
        self.__photo.set_url(thumbnail.get_src())
        self.__bearphoto.set_url(thumbnail.get_src())
        
    def __on_image_load(self, success):
        if self.__current_image is None:
            self._logger.debug("image load complete, but no current image")       
            return
        if not success:
            self.__successive_load_failures = max(self.__successive_load_failures+1, 17)
            self._logger.debug("image load failed, queueing skip to next")                   
            gobject.timeout_add(8000 + (2 ** self.__successive_load_failures) * 1000, self.__do_next)
        else:
            self.__successive_load_failures = 0
        
        self._logger.debug("image load success, syncing metadata")          
        (entity, acct, thumbnail) = self.__current_image

        self.__favicon.set_url(acct.get_icon())
        self.__title.set_property("text", thumbnail.get_title() or "(untitled)")
     
        self.__fromname.set_property("text", entity.get_name())
        self.__fromphoto.set_url(entity.get_photo_url())        

    def __idle_display_image(self):
        self._logger.debug("in idle, doing next image")          
        self.__idle_display_id = 0
        self.__do_next()
        return False
    
    def __handle_person_change(self, person):
        need_reset = False
        
        accts = person.get_external_accounts()
        if not self.__person_accts_len.has_key(person):
            need_reset = True
            self.__person_accts_len[person] = -1
        elif accts and self.__person_accts_len[person] != len(accts):
            self.__person_accts_len[person] = len(accts)
            need_reset = True
    
        if need_reset:
            self.__reset()
    
    def __handle_network_change(self):
        self._logger.debug("handling network change")
        for person in self._mugshot.get_network():
            if not self.__person_accts_len.has_key(person):
                person.connect("changed", self.__handle_person_change)
            accts = person.get_external_accounts()
            self.__person_accts_len[person] = accts and len(accts) or 0
        not_in_network = []
        for person in self.__person_accts_len.iterkeys():
            if not person in self._mugshot.get_network():
                not_in_network.append(person)
        for person in not_in_network:
            self._logger.debug("removing not-in-network person %s", person.get_guid())
            del self.__person_accts_len[person]
        self.__reset()

    def __do_direction(self, is_next):
        self._logger.debug("skipping to %s" % (is_next and "next" or "prev",))
        try:
            self.__set_image(is_next and self.__next_image() or self.__prev_image())
            if self.__displaymode == 'text':
                self.__box.remove(self.__text)
            if self.__displaymode != 'photo':
                self.__box.append(self.__displaybox)
            self.__displaymode = 'photo'
        except StopIteration:
            self._logger.debug("caught StopIteration, displaying no photos text")            
            if self.__displaymode == 'photo':
                self.__box.remove(self.__displaybox)
            if self.__displaymode != 'text':
                self.__box.append(self.__text)        
            self.__displaymode = 'text'
        if self.__idle_display_id > 0:
            gobject.source_remove(self.__idle_display_id)            
        self.__idle_display_id = gobject.timeout_add(self.SLIDE_TIMEOUT_SEC * 1000, self.__idle_display_image)        

    def __do_next(self):
        self.__do_direction(True)
        
    def __do_prev(self):
        self.__do_direction(False)

    def __reset(self):
        self._logger.debug("resetting")        
        self.__images = self.__thumbnails_generator()
        self.__box.remove_all()        
        self.__displaymode = 'uninitialized'
        self.__do_next()
Exemplo n.º 17
0
    def __init__(self, *args, **kwargs):
        super(PhotosStock,self).__init__(*args, **kwargs)

        self.__images = None
        self.__images_reverse = []
        self.__images_forward = []
        self.__current_image = None

        self.__box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL, spacing=4)

        self.__successive_load_failures = 0
        
        self.__photosize = 120

        self.__idle_display_id = 0
        self.__text = hippo.CanvasText(text="No thumbnails found")

        self.__displaymode = "uninitialized" # "none", "photo"
        
        self.__displaybox = CanvasVBox(spacing=4)
        
        self.__photo_header = CanvasHBox(spacing=4)
        self.__favicon = CanvasMugshotURLImage()
        self.__title = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__title.connect("button-press-event", lambda photo, event: self.__visit_photo())        
        self.__photo_header.append(self.__favicon)
        self.__photo_header.append(self.__title)
        
        self.__displaybox.append(self.__photo_header)
        
        self.__photobox = CanvasHBox(spacing=6)
        self.__photo = TransitioningURLImage(self._logger, dimension=self.__photosize)
        self.__photo.connect("loaded", lambda photo, loaded: self.__on_image_load(loaded))
        self.__photo.connect("button-press-event", lambda photo, event: self.__visit_photo())
        self.__metabox = CanvasVBox()
        self.__metabox.append(hippo.CanvasText(text="from"))
        self.__fromphoto = CanvasMugshotURLImage()
        self.__fromphoto.set_clickable(True)
        self.__fromphoto.connect("button-press-event", lambda photo, event: self.__visit_person())           
        self.__metabox.append(self.__fromphoto)
        self.__fromname = ActionLink(size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.__fromname.connect("button-press-event", lambda photo, event: self.__visit_person())              
        self.__metabox.append(self.__fromname)
        self.__photobox.append(self.__photo)
        self.__photobox.append(self.__metabox)

        self.__displaybox.append(self.__photobox)        

        self.__controlbox = CanvasHBox()
        prev_link = ActionLink(text=u"\u00ab Prev", xalign=hippo.ALIGNMENT_START)
        prev_link.connect("button-press-event", lambda b,e: self.__do_prev())
        self.__controlbox.append(prev_link)
        next_link = ActionLink(text=u"Next \u00bb", xalign=hippo.ALIGNMENT_END)
        next_link.connect("button-press-event", lambda b,e: self.__do_next())
        self.__controlbox.append(next_link, hippo.PACK_EXPAND)
        self.__displaybox.append(self.__controlbox)        
        
        self.__person_accts_len = {} # <Person,int>
        
        self.__bearbox = CanvasVBox()
        self.__bearphoto = TransitioningURLImage(self._logger, dimension=self.SIZE_BEAR_CONTENT_PX-6)
        self.__bearphoto.connect("button-press-event", lambda photo, event: self.__visit_photo())        
        self.__bearbox.append(self.__bearphoto)
        
        self._mugshot.connect("network-changed", lambda mugshot: self.__handle_network_change())  
Exemplo n.º 18
0
class EntityItem(PhotoContentItem):
    def __init__(self, **kwargs):
        PhotoContentItem.__init__(self, **kwargs)
        
        self.__entity = None

        self.__photo = CanvasMugshotURLImage(scale_width=30,
                                            scale_height=30,
                                            border=1,
                                            border_color=0x000000ff)

        self.set_photo(self.__photo)

        self.__name = hippo.CanvasText(xalign=hippo.ALIGNMENT_FILL, yalign=hippo.ALIGNMENT_START,
                                      size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
        self.set_child(self.__name)

        self.connect('button-press-event', self.__handle_button_press)
        self.connect('button-release-event', self.__handle_button_release)
        self.__pressed = False

    def __update_color(self):
        if self.__pressed:
            self.set_property('background-color', 0x00000088)
        else:
            self.sync_prelight_color()

    def __handle_button_press(self, self2, event):
        if event.button != 1:
            return False
        
        self.__pressed = True

        self.__update_color()

    def __handle_button_release(self, self2, event):
        if event.button != 1:
            return False

        self.__pressed = False

        self.__update_color()
            
    def set_entity(self, entity):
        if self.__entity == entity:
            return
        self.__entity = entity
        self.__update()

    def get_guid(self):
        return self.__entity.get_guid()

    def get_entity(self):
        return self.__entity

    def set_size(self, size):
        if size == bigboard.stock.SIZE_BULL:
            self.set_child_visible(self.__name, True)
            self.__photo.set_property('xalign', hippo.ALIGNMENT_START)
            self.__photo.set_property('yalign', hippo.ALIGNMENT_START)
        else:
            self.set_child_visible(self.__name, False)
            self.__photo.set_property('xalign', hippo.ALIGNMENT_CENTER)
            self.__photo.set_property('yalign', hippo.ALIGNMENT_CENTER)

    def __update(self):
        if not self.__entity:
            return
        self.__name.set_property("text", self.__entity.get_name())
        if self.__entity.get_photo_url():
            self.__photo.set_url(self.__entity.get_photo_url())

    def get_screen_coords(self):
        return self.get_context().translate_to_screen(self)