Esempio n. 1
0
def create_xml(xml_total):
    """
    Use the merged, parsed, cleaned, DB data to generate an XML used for file check in on the Dalet MAM.
    """

    config = cfg.get_config()
    rootpath = config['paths']['rootpath']
    xml_checkin = config['paths']['xml_checkin_path']
    os.chdir(rootpath)

    xml_1_msg = f"START GORILLA-DIVA XML CREATION"
    logger.info(xml_1_msg)

    try:
        conn = db.connect()
        cur = conn.cursor()
        sql = '''SELECT * FROM assets WHERE xml_created = 0'''

        xml_count = 0

        for row in cur.execute(sql).fetchall():

            if xml_count >= int(xml_total):
                break

            else:
                ROWID = row[0]
                GUID = row[1]
                NAME = row[2]
                FILESIZE = row[3]
                DATATAPEID = row[4]
                OBJECTNM = row[5]
                CONTENTLENGTH = row[6]
                SOURCECREATEDT = row[7]
                CREATEDT = row[8]
                LASTMDYDT = row[9]
                TIMECODEIN = row[10]
                TIMECODEOUT = row[11]
                ONAIRID = row[12]
                RURI = row[13]
                TITLETYPE = row[14]
                FRAMERATE = row[15]
                CODEC = row[16]
                V_WIDTH = row[17]
                V_HEIGHT = row[18]
                TRAFFIC_CODE = row[19]
                DURATION_MS = row[20]
                XML_CREATED = row[21]
                PROXY_COPIED = row[22]
                CONTENT_TYPE = row[23]
                FILENAME = row[24]
                OC_COMPONENT_NAME = row[31]

                if (DATATAPEID != 'unallocated' and DATATAPEID != 'NULL'
                        and OC_COMPONENT_NAME != 'NULL'):
                    guid = GUID
                    name = NAME
                    filename = FILENAME
                    datatapeid = DATATAPEID
                    timecodein = TIMECODEIN
                    folderpath = "T://DaletStorage/Video_Watch_Folder" + str(
                        OC_COMPONENT_NAME)
                    traffic_code = str(TRAFFIC_CODE).strip("=\"")
                    title_type = TITLETYPE
                    framerate = FRAMERATE
                    codec = CODEC
                    v_width = V_WIDTH
                    v_height = V_HEIGHT
                    duration = DURATION_MS
                    content_type = CONTENT_TYPE

                    conn.close()
                    os.chdir(xml_checkin)
                    xml_doc = str(guid) + '.xml'

                    with open(xml_doc, mode="w", encoding='utf-8-sig') as xdoc:

                        xml_body = f"\
                        <Titles>\
                        <Title><!-- title type video -->\
                        <key1>{guid}</key1>\
                        <itemcode>{guid}</itemcode>\
                        <title>{name}</title>\
                        <NGC_NGCITitle>{name}</NGC_NGCITitle>\
                        <NGC_NGCIFilename>{filename}</NGC_NGCIFilename>\
                        <NGC_DivaTapeID>{datatapeid}</NGC_DivaTapeID>\
                        <NGC_FolderPath>{folderpath}</NGC_FolderPath>\
                        <StartOfMaterial>{timecodein}</StartOfMaterial>\
                        <NGC_NGCITrafficCode>{traffic_code}</NGC_NGCITrafficCode>\
                        <titletype>{title_type}</titletype>\
                        <NGC_ContentType>{content_type}</NGC_ContentType>\
                        <AMFieldFromParsing_FrameRate>{framerate}</AMFieldFromParsing_FrameRate>\
                        <AMFieldFromParsing_Codec>{codec}</AMFieldFromParsing_Codec>\
                        <AMFieldFromParsing_Width>{v_width}</AMFieldFromParsing_Width>\
                        <AMFieldFromParsing_Hight>{v_height}</AMFieldFromParsing_Hight>\
                        <duration>{duration}</duration>\
                        \
                        <MediaInfos>\
                        <MediaInfo>\
                        <mediaFormatId>100002</mediaFormatId>\
                        <mediaStorageName>G_DIVA</mediaStorageName>\
                        <mediaStorageId>161</mediaStorageId>\
                        <mediaFileName>{guid}</mediaFileName>\
                        <mediaProcessStatus>Online</mediaProcessStatus>\
                        </MediaInfo>\
                        </MediaInfos>\
                        </Title>\
                        </Titles>"

                        xmlstr = minidom.parseString(xml_body).toprettyxml(
                            indent="   ")

                        xdoc.write(xmlstr)
                        xdoc.close()

                    os.chdir(rootpath)
                    update = db.update_column('assets', 'xml_created', 1,
                                              ROWID)
                    xmlcreate_msg = (f"\n\
                                    RowID: {str(ROWID)}\n\
                                    xml_count: {xml_count}\n\
                                    xml_doc:  {str(xml_doc)}\n")
                    logger.info(xmlcreate_msg)
                    xml_count += 1

                else:
                    xml_pass_msg = f"XML Creation skipped on {ROWID} for asset {GUID}. DATETAPEID = {DATATAPEID}"
                    logger.debug(xml_pass_msg)
                    pass

        os.chdir(rootpath)
        xml_2_msg = f"GORILLA-DIVA XML CREATION COMPLETED"
        logger.info(xml_2_msg)

    except Exception as e:
        xml_excp_msg = f"\n\
        Exception raised on the XML Creation.\n\
        ROWID = {ROWID}\n\
        Error Message:  {str(e)} \n\
        XML Count: {xml_count}\n\
        "

        logger.exception(xml_excp_msg)
Esempio n. 2
0
def update_db(date, tablename):
    """
    Start by creating a backup of the exisiting DB.
    Then update the DB by comparing rows in new CSV export to rows in the existing DB. 
    Add new rows from the CSV into the DB, and remove rows from the DB if they do not exist in
    the new CSV.
    """

    config = cfg.get_config()
    rootpath = config['paths']['rootpath']
    csvpath = config['paths']['csvpath']
    clean_csv = date + "_" + "gor_diva_merged_cleaned.csv"

    if os.path.isfile(os.path.join(rootpath, 'database.db')) is not True:
        return

    else:
        try:
            shutil.copy2(
                os.path.join(rootpath, 'database.db'),
                os.path.join(rootpath, 'database_BKP_' + date + '.db'))

            update_db_msg = f"BEGIN DB UPDATE"
            logger.info(update_db_msg)
            print(update_db_msg)

            cca.crosscheck_assets(tablename)
            os.chdir(csvpath)

            with open(clean_csv, mode='r', encoding='utf-8-sig') as c_csv:

                pd_reader = pd.read_csv(c_csv, header=0)
                df = pd.DataFrame(pd_reader)

                update_count = 0
                update_index = []
                drop_count = 0
                drop_index = []
                insert_count = 0
                insert_index = []
                mismatch_count = 0
                mismatch_index = []
                total_count = 0
                none_count = 0

                for index, row in df.iterrows():

                    os.chdir(rootpath)

                    guid = str(row['GUID'])
                    titletype = str(row['TITLETYPE'])
                    datatapeid = str(row['DATATAPEID'])

                    update_db_msg_01 = f"Updating DB for (Index, GUID): ({index}, {guid})"
                    logger.info(update_db_msg_01)
                    print(str(index) + "    " + guid)

                    db_row_id = db.fetchone_guid(
                        guid
                    )  #fetch db row based on GUID, row ID may not match db Row ID.

                    if db_row_id is not None:
                        db_row = db.select_row(db_row_id[0])

                    else:
                        db_row_msg = f"None value(s) found in db row, skipping this row. \n {db_row}"
                        none_count += 1
                        continue

                    db_datatapeid = db_row[4]
                    db_aoid = db_row[24]
                    db_titletype = db_row[14]

                    if (guid == db_row[1] and db_datatapeid == "NULL"
                            and db_aoid == "NULL"):
                        db.update_row("assets", index, row)
                        update_count += 1
                        update_index.append(index)

                    if (guid != db_row[1] and db.fetchone_guid(guid) is None):
                        db.drop_row('assets', index, guid)
                        drop_count += 1
                        drop_index.append(index)

                    if (db_row is None and row['_merge'] == 'both'):
                        db.insert_row(index, row)
                        insert_count += 1
                        insert_index.append(index)

                    if (titletype != db_titletype):
                        db.update_column("assets", 'TITLETYPE', titletype,
                                         index)
                        update_count += 1
                        update_index.append(index)

                    if (guid != db_row[1] and db.fetchone_guid(guid) != None):
                        mismatch_msg = f"Mismatch in the db update: {db_row[1]} != {guid}"
                        logger.error(mismatch_msg)
                        mismatch_count += 1
                        mismatch_index.append(index)
                        pass

                    else:
                        nochange_msg = f"No change to {guid} at row index {index}."
                        logger.debug(nochange_msg)
                        # print(nochange_msg)
                        pass

                    total_count += 1

            update_summary_msg = f"\n\
                                    Update Count:  {update_count}\n\
                                    Drop Count: {drop_count}\n\
                                    Insert Count: {insert_count}\n\
                                    Mismatch Count: {mismatch_count}\n\
                                    No Change Count: {total_count - (update_count + drop_count + insert_count + mismatch_count)}\n\
                                    Total Count: {total_count}\n\
                                    "

            index_summary_msg = f"\n\
                                None Value Count = {none_count}\n\
                                update index: {update_index}\n\
                                drop index: {drop_index}\n\
                                insert index: {insert_index}\n\
                                mismatch index: {mismatch_index}\n\
                                "

            logger.info(update_summary_msg)
            logger.info(index_summary_msg)

            print(update_summary_msg)
            print("")
            print(index_summary_msg)

            db_update_complete_msg = f"DB UPDATE COMPLETE"
            logger.info(db_update_complete_msg)

        except Exception as e:
            dbupdate_err_msg = f"Error updating the DB."
            logger.exception(dbupdate_err_msg)
Esempio n. 3
0
def basic_auto_migrate_relational_db(app, bind):
    """Inspired with http://stackoverflow.com/questions/2103274/"""

    from sqlalchemy import Table
    from sqlalchemy import MetaData

    print('Performing very simple automigration in', bind, 'database...')
    db.session.commit()
    db.reflect()
    db.session.commit()
    db.create_all(bind=bind)

    with app.app_context():
        engine = db.get_engine(app, bind)
        tables = db.get_tables_for_bind(bind=bind)
        metadata = MetaData()
        metadata.engine = engine

        ddl = engine.dialect.ddl_compiler(engine.dialect, None)

        for table in tables:

            db_table = Table(table.name,
                             metadata,
                             autoload=True,
                             autoload_with=engine)
            db_columns = get_column_names(db_table)

            columns = get_column_names(table)
            new_columns = columns - db_columns
            unused_columns = db_columns - columns
            existing_columns = columns.intersection(db_columns)

            for column_name in new_columns:
                column = getattr(table.c, column_name)
                if column.constraints:
                    print('Column %s skipped due to existing constraints.' %
                          column_name)
                    continue
                print('Creating column: %s' % column_name)

                definition = ddl.get_column_specification(column)
                add_column(engine, table.name, definition)

            if engine.dialect.name == 'mysql':
                sql = 'SHOW CREATE TABLE `%s`' % table.name
                table_definition = engine.execute(sql)
                columns_definitions = {}

                to_replace = {
                    'TINYINT(1)':
                    'BOOL',  # synonymous for MySQL and SQLAlchemy
                    'INT(11)': 'INTEGER',
                    'DOUBLE': 'FLOAT(53)',
                    ' DEFAULT NULL': ''
                }
                for definition in table_definition.first()[1].split('\n'):
                    match = re.match(
                        '\s*`(?P<name>.*?)` (?P<definition>[^,]*),?',
                        definition)
                    if match:
                        name = match.group('name')
                        definition_string = match.group('definition').upper()

                        for mysql_explicit_definition, implicit_sqlalchemy in to_replace.items(
                        ):
                            definition_string = definition_string.replace(
                                mysql_explicit_definition, implicit_sqlalchemy)

                        columns_definitions[
                            name] = name + ' ' + definition_string

                columns_to_update = []
                for column_name in existing_columns:

                    column = getattr(table.c, column_name)
                    old_definition = columns_definitions[column_name]
                    new_definition = ddl.get_column_specification(column)

                    if old_definition != new_definition:
                        columns_to_update.append(
                            [column_name, old_definition, new_definition])

                if columns_to_update:
                    print(
                        '\nFollowing columns in `%s` table differ in definitions '
                        'from those in specified in models:' % table.name)
                for column, old_definition, new_definition in columns_to_update:
                    answer = get_answer(
                        'Column: `%s`\n'
                        'Old definition: %s\n'
                        'New definition: %s\n'
                        'Update column definition?' %
                        (column, old_definition, new_definition))
                    if answer == 'y':
                        update_column(engine, table.name, new_definition)
                        print('Updated %s column definition' % column)
                    else:
                        print('Skipped %s column' % column)

            if unused_columns:
                print('\nFollowing columns in `%s` table are no longer used '
                      'and can be safely removed:' % table.name)
                for column in unused_columns:
                    answer = get_answer('Column: `%s` - remove?' % column)
                    if answer == 'y':
                        drop_column(engine, table.name, column)
                        print('Removed column %s.' % column)
                    else:
                        print('Keeping column %s.' % column)

    print('Automigration of', bind, 'database completed.')
Esempio n. 4
0
def get_proxy(proxy_total):
    """
    Get a set of files where titletype = video and proxy copy status is 0,
    Copy the proxies a tmp location for checkin staging.
    PROXY_COPIED values: 
    0 = proxy not copied
    1 = proxy copied
    2 = proxy path does not exist 
    3 = no proxy, content type is archive 
    """

    config = cfg.get_config()
    conn = db.connect()

    xmlpath = config['paths']['xmlpath']
    proxypath = config['paths']['proxypath']
    tmp_checkin = config['paths']['tmp']
    rootpath = config['paths']['rootpath']

    rows = db.fetchall_proxy('assets')
    
    proxy_count = 0

    for row in rows:
        rowid = row[0]
        guid = str(row[1])
        proxy_copied = row[22]
        guid_x = guid.replace("-", "")
        guid_r = guid_x[24:]
        proxy_fn = guid + '.mov'

        """
        Use the parts GUID to generate a list that will be used to build the path to the proxy.
        """
        n = 2
        glist = [guid_r[i:i+n] for i in range(0, len(guid_r), n)]

        proxy_fpath = os.path.join(
            proxypath, glist[2], glist[3], guid, proxy_fn)
        
        if (proxy_count < int(proxy_total)
            and proxy_copied == 0 
            and os.path.exists(proxy_fpath) is True):
            
            try:
                pcopy = file_copy(proxy_fpath, tmp_checkin)
                
                if len(pcopy) == 0: 
                    row = db.fetchone_proxy(guid)
                    db.update_column('assets', 'proxy_copied', 1, rowid)
                    proxy_cp_msg = f"{proxy_fn} was copied to the dalet tmp."
                    logger.info(proxy_cp_msg)
                    proxy_count += 1
                else: 
                    pass
                    proxy_err_cp_msg = f"{proxy_fn} encountered an error on the copy to the dalet tmp."
                    logger.info(proxy_err_cp_msg)
                    
            except Exception as e:
                proxy_excp_msg = f"\n\
                Exception raised on the Proxy copy.\n\
                Error Message:  {str(e)} \n\
                "
                logger.exception(proxy_excp_msg)
                break
        else:
            if os.path.exists(proxy_fpath) is not True:
                proxy_err_msg = f"Proxy path does not exist. \n\
                {proxy_fpath}"
                logger.error(proxy_err_msg)
                db.update_column('assets', 'proxy_copied', 2, rowid)
                continue

    os.chdir(rootpath)
    proxy_complete_msg = f"PROXY COPY COMPLETE. \n\
                        {proxy_count} proxies copied \n"

    logger.info(proxy_complete_msg)

    return