1. fak3
  2. gosvideo

Commits

fak3  committed 9cac755

calculate lengths and report

  • Participants
  • Parent commits 059bd61
  • Branches default

Comments (0)

Files changed (5)

File gos_logger.py

View file
             'level': 'ERROR',
             'propagate': True,
         },
+        'enzyme.mp4': {
+            'handlers': ['console'],
+            'level': 'ERROR',
+            'propagate': False,
+        },
         'fabric': {
             'handlers': ['console'],
             'level': 'ERROR',

File gui_dialogs.py

View file
 from PyQt4.QtWebKit import *
 from PyQt4.QtNetwork import *
 
-
 import utils
 import conf
 
 
 def fix_orders(regions = None):
     '''  '''
+    
     if not regions:
         regions = load_regions()
         
     def rename(self):
         rename_old_files(self.settings)
         
+
+def parse_lengths():
+    logging.info(u'Вычисляется длительность всех скачанных видеофайлов')
+    settings = load_settings()  
+    orders = load_orders()
+    try:
+        for o in orders.values():
+            parse_order_videolen(settings['download_dir'], o)
+    finally:
+        dump_orders(orders)
+        
+        
+class GetLenAction(ActionSetting):
+    def __init__(self, settings, parent):
+        text = textwrap.dedent(u'''
+            Вычислить длительность всех скачанных видеофайлов
+        ''').replace('\n', '')
+        super(GetLenAction,self).__init__(u'Длительность видео', u'Вычислить', text, parse_lengths, parent)
+        
+    #def rename(self):
+        #parse_lengths(self.settings)
+        
     
     
 class BoolSetting(QGroupBox):
         
         self.settings = load_settings()
         
-        self.download_dir = DirSetting(u'Директория для скачанных файлов', 'download_dir', self.settings, self)
+        download_dir = DirSetting(u'Директория для скачанных файлов', 'download_dir', self.settings, self)
         
         max_time_text = u'Максимальное время, которое можно заказать'
-        self.max_time = OrderTimeSetting(u'Максимальное время для заказа', max_time_text, 'max_time', self.settings, self)
+        max_time = OrderTimeSetting(u'Максимальное время для заказа', max_time_text, 'max_time', self.settings, self)
         
         max_exec_time_text = textwrap.dedent(u'''
             MAX_EXEC - количество дней, за которое должен исполниться заказ.
             Будут проверяться только заказы за последние MAX_EXEC дней.
             Если заказы не успевают исполнить в этот срок, этот параметр следует увеличить.''').replace('\n', ' ')
-        self.max_exec_time = FetchTimeSetting(u'Максимальное время исполнения', max_exec_time_text, 'max_exec_time', self.settings, self)
+        max_exec_time = FetchTimeSetting(u'Максимальное время исполнения', max_exec_time_text, 'max_exec_time', self.settings, self)
         
         text = u"Качать сразу, до показа диалога"
-        self.download_first = BoolSetting(u'Кнопка "Скачать Исполненные"', text, 'download_before_dialog', self.settings, self)
+        download_first = BoolSetting(u'Кнопка "Скачать Исполненные"', text, 'download_before_dialog', self.settings, self)
             
-        self.rename_action = RenameAction(self.settings, self)
+        rename_action = RenameAction(self.settings, self)
+        getlen_action = GetLenAction(self.settings, self)
                     
-        self.ok = QPushButton('OK')
-        self.ok.clicked.connect(self.accept)
+        ok = QPushButton('OK')
+        ok.clicked.connect(self.accept)
         
         self.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
         
-        layout = VBox(self, [self.download_dir, self.max_time, self.max_exec_time, self.download_first, self.rename_action, self.ok])
+        layout = VBox(self, [download_dir, max_time, max_exec_time, download_first, rename_action, getlen_action, ok])
         
         
     def accept(self):
                 yield i
                 
     
+ERRORS = 'archive_err channel_err data_err len_err'.split()
+
 class GroupItem(TypedItem):
     def __init__(self, parent, name):
         super(GroupItem, self).__init__(parent, [name])
         self.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
     
     def check_self(self):
-        channel_errors, archive_errors, data_errors = 0, 0, 0
+        errs = dict(zip(ERRORS, [0, 0, 0, 0]))
         ordered, downloadable, waiting, downloaded = 0, 0, 0, 0
         col = cols['to_download'].num
         to_download_all = Qt.Checked
         for i in self.downloadable(only_leaves = True):
             ordered += 1
-            if i.channel_error: channel_errors += 1
-            if i.archive_error: archive_errors += 1
-            if i.data_error: data_errors += 1
+            for err in ERRORS:
+                if getattr(i, err): errs[err] += 1
             o = i.orderdata
             if not o['unavailable']:
                 if o['archive_urls']:
             if i.checkState(col) != Qt.Checked:
                 to_download_all = Qt.Unchecked
                 
-        self.setText(cols['a'].num, str(archive_errors))
-        self.setText(cols['c'].num, str(channel_errors))
-        self.setText(cols['d'].num, str(data_errors))
+        for err, ecol in zip(ERRORS, 'a c d l'.split()):
+            self.setText(cols[ecol].num, str(errs[err]))
         
         self.setCheckState(col, to_download_all)
         self.setText(cols['ordered'].num, str(ordered))
             
         orderurl = u"https://www.gosuslugi.ru/pgu/personcab/orders/details?elementId=%(orderId)s#_results" % orderdata
         text += u'<a href="%(orderurl)s">%(orderurl)s</a> <br/><br/>' % locals()
+        text += u'заказан %s<br/><br/>' % datetime.fromtimestamp(orderdata['createDate']/1000)
         
         text += u'''<b>Статус</b><br/>
             %(orderStatusName)s<br/><br/>
         self.layout = VBox(self, [self.text, self.bbox])
     
     
+MIN_LEN = 60*29 + 50
+
 class DownloadableItem(TypedItem):
     def __init__(self, parent, order):
-        
-        self.channel_error = ''
-        self.archive_error = ''
-        self.data_error = ''
-        
+        archive_err, channel_err, data_err, len_err = '','','',''
         adata = order.get('archive_data')
         if adata:
             for key in 'region uik lstart'.split():
                 if adata.get(key) != order.get(key):
-                    self.data_error = 'D'
+                    data_err = 'D'
                     break
                     
             if len(adata['channels']) < 2:
-                self.channel_error = 'C'
+                channel_err = 'C'
             adata.get('')
                 
         if order['unavailable']:
             status = u'недоступен'
         elif order['empty_files']:
             status = u'нет файлов'
-            self.archive_error = 'A'
+            archive_err = 'A'
         else:
             status = order['orderStatusName']
             
-        dl_status = u'Скачан' if order['downloaded'] else u''
+        if not order['downloaded']:
+            dl_status = u''
+        else:
+            dl_status = u'Скачан'
+            if adata:
+                #len
+                for n, ch in enumerate(adata['channels']):
+                    l = ch.get('len')
+                    if l is None or l > MIN_LEN:
+                        continue
+                    if len_err:
+                        len_err += ', '
+                    if ch['view'] in [u'Урна', u'Комиссия']:
+                        len_err += ch['view'][0]
+                    else:
+                        len_err += 'C%d' % (n + 1)
+                    len_err += ' %d' % (l/60)
+                    
         wait_status = u'Да' if status.startswith(u'Принято') else ''
         
         time = lambda x: x.split()[1] if x != '?' else x
         
         string = u'%s %s (%s)' % (order['orderId'], dtime, status)
                         
-        super(DownloadableItem, self).__init__(parent, [string, '', self.archive_error, self.channel_error, self.data_error,  '', wait_status, dl_status])
+        super(DownloadableItem, self).__init__(parent, [string, '', archive_err, channel_err, data_err, len_err,  '', wait_status, dl_status])
         
         if status == u'Исполнено':
             self.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
             
         self.setCheckState(cols['to_download'].num, Qt.Checked if order['to_download'] else Qt.Unchecked)
         
-                
         self.orderdata = order
+        
+        for err in ERRORS:
+            setattr(self, err, locals().get(err))
     
     def show_info(self):
         dlg = OrderInfoDailog(self.orderdata)
     ('name',          (460, u'')),
     ('i',             (20,  u'i')),
     ('a',             (30,  u'A')),
-    ('c',             (30,  u'C')),
+    ('c',             (40,  u'C')),
     ('d',             (30,  u'D')),
+    ('l',             (90,  u'L')),
     ('ordered',       (90,  u'Заказано')),
     ('waiting',       (100, u'Ожидается')),
     ('not_downloaded',(110, u'Не Скачано')),
         self.dlg_val = []
         
         
-    sizeHint = lambda self: QSize(1100, 560)
+    sizeHint = lambda self: QSize(1180, 560)
     
     
     def itemChanged(self, item, col):

File gui_main.py

View file
             
             
     def init2(self):
+        try:
+            import enzyme
+        except ImportError:
+            m = QMessageBox.warning(None, u'enzyme не найден', u'Для работы программы требуется пакет enzyme')
+
+
         gui_dialogs.fix_orders()
             
         logging.info(u'Конфигурационные файлы находятся в директории %s' % conf.SHARED_DIR)

File main_utils.py

View file
 import requests
 from requests.exceptions import ConnectionError, Timeout, HTTPError
 
+try:
+    import enzyme
+except ImportError:
+    pass
+
 from pytils.translit import translify
 
 import utils
         region = re.split('[,;]', res['address'])[0],
         channels = res['channels'])
                 
-            
+
+def parse_len(fpath):
+    try:
+        logging.info(u'Вычисляется длительность %s', fpath)
+        return enzyme.parse(fpath).length
+    except enzyme.ParseError as e:
+        logging.error(u'%s %s', fpath, unicode(e))
+        
+        
+def parse_order_videolen(dl_dir, order):
+    adata = order.get('archive_data')
+    if not adata:
+        return
+    for ch, fname in adata_files(adata):
+        fpath = os.path.join(dl_dir, adata_dir(adata), fname)
+        if not os.path.exists(fpath):
+            continue
+        if ch.get('len') is not None:
+            continue
+        ch['len'] = parse_len(fpath)
+        
+        
 def get_files():
     ''' Скачивает файлы в исполненных услугах. '''
     orders = load_orders()
+    settings = load_settings()
+    dl_dir = settings['download_dir']
     
     ready = []
     for id, o in orders.items():
             logging.info(u'Получение файлов для заказа %(orderId)s' % o)
             try:
                 for url in o['archive_urls']:
-                    get_archive_files(url, on_stop = lambda: dump_orders(orders))
+                    get_archive_files(dl_dir, url, on_stop = lambda: dump_orders(orders))
                     o['archive_urls'][url] = {'status':'downloaded'}
                 o['to_download'] = False
                 o['downloaded'] = True
+                parse_order_videolen(dl_dir, o)
             except HTTPError as e:
                 if e.response.status_code == 404:
                     logging.info(u'Файл недоступен для скачивания. Взможно срок хранения заказа в архиве вышел. Попробуйте закать его повторно')
         dump_orders(orders)  
 
     
-def get_archive_files(archive_url, on_stop = None):
+def adata_dir(adata):
+    return os.path.join(adata['region'], adata['uik'])
+    
+    
+#def channel_file(n, ch, adata):
+    #return '%s__%s.mp4' % (name, dtime)
+    
+    
+def adata_files(adata):
+    lstart = datetime.strptime(adata['lstart'], '%d.%m.%Y %H:%M')
+    lend = datetime.strptime(adata['lend'], '%d.%m.%Y %H:%M')
+    dtime = '%s-%s' % (lstart.strftime('%H.%M'), lend.strftime('%H.%M'))
+    for n, ch in enumerate(adata['channels']):
+        name = translify(ch['view'] or u'Камера-%s' % n)
+        yield (ch, '%s__%s.mp4' % (name, dtime))
+        
+
+
+def get_archive_files(dl_dir, archive_url, on_stop = None):
     ''' Скачивает видеофайлы по ссылке '''
-    settings = load_settings()
-    outdir = settings['download_dir']
-    
     data = get_archive_data(archive_url)
     
-    lstart = datetime.strptime(data['lstart'], '%d.%m.%Y %H:%M')
-    lend = datetime.strptime(data['lend'], '%d.%m.%Y %H:%M')
-    dtime = '%s-%s' % (lstart.strftime('%H.%M'), lend.strftime('%H.%M'))
-    dir = os.path.join(outdir, data['region'], data['uik'])
+    dir = os.path.join(dl_dir, adata_dir(data))
     try:
         os.makedirs(dir)
     except:
         pass
     
-    for n, ch in enumerate(data['channels']):
-        #import pdb4qt; pdb4qt.set_trace()
-        name, url = ch['view'] or u'Камера-%s' % n, ch['url']
-        name = translify(name)
-        fname = os.path.join(dir, '__'.join([name, dtime]) + '.mp4')
-        if os.path.exists(fname):
-            logging.info(u'Файл %s уже существует, пропускаю' % fname)
+    for ch, fname in adata_files(data):
+        fpath = os.path.join(dir, fname)
+        
+        if os.path.exists(fpath):
+            logging.info(u'Файл %s уже существует, пропускаю' % fpath)
             continue
-        logging.info(u'Скачивается %s' % fname)
-        res = requests.get(url, timeout = 10, prefetch = False)
+        logging.info(u'Скачивается %s' % fpath)
+        res = requests.get(ch['url'], timeout = 10, prefetch = False)
         res.raise_for_status()
-        utils.download_file(res.raw, fname, on_stop)
-            
+        utils.download_file(res.raw, fpath, on_stop)
 
 
 

File requirements.txt

View file
 requests==0.13.2
 pytils
+enzyme