123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #!/usr/bin/env python
- # -*- coding = utf-8 -*-
- # filename: utils.py
- from configparser import DEFAULTSECT, MissingSectionHeaderError, ParsingError, RawConfigParser, \
- NoSectionError
- import os
- import stat
- from mutagen._compat import StringIO
- from requests.compat import basestring
- SUFFIX = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
- def appromix(size, base=0):
- """Conver bytes stream size to human-readable format.
- Keyword arguments:
- size: int, bytes stream size
- base: int, suffix index
- Return: string
- """
- multiples = 1024
- if size < 0:
- raise ValueError('[-] Error: number must be non-negative.')
- if size < multiples:
- return '{0:d}{1}'.format(size, SUFFIX[base])
- for suffix in SUFFIX[base:]:
- if size < multiples:
- return '{0:.2f}{1}'.format(size, suffix)
- size //= multiples
- raise ValueError('[-] Error: number too big.')
- def get_file_ext_name(filename, double_ext=True):
- li = filename.split(os.extsep)
- if len(li) <= 1:
- return ''
- else:
- if li[-1].find(os.sep) != -1:
- return ''
- if double_ext:
- if len(li) > 2:
- if li[-2].find(os.sep) == -1:
- return '%s.%s' % (li[-2], li[-1])
- return li[-1]
- class Fdfs_ConfigParser(RawConfigParser):
- """
- Extends ConfigParser to allow files without sections.
-
- This is done by wrapping read files and prepending them with a placeholder
- section, which defaults to '__config__'
- """
- def __init__(self, default_section=None, *args, **kwargs):
- RawConfigParser.__init__(self, *args, **kwargs)
- self._default_section = None
- self.set_default_section(default_section or '__config__')
- def get_default_section(self):
- return self._default_section
- def set_default_section(self, section):
- self.add_section(section)
- # move all values from the previous default section to the new one
- try:
- default_section_items = self.items(self._default_section)
- self.remove_section(self._default_section)
- except NoSectionError:
- pass
- else:
- for (key, value) in default_section_items:
- self.set(section, key, value)
- self._default_section = section
- def read(self, filenames):
- if isinstance(filenames, basestring):
- filenames = [filenames]
- read_ok = []
- for filename in filenames:
- try:
- with open(filename) as fp:
- self.readfp(fp)
- except IOError as e:
- continue
- else:
- read_ok.append(filename)
- return read_ok
- def readfp(self, fp, *args, **kwargs):
- stream = StringIO()
- try:
- stream.name = fp.name
- except AttributeError as e:
- pass
- stream.write('[' + self._default_section + ']\n')
- stream.write(fp.read())
- stream.seek(0, 0)
- return self._read(stream, stream.name)
- def write(self, fp):
- # Write the items from the default section manually and then remove them
- # from the data. They'll be re-added later.
- try:
- default_section_items = self.items(self._default_section)
- self.remove_section(self._default_section)
- for (key, value) in default_section_items:
- fp.write("{0} = {1}\n".format(key, value))
- fp.write("\n")
- except NoSectionError:
- pass
- RawConfigParser.write(self, fp)
- self.add_section(self._default_section)
- for (key, value) in default_section_items:
- self.set(self._default_section, key, value)
- def _read(self, fp, fpname):
- """Parse a sectioned setup file.
- The sections in setup file contains a title line at the top,
- indicated by a name in square brackets (`[]'), plus key/value
- options lines, indicated by `name: value' format lines.
- Continuations are represented by an embedded newline then
- leading whitespace. Blank lines, lines beginning with a '#',
- and just about everything else are ignored.
- """
- cursect = None # None, or a dictionary
- optname = None
- lineno = 0
- e = None # None, or an exception
- while True:
- line = fp.readline()
- if not line:
- break
- lineno += 1
- # comment or blank line?
- if line.strip() == '' or line[0] in '#;':
- continue
- if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
- # no leading whitespace
- continue
- # continuation line?
- if line[0].isspace() and cursect is not None and optname:
- value = line.strip()
- if value:
- cursect[optname] = "%s\n%s" % (cursect[optname], value)
- # a section header or option header?
- else:
- # is it a section header?
- mo = self.SECTCRE.match(line)
- if mo:
- sectname = mo.group('header')
- if sectname in self._sections:
- cursect = self._sections[sectname]
- elif sectname == DEFAULTSECT:
- cursect = self._defaults
- else:
- cursect = self._dict()
- cursect['__name__'] = sectname
- self._sections[sectname] = cursect
- # So sections can't start with a continuation line
- optname = None
- # no section header in the file?
- elif cursect is None:
- raise MissingSectionHeaderError(fpname, lineno, line)
- # an option line?
- else:
- mo = self.OPTCRE.match(line)
- if mo:
- optname, vi, optval = mo.group('option', 'vi', 'value')
- if vi in ('=', ':') and ';' in optval:
- # ';' is a comment delimiter only if it follows
- # a spacing character
- pos = optval.find(';')
- if pos != -1 and optval[pos - 1].isspace():
- optval = optval[:pos]
- optval = optval.strip()
- # allow empty values
- if optval == '""':
- optval = ''
- optname = self.optionxform(optname.rstrip())
- if cursect.get(optname):
- if not isinstance(cursect[optname], list):
- cursect[optname] = [cursect[optname]]
- cursect[optname].append(optval)
- else:
- cursect[optname] = optval
- else:
- # a non-fatal parsing error occurred. set up the
- # exception but keep going. the exception will be
- # raised at the end of the file and will contain a
- # list of all bogus lines
- if not e:
- e = ParsingError(fpname)
- e.append(lineno, repr(line))
- # if any parsing errors occurred, raise an exception
- if e:
- raise e
- def split_remote_fileid(remote_file_id):
- """
- Splite remote_file_id to (group_name, remote_file_name)
- arguments:
- @remote_file_id: string
- @return tuple, (group_name, remote_file_name)
- """
- index = remote_file_id.find('/')
- if -1 == index:
- return None
- return remote_file_id[0:index], remote_file_id[(index + 1):]
- def fdfs_check_file(filename):
- ret = True
- errmsg = ''
- if not os.path.isfile(filename):
- ret = False
- errmsg = '[-] Error: %s is not a file.' % filename
- elif not stat.S_ISREG(os.stat(filename).st_mode):
- ret = False
- errmsg = '[-] Error: %s is not a regular file.' % filename
- return ret, errmsg
- if __name__ == '__main__':
- print(get_file_ext_name('/bc.tar.gz'))
|