Added initial code master
authorkinta <kinta@communia.org>
Fri, 12 Dec 2008 12:34:00 +0000 (12:34 +0000)
committerkinta <kinta@communia.org>
Fri, 12 Dec 2008 12:34:00 +0000 (12:34 +0000)
git-svn-id: file:///svnroot/qice/trunk@3 e9839b59-6115-4633-8823-be5c8faaf4ff

13 files changed:
READMEPKG [new file with mode: 0644]
bdist_debian.py [new file with mode: 0644]
build/scripts-2.5/qice.py [new file with mode: 0755]
copyright [new file with mode: 0644]
dist/control [new file with mode: 0644]
dist/control.tar.gz [new file with mode: 0644]
dist/data.tar.gz [new file with mode: 0644]
dist/debian-binary [new file with mode: 0644]
dist/qice-maemo_1.0.0_all.deb [new file with mode: 0644]
qice.desktop [new file with mode: 0644]
qice.png [new file with mode: 0644]
qice.py [new file with mode: 0644]
setup.py [new file with mode: 0644]

diff --git a/READMEPKG b/READMEPKG
new file mode 100644 (file)
index 0000000..0677ae2
--- /dev/null
+++ b/READMEPKG
@@ -0,0 +1 @@
+you do "python setup.py bdist_debian" and it creates the .deb file in the "dist" subdirectory. That's it! You're done!
diff --git a/bdist_debian.py b/bdist_debian.py
new file mode 100644 (file)
index 0000000..16fb890
--- /dev/null
@@ -0,0 +1,149 @@
+# 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])
diff --git a/build/scripts-2.5/qice.py b/build/scripts-2.5/qice.py
new file mode 100755 (executable)
index 0000000..0e05fff
--- /dev/null
@@ -0,0 +1,256 @@
+#!/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)
diff --git a/copyright b/copyright
new file mode 100644 (file)
index 0000000..e2fb8a3
--- /dev/null
+++ b/copyright
@@ -0,0 +1,14 @@
+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
diff --git a/dist/control b/dist/control
new file mode 100644 (file)
index 0000000..ae9e486
--- /dev/null
@@ -0,0 +1,44 @@
+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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
+
diff --git a/dist/control.tar.gz b/dist/control.tar.gz
new file mode 100644 (file)
index 0000000..84d2d27
Binary files /dev/null and b/dist/control.tar.gz differ
diff --git a/dist/data.tar.gz b/dist/data.tar.gz
new file mode 100644 (file)
index 0000000..794ad8f
Binary files /dev/null and b/dist/data.tar.gz differ
diff --git a/dist/debian-binary b/dist/debian-binary
new file mode 100644 (file)
index 0000000..cd5ac03
--- /dev/null
@@ -0,0 +1 @@
+2.0
diff --git a/dist/qice-maemo_1.0.0_all.deb b/dist/qice-maemo_1.0.0_all.deb
new file mode 100644 (file)
index 0000000..c024bbf
Binary files /dev/null and b/dist/qice-maemo_1.0.0_all.deb differ
diff --git a/qice.desktop b/qice.desktop
new file mode 100644 (file)
index 0000000..1a4ae49
--- /dev/null
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Version=1.0.0
+Encoding=UTF-8
+Name=qice-maemo
+Exec=/usr/bin/qice.py
+Icon=qice
+Type=Application
diff --git a/qice.png b/qice.png
new file mode 100644 (file)
index 0000000..d0ea312
Binary files /dev/null and b/qice.png differ
diff --git a/qice.py b/qice.py
new file mode 100644 (file)
index 0000000..bef012e
--- /dev/null
+++ b/qice.py
@@ -0,0 +1,256 @@
+#!/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)
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..39c718d
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,21 @@
+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})