Guillaume
Guillaume

Reputation: 2916

Running a script bash with using VTE module

I'm trying to use the VTE module to run a script bash: I have several errors, One of them is:

avconv version 9.11-6:9.11-2ubuntu2, Copyright (c) 2000-2013 the Libav developers
  built on Mar 24 2014 06:12:33 with gcc 4.8 (Ubuntu 4.8.2-17ubuntu1)
: No such file or directory

Here is a piece of my python script:

def download(self, a, donnees=None):                
      adresse = self.champ.get_text()
      self.v.fork_command('./pluzz.sh', '-u', adresse)  # calling the bash script
[...]
def __init__(self):       
      self.v = vte.Terminal()
      self.v.set_emulation('xterm')
      self.v.show()
      self.box1.add(self.v)

And a piece of the bash script:

echo -e "$VERT""DEBUT DU TRAITEMENT""$NORMAL"

#Recuperation de l' ID de l' emission
UserAgent='Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'
ID=$(wget -q -U "${UserAgent}" "${URL}" -O - | grep -E "og:url.*content.*http://*" | sed 's+.*,\([0-9]*\).*+\1+g')

#wget du json conteant les infos
echo -e "$ROSE""-->RECUPERATION DU JSON""$NORMAL"
JSON="$(wget -q -U "${UserAgent}" "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion=${ID}&catalogue=Pluzz&callback=webserviceCallback_${ID}" -O - | sed 's+\\/+/+g')"

#Recuperation des infos
echo -e "$ROSE""-->TRAITEMENT DU JSON""$NORMAL"
DATE="$(echo "${JSON}" | sed 's+.*date_debut..\"\([^\"]*\)\".*+\1+g')"
PROG="$(echo "${JSON}" | sed 's+.*code_programme..\"\([^\"]*\)\".*+\1+g')"
M3U="$(echo "${JSON}" | sed 's+.*url..\"\([^\"]*m3u8\)\".*+\1+g')"

#Recuperation du master M3U et traitement
echo -e "$BLEU""-->RECUPERATION DU FICHIER VIDEO""$NORMAL"
M3U2="$(wget -q -U "'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'" "${M3U}" -O - | grep -E ".*index_2.*")"

avconv -i "${M3U2}" -vcodec copy -acodec copy "${PROG}_${ID}.mkv"

The bash script is running well in the console:

:~./pluzz.sh http://pluzz.francetv.fr/videos/coluche_un_clown_ennemi_d_etat.html
DEBUT DU TRAITEMENT
-->RECUPERATION DU JSON
-->TRAITEMENT DU JSON
-->RECUPERATION DU FICHIER VIDEO
avconv version 9.11-6:9.11-2ubuntu2, Copyright (c) 2000-2013 the Libav developers
  built on Mar 24 2014 06:12:33 with gcc 4.8 (Ubuntu 4.8.2-17ubuntu1)
[hls,applehttp @ 0x1ebfe00] max_analyze_duration reached
Input #0, hls,applehttp, from 'http://ftvodhdsecz-f.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2014/S18/J5/101152365-20140502-,398,632,934,k.mp4.csmil/index_2_av.m3u8?null=':
  Duration: 00:56:10.00, start: 0.100667, bitrate: 0 kb/s
    Stream #0.0: Video: h264 (Main), yuv420p, 704x396 [PAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0.1: Audio: aac, 48000 Hz, stereo, fltp
    Stream #0.2: Data: [21][0][0][0] / 0x0015

I hope my explaination is clear... Thanks

Edit: I've found a solution: Replace

self.v.fork_command('./pluzz.sh', '-u', adresse)

by

self.v.fork_command(None, ['/bin/bash', '-u', './pluzz.sh', adresse])

Upvotes: 1

Views: 625

Answers (1)

zmo
zmo

Reputation: 24812

my guess is that your problem is due to:

  self.v.fork_command('./pluzz.sh', '-u', adresse)  # calling the bash script

which assumes two things:

  1. that the script is in the same directory as where the application has been launched from ;
  2. that the script is executable and can be ran as standalone

but for 2., the script is missing the #!/bin/bash shebang header to tell the system that it is a shell script to be executed, and for 1. you should better use an absolute path, or a path relative to the current module's file.

You should instead use a path relative to the current script, or an absolute path:

import sys
import os
### if the pluzz script is in same directory as your python app
pluzz_script = os.path.join(os.path.dirname(sys.argv[0]), 'pluzz.sh')
### explicitely run bash, to have it run your script
self.v.fork_command('/bin/bash', pluzz_script, '-u', address)

edit: rereading your post, it looks like it's not actually. Though you should take my previous advice to avoid any further problem with your script once you'll distribute it.

Your problem is that actually the file has not been downloaded, or couldn't be written and avconv can't access it. It's hard to tell what's wrong as the script does not let wget's output through. Though you'd better convert that script to python and use a safe temporary directory to download the file in and work it out.

Here's a translation of your script in python:

# echo -e "$VERT""DEBUT DU TRAITEMENT""$NORMAL"
# retrieval of the show's id

from lxml import etree
import subprocess
import requests
import json
import os

### User defined values:
url='http://pluzz.francetv.fr/videos/doctor_who.html'
target_path=os.path.join(os.environ['HOME'], 'Downloads')
###

headers={'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'}

##### ID=$(wget -q -U "${UserAgent}" "${URL}" -O - | grep -E "og:url.*content.*http://*" | sed 's+.*,\([0-9]*\).*+\1+g')
p = etree.HTML(requests.get(url, headers=headers).text)
show_id = p.xpath('//meta[@property="og:url"]/@content')[0].split(',')[-1].split('.')[0]

##### get the JSON containing the show's data
##### JSON="$(wget -q -U "${UserAgent}" "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion=${ID}&catalogue=Pluzz&callback=webserviceCallback_${ID}" -O - | sed 's+\\/+/+g')"
show_data_url = "http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion={show}&catalogue=Pluzz&callback=webserviceCallback_{show}"
show_data = json.loads("".join(requests.get(show_data_url.format(show=show_id), headers=headers).text.split('(')[1:])[:-1])

# retrieve data from the json
##### DATE="$(echo "${JSON}" | sed 's+.*date_debut..\"\([^\"]*\)\".*+\1+g')"
##### PROG="$(echo "${JSON}" | sed 's+.*code_programme..\"\([^\"]*\)\".*+\1+g')"
##### M3U="$(echo "${JSON}" | sed 's+.*url..\"\([^\"]*m3u8\)\".*+\1+g')"
# date = show_data['diffusion']['date_debut']
# prog = show_data['code_programme']
# m3u = list(filter(lambda x: x['format'] == 'm3u8-download', j['videos']))[0]['url']

p = requests.get(list(filter(lambda x: x['format'] == 'm3u8-download', show_data['videos']))[0]['url'], headers=headers).text

# M3U retrieval
##### M3U2="$(wget -q "${M3U}" -O - | grep -E ".*index_2.*")"
video_url = list(filter(lambda l: "index_2" in l, p.split()))[0]

##### avconv -i "${M3U2}" -vcodec copy -acodec copy "${PROG}_${ID}.mkv"

dest_file = "{}_{}.mkv".format(show_data['code_programme'], show_id)
subprocess.call(['avconv', '-i', video_url, '-vcodec', 'copy', '-acodec', 'copy', os.path.join(target_path, dest_file)])

or you can use to process avconv's output:

p = subprocess.Popen(['avconv', '-i', video_url, '-vcodec', 'copy', '-acodec', 'copy', os.path.join(target_path, dest_file)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

for line in out:
    print(out)

so you can build a progress bar in your application's UI, instead of an ugly terminal output.

I have built another version of the code that has a better design, has a command line argument parser, and processes the line output to show a progressbar:

HTH

Upvotes: 1

Related Questions