Example #1
0
 def create_json(self):
     """create json"""
     file_info = FileInfo()
     file_entry = file_info.get(file=self.file)
     self.orig = {
         "dataFileList": [file_entry],
         "datasetId": self.pid,
         "ownerGroup": "ess",
         "accessGroups": ["loki", "brightness"],
         "size": file_entry["size"]
     }
     print(self.orig)
Example #2
0
 def __init__(self, python_path, root="", kill_on_error=False, debug=False):
     """
     :param python_path: path to file to check
         can be more than one line long
     """
     self.python_path = python_path
     self.test_class = ((python_path.find("/tests/") > 0)
                        or (python_path.find("/unittests/") > 0)
                        or (python_path.find("\\unittests\\") > 0)
                        or (python_path.find("/integration_tests/") > 0)
                        or (python_path.find("\\integration_tests\\") > 0))
     self.debug = debug
     self.kill_on_error = kill_on_error
     self._info = FileInfo(python_path[len(root):])
Example #3
0
    def walk_images(self, folder, destination, sort_option, mode):
        """ Execute the main function, limiting to known images with exif format."""
        # Relative or absolute path
        exif_opt = ExifOptions()
        if os.path.isdir(folder):
            count_files = 0

            if mode == 'r':
                for folder, subs, files in os.walk(folder):
                    count = 0
                    if destination not in subs:
                        for file_name in files:
                            if count == 0:
                                print(folder)
                                count += 1
                            if helper.check_file_extensions(file_name):
                                try:
                                    self.process_image(
                                        FileInfo(file_name, folder,
                                                 destination), sort_option)
                                except:
                                    LOGGER.error("error on file! : " +
                                                 file_name)
                                    self.incr_errors()
                                count_files += 1
                print('Found image files ' + str(count_files))
            else:
                files = [
                    f for f in os.listdir(folder)
                    if helper.check_tiff_extension(file_name)
                    or helper.check_jpeg_extension(file_name)
                ]
                for file_name in files:
                    try:
                        self.process_image(
                            FileInfo(file_name, folder, destination),
                            sort_option)
                    except:
                        print("error on file! : " + file_name)
                        self.incr_errors()
                    count_files += 1

            print('Processed image files ' + str(count_files))
            print('Skipped files ' + str(self.skipped))
            print('Error files ' + str(self.errors))
            print('Written ' + str(self.writes) + ' files')
        else:
            print('Invalid folder given')
 def test_repr(self):
     fi = FileInfo(path='a',
                   file_hash=b64decode('b000'),
                   is_dir='c',
                   mtime='d')
     assert repr(
         fi) == '<FileInfo: path=\'a\' hash=b\'b000\' is_dir=c mtime=d>'
 def test_is_possibly_changed__for_updated_dir_contents(self):
     p = get_mock_dir_path(iterdir=[
         get_mock_file_path("HAM", b"sandwich"),
         get_mock_file_path("EGGS", b"with toast")
     ])
     L = LocalFileInfoBrowser()
     assert L.is_possibly_changed(p)
     L._cache[p]\
         = FileInfo(path=p, is_dir=True, mtime=0, file_hash=get_mock_hash())
     L._cache[p._iterdir[0]]\
         = FileInfo(path="HAM", is_dir=False, mtime=0, file_hash=get_mock_hash())
     L._cache[p._iterdir[1]]\
         = FileInfo(path="EGGS", is_dir=False, mtime=0, file_hash=get_mock_hash())
     assert not L.is_possibly_changed(p)
     p._iterdir[1]._stat.st_mtime_ns += 1
     assert L.is_possibly_changed(p)
Example #6
0
def unpack(file_name, beautify_xml):
    """Unpacks a .bus file.
    Keyword arguments:
    file -- the .bus file's name
    beautify_xml -- whether XML files' output should be beautified.
    """

    with open(file_name, "rb") as input:
        print("Unpacking: {}".format(file_name))
        header = BusFileHeader.decrypt(input)
        files = []
        for i in range(header.length):
            offset = PKG_OFFSET + HEADER_INFO_SIZE + i * FILE_INFO_SIZE
            file = FileInfo.decrypt_header(input, offset)
            files.append(file)

        rdptr = 0
        for file in files:

            print("Unpacking: {}".format(file.name))
            offset = PKG_OFFSET + HEADER_INFO_SIZE + header.length * FILE_INFO_SIZE + rdptr
            decrypted = file.decrypt_contents(input, offset)
            path = Path(file.name)
            path.parent.mkdir(parents=True, exist_ok=True)
            with open(file.name, "w+b") as output_file:
                output_file.write(decrypted)

            rdptr += file.length
            if beautify_xml and file.name.split(".")[-1] == "xml":
                dom = xml.dom.minidom.parse(file.name)
                with open(file.name, "w+b") as output_file:
                    output_file.write(dom.toprettyxml(encoding="utf-8"))
 def list_files(self, folder):
     if folder and folder.name == 'B Folder':
         return
     file_count = 4
     for i in range(file_count):
         name = '{}{} File'.format(self.prefix,
                                   self._get_char(i, file_count))
         yield self._intense_calculation(FileInfo(id=i, name=name))
 def test_is_possibly_changed__for_updated_mtime(self):
     p = get_mock_file_path()
     L = LocalFileInfoBrowser()
     assert L.is_possibly_changed(p)
     L._cache[p]\
         = FileInfo(path=p, is_dir=False, mtime=0, file_hash=get_mock_hash())
     assert not L.is_possibly_changed(p)
     p._stat.st_mtime_ns += 1
     assert L.is_possibly_changed(p)
Example #9
0
def list_files(walk_dir):
    with DiffFileWriter(walk_dir, 'diff-name-only-list.md') as list_file:
        list_file.write_header()
        list_file.write_root()
        for root, subdirs, files in os.walk(walk_dir):
            list_file.write_newline()
            list_file.write_directory(root, 0)
            for filename in files:
                list_file.write_file(FileInfo(root, filename), 1)
Example #10
0
def process(audio_folder_paths, build_folder_path):
    audio_file_names, audio_file_names_no_ext, audio_file_paths = list_audio_files(audio_folder_paths)
    file_info_path = build_folder_path + '/_bn_audio_files_info.txt'
    old_file_info = FileInfo.read(file_info_path)
    new_file_info = FileInfo.build_from_files(audio_file_paths)

    if old_file_info == new_file_info:
        return

    for audio_file_name in audio_file_names:
        print(audio_file_name)

    soundbank_bin_path = build_folder_path + '/_bn_audio_soundbank.bin'
    soundbank_header_path = build_folder_path + '/_bn_audio_soundbank.h'
    total_size = process_audio_files(audio_file_paths, soundbank_bin_path, soundbank_header_path, build_folder_path)
    write_output_files(audio_file_names_no_ext, soundbank_header_path, build_folder_path)
    print('    Processed audio size: ' + str(total_size) + ' bytes')
    os.remove(soundbank_header_path)
    new_file_info.write(file_info_path)
Example #11
0
 def list_files(self, folder):
     folder_abs = os.path.join(self.path, folder.name)
     return [
         FileInfo(
             id=i, 
             name=name.encode('utf-8'), 
             full_path=path.encode('utf-8'), 
             checksum=self.md5_checksum(path) if self._config.checksum else None)
         for i, (name, path) in enumerate((x, os.path.join(folder_abs, x)) for x in os.listdir(folder_abs))
         if self._should_include(name, self._config.include, self._config.exclude) and os.path.isfile(path)
     ]
Example #12
0
 def _get_file_info(self, photo):
     name = photo.title.encode('utf-8') if photo.title else photo.id
     checksum = None
     if photo.originalformat:
         name += "." + photo.originalformat
     if photo.tags:
         tags = photo.tags.split()
         checksum = next((parts[1]
                          for parts in (tag.split('=') for tag in tags)
                          if parts[0] == CHECKSUM_PREFIX), None)
     return FileInfo(id=photo.id, name=name, checksum=checksum)
Example #13
0
    def scan_files(self, folder, destination, sort_option, mode):
        # Relative or absolute path
        if os.path.isdir(folder):
            count_files = 0

            if mode == 'r':
                for folder, subs, files in os.walk(folder):
                    count = 0
                    if destination not in subs:
                        for file_name in files:
                            if count == 0:
                                print(folder)
                                count += 1
                            if helper.check_extension(file_name, MP4):
                                try:
                                    self.process_file(
                                        FileInfo(file_name, folder,
                                                 destination), sort_option)
                                except:
                                    raise
                                    LOGGER.error("error on file! : " +
                                                 file_name)
                                    self.incr_errors()
                                count_files += 1
                print('Found video files ' + str(count_files))
            else:
                files = [
                    f for f in os.listdir(folder)
                    if helper.check_extension(file_name, MP4)
                    or helper.check_jpeg_extension(file_name)
                ]
                for file_name in files:
                    try:
                        self.process_file(
                            FileInfo(file_name, folder, destination),
                            sort_option)
                    except:
                        print("error on file! : " + file_name)
                        self.incr_errors()
                    count_files += 1
Example #14
0
    def __receive_res_list(self):
        file_list = []
        for _ in range(self.fts.recv_int()):
            path = self.fts.recv_rstring().decode()
            (hashd, is_dir, mtime) = self.fts.recv_struct('!32s?Q')

            file_list.append(
                FileInfo(path=Path(path),
                         file_hash=hashd,
                         is_dir=is_dir,
                         mtime=mtime))

        return file_list
Example #15
0
def _explore_at_lv(directory: str, lv: int, max_lv: int) -> FileInfo:
    if lv > max_lv:
        return None
    if path.isfile(directory):
        return FileInfo(name=path.basename(directory),
                        is_file=path.isfile(directory),
                        children=[],
                        path=directory)
    children_names = os.listdir(directory)
    children_directories = [
        path.join(directory, name) for name in children_names
    ]
    children = [
        _explore_at_lv(child_dir, lv + 1, max_lv)
        for child_dir in children_directories
    ]
    not_none_chilren = [child for child in children if child is not None]
    cur_file_info = FileInfo(name=path.basename(directory),
                             is_file=path.isfile(directory),
                             children=not_none_chilren,
                             path=directory)

    return cur_file_info
    def test_depth_param_should_limit_return_value(self):
        actual = file_explorer.explore(ROOT_TEST_FOLDER, depth=2)
        expected = FileInfo(
            name=path.basename(ROOT_TEST_FOLDER),
            is_file=False,
            path=ROOT_TEST_FOLDER,
            children=[
                FileInfo(
                    name='folder1',
                    is_file=False,
                    children=[],
                    path=path.join(ROOT_TEST_FOLDER, 'folder1')
                ),
                FileInfo(
                    name='folder2',
                    is_file=False,
                    children=[],
                    path=path.join(ROOT_TEST_FOLDER, 'folder2')
                ),
            ]
        )

        assert actual == expected
Example #17
0
 def _get_file_info(self, photo):
     name = photo.title.encode('utf-8') if photo.title else photo.id
     checksum = None
     extension = None
     if photo.tags:
         # If we've just pulled the photo, tags is a string, if we've inspected any properties like 'media', it becomes a list
         tags = photo.tags.split() if isinstance(
             photo.tags, basestring) else [tag.text for tag in photo.tags]
         checksum = next((parts[1]
                          for parts in (tag.split('=') for tag in tags)
                          if parts[0] == CHECKSUM_PREFIX), None)
         extension = next((parts[1]
                           for parts in (tag.split('=') for tag in tags)
                           if parts[0] == EXTENSION_PREFIX), None)
     if not extension:
         extension = photo.originalformat
     if extension:
         name += "." + extension
     return FileInfo(id=photo.id, name=name, checksum=checksum)
Example #18
0
def list_dmg_audio_file_infos(audio_folder_paths, build_folder_path):
    audio_folder_path_list = audio_folder_paths.split(' ')
    audio_file_infos = []
    file_names_set = set()

    for audio_folder_path in audio_folder_path_list:
        audio_file_names = os.listdir(audio_folder_path)

        for audio_file_name in audio_file_names:
            audio_file_path = audio_folder_path + '/' + audio_file_name

            if os.path.isfile(audio_file_path) and FileInfo.validate(
                    audio_file_name):
                audio_file_name_split = os.path.splitext(audio_file_name)
                audio_file_name_ext = audio_file_name_split[1]
                mod_extension = audio_file_name_ext == '.mod'

                if mod_extension or audio_file_name_ext == '.s3m':
                    audio_file_name_no_ext = audio_file_name_split[0]

                    if audio_file_name_no_ext in file_names_set:
                        raise ValueError(
                            'There\'s two or more DMG audio files with the same name: '
                            + audio_file_name_no_ext)

                    file_names_set.add(audio_file_name_no_ext)
                    file_info_path = build_folder_path + '/_bn_' + audio_file_name_no_ext + '_dmg_audio_file_info.txt'

                    if not os.path.exists(file_info_path):
                        build = True
                    else:
                        file_info_mtime = os.path.getmtime(file_info_path)
                        audio_file_mtime = os.path.getmtime(audio_file_path)
                        build = file_info_mtime < audio_file_mtime

                    if build:
                        audio_file_infos.append(
                            DmgAudioFileInfo(audio_file_path, audio_file_name,
                                             audio_file_name_no_ext,
                                             file_info_path, mod_extension))

    return audio_file_infos
    def test_fl_sr(self):
        # Test send/recv of filelist
        c1 = FTConn(MockFTSock(True))
        c2 = FTConn(MockFTSock(True))

        fl = [FileInfo(path=Path(), file_hash=b'12345678901234567890123456789012', \
            is_dir=False, mtime=98)]

        c1.send_file_list(fl)
        c2.fts.sock.append_bytes(c1.fts.sock.retrieve_bytes())
        t, flr = c2.receive_data()
        assert t == FTProto.RES_LIST

        assert len(fl) == len(flr)

        for orig, recv in zip(fl, flr):
            assert file_info_equals(orig, recv)

        assert c1.fts.sock.ensure_esend() and c1.fts.sock.ensure_erecv()
        assert c2.fts.sock.ensure_esend() and c2.fts.sock.ensure_erecv()
Example #20
0
def list_audio_files(audio_folder_paths):
    audio_folder_path_list = audio_folder_paths.split(' ')
    audio_file_names = []
    audio_file_names_no_ext = []
    audio_file_paths = []

    for audio_folder_path in audio_folder_path_list:
        folder_audio_file_names = sorted(os.listdir(audio_folder_path))

        for audio_file_name in folder_audio_file_names:
            if FileInfo.validate(audio_file_name):
                audio_file_path = audio_folder_path + '/' + audio_file_name

                if os.path.isfile(audio_file_path):
                    audio_file_name_split = os.path.splitext(audio_file_name)
                    audio_file_name_no_ext = audio_file_name_split[0]
                    audio_file_names.append(audio_file_name)
                    audio_file_names_no_ext.append(audio_file_name_no_ext)
                    audio_file_paths.append(audio_file_path)

    return audio_file_names, audio_file_names_no_ext, audio_file_paths
Example #21
0
def list_graphics_file_infos(graphics_folder_paths, build_folder_path):
    graphics_folder_path_list = graphics_folder_paths.split(' ')
    graphics_file_infos = []
    sprite_file_names_set = set()
    regular_bg_file_names_set = set()

    for graphics_folder_path in graphics_folder_path_list:
        graphics_file_names = sorted(os.listdir(graphics_folder_path))

        for graphics_file_name in graphics_file_names:
            graphics_file_path = graphics_folder_path + '/' + graphics_file_name

            if FileInfo.validate(graphics_file_name):
                graphics_file_name_split = os.path.splitext(graphics_file_name)
                graphics_file_name_no_ext = graphics_file_name_split[0]
                graphics_file_name_ext = graphics_file_name_split[1]

                if graphics_file_name_ext == '.bmp':
                    json_file_path = graphics_folder_path + '/' + graphics_file_name_no_ext + '.json'

                    if not os.path.isfile(json_file_path):
                        raise ValueError('Graphics json file not found: ' + json_file_path)

                    try:
                        with open(json_file_path) as json_file:
                            info = json.load(json_file)
                    except Exception as exception:
                        raise ValueError(json_file_path + ' graphics json file parse failed: ' + str(exception))

                    try:
                        graphics_type = str(info['type'])
                    except KeyError:
                        raise ValueError('type filed not found in graphics json file: ' + json_file_path)

                    if graphics_type == 'sprite':
                        file_names_set = sprite_file_names_set
                    elif graphics_type == 'regular_bg':
                        file_names_set = regular_bg_file_names_set
                    else:
                        raise ValueError('Unknown type (' + graphics_type + ') in graphics json file: ' +
                                         json_file_path)

                    if graphics_file_name_no_ext in file_names_set:
                        raise ValueError('There\'s two or more ' + graphics_type +
                                         ' graphics files with the same name: ' + graphics_file_name_no_ext)

                    file_names_set.add(graphics_file_name_no_ext)

                    file_info_path_prefix = build_folder_path + '/_btn_' + graphics_file_name_no_ext + '_'
                    file_info_path = file_info_path_prefix + graphics_type + '_file_info.txt'
                    json_file_info_path = file_info_path_prefix + graphics_type + '_json_file_info.txt'
                    old_file_info = FileInfo.read(file_info_path)
                    new_file_info = FileInfo.build_from_file(graphics_file_path)
                    old_json_file_info = FileInfo.read(json_file_info_path)
                    new_json_file_info = FileInfo.build_from_file(json_file_path)

                    if old_file_info != new_file_info or old_json_file_info != new_json_file_info:
                        graphics_file_infos.append(GraphicsFileInfo(
                            graphics_type, info, graphics_file_path, graphics_file_name, graphics_file_name_no_ext,
                            new_file_info, file_info_path, new_json_file_info, json_file_info_path))

    return graphics_file_infos
    def test_should_explore_right_value(self):
        actual = file_explorer.explore(ROOT_TEST_FOLDER, depth=10)
        expected = FileInfo(
            name=path.basename(ROOT_TEST_FOLDER),
            is_file=False,
            path=ROOT_TEST_FOLDER,
            children=[
                FileInfo(
                    name='folder1',
                    is_file=False,
                    path=path.join(ROOT_TEST_FOLDER, 'folder1'),
                    children=[
                        FileInfo(
                            name='folder3',
                            is_file=False,
                            path=path.join(ROOT_TEST_FOLDER, 'folder1', 'folder3'),
                            children=[
                                FileInfo(
                                    name='g.txt',
                                    is_file=True,
                                    children=[],
                                    path=path.join(ROOT_TEST_FOLDER, 'folder1', 'folder3', 'g.txt'),
                                ),
                                FileInfo(
                                    name='h.txt',
                                    is_file=True,
                                    children=[],
                                    path=path.join(ROOT_TEST_FOLDER, 'folder1', 'folder3', 'h.txt'),
                                ),
                                FileInfo(
                                    name='j.txt',
                                    is_file=True,
                                    children=[],
                                    path=path.join(ROOT_TEST_FOLDER, 'folder1', 'folder3', 'j.txt'),
                                ),
                                FileInfo(
                                    name='k.txt',
                                    is_file=True,
                                    children=[],
                                    path=path.join(ROOT_TEST_FOLDER, 'folder1', 'folder3', 'k.txt'),
                                ),
                            ]
                        ),
                        FileInfo(
                            name='a.txt',
                            is_file=True,
                            children=[],
                            path=path.join(ROOT_TEST_FOLDER, 'folder1', 'a.txt'),
                        ),
                        FileInfo(
                            name='b.txt',
                            is_file=True,
                            children=[],
                            path=path.join(ROOT_TEST_FOLDER, 'folder1', 'b.txt'),
                        ),
                        FileInfo(
                            name='c.txt',
                            is_file=True,
                            children=[],
                            path=path.join(ROOT_TEST_FOLDER, 'folder1', 'c.txt'),
                        ),
                    ]
                ),
                FileInfo(
                    name='folder2',
                    is_file=False,
                    path=path.join(ROOT_TEST_FOLDER, 'folder2'),
                    children=[
                        FileInfo(
                            name='d.txt',
                            is_file=True,
                            children=[],
                            path=path.join(ROOT_TEST_FOLDER, 'folder2', 'd.txt'),
                        ),
                        FileInfo(
                            name='e.txt',
                            is_file=True,
                            path=path.join(ROOT_TEST_FOLDER, 'folder2', 'e.txt'),
                            children=[]
                        ),
                    ]
                ),
            ]
        )

        assert actual == expected
Example #23
0
def find_file_by_id(file_id):
    sql = "select id,file_name,file_size,key_words,creator,created_at,file_path,file_doc,permission,download_count " \
          "from `files` where id=%d" % file_id
    global cursor
    cursor.execute(sql)
    values = cursor.fetchall()
    for file_id, file_name, file_size, key_words, creator, created_at, file_path, file_doc, permission, download_count in values:
        f = FileInfo()
        f.file_id = file_id
        f.file_name = file_name
        f.file_size = file_size
        f.key_words = key_words
        f.creator = creator
        f.created_at = created_at
        f.file_path = file_path
        f.file_doc = file_doc
        f.permission = int(permission)
        f.download_count = download_count
        return f
Example #24
0
    max_nest_size = 3
    min_nest_size = 1
    nest_step = 1

    total_generations = int((max_level_size-min_level_size)/level_step) \
                             * int((max_nest_size-min_nest_size)/nest_step)

    nest_sizes = np.arange(min_nest_size, max_nest_size, nest_step)
    level_sizes = np.arange(min_level_size, max_level_size, level_step)

    columns = ['file_type', 'output_type', 'size', 'load_time', 'nest_level', 'records_per_level']
    df = pd.DataFrame(columns=columns)

    for nest_level in nest_sizes:
        for records_per_level in level_sizes:
            progress(count=count, total=total_generations, status='Running Data Collection')

            generate_fake_data_files(nest_level=nest_level, records_per_level=records_per_level)
            file_handler = FileInfo()
            file_handler.get_file_info()
            df2 = pd.DataFrame(file_handler.file_info)
            df2['nest_level'] = nest_level
            df2['records_per_level'] = records_per_level
            df = df.append(df2, ignore_index=True, sort=True)

            count += 1

    print(len(df))
    export_data(df)
Example #25
0
def get_file_info(file_path):
    return FileInfo(file_path)
Example #26
0
def query_all_files():
    sql = "select id,file_name,file_size,key_words,creator,created_at,file_path,file_doc,permission,download_count " \
          "from `files`"
    global cursor
    cursor.execute(sql)
    values = cursor.fetchall()
    result = []
    for file_id, file_name, file_size, key_words, creator, created_at, file_path, file_doc, permission, download_count in values:
        f = FileInfo()
        f.file_id = file_id
        f.file_name = file_name
        f.file_size = file_size
        f.key_words = key_words
        f.creator = creator
        f.created_at = created_at
        f.file_path = file_path
        f.file_doc = file_doc
        f.permission = int(permission)
        f.download_count = download_count
        result.append(f)
    return result
Example #27
0
def insert_new_file(file_io, user_name, file_permission):
    if not allowed_file(file_io.filename):
        return None
    sec_file_name = file_io.filename
    save_path = os.path.join(UPLOAD_FOLDER, sec_file_name)
    file_io.save(save_path)

    file_info = FileInfo()
    file_info.file_name = sec_file_name
    file_info.file_doc = sec_file_name.rsplit('.', 1)[1]
    file_info.creator = user_name
    file_info.download_count = 0
    file_info.permission = file_permission
    file_info.file_path = save_path
    file_info.file_size = os.path.getsize(save_path)
    file_info.created_at = time.time() * 1000
    file_info.key_words = search_service.cal_keys_from_file(file_info)

    db_helper.insert_file_info(file_info)
    return file_info
Example #28
0
class FileDocChecker(object):
    """ Sets the Class up to test a file assumes to be python \
        with sphinx style docstrings.
    """

    _code_state = CodeState.START
    _part_line = ""
    _lineNum = 0
    _param_indent = None
    _def_string = ""
    _def_type = None
    _def_params = []
    _doc_params = []
    _doc_types = []
    _def_name = None
    _info = None
    cl_info = None
    test_class = None
    _at_line = None

    def __init__(self, python_path, root="", kill_on_error=False, debug=False):
        """
        :param python_path: path to file to check
            can be more than one line long
        """
        self.python_path = python_path
        self.test_class = ((python_path.find("/tests/") > 0)
                           or (python_path.find("/unittests/") > 0)
                           or (python_path.find("\\unittests\\") > 0)
                           or (python_path.find("/integration_tests/") > 0)
                           or (python_path.find("\\integration_tests\\") > 0))
        self.debug = debug
        self.kill_on_error = kill_on_error
        self._info = FileInfo(python_path[len(root):])

    def check_all_docs(self):
        if self.debug:
            print(self.python_path)
        try:
            with open(self.python_path, "r") as python_file:
                for line in python_file:
                    if SLOTS_IMPOSSIBLE_MARKER in line:
                        self.cl_info.slots = SLOTS_IMPOSSIBLE
                    else:
                        self._check_line(line.rstrip().split("#")[0].rstrip())
            return self._info
        except Exception:
            traceback.print_exc()
            print("Exception call processing:")
            print(self.python_path + ":" + str(self._lineNum))
            sys.exit(-1)

    def _check_line(self, line):
        if self.debug:
            print(line)
        self._lineNum += 1
        if line.strip().endswith("\\"):
            self._part_line = self._part_line + line[:-1] + " "
            return
        else:
            if len(self._part_line) > 0:
                line = self._part_line + line
                self._part_line = ""

        if self._code_state == CodeState.START:
            self._check_in_start(line)
        elif self._code_state == CodeState.CODE:
            self._check_in_code(line)
        elif self._code_state == CodeState.IN_CLASS:
            self._check_in_class(line)
        elif self._code_state == CodeState.AFTER_CLASS:
            self._check_after_class(line)
        elif self._code_state == CodeState.CLASS_DOC:
            self._check_in_class_doc(line)
        elif self._code_state == CodeState.IN_SLOTS:
            self._check_in_slots(line)
        elif self._code_state == CodeState.IN_DEF:
            self._check_in_def(line)
        elif self._code_state == CodeState.AFTER_DEF:
            self._check_after_def(line)
        elif self._code_state == CodeState.DOCS_START:
            self._check_in_doc_start(line)
        elif self._code_state == CodeState.DOCS_START_AFTER_BLANK:
            self._check_in_doc_start_after_blank(line)
        elif self._code_state == CodeState.DOCS_DECLARATION:
            self._check_in_doc_declaration(line)
        elif self._code_state == CodeState.COMMENT:
            self._check_in_comment(line)
        # elif self._code_state == CodeState.DOCS_END:
        #    self._check_in_doc_end(line)
        # elif self._code_state == CodeState.IN_PARAM:
        #    self._check_in_param(line)
        else:
            print(self._code_state)
            raise NotImplementedError
        if self.debug:
            print(str(self._lineNum) + "   " + str(self._code_state))

    def _check_in_start(self, line):
        if "\"\"\"" in line:
            return self._verify_doc_start(line, CodeState.CLASS_DOC,
                                          CodeState.START)
        stripped = line.strip()
        return self._code_check(stripped)

    def _verify_doc_start(self, line, doc_state, none_doc_state):
        stripped = line.strip()
        if stripped.startswith("r\"\"\""):
            stripped = stripped[1:]
        elif not stripped.startswith("\"\"\""):
            msg = "unexpected doc tags"
            return self._report(line, msg, _UNEXPECTED)
        parts = stripped.split("\"\"\"")
        if len(parts) <= 2:
            self._code_state = doc_state
            return OK
        elif len(parts) == 3:
            if len(parts[2]) == 0:
                self._code_state = none_doc_state
                return OK
            else:
                msg = "unexpected stuff after one line doc end"
                return self._report(line, msg, _UNEXPECTED)
        else:
            msg = "three doc tags found in one line"
            return self._report(line, msg, _UNEXPECTED)

    def _code_check(self, stripped):
        if stripped.startswith("class "):
            return self._check_in_class(stripped)
        if stripped.startswith("def "):
            return self._check_in_def(stripped)
        if stripped.startswith("__slots__"):
            return self._check_in_slots(stripped)
        if stripped.startswith("@"):
            return self._check_in_at(stripped)
        return OK

    def _check_in_code(self, line):
        if "\"\"\"" in line:
            return self._verify_doc_start(line, CodeState.COMMENT,
                                          CodeState.CODE)
        stripped = line.strip()
        return self._code_check(stripped)

    def _check_in_class(self, line):
        self._def_string += line
        if line.endswith(":"):
            self._extract_class_def(line)
            self._code_state = CodeState.AFTER_CLASS
            return OK
        else:
            self._code_state = CodeState.IN_CLASS
            if "\"\"\"" in line:
                msg = "unexpected doc start in class declaration"
                return self._report(line, msg, _CRITICAL)
            else:
                return OK

    def _extract_class_def(self, line):
        if self.test_class:
            self.cl_info = None
        else:
            declaration = self._def_string.replace(" ", "")
            cl_name = declaration[5:declaration.index("(")]
            if cl_name == "(":
                print(self.python_path + ":" + str(self._lineNum))
            self.cl_info = ClassInfo.info_by_name(cl_name, self._info,
                                                  self._lineNum)
            if not cl_name.startswith("_"):
                self._info.add_class(self.cl_info)
                supers_string = declaration[declaration.index("(") +
                                            1:declaration.index(")")]
                if supers_string.startswith("namedtuple"):
                    pass
                elif supers_string.startswith("collections."):
                    pass
                else:
                    supers = supers_string.split(",")
                    for super in supers:
                        self._extract_super(line, super)
        if self._at_line is not None:
            if "ABCMeta" in self._at_line:
                print("{}:{} ABCMmeta!".format(self.python_path,
                                               self._lineNum))
            self._at_line = None
        self._def_string = ""

    def _extract_super(self, line, super):
        if super.startswith("exceptions."):
            super = super[11:]
        if super.startswith("_"):
            print(self.python_path + ":" + str(self._lineNum))
        if super.startswith("logging."):
            return
        else:
            self.cl_info.add_super_by_name(super)

    def _check_after_class(self, line):
        if "\"\"\"" in line:
            return self._verify_doc_start(line, CodeState.CLASS_DOC,
                                          CodeState.CODE)
        stripped = line.strip()
        if len(stripped) == 0:
            return OK
        else:
            self._code_state = CodeState.CODE
            return self._check_in_code(line)

    def _check_in_class_doc(self, line):
        stripped = line.strip()
        if stripped.startswith("\"\"\""):
            return self._end_docs(line)
        if stripped.startswith(":return"):
            msg = ":return does not make sense in class doc"
            return self._report(line, msg, _UNEXPECTED)
        return OK

    def _check_in_slots(self, line):
        self._code_state = CodeState.IN_SLOTS
        stripped = line.strip()
        if stripped.startswith("#"):
            return OK
        self._def_string += stripped
        if stripped.endswith(")"):
            declaration = self._def_string[self._def_string.index("(") + 1:-1]
        elif stripped.endswith("]"):
            declaration = self._def_string[self._def_string.index("[") + 1:-1]
        else:
            return OK
        if not self.test_class:
            declaration = declaration.replace(" ", "")
            declaration = declaration.replace("\"", "")
            declaration = declaration.replace("'", "")
            if len(declaration) == 0:
                slots = []
            else:
                slots = declaration.split(",")
            self.cl_info.slots = slots
        self._def_string = ""
        self._code_state = CodeState.CODE
        return OK

    def _check_in_at(self, stripped):
        self._at_line = stripped
        self._code_state = CodeState.CODE
        return OK

    def _check_in_def(self, line):
        self._code_state = CodeState.IN_DEF
        self._def_string += line
        if line.endswith(":"):
            self._code_state = CodeState.AFTER_DEF
            return self._extract_params(line)
        if "\"\"\"" in line:
            msg = "unexpected doc start in def declaration"
            return self._report(line, msg, _UNEXPECTED)
        return OK

    def _extract_params(self, line):
        declaration = self._def_string.replace("(", " ", 1)
        declaration = rreplace(declaration, ")", " ", 1)
        declaration = declaration.replace(",", " ")
        declaration = declaration.replace('"="', "x")
        declaration = re.sub(r"\(.*?\)", "junk", declaration)
        declaration = re.sub(' +', ' ', declaration)
        self._def_string = ""
        parts = declaration.split(" ")
        if (parts[0] != "def"):
            msg = "unexpected start in def declaration"
            return self._report(line, msg, _UNEXPECTED)
        self._def_name = parts[1]
        if not self.test_class and self.cl_info is not None:
            try:
                self.cl_info.add_method(self._def_name)
            except Exception as ex:
                print(self.python_path + ":" + str(self._lineNum))
                raise ex
        self._doc_params = []
        self._doc_types = []
        if (parts[1] == "__init__"):
            self._def_type = INIT
        elif (parts[1][0] == "_"):
            self._def_type = PRIVATE
        else:
            self._def_type = PUBLIC
        self._def_params = []
        if (parts[2] == "self"):
            start = 3
        else:
            start = 2
        for part in parts[start:-1]:
            if (part[0] == "=") or (part[-1] == "="):
                msg = "E251 unexpected spaces around keyword/parameter equals"
                return self._report(line, msg, _UNEXPECTED)
            param_parts = part.split("=")
            if len(param_parts) > 2:
                msg = "Multiple = found in one paramter"
                return self._report(line, msg, _UNEXPECTED)
            name = param_parts[0]
            if name[0] == "*":
                if len(name) == 1:
                    msg = "* only parameter name"
                    return self._report(line, msg, _UNEXPECTED)
                if name[1] == "*":
                    name = name[2:]
                else:
                    name = name[1:]
            self._def_params.append(name)
        if (parts[-1] != ":"):
            msg = "No : found at end of def declaration"
            return self._report(line, msg, _UNEXPECTED)
        self._at_line = None
        return OK

    def _check_after_def(self, line):
        if "\"\"\"" in line:
            self._code_state = CodeState.DOCS_START
            parts = line.split("\"\"\"")
            if len(parts) == 1:
                # Ok just the doc start
                pass
            elif len(parts) == 2:
                return self._check_in_doc_start(parts[1])
            elif len(parts) == 3:
                # Ok start and end comment on same line
                self._code_state = CodeState.CODE
                pass
            else:
                print(line)
                print(parts)
                raise NotImplementedError
        # Oops no docs
        self._code_state = CodeState.CODE
        if self._def_type != PRIVATE:
            msg = "No Docs found for function " + self._def_name
            return self._report(line, msg, _NO_DOCS)
        return OK

    def _check_in_doc_start(self, line):
        stripped = line.strip()
        if "\"\"\"" in stripped:
            return self._end_docs(line)
        if len(stripped) == 0:
            self._code_state = CodeState.DOCS_START_AFTER_BLANK
        if stripped.startswith(":py:"):
            return OK
        if stripped.startswith(":"):
            return self._report(line, ":param without blank line", _HIDDEN)
        return OK

    def _end_docs(self, line):
        self._code_state = CodeState.CODE
        stripped = line.strip()
        if stripped == ("\"\"\""):
            return OK
        msg = "Closing quotes should be on their own line (See per-0257)"
        return self._report(line, msg, _STYLE)

    def _check_in_doc_start_after_blank(self, line):
        stripped = line.strip()
        if stripped.startswith("\"\"\""):
            return self._end_docs(line)
        if stripped.startswith(":py"):
            return OK
        if stripped.startswith(":"):
            self._code_state = CodeState.DOCS_DECLARATION
            return self._check_in_doc_declaration(line)
        if len(stripped) > 0:
            self._code_state = CodeState.DOCS_START
        return OK

    def _check_in_doc_declaration(self, line):
        stripped = line.strip()
        if len(stripped) == 0:
            return OK
        if stripped.startswith("\"\"\""):
            self._previous_indent = None
            return self._end_docs(line)
        # Line has already had a rstrip
        indent = len(line) - len(stripped)
        if stripped.startswith(":param"):
            self._param_indent = indent
            self._previous_indent = None
            return self._verify_param(line)
        if stripped.startswith(":type"):
            self._param_indent = indent
            self._previous_indent = None
            return self._verify_type(line)
        if stripped.startswith(":return"):
            self._param_indent = indent
            self._previous_indent = None
            return self._verify_return(line)
        if stripped.startswith(":rtype:"):
            self._param_indent = indent
            self._previous_indent = None
            return self._verify_rtype(line)
        if stripped.startswith(":raise"):
            self._param_indent = indent
            self._previous_indent = None
            return self._verify_raise(line)
        if stripped.startswith(":"):
            if stripped.startswith(":py"):
                return OK
            if stripped == "::":
                return OK
            msg = "Unxpected : line in param doc section"
            return self._report(line, msg, _CRITICAL)
        if indent <= self._param_indent:
            msg = "Unxpected non indented line in param doc section"
            return self._report(line, msg, _CRITICAL)
        return OK

    def _verify_param(self, line):
        stripped = line.strip()
        parts = stripped.split(' ')
        if parts[0] != ":param":
            return self._report(line, "No space after :param", _CRITICAL)
        if len(parts) == 1:
            return self._report(line, "singleton :param", _UNEXPECTED)
        if parts[1][-1] != ":":
            if len(parts) > 2:
                if parts[2][-1] == ":":
                    check = self._verify_param_name(parts[2], line)
                    if check == OK:
                        self._doc_types.append(parts[2][:-1])
                        if len(parts) == 3:  #: param type name:
                            msg = "parameter " + parts[2] + " in " + \
                                  self._def_name + " has no text"
                            return self._report(line, msg, _MISSING)
                    return check
            return self._report(line, "paramater name must end with :",
                                _CRITICAL)
        else:
            return self._verify_param_name(parts[1], line)

    def _verify_param_name(self, name, line):
        name = name[:-1]
        if name not in self._def_params:
            msg = "param " + name + " not in parameter list " + \
                  str(self._def_params)
            return self._report(line, msg, _CRITICAL)
        self._doc_params.append(name)
        return OK

    def _verify_type(self, line):
        stripped = line.strip()
        parts = stripped.split(' ')
        if parts[0] != ":type":
            return self._report(line, "No space after :type", _CRITICAL)
        if len(parts) == 1:
            return self._report(line, ":type requires a param_name: type",
                                _UNEXPECTED)
        if len(parts[1]) == 0:
            return self._report(line, "Double space after :type", _CRITICAL)
        if parts[1][-1] != ":":
            return self._report(line, "in type paramater_name must end with :",
                                _CRITICAL)
        else:
            report = self._verify_param_name(parts[1], line)
            if report != OK:
                return report
        if len(parts) == 2:
            # return self._report(line, ":type requires a param_name: type",
            #                   _MISSING)
            pass
        else:
            if parts[2].lower() == "bytestring":
                msg = "bytestring not a python type use str"
                return self._report(line, msg, _CRITICAL)

        return OK

    def _verify_rtype(self, line):
        stripped = line.strip()
        parts = stripped.split(' ')
        if parts[0] != ":rtype:":
            return self._report(line, "No space after :rtype:", _CRITICAL)
        if len(parts) == 1:
            return self._report(line, ":rtype: requires a type", _UNEXPECTED)
        return OK

    def _verify_raise(self, line):
        stripped = line.strip()
        parts = stripped.split(' ')
        if not parts[0] in [":raise", ":raise:", ":raises", ":raises:"]:
            return self._report(line, "No space after :raise", _CRITICAL)
        if len(parts) == 1:
            return self._report(line, ":raise requires a type", _UNEXPECTED)
        # if parts[1].lower().startswith("none"):
        #    return self._report(line, "Do not use :raise None", _UNEXPECTED)
        return OK

    def _verify_return(self, line):
        stripped = line.strip()
        parts = stripped.split(' ')
        if len(parts) == 1:
            msg = "singleton :return possible :rtype: None"
            return self._report(line, msg, _UNEXPECTED)
        if parts[0] != ":return":
            if parts[0] == ":return:":
                if parts[1].lower() == "none":
                    if len(parts) == 2:
                        msg = "replace :return: None with :rtype: None"
                        return self._report(line, msg, _UNEXPECTED)
                return OK
            else:
                return self._report(line, "No space after :return", _WRONG)
        if parts[1][-1] != ":":
            if len(parts) > 2:
                if len(parts[2]) > 0 and parts[2][-1] == ":":
                    return OK
            return self._report(line, "return must end with :", _MISSING)
        return OK

    def _check_in_comment(self, line):
        stripped = line.strip()
        if "\"\"\"" in stripped:
            return self._end_docs(line)
        return OK

    def _report(self, line, msg, level):
        error = self.python_path + ":" + str(self._lineNum) + "  " + msg
        if not self.test_class:
            # print error
            pass
        if level < _MISSING:
            if self.kill_on_error:
                raise DocException(self.python_path, msg, self._lineNum)
            else:
                self._info.add_error(error)
        return error