예제 #1
0
파일: cli.py 프로젝트: duijf/pxl
def build_cmd(force: bool) -> None:
    """Build a static site based on current state."""
    output_dir = build_path
    output_dir.mkdir(parents=True, exist_ok=True)

    click.echo(f"Building site to {output_dir}...", err=True)
    design_dir = Path(entrypoint) / "design"

    cfg = config.load()
    with upload.client(cfg, break_lock=force) as client:
        try:
            pxl_state_json = upload.get_json(client, "state.json")
            overview = state.Overview.from_json(pxl_state_json)
            assert overview is not None, "Expected state to be valid"
        except client.boto.exceptions.NoSuchKey as e:
            click.echo(
                "Remote state not found. Please upload before continuing.", err=True
            )
            sys.exit(1)
        except Exception as e:
            click.echo(e, err=True)
            sys.exit(1)

        bucket_puburl = f"https://{cfg.s3_bucket}.{cfg.s3_region}.{cfg.s3_endpoint}"

        generate.build(
            overview=overview,
            output_dir=output_dir,
            template_dir=design_dir,
            bucket_puburl=bucket_puburl,
            public_image_url=cfg.public_image_url,
        )
    click.echo("Done.", err=True)
예제 #2
0
파일: cli.py 프로젝트: duijf/pxl
def upload_cmd(dir_name: str, force: bool) -> None:
    """
    Upload a directory to the photo hosting.
    """
    cfg = config.load()

    dir_path = Path(dir_name)
    if not dir_path.is_dir():
        click.echo(f"{dir_path} is not a directory.", err=True)
        sys.exit(1)

    with upload.client(cfg, break_lock=force) as client:
        album_name = click.prompt(
            "What name should the album have?", default=dir_path.name.title()
        )

        try:
            pxl_state_json = upload.get_json(client, "state.json")
            pxl_state = state.Overview.from_json(pxl_state_json)
            assert pxl_state is not None, "Expected state to be valid"
        except client.boto.exceptions.NoSuchKey as e:
            pxl_state = state.Overview.empty()
        except Exception as e:
            print(e)
            sys.exit(1)

        print(pxl_state)

        # Get existing album with this name for appending.
        album = pxl_state.get_album_by_name(album_name)
        if album:
            click.confirm("Album already exists. Add to existing album?", abort=True)
        else:
            click.echo("Creating new album.", err=True)
            album = state.Album(
                name_display=album_name,
                name_nav=album_name.lower().replace(" ", "-"),
                created=datetime.datetime.now(),
                images=[],
            )

        # Find all files with known JPEG extensions. We don't
        # traverse nested directories, just the toplevel.
        for entry in dir_path.iterdir():
            if not entry.is_file():
                continue

            if not entry.suffix.lower() in [".jpeg", ".jpg"]:
                continue

            image = upload.public_image_with_size(client, entry)
            album = album.add_image(image)

        pxl_state = pxl_state.add_or_replace_album(album)
        upload.private_json(client, json.dumps(pxl_state.to_json()), "state.json")
예제 #3
0
파일: cli.py 프로젝트: kimjeonghwa/pxl
def edit_cmd(album_name: str, force: bool) -> None:
    """
    Edit the name and date of an album
    """
    cfg = config.load()
    with upload.client(cfg, break_lock=force) as client:
        try:
            pxl_state_json = upload.get_json(client, "state.json")
            pxl_state = state.Overview.from_json(pxl_state_json)
            assert pxl_state is not None, "Expected state to be valid"
        except client.boto.exceptions.NoSuchKey as e:
            pxl_state = state.Overview.empty()
        except Exception as e:
            print(e)
            sys.exit(1)

        print(pxl_state)
        old_album = pxl_state.get_album_by_name(album_name)
        if not (old_album):
            click.echo(f"{album_name} does not exist", err=True)
            sys.exit(1)
        else:
            new_album = copy.deepcopy(old_album)
            album_name = click.prompt("What should the new album name be?",
                                      default=old_album.name_display)
            album_date = click.prompt(  # type: ignore
                "What should the new album date be?",
                default=str(old_album.created),
                value_proc=validate,
            )

            alt_album = pxl_state.get_album_by_name(album_name)
            if alt_album and not (album_name == old_album.name_display):
                click.confirm(
                    "An album with that name already exists. Merge albums?",
                    abort=True)
                alt_album.created = album_date
                alt_album.images = alt_album.images + old_album.images
                pxl_state = pxl_state.remove_album(old_album)
                pxl_state = pxl_state.edit_album(alt_album, alt_album)
                upload.private_json(client, json.dumps(pxl_state.to_json()),
                                    "state.json")
            else:
                new_album.name_display = album_name
                new_album.name_nav = album_name.lower().replace(" ", "-")
                new_album.created = album_date

                pxl_state = pxl_state.edit_album(old_album, new_album)
                upload.private_json(client, json.dumps(pxl_state.to_json()),
                                    "state.json")
예제 #4
0
파일: cli.py 프로젝트: duijf/pxl
def deploy_cmd() -> None:
    """Deploy the static output."""
    if not config.is_initialized():
        click.echo("Config not initialized. Please run `pxl init` first.", err=False)
        sys.exit(1)

    output_dir = build_path
    if not output_dir.is_dir():
        click.echo("No output to deploy. Please run `pxl build` first.", err=False)
        sys.exit(1)

    cfg = config.load()

    deploy_command = [
        "rsync",
        "-rzP",
        "--delete",
        f"{output_dir}/",
        f"{cfg.deploy_user}@{cfg.deploy_host}:{cfg.deploy_path}",
    ]
    subprocess.run(deploy_command)
예제 #5
0
파일: cli.py 프로젝트: kimjeonghwa/pxl
def delete_cmd(album_name: str, force: bool) -> None:
    """
    Delete an album and its pictures.
    """
    cfg = config.load()

    with upload.client(cfg, break_lock=force) as client:

        try:
            pxl_state_json = upload.get_json(client, "state.json")
            pxl_state = state.Overview.from_json(pxl_state_json)
            assert pxl_state is not None, "Expected state to be valid"
        except client.boto.exceptions.NoSuchKey as e:
            pxl_state = state.Overview.empty()
        except Exception as e:
            print(e)
            sys.exit(1)

        print(pxl_state)

        # Get existing album with this name to check if it exists
        album = pxl_state.get_album_by_name(album_name)
        if album:
            click.echo("Album found, deleting pictures...")
            for image in album.images:
                upload.delete_image(client, image.get_name("original"))
                upload.delete_image(client, image.get_name("display_w_1600"))
                upload.delete_image(client, image.get_name("thumbnail_w_400"))

        else:
            click.echo("Given album not found")
            sys.exit(1)

        click.echo("deleting album...")

        pxl_state = pxl_state.remove_album(album)
        upload.private_json(client, json.dumps(pxl_state.to_json()),
                            "state.json")

        click.echo("deleted album, please run build and deploy now")
예제 #6
0
파일: cli.py 프로젝트: kimjeonghwa/pxl
def deploy_cmd() -> None:
    """Deploy the static output."""
    if not config.is_initialized():
        click.echo("Config not initialized. Please run `pxl init` first.",
                   err=False)
        sys.exit(1)

    output_dir = build_path
    if not output_dir.is_dir():
        click.echo("No output to deploy. Please run `pxl build` first.",
                   err=False)
        sys.exit(1)

    cfg = config.load()

    dry_run_result = subprocess.run(
        build_deploy_rsync(output_dir, cfg, dry_run=True),
        capture_output=True,
        text=True,
    )

    # Inspect dry run output to check whether there are any files to delete
    if len(dry_run_result.stdout) > 0:
        stdout_lines = dry_run_result.stdout.split("\n")
        click.echo(
            click.style(
                "Warning! Rsync reports that it will delete these files:",
                fg="yellow"))

        for line in stdout_lines[:-1]:
            parts = line.split(" ", 1)

            click.echo(click.style(parts[1], fg="yellow"))

        if not click.confirm("Continue?"):
            click.echo("Aborting.")
            return

    dry_run_result = subprocess.run(
        build_deploy_rsync(output_dir, cfg, dry_run=False))