ports/90627: [NEW PORTS] multimedia/quodlibet
Byung-Hee HWANG
bh at izb.knu.ac.kr
Sat Dec 24 07:00:27 UTC 2005
The following reply was made to PR ports/90627; it has been noted by GNATS.
From: Byung-Hee HWANG <bh at izb.knu.ac.kr>
To: bug-followup at FreeBSD.org
Cc: bh at izb.knu.ac.kr, edwin at FreeBSD.org, ehaupt at FreeBSD.org
Subject: Re: ports/90627: [NEW PORTS] multimedia/quodlibet
Date: Fri, 23 Dec 2005 23:57:13 -0700
This is a multi-part message in MIME format.
--Multipart=_Fri__23_Dec_2005_23_57_13_-0700_onhdplBKEBpuGBhH
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
On Wed, 21 Dec 2005 04:37:38 GMT, Edwin Groothuis wrote:
> Synopsis: [NEW PORTS] multimedia/quodlibet
>
> State-Changed-From-To: open->feedback
> State-Changed-By: edwin
> State-Changed-When: Wed Dec 21 04:35:46 UTC 2005
> State-Changed-Why:
> Checking for PyGTK >= 2.6:
> Traceback (most recent call last):
> File "./check.py", line 20, in ?
> import gtk
> File "/usr/local/lib/python2.4/site-packages/gtk-2.0/gtk/__init__.py", line 37, in ?
> from _gtk import *
> RuntimeError: could not open display
>
> I take it this is an X issue. Wonder how other ports which require
> X and sometimes require a terminal handle this on the package
> building system.
I fixed it. And now, I re-submit updated shar files. It's 3rd.
Sincerely,
--
Byung-Hee
--Multipart=_Fri__23_Dec_2005_23_57_13_-0700_onhdplBKEBpuGBhH
Content-Type: text/plain;
name="ports-quodlibet-20051224.txt"
Content-Disposition: attachment;
filename="ports-quodlibet-20051224.txt"
Content-Transfer-Encoding: 7bit
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# /usr/ports/multimedia/quodlibet
# /usr/ports/multimedia/quodlibet/Makefile
# /usr/ports/multimedia/quodlibet/files
# /usr/ports/multimedia/quodlibet/files/patch-Makefile
# /usr/ports/multimedia/quodlibet/files/qlscrobbler.py
# /usr/ports/multimedia/quodlibet/distinfo
# /usr/ports/multimedia/quodlibet/pkg-descr
# /usr/ports/multimedia/quodlibet/pkg-plist
#
echo c - /usr/ports/multimedia/quodlibet
mkdir -p /usr/ports/multimedia/quodlibet > /dev/null 2>&1
echo x - /usr/ports/multimedia/quodlibet/Makefile
sed 's/^X//' >/usr/ports/multimedia/quodlibet/Makefile << 'END-of-/usr/ports/multimedia/quodlibet/Makefile'
X# New ports collection makefile for: quodlibet
X# Date created: 19 December 2005
X# Whom: Byung-Hee HWANG <bh at izb.knu.ac.kr>
X#
X# $FreeBSD$
X#
X
XPORTNAME= quodlibet
XPORTVERSION= 0.15
XCATEGORIES= multimedia audio python
XMASTER_SITES= http://www.sacredchao.net/~piman/software/ \
X ${MASTER_SITE_LOCAL}
X
XMAINTAINER= bh at izb.knu.ac.kr
XCOMMENT= A GTK+-based audio player written in Python
X
XBUILD_DEPENDS= ${PYTHON_SITELIBDIR}/gst/__init__.py:${PORTSDIR}/multimedia/py-gstreamer \
X ${PYTHON_SITELIBDIR}/ogg/_ogg.so:${PORTSDIR}/audio/py-ogg \
X ${PYTHON_SITELIBDIR}/ogg/vorbis.so:${PORTSDIR}/audio/py-vorbis \
X ${PYTHON_SITELIBDIR}/madmodule.so:${PORTSDIR}/audio/py-mad \
X ${PYTHON_SITELIBDIR}/gtk-2.0/egg/__init__.py:${PORTSDIR}/x11-toolkits/py-gnome-extras
XRUN_DEPENDS= ${BUILD_DEPENDS}
X
XUSE_PYTHON= 2.3+
XUSE_GNOME= pygtk2
XUSE_GMAKE= yes
XUSE_X_PREFIX= yes
X
X.if !defined(DISPLAY)
XBUILD_DEPENDS+= Xvfb:${X_VFBSERVER_PORT}
XDISPLAYHACK= localhost:1001
X.endif
X
Xpre-configure:
X.if !defined(DISPLAY)
X.if exists(${WRKDIR}/.Xvfb.pid)
X @-${CAT} ${WRKDIR}/.Xvfb.pid | ${XARGS} kill
X @${RM} -f ${WRKDIR}/.Xvfb.pid
X.endif
X ${X11BASE}/bin/Xvfb :1001 -screen 0 800x600x24 > /dev/null 2>&1 & ${ECHO_CMD} $$! > \
X ${WRKDIR}/.Xvfb.pid
X.endif
X
Xdo-configure:
X.if !defined(DISPLAY)
X @${SETENV} DISPLAY=${DISPLAYHACK} ${PYTHON_CMD} ${WRKSRC}/check.py
X.else
X @${PYTHON_CMD} ${WRKSRC}/check.py
X.endif
X
Xpost-configure:
X.if !defined(DISPLAY)
X @${CAT} ${WRKDIR}/.Xvfb.pid | ${XARGS} kill
X @${RM} ${WRKDIR}/.Xvfb.pid
X.endif
X
Xdo-build:
X @cd ${WRKSRC} && ${GMAKE} extensions
X
Xpost-install:
X.if !defined(WITHOUT_PLUGINS)
X @${MKDIR} ${PREFIX}/lib/${PORTNAME}/plugins
X @${INSTALL_DATA} ${FILESDIR}/qlscrobbler.py ${PREFIX}/lib/${PORTNAME}/plugins
X.endif
X
X.include <bsd.port.mk>
END-of-/usr/ports/multimedia/quodlibet/Makefile
echo c - /usr/ports/multimedia/quodlibet/files
mkdir -p /usr/ports/multimedia/quodlibet/files > /dev/null 2>&1
echo x - /usr/ports/multimedia/quodlibet/files/patch-Makefile
sed 's/^X//' >/usr/ports/multimedia/quodlibet/files/patch-Makefile << 'END-of-/usr/ports/multimedia/quodlibet/files/patch-Makefile'
X--- Makefile.orig 2005-11-11 08:06:26.000000000 -0700
X+++ Makefile 2005-12-21 17:30:49.447341885 -0700
X@@ -28,9 +28,9 @@
X install-%: make-install-dirs
X install -m 755 $*.py $(DESTDIR)$(PREFIX)/$(TO)
X install -m 644 $*.1 $(DESTDIR)$(PREFIX)/share/man/man1/$*.1
X- install -D -m 644 $*.png $(DESTDIR)$(PREFIX)/share/pixmaps/$*.png
X+ install -m 644 $*.png $(DESTDIR)$(PREFIX)/share/pixmaps/$*.png
X install -m 644 $*.png $(DESTDIR)$(PREFIX)/$(TO)
X- install -D -m 644 $*.desktop $(DESTDIR)$(PREFIX)/share/applications/$*.desktop
X+ install -m 644 $*.desktop $(DESTDIR)$(PREFIX)/share/applications/$*.desktop
X ln -sf ../$(TO)/$*.py $(DESTDIR)$(PREFIX)/bin/$*
X
X clean:
END-of-/usr/ports/multimedia/quodlibet/files/patch-Makefile
echo x - /usr/ports/multimedia/quodlibet/files/qlscrobbler.py
sed 's/^X//' >/usr/ports/multimedia/quodlibet/files/qlscrobbler.py << 'END-of-/usr/ports/multimedia/quodlibet/files/qlscrobbler.py'
X# QLScrobbler: an Audioscrobbler client plugin for Quod Libet.
X# version 0.7
X# (C) 2005 by Joshua Kwan <joshk at triplehelix.org>,
X# Joe Wreschnig <piman at sacredchao.net>
X# Licensed under GPLv2. See Quod Libet's COPYING for more information.
X
Ximport random
Ximport md5, urllib, urllib2, time, threading, os
Ximport player, config, const
Ximport gobject, gtk
Xfrom qltk import Message
Xfrom util import to
X
Xclass QLScrobbler(object):
X # session invariants
X PLUGIN_NAME = "QLScrobbler"
X PLUGIN_DESC = "Audioscrobbler client for Quod Libet"
X PLUGIN_ICON = gtk.STOCK_CONNECT
X PLUGIN_VERSION = "0.7"
X CLIENT = "qlb"
X PROTOCOL_VERSION = "1.1"
X DUMP = os.path.join(const.DIR, "scrobbler_cache")
X
X # things that could change
X
X username = ""
X password = ""
X pwhash = ""
X
X timeout_id = -1
X submission_tid = -1
X
X challenge = ""
X submit_url = ""
X
X # state management
X waiting = False
X challenge_sent = False
X broken = False
X need_config = False
X need_update = False
X already_submitted = False
X locked = False
X flushing = False
X disabled = False
X
X # we need to store this because not all events get the song
X song = None
X
X queue = []
X
X def __init__(self):
X # Read dumped queue and delete it
X try:
X dump = open(self.DUMP, 'r')
X self.read_dump(dump)
X except: pass
X
X # Set up exit hook to dump queue
X gtk.quit_add(0, self.dump_queue)
X
X def read_dump(self, dump):
X print "Loading dumped queue."
X
X current = {}
X
X for line in dump.readlines():
X key = ""
X value = ""
X
X line = line.rstrip()
X try: (key, value) = line.split(" = ", 1)
X except:
X if line == "-":
X for key in ["album", "mbid"]:
X if key not in current:
X current[key] = ""
X
X for reqkey in ["artist", "title", "length", "stamp"]:
X # discard if somehow invalid
X if reqkey not in current:
X current = {}
X
X if current != {}:
X self.queue.append(current)
X current = {}
X continue
X
X if key == "length": current[key] = int(value)
X else: current[key] = value
X
X dump.close()
X
X os.remove(self.DUMP)
X
X# print "Queue contents:"
X# for item in self.queue:
X# print "\t%s - %s" % (item['artist'], item['title'])
X
X # Try to flush it immediately
X if len(self.queue) > 0:
X self.flushing = True
X self.submit_song()
X else: print "Queue was empty!"
X
X def dump_queue(self):
X if len(self.queue) == 0: return 0
X
X print "Dumping offline queue, will submit next time."
X
X dump = open(self.DUMP, 'w')
X
X for item in self.queue:
X for key in item:
X dump.write("%s = %s\n" % (key, item[key]))
X
X dump.close()
X
X return 0
X
X def plugin_on_removed(self, songs):
X try:
X if self.song in songs:
X self.already_submitted = True
X except:
X # Older version compatibility.
X if self.song is songs:
X self.already_submitted = True
X
X def plugin_on_song_ended(self, song, stopped):
X if song is None: return
X
X if self.timeout_id > 0:
X gobject.source_remove(self.timeout_id)
X self.timeout_id = -1
X
X def plugin_on_song_started(self, song):
X if song is None: return
X
X self.already_submitted = False
X if self.timeout_id > 0:
X gobject.source_remove(self.timeout_id)
X
X self.timeout_id = -1
X
X # Protocol stipulation:
X # * don't submit when length < 00:30
X # NOTE: >30:00 stipulation has been REMOVED as of Protocol1.1
X # * don't submit if artist and title are not available
X if song["~#length"] < 30: return
X elif 'title' not in song: return
X elif "artist" not in song:
X if ("composer" not in song) and ("performer" not in song): return
X
X self.song = song
X if player.playlist.paused == False:
X self.prepare()
X
X def plugin_on_paused(self):
X if self.timeout_id > 0:
X gobject.source_remove(self.timeout_id)
X # special value that will tell on_unpaused to check song length
X self.timeout_id = -2
X
X def plugin_on_unpaused(self):
X if self.already_submitted == False and self.timeout_id == -1: self.prepare()
X
X def plugin_on_seek(self, song, msec):
X if self.timeout_id > 0:
X gobject.source_remove(self.timeout_id)
X self.timeout_id = -1
X
X if msec == 0: #I think this is okay!
X self.prepare()
X else:
X self.already_submitted = True # cancel
X
X def prepare(self):
X if self.song is None: return
X
X # Protocol stipulations:
X # * submit 240 seconds in or at 50%, whichever comes first
X delay = int(min(self.song["~#length"] / 2, 240))
X
X if self.timeout_id == -2: # change delta based on current progress
X # assumption is that self.already_submitted == 0, therefore
X # delay - progress > 0
X progress = int(player.playlist.info.time[0] / 1000)
X delay -= progress
X
X self.timeout_id = gobject.timeout_add(delay * 1000, self.submit_song)
X
X def read_config(self):
X username = ""
X password = ""
X try:
X username = config.get("plugins", "scrobbler_username")
X password = config.get("plugins", "scrobbler_password")
X except:
X if self.need_config == False:
X self.quick_info("Please visit the Preferences window to set QLScrobbler up. Until then, songs will not be submitted.")
X self.need_config = True
X return
X
X self.username = username
X
X hasher = md5.new()
X hasher.update(password);
X self.password = hasher.hexdigest()
X self.need_config = False
X
X def __destroy_cb(self, dialog, response_id):
X dialog.destroy()
X
X def quick_error_helper(self, str):
X dialog = Message(gtk.MESSAGE_ERROR, None, "QLScrobbler", str)
X dialog.connect('response', self.__destroy_cb)
X dialog.show()
X
X def quick_error(self, str):
X gobject.idle_add(self.quick_error_helper, str)
X
X def quick_info_helper(self, str):
X dialog = Message(gtk.MESSAGE_INFO, widgets.widgets.main, "QLScrobbler", str).run()
X dialog.connect('response', self.__destroy_cb)
X dialog.show()
X
X def quick_info(self, str):
X gobject.idle_add(self.quick_info_helper, str)
X
X def clear_waiting(self):
X self.waiting = False
X
X def send_handshake(self):
X # construct url
X url = "http://post.audioscrobbler.com/?hs=true&p=%s&c=%s&v=%s&u=%s" % ( self.PROTOCOL_VERSION, self.CLIENT, self.PLUGIN_VERSION, self.username )
X
X print "Sending handshake to Audioscrobbler."
X
X resp = None
X
X try:
X resp = urllib2.urlopen(url);
X except:
X print "Server not responding, handshake failed."
X return # challenge_sent is NOT set to 1
X
X # check response
X lines = resp.read().rstrip().split("\n")
X status = lines.pop(0)
X
X print "Handshake status: %s" % status
X
X if status == "UPTODATE" or status.startswith("UPDATE"):
X if status.startswith("UPDATE"):
X self.quick_info("A new plugin is available at %s! Please download it, or your Audioscrobbler stats may not be updated, and this message will be displayed every session." % status.split()[1])
X self.need_update = True
X
X # Scan for submit URL and challenge.
X self.challenge = lines.pop(0)
X
X print "Challenge: %s" % self.challenge
X
X # determine password
X hasher = md5.new()
X hasher.update(self.password)
X hasher.update(self.challenge)
X self.pwhash = hasher.hexdigest()
X
X self.submit_url = lines.pop(0)
X
X self.challenge_sent = True
X elif status == "BADUSER":
X self.quick_error("Authentication failed: invalid username %s or bad password." % self.username)
X
X self.broken = True
X
X # Honor INTERVAL if available
X try: interval = int(lines.pop(0).split()[1])
X except: interval = 0
X
X if interval > 1:
X self.waiting = True
X gobject.timeout_add(interval * 1000, self.clear_waiting)
X print "Server says to wait for %d seconds." % interval
X
X def submit_song(self):
X bg = threading.Thread(None, self.submit_song_helper)
X bg.setDaemon(True)
X bg.start()
X
X def submit_song_helper(self):
X enabled = getattr(self, 'PMEnFlag', False)
X if enabled and self.disabled:
X print "Plugin re-enabled - accepting new songs."
X self.disabled = False
X if self.submission_tid != -1:
X gobject.source_remove(self.submission_tid);
X self.submission_tid = -1
X elif not enabled and not self.disabled: #if we've already printed
X print "Plugin disabled - not accepting any new songs."
X self.disabled = True
X if len(self.queue) > 0:
X self.submission_tid = gobject.timeout_add(120 * 1000, self.submit_song_helper)
X print "Attempts will continue to submit the last %d songs." % len(self.queue)
X
X if self.already_submitted == True or self.broken == True: return
X
X if self.flushing == False:
X stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
X
X store = {
X "title": self.song.comma("title"),
X "length": str(self.song["~#length"]),
X "album": self.song.comma("album"),
X "mbid": "", # will be correctly set if available
X "stamp": stamp
X }
X
X if "artist" in self.song:
X store["artist"] = self.song.comma("artist")
X elif "composer" in self.song:
X store["artist"] = self.song.comma("composer")
X elif "performer" in self.song:
X performer = self.song.comma('performer')
X if performer[-1] == ")" and "(" in performer:
X store["artist"] = performer[:performer.rindex("(")].strip()
X else:
X store["artist"] = performer
X elif "musicbrainz_trackid" in self.song:
X store["mbid"] = self.song["musicbrainz_trackid"]
X
X self.queue.append(store)
X else: self.flushing = False
X
X if self.locked == True:
X # another instance running, let it deal with this
X return
X
X self.locked = True
X
X while self.waiting == True: time.sleep(1)
X
X # Read config, handshake, and send challenge if not already done
X if self.challenge_sent == False:
X self.read_config()
X if self.broken == False and self.need_config == False:
X self.send_handshake()
X
X # INTERVAL may have been set during handshake.
X while self.waiting == True: time.sleep(1)
X
X if self.challenge_sent == False:
X self.locked = False
X return
X
X data = {
X 'u': self.username,
X 's': self.pwhash
X }
X
X # Flush the cache
X for i in range(len(self.queue)):
X print to("Sending song: %s - %s" % (self.queue[i]['artist'], self.queue[i]['title']))
X data["a[%d]" % i] = self.queue[i]['artist'].encode('utf-8')
X data["t[%d]" % i] = self.queue[i]['title'].encode('utf-8')
X data["l[%d]" % i] = str(self.queue[i]['length'])
X data["b[%d]" % i] = self.queue[i]['album'].encode('utf-8')
X data["m[%d]" % i] = self.queue[i]['mbid']
X data["i[%d]" % i] = self.queue[i]['stamp']
X
X (host, file) = self.submit_url[7:].split("/")
X
X resp = None
X
X try:
X data_str = urllib.urlencode(data)
X resp = urllib2.urlopen("http://" + host + "/" + file, data_str)
X except:
X print "Audioscrobbler server not responding, will try later."
X self.locked = False
X return # preserve the queue, yadda yadda
X
X resp_save = resp.read()
X lines = resp_save.rstrip().split("\n")
X
X try: (status, interval) = lines
X except:
X try: status = lines[0]
X except:
X print "Truncated server response, will try later..."
X self.locked = False
X return
X interval = None
X
X print "Submission status: %s" % status
X
X if status == "BADAUTH":
X print "Attempting to re-authenticate."
X self.challenge_sent = False
X self.send_handshake()
X if self.challenge_sent == False:
X self.quick_error("Your Audioscrobbler login data is incorrect, so you must re-enter it before any songs will be submitted.\n\nThis message will not be shown again.")
X self.broken = True
X elif status == "OK":
X self.queue = []
X elif status.startswith("FAILED"):
X if status.startswith("FAILED Plugin bug"):
X print "Plugin bug!? Ridiculous! Dumping queue contents."
X for item in self.queue:
X for key in item:
X print "%s = %s" % (key, item[key])
X # possibly handle other specific cases here for debugging later
X else:
X print "Unknown response from server: %s" % status
X print "Dumping full response:"
X print resp_save
X
X if interval != None: interval_secs = int(interval.split()[1])
X else: interval_secs = 0
X
X if interval_secs > 1:
X self.waiting = True
X gobject.timeout_add(interval_secs * 1000, self.clear_waiting)
X print "Server says to wait for %d seconds." % interval_secs
X
X if self.disabled and len(self.queue) == 0 and self.submission_tid != -1:
X print "All songs submitted, disabling retries."
X gobject.source_remove(self.submission_tid)
X self.submission_tid = -1
X
X self.already_submitted = True
X self.locked = False
X
X def PluginPreferences(self, parent):
X def changed(entry, key):
X # having two functions is unnecessary..
X config.set("plugins", "scrobbler_" + key, entry.get_text())
X
X def destroyed(*args):
X # if changed, let's say that things just got better and we should
X # try everything again
X newu = None
X newp = None
X try:
X newu = config.get("plugins", "scrobbler_username")
X newp = config.get("plugins", "scrobbler_password")
X except:
X return
X
X if self.username != newu or self.password != newp:
X self.broken = False
X
X table = gtk.Table(3, 2)
X table.set_col_spacings(3)
X lt = gtk.Label(_("Please enter your Audioscrobbler username and password."))
X lt.set_size_request(260, -1)
X lu = gtk.Label(_("Username:"))
X lp = gtk.Label(_("Password:"))
X for l in [lt, lu, lp]:
X l.set_line_wrap(True)
X l.set_alignment(0.0, 0.5)
X table.attach(lt, 0, 2, 0, 1, xoptions=gtk.FILL)
X table.attach(lu, 0, 1, 1, 2, xoptions=gtk.FILL)
X table.attach(lp, 0, 1, 2, 3, xoptions=gtk.FILL)
X userent = gtk.Entry()
X pwent = gtk.Entry()
X pwent.set_visibility(False)
X pwent.set_invisible_char('*')
X table.set_border_width(6)
X
X try: userent.set_text(config.get("plugins", "scrobbler_username"))
X except: pass
X try: pwent.set_text(config.get("plugins", "scrobbler_password"))
X except: pass
X
X table.attach(userent, 1, 2, 1, 2)
X table.attach(pwent, 1, 2, 2, 3)
X pwent.connect('changed', changed, 'password')
X userent.connect('changed', changed, 'username')
X table.connect('destroy', destroyed)
X return table
END-of-/usr/ports/multimedia/quodlibet/files/qlscrobbler.py
echo x - /usr/ports/multimedia/quodlibet/distinfo
sed 's/^X//' >/usr/ports/multimedia/quodlibet/distinfo << 'END-of-/usr/ports/multimedia/quodlibet/distinfo'
XMD5 (quodlibet-0.15.tar.gz) = 09b14d03e587af6ba929b18ed8e0df56
XSHA256 (quodlibet-0.15.tar.gz) = 20851cc270f17330204683b0a29ab86dcfbbfdda0e1c399c8f97836347063cf5
XSIZE (quodlibet-0.15.tar.gz) = 476236
END-of-/usr/ports/multimedia/quodlibet/distinfo
echo x - /usr/ports/multimedia/quodlibet/pkg-descr
sed 's/^X//' >/usr/ports/multimedia/quodlibet/pkg-descr << 'END-of-/usr/ports/multimedia/quodlibet/pkg-descr'
XQuod Libet is a GTK+-based audio player written in Python.
X
XWWW: http://www.sacredchao.net/quodlibet/
END-of-/usr/ports/multimedia/quodlibet/pkg-descr
echo x - /usr/ports/multimedia/quodlibet/pkg-plist
sed 's/^X//' >/usr/ports/multimedia/quodlibet/pkg-plist << 'END-of-/usr/ports/multimedia/quodlibet/pkg-plist'
Xbin/exfalso
Xbin/quodlibet
Xlib/quodlibet/exfalso.png
Xlib/quodlibet/exfalso.py
Xlib/quodlibet/mmkeys.so
Xlib/quodlibet/plugins/qlscrobbler.py
Xlib/quodlibet/ql-volume-max.png
Xlib/quodlibet/ql-volume-medium.png
Xlib/quodlibet/ql-volume-min.png
Xlib/quodlibet/ql-volume-zero.png
Xlib/quodlibet/quodlibet.png
Xlib/quodlibet/quodlibet.py
Xlib/quodlibet/quodlibet.zip
Xlib/quodlibet/trayicon.so
Xshare/applications/exfalso.desktop
Xshare/applications/quodlibet.desktop
Xshare/locale/bg/LC_MESSAGES/quodlibet.mo
Xshare/locale/de/LC_MESSAGES/quodlibet.mo
Xshare/locale/en_CA/LC_MESSAGES/quodlibet.mo
Xshare/locale/en_GB/LC_MESSAGES/quodlibet.mo
Xshare/locale/es/LC_MESSAGES/quodlibet.mo
Xshare/locale/fi/LC_MESSAGES/quodlibet.mo
Xshare/locale/fr/LC_MESSAGES/quodlibet.mo
Xshare/locale/gl/LC_MESSAGES/quodlibet.mo
Xshare/locale/he/LC_MESSAGES/quodlibet.mo
Xshare/locale/it/LC_MESSAGES/quodlibet.mo
Xshare/locale/nl/LC_MESSAGES/quodlibet.mo
Xshare/locale/pl/LC_MESSAGES/quodlibet.mo
Xshare/locale/pt/LC_MESSAGES/quodlibet.mo
Xshare/locale/ru/LC_MESSAGES/quodlibet.mo
Xshare/man/man1/exfalso.1
Xshare/man/man1/quodlibet.1
Xshare/pixmaps/exfalso.png
Xshare/pixmaps/quodlibet.png
X at dirrm lib/quodlibet/plugins
X at dirrm lib/quodlibet
END-of-/usr/ports/multimedia/quodlibet/pkg-plist
exit
--Multipart=_Fri__23_Dec_2005_23_57_13_-0700_onhdplBKEBpuGBhH--
More information about the freebsd-ports-bugs
mailing list