Exemple #1
0
class PkginfoParser(Parser):
	''' The PKGINFO parser '''

	#: Pattern matches 'key = val'
	PATTERN = compile_pattern('([a-z]+) = ([^\n]+)\n')

	#: Translations from PKGINFO to local-repo
	TRANS = {'pkgname': 'name',
	         'pkgver': 'version',
	         'pkgdesc': 'desc',
	         'size': 'isize',
	         'url': 'url',
	         'license': 'license',
	         'arch': 'arch',
	         'builddate': 'builddate',
	         'packager': 'packager'}

	def parse(self):
		''' Parses a PKGINFO '''
		info = dict(PkginfoParser.PATTERN.findall(self._data))

		try:
			return {t: info[k] for k, t in PkginfoParser.TRANS.items()}
		except KeyError as e:
			raise ParserError(_('Missing PKGINFO entry: {0}').format(e))
Exemple #2
0
class DescParser(Parser):
	''' The database desc parser '''

	#: Pattern matches '%key%\nval'
	PATTERN = compile_pattern('%([A-Z256]+)%\n([^\n]+)\n')

	#: List of mandatory fields
	MANDATORY = ['filename', 'name', 'version']

	#: List of fields with informational character
	OPTIONAL = ['desc', 'csize', 'isize', 'md5sum', 'sha256sum', 'url', 'license',
	            'arch', 'builddate', 'packager']

	#: List of fields of which we just want to know wether they are availble or not
	BOOL = ['pgpsig']

	def parse(self):
		''' Parses a desc file '''
		info = {k.lower(): v for k, v in DescParser.PATTERN.findall(self._data)}
		missing = [field for field in DescParser.MANDATORY if field not in info]

		if missing:
			raise ParserError(_('Missing fields: {0}').format(', '.join(missing)))

		for opt in [o for o in DescParser.OPTIONAL if o not in info]:
			info[opt] = None

		for opt in DescParser.BOOL:
			info[opt] = bool(info[opt]) if opt in info else False

		return info
Exemple #3
0
class PkgbuildParser(Parser):
	''' The PKGBUILD parser '''

	#: Path to bash
	BASH = '/bin/bash'

	#: Path to makepkg.conf
	MAKEPKG_CONF = '/etc/makepkg.conf'

	#: Pattern matches 'key=val'
	PATTERN = compile_pattern('([a-z]+)=([^\n]*)\n')

	#: Translations from PKGBUILD to local-repo
	TRANS = {'pkgname': 'name',
	         'pkgver': 'version',
	         'depends': list,
	         'makedepends': list}

	#: Bash command that prints needed info 'key=val' style
	ECHO = ' && '.join(('echo "{0}=${{{0}[@]}}"'.format(k) for k in TRANS))

	def parse(self):
		''' Parses a PKGBUILD - self._data must be the path to a PKGBUILD file'''
		cmd = 'source {0} && source {1} && {2}'.format(PkgbuildParser.MAKEPKG_CONF, self._data,
		                                               PkgbuildParser.ECHO)

		try:
			data = check_output([PkgbuildParser.BASH, '-c', cmd]).decode('utf8')
		except:
			raise ParserError(_('Could not parse PKGBUILD: {0}').format(self._data))

		data = dict(PkgbuildParser.PATTERN.findall(data))
		info = {}

		for k, t in PkgbuildParser.TRANS.items():
			if k not in data:
				raise ParserError(_('Could not parse PKGBUILD: {0}').format(self._data))

			if t is list:
				info[k] = data[k].split()
			elif data[k] != '':
				info[t] = data[k]
			else:
				raise ParserError(_('Missing PKGBUILD entry: {0}').format(k))

		return info
Exemple #4
0
from Choice import create_Choice
from Course import create_Course
from Question import create_Question
from Question import find_question_by_key
from Quiz import create_Quiz
from Quiz import find_quiz_by_key
from re import compile as compile_pattern
from Student import create_Student
from Student import lookup_student
from Teacher import create_Teacher

group_positive_integer_pattern = r'([1-9][0-9]*)'

choice_number_match = compile_pattern(
    r'^' + group_positive_integer_pattern  #   course number
    + '.' + group_positive_integer_pattern  #   question number
    + '.' + group_positive_integer_pattern  #   quiz number
    + r'([A-Z])'  #   choice letter
    + '\Z').match

question_number_match = compile_pattern(
    r'^' + group_positive_integer_pattern  #   course number
    + '.' + group_positive_integer_pattern  #   question number
    + '.' + group_positive_integer_pattern  #   quiz number
    + '\Z').match


#
#   create_choice_and_print
#
def create_choice_and_print(i, name, number, correct, choice_text):
    m = choice_number_match(number)
Exemple #5
0
class Pacman:
    ''' A wrapper for program calls of the pacman package '''

    #: Path to su
    SU = '/bin/su'

    #: Path to sudo
    SUDO = '/usr/bin/sudo'

    #: Path to pacman
    PACMAN = '/usr/bin/pacman'

    #: Path to makepkg
    MAKEPKG = '/usr/bin/makepkg'

    #: Path to repo-add
    REPO_ADD = '/usr/bin/repo-add'

    #: Path to repo-remove
    REPO_REMOVE = '/usr/bin/repo-remove'

    #: Path to repo-elephant
    REPO_ELEPHANT = '/usr/bin/repo-elephant'

    #: Split pattern, used to remove the version requirement from the package name
    VERSION_SEP = compile_pattern('<|>|=')

    @staticmethod
    def call(cmd):
        ''' Calls a command '''
        if type(cmd) is str:
            cmd = [cmd]

        if call(cmd) is not 0:
            raise PacmanCallError(' '.join(cmd))

    @staticmethod
    def _run_as_root(cmd):
        ''' Runs a command as root '''
        if getuid() is not 0:
            if access(Pacman.SUDO, X_OK):
                cmd.insert(0, Pacman.SUDO)
            else:
                cmd = [Pacman.SU, '-c', '\'{0}\''.format(' '.join(cmd))]

        Pacman.call(cmd)

    @staticmethod
    def install(pkgs, as_deps=False):
        ''' Installs packages '''
        cmd = [Pacman.PACMAN, '-Sy'] + pkgs

        if as_deps:
            cmd.append('--asdeps')

        Pacman._run_as_root(cmd)

    @staticmethod
    def uninstall(pkgs):
        ''' Unnstalls packages '''
        for i, pkg in enumerate(pkgs):
            pkgs[i] = Pacman.VERSION_SEP.split(pkg)[0]

        Pacman._run_as_root([Pacman.PACMAN, '-Rs'] + list(set(pkgs)))

    @staticmethod
    def check_from_aur(pkgs):
        ''' Checks whether packages are from AUR '''
        res = {}
        for pkg in pkgs:
            # Try to find `pkg` in official repositories
            cmd = [Pacman.PACMAN, '-Ssq', pkg]
            try:
                check_output(cmd)
                res[pkg] = False
            except CalledProcessError as e:
                res[pkg] = True

        return res

    @staticmethod
    def check_deps(pkgs):
        ''' Checks for unresolved dependencies '''
        cmd = [Pacman.PACMAN, '-T'] + pkgs

        try:
            check_output(cmd)
            return []
        except CalledProcessError as e:
            if e.returncode is 127:
                return e.output.decode('utf8').split()

            raise PacmanCallError(' '.join(cmd))

    @staticmethod
    def make_package(path, force=False):
        ''' Calls makepkg '''
        try:
            chdir(path)
        except:
            raise PacmanError(
                _('Could not change working directory: {0}').format(path))

        cmd = [Pacman.MAKEPKG, '-d']

        if force:
            cmd.append('-f')

        if Config.get('buildlog', False):
            cmd += ['-L', '-m']

        if Config.get('sign', False):
            cmd.append('--sign')
        else:
            cmd.append('--nosign')

        Pacman.call(cmd)

    @staticmethod
    def _repo_script(script, db, pkgs):
        ''' Calls one of the repo- scripts '''
        cmd = [script, db] + pkgs

        if Config.get('signdb', False):
            cmd += ['--verify', '--sign']

        Pacman.call(cmd)

    @staticmethod
    def repo_add(db, pkgs):
        ''' Calls repo-add  '''
        Pacman._repo_script(Pacman.REPO_ADD, db, pkgs)

    @staticmethod
    def repo_remove(db, pkgs):
        ''' Calls repo-remove '''
        Pacman._repo_script(Pacman.REPO_REMOVE, db, pkgs)

    @staticmethod
    def repo_elephant():
        ''' The elephant never forgets '''
        if call([Pacman.REPO_ELEPHANT]) is not 0:
            raise PacmanError(_('Ooh no! Somebody killed the repo elephant'))