def scan_file(fullpath, relpath, assign_id):
    """ scan a file and put it into the index """
    # pylint: disable=too-many-branches,too-many-statements,too-many-locals

    # Since a file has changed, the lrucache is invalid.
    load_message.cache_clear()

    try:
        entry = load_message(fullpath)
    except FileNotFoundError:
        # The file doesn't exist, so remove it from the index
        record = model.Entry.get(file_path=fullpath)
        if record:
            expire_record(record)
        return True

    entry_id = get_entry_id(entry, fullpath, assign_id)
    if entry_id is None:
        return False

    fixup_needed = False

    basename = os.path.basename(relpath)
    title = entry['title'] or guess_title(basename)

    values = {
        'file_path': fullpath,
        'category': entry.get('Category', utils.get_category(relpath)),
        'status': model.PublishStatus[entry.get('Status', 'SCHEDULED').upper()].value,
        'entry_type': entry.get('Entry-Type', ''),
        'slug_text': make_slug(entry.get('Slug-Text', title)),
        'redirect_url': entry.get('Redirect-To', ''),
        'title': title,
        'sort_title': entry.get('Sort-Title', title),
        'entry_template': entry.get('Entry-Template', '')
    }

    entry_date = None
    if 'Date' in entry:
        try:
            entry_date = arrow.get(entry['Date'], tzinfo=config.timezone)
        except arrow.parser.ParserError:
            entry_date = None
    if entry_date is None:
        del entry['Date']
        entry_date = arrow.get(
            os.stat(fullpath).st_ctime).to(config.timezone)
        entry['Date'] = entry_date.format()
        fixup_needed = True

    if 'Last-Modified' in entry:
        last_modified_str = entry['Last-Modified']
        try:
            last_modified = arrow.get(
                last_modified_str, tzinfo=config.timezone)
        except arrow.parser.ParserError:
            last_modified = arrow.get()
            del entry['Last-Modified']
            entry['Last-Modified'] = last_modified.format()
            fixup_needed = True

    values['display_date'] = entry_date.isoformat()
    values['utc_date'] = entry_date.to('utc').datetime
    values['local_date'] = entry_date.naive

    logger.debug("getting entry %s with id %d", fullpath, entry_id)
    record = model.Entry.get(id=entry_id)
    if record:
        logger.debug("Reusing existing entry %d", record.id)
        record.set(**values)
    else:
        record = model.Entry(id=entry_id, **values)

    # Update the entry ID
    if str(record.id) != entry['Entry-ID']:
        del entry['Entry-ID']
        entry['Entry-ID'] = str(record.id)
        fixup_needed = True

    if 'UUID' not in entry:
        entry['UUID'] = str(uuid.uuid5(
            uuid.NAMESPACE_URL, 'file://' + fullpath))
        fixup_needed = True

    # add other relationships to the index
    path_alias.remove_aliases(record)
    if record.visible:
        for alias in entry.get_all('Path-Alias', []):
            path_alias.set_alias(alias, entry=record)

    with orm.db_session:
        set_tags = {
            t.lower()
            for t in entry.get_all('Tag', [])
            + entry.get_all('Hidden-Tag', [])
        }

        for tag in record.tags:
            if tag.key in set_tags:
                set_tags.remove(tag.key)
            else:
                tag.delete()
        for tag in set_tags:
            model.EntryTag(entry=record, key=tag)
        orm.commit()

    if record.status == model.PublishStatus.DRAFT.value:
        logger.info("Not touching draft entry %s", fullpath)
    elif fixup_needed:
        logger.info("Fixing up entry %s", fullpath)
        save_file(fullpath, entry)

    return record
def scan_file ( fullpath , relpath , assign_id ) : load_message . cache_clear ( ) try : entry = load_message ( fullpath ) except FileNotFoundError : record = model . Entry . get ( file_path = fullpath ) if record : expire_record ( record ) return True entry_id = get_entry_id ( entry , fullpath , assign_id ) if entry_id is None : return False fixup_needed = False basename = os . path . basename ( relpath ) title = entry [ 'title' ] or guess_title ( basename ) values = { 'file_path' : fullpath , 'category' : entry . get ( 'Category' , utils . get_category ( relpath ) ) , 'status' : model . PublishStatus [ entry . get ( 'Status' , 'SCHEDULED' ) . upper ( ) ] . value , 'entry_type' : entry . get ( 'Entry-Type' , '' ) , 'slug_text' : make_slug ( entry . get ( 'Slug-Text' , title ) ) , 'redirect_url' : entry . get ( 'Redirect-To' , '' ) , 'title' : title , 'sort_title' : entry . get ( 'Sort-Title' , title ) , 'entry_template' : entry . get ( 'Entry-Template' , '' ) } entry_date = None if 'Date' in entry : try : entry_date = arrow . get ( entry [ 'Date' ] , tzinfo = config . timezone ) except arrow . parser . ParserError : entry_date = None if entry_date is None : del entry [ 'Date' ] entry_date = arrow . get ( os . stat ( fullpath ) . st_ctime ) . to ( config . timezone ) entry [ 'Date' ] = entry_date . format ( ) fixup_needed = True if 'Last-Modified' in entry : last_modified_str = entry [ 'Last-Modified' ] try : last_modified = arrow . get ( last_modified_str , tzinfo = config . timezone ) except arrow . parser . ParserError : last_modified = arrow . get ( ) del entry [ 'Last-Modified' ] entry [ 'Last-Modified' ] = last_modified . format ( ) fixup_needed = True values [ 'display_date' ] = entry_date . isoformat ( ) values [ 'utc_date' ] = entry_date . to ( 'utc' ) . datetime values [ 'local_date' ] = entry_date . naive logger . debug ( "getting entry %s with id %d" , fullpath , entry_id ) record = model . Entry . get ( id = entry_id ) if record : logger . debug ( "Reusing existing entry %d" , record . id ) record . set ( ** values ) else : record = model . Entry ( id = entry_id , ** values ) if str ( record . id ) != entry [ 'Entry-ID' ] : del entry [ 'Entry-ID' ] entry [ 'Entry-ID' ] = str ( record . id ) fixup_needed = True if 'UUID' not in entry : entry [ 'UUID' ] = str ( uuid . uuid5 ( uuid . NAMESPACE_URL , 'file://' + fullpath ) ) fixup_needed = True path_alias . remove_aliases ( record ) if record . visible : for alias in entry . get_all ( 'Path-Alias' , [ ] ) : path_alias . set_alias ( alias , entry = record ) with orm . db_session : set_tags = { t . lower ( ) for t in entry . get_all ( 'Tag' , [ ] ) + entry . get_all ( 'Hidden-Tag' , [ ] ) } for tag in record . tags : if tag . key in set_tags : set_tags . remove ( tag . key ) else : tag . delete ( ) for tag in set_tags : model . EntryTag ( entry = record , key = tag ) orm . commit ( ) if record . status == model . PublishStatus . DRAFT . value : logger . info ( "Not touching draft entry %s" , fullpath ) elif fixup_needed : logger . info ( "Fixing up entry %s" , fullpath ) save_file ( fullpath , entry ) return record
scan a file and put it into the index