Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 10/10/2013, à 07:56

k3c

conseils pour une petite application graphique

Ave

J'ai écrit un petit programme graphique avec 3 boutons qui enrobe la récupération de vidéos de la BBC avec get_iplayer.

J'ai utilisé Tkinter, c'est moche et ça marche.

Que me conseillez-vous ?

Pyqt, WxPython...

Merci pour vos lumières/ idées d'amélioration

Si vous voulez tester, installez get_iplayer, rentrez par exemple
Wrong Mans
puis cliquer sur Film
cela va vous proposer les épisodes 1, 2, et 3
vous en sélectionnez un, puis cliquez sur download
et vous aurez une vidéo et un fichier de sous-titres, du même nom.

le code du programme graphique

#!/usr/bin/python
#-*- coding:utf-8 -*-
#

import os
import os.path
import posixpath
import shutil
import re
import StringIO
import ConfigParser
import subprocess
from threading   import Thread
try:
    from tkinter import *
except:
    from Tkinter import *
from ScrolledText import ScrolledText
import tkMessageBox
from tkColorChooser import askcolor              
import tkFileDialog
import distutils.dir_util
from Queue import Queue, Empty

ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False
thread1 = None
force = None
root = None
process = None
queue = Queue()

def start_thread(func, *args):
    t = Thread(target=func, args=args)
    t.daemon = True
    t.start()
    return t

def consume(infile):
    for line in iter(infile.readline, ''):
        queue.put(line)
    infile.close()

def callback1():
    global dirfilms, lsb, thread1, txt
    # print 'callback1', dirfilms.get()
    lsb.delete(0, END)
    args = ["get_iplayer", dirfilms.get()]
    app = subprocess.Popen(args=args, stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT)
    (stdout, stderr) = app.communicate()
    if app.returncode == 1:   # sortie en erreur →
        txt.insert(END, 'get_iplayer fail\n')
    else:
        lines = stdout.split('\n')
        for line in lines:
            txt.insert(END, line + '\n')
        lines = lines[6:-3]
        n = 0
        for line in lines:
            line = line.replace('\t', ' ')
            if line.startswith('...'): continue
            line = line.replace('Added: ','')
            n += 1
            lsb.insert(END, line)
        txt.insert(END, 'get_iplayed success, %s founds\n' % (n,))


def callback3():
    global lsb, process
    sel = lsb.curselection()
    sel = None if len(sel) == 0 else sel[0]
    # print 'callback3', sel,
    if sel:
        # print lsb.get(sel)
        # print 'force=', force.get()
        args = ["python", "/home/gg/bbc33.py", lsb.get(sel).split(':')[0], str(force.get())]
        process = subprocess.Popen(args=args, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, close_fds=ON_POSIX)
        thread1 = start_thread(consume, process.stdout)
        # thread1.join() # wait for IO completion
        # if app.returncode == 1:   # sortie en erreur →
        #     print 'ko'
        # else:
        #     print 'ok', stdout
    else:
        print

def on_delete():
    global root, process
    if process:
        process.kill()
    print "sortie du programme"
    root.destroy()

def on_after():
    global queue, txt, root
    while True:
        try:
            v = queue.get_nowait()
        except Empty:
            break;
        txt.insert(END, v)
    root.after(200, on_after)

root = Tk()

bt1 = Button(root, text='Films', command=callback1)
dirfilms = StringVar()
Entry(root, textvariable=dirfilms, width=100).pack()
bt1.pack()
fr = Frame(root)
scrollbar = Scrollbar(fr)
scrollbar.pack(side=RIGHT, fill=Y)
lsb = Listbox(fr)
lsb.pack(fill=X)
fr.pack(fill=X)
# attach listbox to scrollbar
lsb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lsb.yview)
fr = Frame()
bt2 = Button(fr, text='Download', command=callback3)
bt2.pack(side=LEFT)
force = IntVar()
force.set(0)
Checkbutton(fr, text="Force", variable=force).pack(side=LEFT)
fr.pack()

txt=ScrolledText(root, width=100,height=50)
txt.pack(fill=X)

root.wm_protocol ("WM_DELETE_WINDOW", on_delete)
root.after(1000, on_after)

root.mainloop()

Le code du script Python appelé

#!/usr/bin/env python                                                                                                                                                   
# -*- coding:utf-8 -*-                                                                                                                                                  
# bbc_proxy version 0.2 par k3c, sortie quand deja telecharge                                                                                                                                         
# passage de proxy en 2 ème parametre                                                                                                                                   
import subprocess, sys, shlex
import random
import urllib2
import bs4 as BeautifulSoup
import socket
from threading   import Thread

ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False

listeUserAgents = [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
                                                'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1',
                                                'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13\
',
                                                'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) midori',
                                                'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.107 Safari/535.1',
                                                'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312',
                                                'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11',
                                                'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.940.0 Safari/535.8' ]
allTimeouts = (3, 10, 15, 20)

class FlushFile(object):
    """Write-only flushing wrapper for file-type objects."""
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

def start_thread(func, *args):
    t = Thread(target=func, args=args)
    t.daemon = True
    t.start()
    return t

def consume(infile):
    global Finished
    for line in iter(infile.readline, ''):
        if 'Finished writing to temp file.' in line:
            Finished = True
        if 'Already in history' in line:
            Finished = True
        print line,

    infile.close()

def getProxy():
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', random.choice(listeUserAgents))]
    data = opener.open('http://free-proxy-list.net/uk-proxy.html').read()
    opener.close()
    soup = BeautifulSoup.BeautifulSoup(data)
    lst = []
    for tr in soup.tbody.findAll('tr'):
        i = 0
        slst = []
        for td in tr.find_all('td'):
            i += 1
            if i in (1, 2, 5):
                slst.append(td.contents[0])
            elif i == 8:
                i = 0
                lst.append(slst)
                slst = []
    for href in lst:
        yield href

def getValidProxy():
    for timeout in allTimeouts:
        print 'Timeout =', timeout
        socket.setdefaulttimeout(timeout)
        for host, port, typeproxy in getProxy():
            try:
                print 'Trying %s:%s' % (host, port)
                params = (host, int(port))
#                buffer_size = 1024
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect(params)
                s.close()
                yield host, port, typeproxy
                #   except urllib2.URLError:
                #       pass
            except socket.timeout:
                pass
            except socket.error:
                pass

def main():
    global Finished
    # Replace stdout with an automatically flushing version
    sys.stdout = FlushFile(sys.__stdout__)
    idvideo = sys.argv[1]
    for host, port, typeproxy in getValidProxy():
        print host, port, typeproxy
        if len(sys.argv) > 1 and sys.argv[2] == '1':

            cmds = "get_iplayer --get "+idvideo + " --subtitles --force -p 'http://"+host+":"+port+"'"
        else:
            cmds = "get_iplayer --get "+idvideo + " --subtitles -p 'http://"+host+":"+port+"'"

        arguments = shlex.split(cmds)
        print cmds
        Finished = False
        process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        thread1 = start_thread(consume, process.stdout)
        thread2 = start_thread(consume, process.stderr)
        thread1.join() # wait for IO completion
        thread2.join() # wait for IO completion
        retcode = process.wait()
        print retcode
        if Finished:
            break

if __name__ == "__main__":
    main()

Debian 12 sur Thinkpad reconditionné

Hors ligne

#2 Le 10/10/2013, à 16:59

k3c

Re : conseils pour une petite application graphique

Nouvelle version de la partie graphique

#!/usr/bin/python
#-*- coding:utf-8 -*-
#

import os
import os.path
import posixpath
import shutil
import re
import StringIO
import ConfigParser
import subprocess
from threading   import Thread
try:
    from tkinter import *
except:
    from Tkinter import *
from ScrolledText import ScrolledText
import tkMessageBox
from tkColorChooser import askcolor              
import tkFileDialog
import distutils.dir_util
from Queue import Queue, Empty

ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False
thread1 = None
force = None
root = None
process = None
queue = Queue()
manager = None
txt = None
df = None

def busy():
    global manager, df
    txt.config(cursor="watch")
    df.config(cursor="watch")
    root.config(cursor="watch")

def notbusy():
    global manager, df
    txt.config(cursor="")
    df.config(cursor="")
    root.config(cursor="")

def start_thread(func, *args):
    t = Thread(target=func, args=args)
    t.daemon = True
    t.start()
    return t

def consume(infile):
    for line in iter(infile.readline, ''):
        queue.put(line)
    infile.close()

def callback0():
    global dirfilms, lsb, thread1, txt
    # print 'callback1', dirfilms.get()
    lsb.delete(0, END)
    txt.delete(1.0, END)
    args = ["get_iplayer", dirfilms.get()]
    if refresh.get():
        args.append('-f')
    app = subprocess.Popen(args=args, stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT)
    (stdout, stderr) = app.communicate()
    notbusy()
    if app.returncode == 1:   # sortie en erreur →
        txt.insert(END, 'get_iplayer fail\n')
    else:
        lines = stdout.split('\n')
        for line in lines:
            txt.insert(END, line + '\n')
        n = 1
        for line in lines:
            if line.startswith('Matches:'):
                break
            n += 1
        
        lines = lines[n:-3] if n <= len(lines) else []
        n = 0
        for line in lines:
            line = line.replace('\t', ' ')
            line = line.replace('Added: ','')
            n += 1
            lsb.insert(END, line)
        txt.insert(END, 'get_iplayed success, %s founds\n' % (n,))

def callback1():
    global root
    busy()
    root.after_idle(callback0)

def callback3():
    global lsb, process
    sel = lsb.curselection()
    sel = None if len(sel) == 0 else sel[0]
    # print 'callback3', sel,
    if sel:
        # print lsb.get(sel)
        # print 'force=', force.get()
        args = ["python", "/home/gg/bbc33.py", lsb.get(sel).split(':')[0], str(force.get())]
        process = subprocess.Popen(args=args, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, close_fds=ON_POSIX)
        thread1 = start_thread(consume, process.stdout)
        # thread1.join() # wait for IO completion
        # if app.returncode == 1:   # sortie en erreur →
        #     print 'ko'
        # else:
        #     print 'ok', stdout
    else:
        print

def on_delete():
    global root, process
    if process:
        process.kill()
    print "sortie du programme"
    root.destroy()

def on_after():
    global queue, txt, root
    while True:
        try:
            v = queue.get_nowait()
        except Empty:
            break;
        txt.insert(END, v)
    root.after(200, on_after)

root = Tk(root)
fr = Frame()
bt1 = Button(fr, text='Films/Séries', command=callback1)
dirfilms = StringVar()
refresh = IntVar()
refresh.set(0)
df = Entry(fr, textvariable=dirfilms, width=100)
df.pack(side=LEFT)
bt1.pack(side=LEFT)
Checkbutton(fr, text="refresh du cache de la BBC", variable=refresh).pack(side=LEFT)
fr.pack()
fr = Frame(root)
scrollbar = Scrollbar(fr)
scrollbar.pack(side=RIGHT, fill=Y)
lsb = Listbox(fr)
lsb.pack(fill=X)
fr.pack(fill=X)
# attach listbox to scrollbar
lsb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lsb.yview)
fr = Frame(root)
bt2 = Button(fr, text='Download', command=callback3)
bt2.pack(side=LEFT)
force = IntVar()
force.set(0)
Checkbutton(fr, text="Force", variable=force).pack(side=LEFT)
fr.pack()

fr = Frame(root)
txt = ScrolledText(fr, width=100,height=50)
txt.pack(fill=X)
fr.pack(fill=X)

root.wm_protocol ("WM_DELETE_WINDOW", on_delete)
root.after(1000, on_after)

root.mainloop()

Debian 12 sur Thinkpad reconditionné

Hors ligne

#3 Le 11/10/2013, à 08:34

LapiGNU

Re : conseils pour une petite application graphique

Salut,

je ne sais pas à quoi ressemble ton appli, mais si tu veux quelque chose qui ressemble à tes applis GTK, je te suggère gtkdialog ; pour voir à quoi ça ressemble côté visuel et côté code (dans du bash, en l'occurence) : http://puppy2.org/slaxer/Porteus/Gtkdia … color.html

Hoplà !

PS: tu bootes quoi sur clé USB dans ton Ebox ? Perso, j'ai mis un dur 2"5 dans le mien, ça ouvre pas mal de perspectives ! (bon, là mon dur est mort ...)


frenchKISS sur www.tchitcha.info, Ubuntu clé en main pour les réseaux de postes de travail.
et surtout : Sauvez les arbres, mangez des castors. Sauvez les castors, ne mangez pas d'arbres !

Hors ligne

#4 Le 11/10/2013, à 12:19

k3c

Re : conseils pour une petite application graphique

Je vais regarder GTKDialog, merci.

J'ai essayé plusieurs OS, j'ai préféré Toutou Linux (variante française de Puppy Linux).
Sinon DSL (Damn Small Linux) est très bien aussi.


Debian 12 sur Thinkpad reconditionné

Hors ligne