--- /dev/null
+you do "python setup.py bdist_debian" and it creates the .deb file in the "dist" subdirectory. That's it! You're done!
--- /dev/null
+# bdist_debian.py
+#
+# Add 'bdist_debian' Debian binary package distribution support to 'distutils'.
+#
+# This command builds '.deb' packages and supports the "Maemo" extensions for the Nokia N770/N800/N810.
+#
+# Written by: Gene Cash <gene.cash@gmail.com> 16-NOV-2007
+
+import os, base64
+from distutils.core import Command, Distribution
+from distutils.dir_util import remove_tree
+from distutils.util import byte_compile
+
+# make these legal keywords for setup()
+Distribution.icon=None
+Distribution.section=None
+Distribution.depends=None
+
+class ControlFile(object):
+ def __init__(self, Installed_Size=0, Long_Description='', Description='', Icon='', **kwargs):
+ self.options=kwargs
+ self.description=Description
+ self.long_description=Long_Description
+ self.icon=Icon
+ self.installed_size=Installed_Size
+
+ def getContent(self):
+ content=['%s: %s' % (k, v) for k,v in self.options.iteritems()]
+
+ content.append('Installed-Size: %d' % self.installed_size)
+ if self.description != 'UNKNOWN':
+ content.append('Description: %s' % self.description.strip())
+ if self.long_description != 'UNKNOWN':
+ self.long_description=self.long_description.replace('\n', '\n ')
+ content.append(' '+self.long_description.strip())
+
+ if self.icon:
+ # generate Base64-encoded icon
+ s=file(self.icon, 'rb').read()
+ x=base64.b64encode(s)
+ # wrap width MUST be 76 characters to make application manager happy after install
+ lw=76
+ # trailing blank is important, and the XB- is NOT legal
+ content.append('XB-Maemo-Icon-26: ')
+ for i in range(0, len(x), lw):
+ content.append(' '+x[i:i+lw])
+
+ # must have two returns
+ return '\n'.join(content)+'\n\n'
+
+class bdist_debian(Command):
+ description=''
+ # List of option tuples: long name, short name (None if no short name), and help string.
+ user_options=[('name=', None, 'Package name'),
+ ('section=', None, 'Section (Only "user/*" will display in App Mgr usually)'),
+ ('priority=', None, 'Priority'),
+ ('depends=', None, 'Other Debian package dependencies (comma separated)'),
+ ('icon=', None, 'Name of icon file to be displayed by App Mgr')]
+
+ def initialize_options(self):
+ self.section=None
+ self.priority=None
+ self.depends=None
+ self.icon=None
+
+ def finalize_options(self):
+ if self.section is None:
+ self.section='user/other'
+
+ if self.priority is None:
+ self.priority='optional'
+
+ self.maintainer='%s <%s>' % (self.distribution.get_maintainer(), self.distribution.get_maintainer_email())
+
+ if self.depends is None:
+ self.depends='python2.5'
+
+ self.name=self.distribution.get_name()
+ self.description=self.distribution.get_description()
+ self.long_description=self.distribution.get_long_description()
+ self.version=self.distribution.get_version()
+
+ # process new keywords
+ if self.distribution.icon != None:
+ self.icon=self.distribution.icon
+ if self.distribution.section != None:
+ self.section=self.distribution.section
+ if self.distribution.depends != None:
+ self.depends=self.distribution.depends
+
+ def run(self):
+ build_dir=os.path.join(self.get_finalized_command('build').build_base, 'nokia')
+ dist_dir='dist'
+ binary_fn='debian-binary'
+ control_fn='control'
+ data_fn='data'
+ tgz_ext='.tar.gz'
+
+ # build everything locally
+ self.run_command('build')
+ install=self.reinitialize_command('install', reinit_subcommands=1)
+ install.root=build_dir
+ self.run_command('install')
+
+ # find out how much space it takes
+ installed_size=0
+ for root, dirs, files in os.walk('build'):
+ installed_size+=sum(os.path.getsize(os.path.join(root, name)) for name in files)
+
+ # make compressed tarball
+ self.make_archive(os.path.join(dist_dir, data_fn), 'gztar', root_dir=build_dir)
+
+ # remove all the stuff we just built
+ remove_tree(build_dir)
+
+ # create control file contents
+ ctl=ControlFile(Package=self.name, Version=self.version, Section=self.section, Priority=self.priority,
+ Installed_Size=installed_size/1024+1, Architecture='all', Maintainer=self.maintainer,
+ Depends=self.depends, Description=self.description, Long_Description=self.long_description,
+ Icon=self.icon).getContent()
+
+ # grab scripts
+ scripts={}
+ for fn in ('postinst', 'preinst', 'postrm', 'prerm', 'config'):
+ if os.path.exists(fn):
+ scripts[fn]=file(fn, 'rb').read()
+
+ # now to create the deb package
+ os.chdir(dist_dir)
+
+ # write control file
+ file(control_fn, 'wb').write(ctl)
+
+ # write any scripts and chmod a+rx them
+ files=[control_fn]
+ for fn in scripts:
+ files.append(fn)
+ file(fn, 'wb').write(scripts[fn])
+ os.chmod(fn, 0555)
+
+ # make "control" compressed tarball with control file and any scripts
+ self.spawn(['tar', '-czf', control_fn+tgz_ext]+files)
+
+ # make debian-binary file
+ file(binary_fn, 'wb').write('2.0\n')
+
+ # make final archive
+ package_filename='%s_%s_all.deb' % (self.name, self.version)
+ self.spawn(['ar', '-cr', package_filename, binary_fn, control_fn+tgz_ext, data_fn+tgz_ext])
--- /dev/null
+#!/usr/bin/python
+# qice.py
+# Copyright 2008 kinta <kinta@communia.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+# deps= libshout shout2send aumix osso-xterm mplayer
+import sys
+from PyQt4 import QtCore
+from PyQt4 import QtGui
+import os
+import subprocess
+import pygst
+pygst.require('0.10')
+import gst
+import gst.interfaces
+import ConfigParser
+#
+import gobject
+#
+
+stream=["host", "port", "mountpoint", "user", "pw"]
+sndarch="dsppcmsrc"#"alsasrc"
+sndarchsink="dsppcmsink"#"alsasink"
+term="osso-xterm"#"xterm"
+home_directory = os.popen("echo $HOME").readline()[0:-1]
+config_directory = home_directory + '/.qice'
+if os.path.isdir(config_directory):
+ pass
+else:
+ os.popen("mkdir "+config_directory)
+config_file = config_directory + '/server.cfg'
+config = ConfigParser.ConfigParser()
+config.read(config_file)
+if config.has_section("server"):
+ print("configuracio trobada")
+else:
+ print("no te lopcio per tant escribim")
+ config.add_section("server")
+ for index,item in enumerate(stream):
+ config.set("server",item,item)
+ targetwrite=file(config_file,'w')
+ config.write(targetwrite)
+ targetwrite.close()
+
+
+class MainWindow(QtGui.QMainWindow):
+ def __init__(self, * args):
+ apply(QtGui.QMainWindow.__init__, (self, ) + args)
+ gobject.threads_init()
+ self.vlayout = QtGui.QGridLayout()
+
+ self.fileMenu = QtGui.QMenu(self.tr("&File"), self)
+ self.quitAction = self.fileMenu.addAction(self.tr("E&xit"))
+ self.editServer = self.fileMenu.addAction(self.tr("Edit c&onnection"))
+ self.mixer = self.fileMenu.addAction(self.tr("&Mixer"))
+ self.menuBar().addMenu(self.fileMenu)
+
+ self.stream = QtGui.QPushButton("Stream", self)
+ self.dump = QtGui.QPushButton("dump", self)
+ self.monitor = QtGui.QPushButton("Monitor", self)
+ self.record = QtGui.QPushButton("Record", self)
+ self.label = QtGui.QTextEdit("",self)
+
+ self.label.setReadOnly(True)
+ self.label.setGeometry(10, 100, 361, 141)
+ self.stream.setCheckable(1)
+ self.dump.setCheckable(1)
+ self.monitor.setCheckable(1)
+ self.record.setCheckable(1)
+
+ self.dump.setEnabled(False)
+
+ self.vlayout.addWidget(self.stream,0,0,1,1)
+ self.vlayout.addWidget(self.dump,1,0,1,1)
+ #self.vlayout.addSpacing(20)
+ self.vlayout.addWidget(self.monitor,0,1,1,1)
+ self.vlayout.addWidget(self.record,0,2,1,1)
+ self.vlayout.addWidget(self.label,2,0,1,3)
+
+ self.connect(self.stream, QtCore.SIGNAL("clicked()"), self.streamcon)
+ self.connect(self.dump, QtCore.SIGNAL("clicked()"), self.dumpstream)
+ self.connect(self.monitor, QtCore.SIGNAL("clicked()"), self.monstr)
+ self.connect(self.record, QtCore.SIGNAL("clicked()"), self.recordstr)
+ self.connect(self.quitAction, QtCore.SIGNAL("triggered()"), self.quito)
+ self.connect(self.editServer, QtCore.SIGNAL("triggered()"), self.setserver)
+ self.connect(self.mixer, QtCore.SIGNAL("triggered()"), self.aumixer)
+ central = QtGui.QWidget(self)
+ central.setLayout(self.vlayout)
+ self.setCentralWidget(central)
+
+ def streamcon(self):
+ if self.stream.isChecked():
+ try:
+ self.label.append("connecting")
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ self.audio_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! shout2send ip="+self.server+" port="+self.port+" password="+self.pw+" mount=/"+self.mount)
+ self.audio_pipeline.get_bus().add_watch(self.connectEventos)
+ self.audio_pipeline.set_state(gst.STATE_PLAYING)
+ self.label.append("connected")
+ self.record.setEnabled(False)
+ self.monitor.setEnabled(False)
+ self.dump.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.stream.setChecked(0)
+ return -1
+ else:
+ self.label.append("disconnecting")
+ try:
+ self.dump.setChecked(False)
+ self.dumpstream()
+ self.audio_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("disconnected")
+ self.record.setEnabled(True)
+ self.monitor.setEnabled(True)
+ self.dump.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+ def monstr(self):
+ if self.monitor.isChecked():
+ try:
+ self.label.append("monitoring")
+ self.mon_pipeline = gst.parse_launch(sndarch+" !"+sndarchsink)
+ self.mon_pipeline.get_bus().add_watch(self.eventos)
+ self.mon_pipeline.set_state(gst.STATE_PLAYING)
+ self.record.setEnabled(False)
+ self.stream.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.monitor.setChecked(0)
+ return -1
+ else:
+ self.label.append("disabling monitor")
+ try:
+ self.mon_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("unmonitoring")
+ self.record.setEnabled(True)
+ self.stream.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+ def recordstr(self):
+ if self.record.isChecked():
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ filename = str(filename)
+ try:
+ self.label.append("recording")
+ self.rec_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! filesink location="+filename)
+ self.rec_pipeline.get_bus().add_watch(self.eventos)
+ self.rec_pipeline.set_state(gst.STATE_PLAYING)
+ self.stream.setEnabled(False)
+ self.monitor.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.record.setChecked(0)
+ return -1
+ else:
+ self.label.append("stop recording")
+ try:
+ self.rec_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("stoped")
+ self.stream.setEnabled(True)
+ self.monitor.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+
+ def alert(self, msg):
+ QtGui.QMessageBox.critical(self, 'CRITICAL', msg, QtGui.QMessageBox.Ok)
+ def pregunta(self, msg):
+ pregunta=QtGui.QMessageBox.question(self, 'ATENCIO', msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ #resposta=pregunta.exec()
+ if pregunta == 1024:
+ return "OK"
+ else :
+ return "Cancel"
+ def quito(self,**kwargs):
+ self.close()
+ def setserver(self,**kwargs):
+ os.popen2(term+" -e \"nano ~/.qice/server.cfg\"")
+ config.read(config_file)
+ def aumixer(self,**kwargs):
+ os.popen2("aumix")
+ def eventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ return True
+ def connectEventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ self.stream.setChecked(False)
+ self.streamcon()
+ return True
+ def dumpstream(self):
+ if self.dump.isChecked():
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ self.filename = str(filename)
+ self.label.append("dumping")
+ mplayer=os.popen2( term+" -e \"mplayer http://"+self.server+":"+self.port+"/"+self.mount+" -dumpstream -dumpfile "+self.filename+" && sleep 2\"")[1].readline()
+
+ else:
+ pidofmp=os.popen2("pidof mplayer")[1].readline()
+ if pidofmp!="":
+ os.popen2("kill -15 `pidof mplayer`")
+
+
+def main(args):
+ app=QtGui.QApplication(args)
+ win=MainWindow()
+ win.show()
+ win.setWindowTitle("Qice")
+ app.connect(app, QtCore.SIGNAL("lastWindowClosed()")
+ , app
+ , QtCore.SLOT("quit()")
+ )
+ app.exec_()
+
+if __name__=="__main__":
+ main(sys.argv)
--- /dev/null
+qice.py
+
+Copyright: Aleix Quintana Alsius <kinta@communia.org>
+
+2008-12-07
+
+The entire code qice.py may be distributed under the terms of the GNU General
+Public License (GPL), which appears immediately below. Alternatively, all
+of the source code as any code derived from that code may instead be
+distributed under the GNU Lesser General Public License (LGPL), at the
+choice of the distributor. The complete text of the LGPL appears at the
+bottom of this file.
+
+See /usr/share/common-licenses/(GPL|LGPL)
\ No newline at end of file
--- /dev/null
+Maintainer: UNKNOWN <UNKNOWN>
+Package: qice-maemo
+Section: user/extras
+Priority: optional
+Depends: libshout3, aumix-gtk, python2.5-qt4-common, python2.5-gstreamer, mplayer
+Version: 1.0.0
+Architecture: all
+Installed-Size: 271
+Description: Client to Icecast, and ogg recorder
+ Client to Icecast, using the microphone to stream directly to an icecast server. You can also use it to record in ogg
+XB-Maemo-Icon-26:
+ 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
+
--- /dev/null
+[Desktop Entry]
+Version=1.0.0
+Encoding=UTF-8
+Name=qice-maemo
+Exec=/usr/bin/qice.py
+Icon=qice
+Type=Application
--- /dev/null
+#!/usr/bin/env python
+# qice.py
+# Copyright 2008 kinta <kinta@communia.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+# deps= libshout shout2send aumix osso-xterm mplayer
+import sys
+from PyQt4 import QtCore
+from PyQt4 import QtGui
+import os
+import subprocess
+import pygst
+pygst.require('0.10')
+import gst
+import gst.interfaces
+import ConfigParser
+#
+import gobject
+#
+
+stream=["host", "port", "mountpoint", "user", "pw"]
+sndarch="dsppcmsrc"#"alsasrc"
+sndarchsink="dsppcmsink"#"alsasink"
+term="osso-xterm"#"xterm"
+home_directory = os.popen("echo $HOME").readline()[0:-1]
+config_directory = home_directory + '/.qice'
+if os.path.isdir(config_directory):
+ pass
+else:
+ os.popen("mkdir "+config_directory)
+config_file = config_directory + '/server.cfg'
+config = ConfigParser.ConfigParser()
+config.read(config_file)
+if config.has_section("server"):
+ print("configuracio trobada")
+else:
+ print("no te lopcio per tant escribim")
+ config.add_section("server")
+ for index,item in enumerate(stream):
+ config.set("server",item,item)
+ targetwrite=file(config_file,'w')
+ config.write(targetwrite)
+ targetwrite.close()
+
+
+class MainWindow(QtGui.QMainWindow):
+ def __init__(self, * args):
+ apply(QtGui.QMainWindow.__init__, (self, ) + args)
+ gobject.threads_init()
+ self.vlayout = QtGui.QGridLayout()
+
+ self.fileMenu = QtGui.QMenu(self.tr("&File"), self)
+ self.quitAction = self.fileMenu.addAction(self.tr("E&xit"))
+ self.editServer = self.fileMenu.addAction(self.tr("Edit c&onnection"))
+ self.mixer = self.fileMenu.addAction(self.tr("&Mixer"))
+ self.menuBar().addMenu(self.fileMenu)
+
+ self.stream = QtGui.QPushButton("Stream", self)
+ self.dump = QtGui.QPushButton("dump", self)
+ self.monitor = QtGui.QPushButton("Monitor", self)
+ self.record = QtGui.QPushButton("Record", self)
+ self.label = QtGui.QTextEdit("",self)
+
+ self.label.setReadOnly(True)
+ self.label.setGeometry(10, 100, 361, 141)
+ self.stream.setCheckable(1)
+ self.dump.setCheckable(1)
+ self.monitor.setCheckable(1)
+ self.record.setCheckable(1)
+
+ self.dump.setEnabled(False)
+
+ self.vlayout.addWidget(self.stream,0,0,1,1)
+ self.vlayout.addWidget(self.dump,1,0,1,1)
+ #self.vlayout.addSpacing(20)
+ self.vlayout.addWidget(self.monitor,0,1,1,1)
+ self.vlayout.addWidget(self.record,0,2,1,1)
+ self.vlayout.addWidget(self.label,2,0,1,3)
+
+ self.connect(self.stream, QtCore.SIGNAL("clicked()"), self.streamcon)
+ self.connect(self.dump, QtCore.SIGNAL("clicked()"), self.dumpstream)
+ self.connect(self.monitor, QtCore.SIGNAL("clicked()"), self.monstr)
+ self.connect(self.record, QtCore.SIGNAL("clicked()"), self.recordstr)
+ self.connect(self.quitAction, QtCore.SIGNAL("triggered()"), self.quito)
+ self.connect(self.editServer, QtCore.SIGNAL("triggered()"), self.setserver)
+ self.connect(self.mixer, QtCore.SIGNAL("triggered()"), self.aumixer)
+ central = QtGui.QWidget(self)
+ central.setLayout(self.vlayout)
+ self.setCentralWidget(central)
+
+ def streamcon(self):
+ if self.stream.isChecked():
+ try:
+ self.label.append("connecting")
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ self.audio_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! shout2send ip="+self.server+" port="+self.port+" password="+self.pw+" mount=/"+self.mount)
+ self.audio_pipeline.get_bus().add_watch(self.connectEventos)
+ self.audio_pipeline.set_state(gst.STATE_PLAYING)
+ self.label.append("connected")
+ self.record.setEnabled(False)
+ self.monitor.setEnabled(False)
+ self.dump.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.stream.setChecked(0)
+ return -1
+ else:
+ self.label.append("disconnecting")
+ try:
+ self.dump.setChecked(False)
+ self.dumpstream()
+ self.audio_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("disconnected")
+ self.record.setEnabled(True)
+ self.monitor.setEnabled(True)
+ self.dump.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+ def monstr(self):
+ if self.monitor.isChecked():
+ try:
+ self.label.append("monitoring")
+ self.mon_pipeline = gst.parse_launch(sndarch+" !"+sndarchsink)
+ self.mon_pipeline.get_bus().add_watch(self.eventos)
+ self.mon_pipeline.set_state(gst.STATE_PLAYING)
+ self.record.setEnabled(False)
+ self.stream.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.monitor.setChecked(0)
+ return -1
+ else:
+ self.label.append("disabling monitor")
+ try:
+ self.mon_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("unmonitoring")
+ self.record.setEnabled(True)
+ self.stream.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+ def recordstr(self):
+ if self.record.isChecked():
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ filename = str(filename)
+ try:
+ self.label.append("recording")
+ self.rec_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! filesink location="+filename)
+ self.rec_pipeline.get_bus().add_watch(self.eventos)
+ self.rec_pipeline.set_state(gst.STATE_PLAYING)
+ self.stream.setEnabled(False)
+ self.monitor.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.record.setChecked(0)
+ return -1
+ else:
+ self.label.append("stop recording")
+ try:
+ self.rec_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("stoped")
+ self.stream.setEnabled(True)
+ self.monitor.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+
+ def alert(self, msg):
+ QtGui.QMessageBox.critical(self, 'CRITICAL', msg, QtGui.QMessageBox.Ok)
+ def pregunta(self, msg):
+ pregunta=QtGui.QMessageBox.question(self, 'ATENCIO', msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ #resposta=pregunta.exec()
+ if pregunta == 1024:
+ return "OK"
+ else :
+ return "Cancel"
+ def quito(self,**kwargs):
+ self.close()
+ def setserver(self,**kwargs):
+ os.popen2(term+" -e \"nano ~/.qice/server.cfg\"")
+ config.read(config_file)
+ def aumixer(self,**kwargs):
+ os.popen2("aumix")
+ def eventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ return True
+ def connectEventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ self.stream.setChecked(False)
+ self.streamcon()
+ return True
+ def dumpstream(self):
+ if self.dump.isChecked():
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ self.filename = str(filename)
+ self.label.append("dumping")
+ mplayer=os.popen2( term+" -e \"mplayer http://"+self.server+":"+self.port+"/"+self.mount+" -dumpstream -dumpfile "+self.filename+" && sleep 2\"")[1].readline()
+
+ else:
+ pidofmp=os.popen2("pidof mplayer")[1].readline()
+ if pidofmp!="":
+ os.popen2("kill -15 `pidof mplayer`")
+
+
+def main(args):
+ app=QtGui.QApplication(args)
+ win=MainWindow()
+ win.show()
+ win.setWindowTitle("Qice")
+ app.connect(app, QtCore.SIGNAL("lastWindowClosed()")
+ , app
+ , QtCore.SLOT("quit()")
+ )
+ app.exec_()
+
+if __name__=="__main__":
+ main(sys.argv)
--- /dev/null
+import bdist_debian
+from distutils.core import setup
+
+setup(name='qice-maemo',
+ version='1.0.0',
+ scripts=['qice.py'],
+ section='user/extras',
+ mantainer='Aleix Quintana',
+ mantainer_email='kinta@communia.org',
+ depends='libshout3, aumix-gtk, python2.5-qt4-common, python2.5-gstreamer, mplayer',
+ description='Client to Icecast, and ogg recorder',
+ long_description='Client to Icecast, using the microphone to stream directly to an icecast server. You can also use it to record in ogg',
+ data_files = [
+ ('share/pixmaps', ['qice.png']),
+ ('share/applications/hildon', ['qice.desktop']),
+ ('share/doc/qice-maemo', ['copyright']),
+ ('lib/gstreamer-0.10', ['libgstshout2.so']),
+ ('lib/gstreamer-0.10', ['libgstvorbis.so']),
+ ],
+ icon='qice.png',
+ cmdclass={'bdist_debian': bdist_debian.bdist_debian})