Exemple #1
0
 def _modifier_wrapper(self, tmp_path: Path, name: str, impact: str,
                       ask: bool, modifier: Callable[[int], None]) -> None:
     count = count_lines(tmp_path)
     if ask and not pause(
             f'{cyan(name)} keywords (impact: {impact} => {eval(f"{count}{impact}")})',
             cancel=True):
         return
     modifier(tmp_path, count)
     new_count = count_lines(tmp_path)
     pr(f'{name} added {cyan(new_count - count)} new keywords, total: {cyan(new_count)}'
        )
Exemple #2
0
    def clear(self, args: tuple) -> None:
        if not pause('truncatete wordlist', cancel=True):
            return

        f = self._get_wordlist_path()
        if not f:
            return

        with f.open('w') as file:
            file.truncate()
        pr('Wordlist truncateted!')
Exemple #3
0
def aur_deploy(args):
    if args.directory:
        directory = Path(args.directory)
        if directory.is_file():
            directory = directory.parent
    else:
        directory = Path.cwd()
    if not directory.is_dir():
        pr(f'Cnnot run in directory, No such directory {directory} !', 'X')
        return 1

    pr(f'Running in: {directory} directory')
    if not directory.joinpath('setup.py').is_file():
        pr(
            'No setup.py found in directory, ' +
            'Please prepare setup.py for deployment!', 'X')
        return 1

    # Load setup.py
    title, new_ver, description = check_output(
        ['python3', 'setup.py', '--name', '--version', '--description'],
        cwd=directory).decode().splitlines()
    pr(f'Project {title} {new_ver} in: {directory}')

    # Check PyPI
    if args.force or version.parse(new_ver) > version.parse(
            get_pypi_ver(title)):
        if not pause('publish to PyPI', cancel=True) \
                or not pypi_procedure(directory):
            return 1

    # Check AUR
    if args.no_aur:
        return
    aur_ver = get_aur_ver(title)
    if args.force or version.parse(new_ver) > version.parse(aur_ver):
        if not pause('publish to AUR', cancel=True) \
            or not aur_procedure(aur_ver == '0', args.aur_depends,
                                 directory, title, new_ver):
            return 1
Exemple #4
0
    def duplicate(self, args: tuple) -> None:
        if not args:
            return pr('Usage: duplicate <copy_name>', '*')

        f = self._get_wordlist_path()
        if not f:
            return

        dst = Path(args[0])
        if dst.is_file():
            pr(f'File {cyan(dst)} already exists, overwrite?', '!')
            if not pause(cancel=True):
                return
        copy(f, dst)
        pr(f'Copied to {cyan(dst)}!')
Exemple #5
0
    def crunch(self, args: tuple) -> None:
        if not is_package('crunch'):
            return pr('Package "crunch" not installed!', 'X')

        # Get args
        is_mask = args and args[0] == 'mask'

        # Mode switch: [Mask / Charset]
        if is_mask:
            mask = prompt_mask()
            if not mask:
                return pr('Invalid mask!', '!')

            file_name = f'mask_{ask("Enter save name:")}.dict'
            l = str(len(mask))
            return self._crunch(
                lambda: self._gen(file_name, ['crunch', l, l, '-t', mask]))

        # Get min and max seq len
        min_len = prompt_int('Enter minimum length')
        max_len = prompt_int('Enter maximum length')
        if not min_len or not max_len or \
                min_len < 1 or max_len < min_len:
            return pr('Invalid paramenters!', '!')

        # Ask for a charset to use
        with CHAR_FILE.open(encoding='utf-8') as char_file:
            sets = [n[:-1] for n in char_file if '=' in n and 'sv' not in n]
        select = choose(sets, 'Choose charset:', default=26)  # Actually 27
        if select < 0:
            exit(-1)
        charset = sets[select].split(' ')[0]

        # Confirm
        if not pause(
                f'generate ({cyan(min_len)}-{cyan(max_len)}) length dict via "{cyan(charset)}" charset',
                cancel=True):
            return

        file_name = f'{charset}_{min_len}-{max_len}.dict'
        return self._crunch(lambda: self._gen(file_name, [
            'crunch',
            str(min_len),
            str(max_len), '-f', CHAR_FILE, charset
        ]))
Exemple #6
0
    def use(self, args: tuple) -> None:
        if self.current:
            if not pause(
                    f'Switching from {cyan(self.current)} to new wordlist',
                    cancel=True):
                return
        f = choose_file(self.workspace)
        if not f:
            return

        sb, lc, txt = file_volume(f)
        pr(txt)

        # if sb > 1*1024**3:  # 1 GB
        #     pr(f'File is too larget to be loaded into RAM!', '!')
        #     return
        self.current = f
        pr(f'Now using {cyan(self.current)} wordlist!')
Exemple #7
0
    def ask_two_wl(self, _total_calc=Callable[[int, int], int], _write_action=Callable[[Path, Path, Path, IterationTimer], None]):
        def _select_wordlist(title: str):
            pr(f'Select {title} wordlist:')
            f = choose_file(self.workspace)
            if not f:
                raise KeyboardInterrupt
            fsb, flc, ftxt = file_volume(f)
            pr(f'  {ftxt}')
            return f, fsb, flc

        # Get wordlists
        try:
            f1, f1sb, f1lc = _select_wordlist('first')
            f2, f2sb, f2lc = _select_wordlist('secund')
        except KeyboardInterrupt:
            print()
            return pr('Interrupted', '!')

        # Calculate impact and let the user accept the facts
        tsb = _total_calc(f1sb, f2sb)
        tlc = _total_calc(f1lc, f2lc)
        pr(f'Mixing will allocate {cyan(human_bytes(tsb))} for {cyan("{:,}".format(tlc))} lines')

        free = disk_usage(self.workspace.resolve()).free
        pr(f"Available space on workspace's disk: " + cyan(human_bytes(free)))
        if tsb > free:
            pr('Not enough space on the workspace disk for allocation!', '!')
            return
        max_size = self.config['max_created_file_size']
        if tsb > max_size:
            return pr(f'Calculation resulted in an oversized file (>{human_bytes(max_size)}), aborting!', '!')
        if not pause(cancel=True):
            return

        out_path = self.dest_dir.joinpath(f'{f1.stem}_{f2.stem}')
        with out_path.open('w', encoding='utf-8') as out_file:
            itmr = IterationTimer(tlc, init_interval=1, max_interval=15)
            _write_action(f1, f2, out_file, itmr)

        # Finalize
        pr('Wordlist written into: ' + cyan(out_path.name))
        show_ebt({  # TODO Move to config
            'WPA2': 57000
        }, tlc)
Exemple #8
0
    def print_all(self, args: tuple) -> None:
        f = self._get_wordlist_path()
        if not f:
            return

        lc = count_lines(f)
        if not lc:
            return pr('Wordlist is empty!', '!')

        # Get arguments
        total = False
        if args:
            total = args[0] == 'total'

        # Print relevant info
        if not total:
            if lc > self.config['list_treshold']:
                if not pause(f'show all {cyan(lc)} keywords', cancel=True):
                    return
            for v in self._gen_wordlist(f):
                cprint('  ' + v, "yellow")
        pr(f'Total keywords count: ' + cyan(lc))
Exemple #9
0
    def expand(self, args: tuple) -> None:
        f = self._get_wordlist_path()
        if not f:
            return

        lc = count_lines(f)
        if not self:
            return pr('Wordlist is empty!', '!')

        # Get new wordlist name
        try:
            print('Enter name for new expanded wordlist:')
            save_path = input(colored('>', 'yellow'))
            if not save_path:
                return
            save_path = self.workspace.joinpath('expand_' + str(save_path))
            if save_path.is_file():
                pr(f'File {cyan(save_path)} already exists, overwrite?', '!')
                if not pause(cancel=True):
                    return
        except KeyboardInterrupt:
            return

        # Get arguments
        auto_all = False
        if args:
            auto_all = args[0] == 'all'

        _, tmp_path = mkstemp('stargen')
        tmp_path = Path(tmp_path)

        # Copy initial content
        tmp_path.write_bytes(f.read_bytes())

        def _capitalize(tmp_p: Path, count: int) -> None:
            with tmp_p.open('a', encoding='utf8') as file:
                for k in self._gen_wordlist(f):
                    file.write(k.capitalize() + '\n')

        self._modifier_wrapper(tmp_path, 'Capitalize', '*2', not auto_all,
                               _capitalize)

        def _leetify(tmp_p: Path, count: int) -> None:
            with tmp_p.open('a', encoding='utf8') as file:
                for k in self._gen_wordlist(f):
                    file.write(leetify(k) + '\n')

        self._modifier_wrapper(tmp_path, '13371fy', '*2', not auto_all,
                               _leetify)

        def _mockify(tmp_p: Path, count: int) -> None:
            with tmp_p.open('a', encoding='utf8') as file:
                for k in self._gen_wordlist(f):
                    file.write(mockify(k, True) + '\n')
                    file.write(mockify(k, False) + '\n')

        self._modifier_wrapper(tmp_path, 'MoCkIfY', '*3', not auto_all,
                               _mockify)

        def _intermix(tmp_p: Path, count: int) -> None:
            itmr = IterationTimer(count**2)
            with tmp_p.open('a', encoding='utf8') as file:
                for a in self._gen_wordlist(f):
                    for b in self._gen_wordlist(f):
                        file.write(a + b + '\n')
                        file.write(b + a + '\n')
                        itmr.tick()

        self._modifier_wrapper(tmp_path, 'Intermix', '**2', not auto_all,
                               _intermix)

        # Save as
        pr(f'Saving as: {cyan(save_path)}')
        move(tmp_path, save_path)
        new_lc = count_lines(save_path)

        # Show current status
        print()
        a = []
        if new_lc > self.config['list_treshold']:
            a += ['total']
        self.print_all(a)
Exemple #10
0
def aur_procedure(new_package: bool, aur_deps: iter, directory: Path,
                  title: str, new_ver: str):
    aur_subdir = directory.joinpath('aur')
    create = False
    if not aur_subdir.is_dir():
        pr('No "aur" subdirectory found, initiate?', '!')
        if not pause(cancel=True):
            return
        create = True

    pkgbuild = aur_subdir.joinpath('PKGBUILD')
    aur_remote_url = f'ssh://[email protected]/python-{title}.git'
    if not create:
        # Only update pkgbuild version info
        if not update_pkgbuild_version(pkgbuild, directory, title, new_ver):
            return
    else:
        if not new_package:
            # clone
            pr('Cloning existing AUR repo')
            call(['git', 'clone', aur_remote_url, 'aur'], cwd=directory)

            # Update pkgbuild version info
            if not update_pkgbuild_version(pkgbuild, directory, title,
                                           new_ver):
                return
        else:
            pr('Creating submodule named aur which will host AUR repo')
            aur_subdir.mkdir()
            call(['git', 'init'], cwd=aur_subdir)
            call(['git', 'remote', 'add', 'aur', aur_remote_url],
                 cwd=aur_subdir)

            # Get deps:
            requires = {
                'python-' + i
                for i in check_output(['python3', 'setup.py', '--requires'],
                                      cwd=directory).decode().splitlines() if i
            }
            lreq = len(requires)
            pr(f'Added {lreq} dependencies from setup.py')
            if aur_deps:
                if 'python' in aur_deps:
                    aur_deps.remove('python')
                requires.update(aur_deps)
                pr(f'Added {len(requires) - lreq} dependencies from cli arguments'
                   )
            for i in requires:
                print('\t', i)
            pr('Using pip2pkgbuild to create a new PKGBUILD in ./aur directory'
               )
            pkgbuild.write_bytes(
                check_output(['pip2pkgbuild', '-d'] + list(requires) +
                             ['-o', title]))
            # TODO Insert Maintainer tag

        pr('Created, go edit it as you see fit and then continue')
        if not pause(cancel=True):
            return
            # TODO Check with namcap

    # makepkg_srcinfo
    pr('Dumping SRCINFO')
    with aur_subdir.joinpath('.SRCINFO').open('w') as srcinfo:
        if 0 != call(
            ['makepkg', '--printsrcinfo'], cwd=aur_subdir, stdout=srcinfo):
            return pr('Bad exit code from makepkg!', 'X')

    # Commit and push changes to AUR
    branch_name = check_output(['git', 'branch', '--show-current'],
                               cwd=aur_subdir).decode().strip()
    if branch_name != 'master':  # Currently AUR declines other names
        pr(f'Renaming branch: {branch_name} to "master" (per AUR policy)')
        call(['git', 'branch', '-m', 'master'], cwd=aur_subdir)
        branch_name = check_output(['git', 'branch', '--show-current'],
                                   cwd=aur_subdir).decode().strip()

    pr('Staging updated files')
    call(['git', 'add', 'PKGBUILD', '.SRCINFO'], cwd=aur_subdir)
    commit_msg = f'"Updated to v{new_ver}"'

    pr(f'Committing: {commit_msg}')
    call(['git', 'commit', '-m', commit_msg], cwd=aur_subdir)

    pr('Pushing to AUR!')
    remote_name = check_output(['git', 'remote', 'show'],
                               cwd=aur_subdir).decode().strip()
    call(['git', 'push', '--set-upstream', remote_name, branch_name],
         cwd=aur_subdir)
    if create:
        if 128 == call(['git', 'status'], stdout=DEVNULL, cwd=directory):
            return pr(
                'No git repo initialized so cannot register the "aur" submodule',
                '!')
        pr('Registering a submodule "aur"')
        call(['git', 'submodule', 'add', aur_remote_url, 'aur'], cwd=directory)
    return 1  # Success