2010-01-23 3 views
3

У меня есть сценарий загрузки. Но мне нужно выяснить, как создать скрипт, который я могу запустить как демон в python, чтобы обработать часть преобразования и переместить файл, который был преобразован в свое окончательное место отдыха. что я до сих пор использовал для сценария наблюдателя в каталоге:python automate ffmpeg преобразование из каталога загрузки

#!/usr/bin/python 

import os 
import pyinotify import WatchManager, Notifier, ThreadedNotifier, ProcessEvent, EventCodes 
import sys, time, syslog, config 
from os import system 
from daemon import Daemon 

class myLog(ProcessEvent): 
def process_IN_CREATE(self, event): 
    syslog.syslog("creating: " + event.pathname) 
def process_IN_DELETE(self, event): 
    syslog.syslog("deleting: " + event.pathname) 
def process_default(self, event): 
    syslog.syslog("default: " + event.pathname) 

class MyDaemon(Daemon): 
def loadConfig(self): 
    """Load user configuration file""" 
    self.config = {} 
    self.parser = ConfigParser.ConfigParser() 
    if not os.path.isfile(self.configfile): 
    self.parser.write(open(self.configfile, 'w')) 
    self.parser.readfp(open(self.configfile, 'r')) 

    variables = { \ 
    'mplayer': ['paths', self.findProgram("mplayer")], \ 
    'mencoder': ['paths', self.findProgram("mencoder")], \ 
    'tcprobe': ['paths', self.findProgram("tcprobe")], \ 
    'transcode': ['paths', self.findProgram("transcode")], \ 
    'ogmmerge': ['paths', self.findProgram("ogmmerge")], \ 
    'outputdir': ['paths', os.path.expanduser("~")], \ 
    } 

    for key in variables.keys(): 
    self.cautiousLoad(variables[key][0], key, variables[key][1]) 

def cautiousLoad(self, section, var, default): 
    """Load a configurable variable within an exception clause, 
    in case variable is not in configuration file""" 
    try: 
    self.config[var] = int(self.parser.get(section, var)) 
    except: 
    self.config[var] = default 
    try: 
    self.parser.set(section, var, default) 
    except: 
    self.parser.add_section(section) 
    self.parser.set(section, var, default) 
    self.parser.write(open(self.configfile, 'w')) 


def findProgram(self, program): 
    """Looks for program in path, and returns full path if found""" 
    for path in config.paths: 
    if os.path.isfile(os.path.join(path, program)): 
    return os.path.join(path, program) 
    self.ui_configError(program) 

def run(self): 
    syslog.openlog('mediaConvertor', syslog.LOG_PID,syslog.LOG_DAEMON) 
    syslog.syslog('daemon started, entering loop') 
    wm = WatchManager() 
    mask = IN_DELETE | IN_CREATE 
    notifier = ThreadedNotifier(wm, myLog()) 
    notifier.start() 
    wdd = wm.add_watch(self.config['outputdir'], mask, rec=True) 
    while True: 
    time.sleep(1) 
    wm.rm_watch(wdd.values()) 
    notifier.stop() 
    syslog.syslog('exiting media convertor') 
    syslog.closelog() 

if __name__ == "__main__": 
daemon = MyDaemon('/tmp/mediaconvertor.pid') 
if len(sys.argv) == 2: 
    if 'start' == sys.argv[1]: 
    daemon.run() 
    if 'stop' == sys.argv[1]: 
    daemon.stop() 
    if 'restart' == sys.argv[1]: 
    daemon.restart() 
    else: 
    print "Unknown Command" 
    sys.exit(2) 
    sys.exit(0) 
else: 
    print "Usage: %s start|stop|restart" % sys.argv[0] 
    sys.exit(2) 

не уверен, куда идти отсюда.

+0

У кого-нибудь есть идеи по этому поводу? – Moos3

ответ

3

Я не работаю на Linux и никогда не использовал возможности inotify, которые вы используете здесь. Я опишу, как я буду делать вещи в целом.

В простейшем случае вам нужно проверить, есть ли новый файл в каталоге загрузки, а когда есть, начните делать уведомление об изменении.

Чтобы проверить, есть ли новые файлы, которые вы можете сделать что-то вроде:

import os 
import time 

def watch_directory(dirname="."): 
    old_files = set(os.listdir(dirname)) 
    while 1: 
     time.sleep(1) 
     new_files = set(os.listdir(dirname)) 
     diff = new_files - old_files 
     if diff: 
      print "New files", diff 
     old_files = new_files 

watch_directory() 

Вы можете быть в состоянии минимизировать некоторые файловую систему накладных расходов на первом применение stat каталога, чтобы увидеть, есть ли какое-либо изменение.

def watch_directory(dirname="."): 
    old_files = set(os.listdir(dirname)) 
    old_stat = os.stat(dirname) 
    while 1: 
     time.sleep(1) 
     new_stat = os.stat(dirname) 
     if new_stat == old_stat: 
      continue 
     new_files = set(os.listdir(dirname)) 
     diff = new_files - old_files 
     if diff: 
      print "New files", diff 
     old_stat = new_stat 
     old_files = new_files 

С Inotify Я думаю, что это все обрабатывается для вас, и вы поставите свой код в process_IN_CREATE(), который вызывается, когда новый файл доступен.

Один из недостатков - как наблюдатель знает, что загрузка завершена? Что произойдет, если загрузка будет отменена частично путем загрузки? Это может быть так же просто, как заставить веб-сервер переименовать() для использования одного расширения во время загрузки и другого расширения, когда это будет сделано.

После того, как вы знаете файл, используйте subprocess.Popen (conversion_program, «new_filename») или os.system («conversion_program new_filename &») на икру от преобразования в новом процессе, который делает преобразование. Вам нужно будет обрабатывать такие вещи, как отчет об ошибках, например, когда вход не в правильном формате. Он также должен очищать, что означает, что после завершения преобразования он должен удалить входной файл из соображений. Это может быть так же просто, как удалить файл.

Вам также нужно будет беспокоиться о перезапуске любых убитых конверсий. Если машина работает, как перезапустимый наблюдатель знает, какие преобразования файлов данных также были убиты и их необходимо перезапустить. Но это может быть выполнимо как ручной шаг.

+0

круто спасибо, я собираюсь попробовать то, что вы упомянули, и выяснить больше о том, как inotify знает, как процесс создания файла завершен или неполный. – Moos3

+0

Он знает, потому что есть подсистема, специфичная для Linux, программы которой могут использовать для просмотра каталога для изменений. Это не стандарт и не работает на других ОС. –