def get_commit_details(commit, revision=None): """Return the details about a specific commit. :param commit: The commit to get details from :type commit: Git.Commit :param revision: Optional commit revision :type revision: int :returns: Details about the commit :rtype: CommitDetails :raises: CommitTimeValError or Ggit exceptions """ message = commit.get_message() commit_str = commit.get_id().to_string() sig = commit.get_committer() datetime = sig.get_time() # XXX What do we do with timezone? _timezone = sig.get_time_zone() timeval = GLib.TimeVal() ok = datetime.to_timeval(timeval) if not ok: raise CommitTimeValError time_str = timeval.to_iso8601() return CommitDetails(commit_str, time_str, message, revision)
def __init__(self, filepath, size=128, *args, **kwargs): super().__init__(*args, **kwargs) self.props.name = "stash-container" self.path = filepath self.pixbuf_original = GdkPixbuf.PixbufAnimation.new_from_file( filepath) self.pixbuf_original_height = self.pixbuf_original.get_height() self.pixbuf_original_width = self.pixbuf_original.get_width() self.iter = self.pixbuf_original.get_iter() for i in range(0, 250): timeval = GLib.TimeVal() timeval.tv_sec = int(str(GLib.get_real_time())[:-3]) self.iter.advance(timeval) self.queue_draw() self.ratio_h_w = self.pixbuf_original_height / self.pixbuf_original_width self.ratio_w_h = self.pixbuf_original_width / self.pixbuf_original_height if self.ratio_w_h > 1: self.set_size_request(size, int((10 / 16) * size) + 1) else: self.set_size_request(size, size) drawing_area = Gtk.DrawingArea() drawing_area.props.expand = True drawing_area.props.halign = drawing_area.props.valign = Gtk.Align.FILL drawing_area.connect("draw", self.draw) drawing_area.props.can_focus = False self.attach(drawing_area, 0, 0, 1, 1) self.props.halign = self.props.valign = Gtk.Align.CENTER
def do_render(self, ctx, widget, background_area, cell_area, flags): if not self.image: return if self.image.get_storage_type() == Gtk.ImageType.ANIMATION: if self.image not in self.iters: if not isinstance(widget, Gtk.TreeView): return animation = self.image.get_animation() timeval = GLib.TimeVal() timeval.tv_sec = GLib.get_monotonic_time() / 1000000 iter_ = animation.get_iter(timeval) self.iters[self.image] = iter_ GLib.timeout_add(iter_.get_delay_time(), self.animation_timeout, widget, self.image) pix = self.iters[self.image].get_pixbuf() elif self.image.get_storage_type() == Gtk.ImageType.PIXBUF: pix = self.image.get_pixbuf() else: return calc_width = self.get_property('xpad') * 2 + pix.get_width() calc_height = self.get_property('ypad') * 2 + pix.get_height() x_pos = cell_area.x + self.get_property('xalign') * \ (cell_area.width - calc_width - self.get_property('xpad')) y_pos = cell_area.y + self.get_property('yalign') * \ (cell_area.height - calc_height - self.get_property('ypad')) Gdk.cairo_set_source_pixbuf(ctx, pix, x_pos, y_pos) ctx.paint()
def load_pixbuf(self, path: Path): """ Loads a pixbuf from a given image file """ enable_anime = config['ANIMATION_MODE'] != Animation.DISABLED.value n_frames = None loop = None try: with LockedFileIO(path) as fio: with Image.open(fio) as im: # make sure n_frames loaded im.load() if enable_anime and im.is_animated: n_frames = im.n_frames loop = im.info['loop'] return self.load_animation(im) return self.pil_to_pixbuf(im, keep_orientation=True) except Exception as ex: # should only be hit when loading trying to load a gif logger.debug(f'failed to load pixbuf: {ex}') if not enable_anime: return GdkPixbuf.Pixbuf.new_from_file(str(path)) pixbuf = GdkPixbuf.PixbufAnimation.new_from_file(str(path)) if pixbuf.is_static_image(): return pixbuf.get_static_image() if n_frames is None or n_frames < 2: # not recognized by PIL or not animation, or only a single frame return pixbuf # assume PIL and GdkPixbuf count frames in same way. anime = AnimeFrameBuffer(n_frames, loop=loop) cur = GLib.TimeVal() frame_iter = pixbuf.get_iter(cur) for n in range(n_frames): frame_ref = frame_iter.get_pixbuf() frame = frame_ref.copy() frame_ref.copy_options(frame) delay = frame_iter.get_delay_time() cur.tv_usec += delay * 1000 while not frame_iter.advance(cur): delay += frame_iter.get_delay_time() cur.tv_usec += delay * 1000 anime.add_frame(n, frame, delay) if n == n_frames - 1: # end of animation break return anime.create_animation()
def do_set_time(self, t): """ Set the player at time t. Should run on the main thread to ensure we avoid vlc plugins' reentrency problems. Args: t (`int`): the timestamp, in ms Returns: `bool`: `True` iff this function should be run again (:meth:`~GLib.idle_add` convention) """ start = GLib.TimeVal() GLib.DateTime.new_now_local().to_timeval(start) start.add(-t) self.iter = self.anim.get_iter(start) self.advance_gif() return False
def animation_timeout(self, tree, image): if image.get_storage_type() != Gtk.ImageType.ANIMATION: return self.redraw = 0 iter_ = self.iters[image] timeval = GLib.TimeVal() timeval.tv_sec = GLib.get_monotonic_time() / 1000000 iter_.advance(timeval) model = tree.get_model() if model: model.foreach(self.func, (image, tree)) if self.redraw: GLib.timeout_add(iter_.get_delay_time(), self.animation_timeout, tree, image) elif image in self.iters: del self.iters[image]
def _create_indicator(self, subtype, sender, body, extra_text='', icid=None): """ This creates a new indicator item, called by on_message, online & offline. """ if indicate: ind = indicate.Indicator() #Get user icon. if hasattr(ind, 'set_property_icon'): contact = self.handler.session.contacts.safe_get(body) pixbuf = utils.safe_gtk_pixbuf_load(contact.picture or '', (48, 48)) if pixbuf is not None: ind.set_property_icon("icon", pixbuf) ind.set_property("subtype", subtype) ind.set_property("sender", sender + extra_text) if icid is not None: ind.set_property("body", str(icid)) else: ind.set_property("body", body) if check_gtk3(): ind.set_property_time("time", GLib.TimeVal()) else: ind.set_property_time("time", time.time()) ind.set_property("draw-attention", "true") ind.connect("user-display", self._display) ind.show() # Add indicator to the dictionary if subtype == "im": self.indicator_dict[ind] = icid self.r_indicator_dict[icid] = ind for old_icid in self.indicator_dict.values(): if old_icid not in self.handler.session.conversations.keys(): # workaround: kill the orphan indicator ind = self.r_indicator_dict[old_icid] del self.indicator_dict[ind] del self.r_indicator_dict[old_icid] else: return
def do_get_preferred_width(self, widget): """ Return the width we need for this cell. Each cell is drawn individually and is only as wide as it needs to be, we let the TreeViewColumn take care of making them all line up. """ if not self.image: return 0, 0 if self.image.get_storage_type() == Gtk.ImageType.ANIMATION: animation = self.image.get_animation() timeval = GLib.TimeVal() timeval.tv_sec = GLib.get_monotonic_time() / 1000000 pix = animation.get_iter(timeval).get_pixbuf() elif self.image.get_storage_type() == Gtk.ImageType.PIXBUF: pix = self.image.get_pixbuf() else: return 0, 0, 0, 0 calc_width = self.get_property('xpad') * 2 + pix.get_width() return calc_width, calc_width
def scale_gif(widget, scale): anim = widget.get_animation() timestamp = GLib.TimeVal() pixbuf_iter = anim.get_iter(timestamp) max_height = 0 max_width = 0 pixbufs = [] for i in range(4): pixbuf = pixbuf_iter.get_pixbuf() pixbuf, width, height = scale_pixbuf(pixbuf, scale) pixbufs.append(pixbuf) if width > max_width: max_width = width if height > max_height: max_height = height # the factor of 1000 is due to conveting from milliseconds to # microseconds time_to_next_frame = pixbuf_iter.get_delay_time() * 1000 timestamp.add(time_to_next_frame) pixbuf_iter.advance(timestamp) # This is the animation we want to fill up simpleanim = GdkPixbuf.PixbufSimpleAnim.new(max_width, max_height, 10) # Set it so it runs in a loop forever simpleanim.set_loop(True) for pixbuf in pixbufs: simpleanim.add_frame(pixbuf) image = Gtk.Image() image.set_from_animation(simpleanim) return image
except: pass if not enable_anime: return GdkPixbuf.Pixbuf.new_from_file(path) if (pixbuf := GdkPixbuf.PixbufAnimation.new_from_file(path)).is_static_image(): return pixbuf.get_static_image() if n_frames is None: # not recognized by PIL or not animation return pixbuf if n_frames < 2: # only one frame return pixbuf # assume PIL and GdkPixbuf count frames in same way. anime = anime_tools.AnimeFrameBuffer(n_frames, loop=loop) frame_iter = pixbuf.get_iter(cur := GLib.TimeVal()) for n in range(n_frames): frame = (frame_ref := frame_iter.get_pixbuf()).copy() frame_ref.copy_options(frame) cur.tv_usec += (delay := frame_iter.get_delay_time()) * 1000 while not frame_iter.advance(cur): cur.tv_usec += (delay := delay + frame_iter.get_delay_time()) * 1000 anime.add_frame(n, frame, delay) if n == n_frames - 1: # end of animation break return anime.create_animation() def load_pixbuf_size(path, width, height):