Skip to content

Commit

Permalink
Merge pull request #17 from stepanzubkov/dev
Browse files Browse the repository at this point in the history
Version v0.11.0: Paste edit
  • Loading branch information
stepanzubkov authored Jul 17, 2023
2 parents ebc4bbc + 36a4089 commit 0e2aad1
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 5 deletions.
64 changes: 60 additions & 4 deletions florgon_cc_cli/commands/paste.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from io import TextIOWrapper
from datetime import datetime
from typing import List, Optional
import subprocess

import click

Expand All @@ -18,8 +19,10 @@
extract_hash_from_paste_short_url,
get_paste_stats_by_hash,
clear_paste_stats_by_hash,
edit_paste_by_hash,
)
from florgon_cc_cli.services.files import concat_files
from florgon_cc_cli import config


@click.group()
Expand Down Expand Up @@ -65,7 +68,9 @@ def create(
text: Optional[str],
from_files: List[TextIOWrapper],
):
"""Creates paste from text or file."""
"""
Creates paste from text or file.
"""
if from_files and text:
click.secho("Pass --from-file or --text, but not both!", fg="red", err=True)
return
Expand Down Expand Up @@ -109,7 +114,9 @@ def create(
"-e", "--exclude-expired", is_flag=True, default=False, help="Do not show expired pastes."
)
def list(exclude_expired: bool):
"""Prints a list of your pastes. Auth expired."""
"""
Prints a list of your pastes. Auth expired.
"""
success, response = get_pastes_list(access_token=get_access_token())
if not success:
click.secho(response["message"], err=True, fg="red")
Expand All @@ -134,7 +141,10 @@ def list(exclude_expired: bool):
@click.option("-s", "--short_url", type=str, help="Short url.")
@click.option("-o", "--only-text", is_flag=True, default=False, help="Prints only paste text.")
def read(short_url, only_text):
"""Prints text and info about paste."""
"""
Prints text and info about paste.
If short url is not passed, you can choose it from your pastes interactively.
"""
if short_url:
short_url_hash = extract_hash_from_paste_short_url(short_url)
else:
Expand All @@ -161,6 +171,7 @@ def read(short_url, only_text):
def delete(short_url: str):
"""
Deletes paste. Auth Required.
If short url is not passed, you can choose it from your pastes interactively.
"""
if short_url:
short_url_hash = extract_hash_from_paste_short_url(short_url)
Expand Down Expand Up @@ -196,7 +207,10 @@ def delete(short_url: str):
help="Paste views dates as.",
)
def stats(short_url: str, referers_as: str, dates_as: str):
"""Prints paste views statistics."""
"""
Prints paste views statistics.
If short url is not passed, you can choose it from your pastes interactively.
"""
if short_url:
paste_hash = extract_hash_from_paste_short_url(short_url)
else:
Expand Down Expand Up @@ -251,3 +265,45 @@ def clear_stats(short_url: str):
return

click.secho("Paste stats was successfully cleared!", fg="green")


@paste.command()
@click.option("-s", "--short-url", type=str, help="Short url.")
@click.option(
"-e",
"--editor",
type=str,
envvar="EDITOR",
prompt="Editor for paste",
help="Open in specified editor. Defaults to EDITOR environment variable.",
)
def edit(short_url: str, editor: str):
if short_url:
short_url_hash = extract_hash_from_paste_short_url(short_url)
else:
click.echo("Short url is not specified, requesting for list of your pastes.")
short_url_hash = request_hash_from_pastes_list(access_token=get_access_token())

success, response = get_paste_info_by_hash(hash=short_url_hash)
if not success:
click.secho(response["message"], err=True, fg="red")
return

paste_filename = config.TEMP_FILES_DIR / f"florgon_cc_cli_paste_{short_url_hash}"
with open(paste_filename, "w") as paste_file:
paste_file.write(response["text"])

process_result = subprocess.run([editor, paste_filename])
if process_result.returncode != 0:
click.secho(
f"An error occured during editing the paste! Exit code: {process_result.returncode}"
)

with open(paste_filename, "r") as paste_file:
new_text = paste_file.read()
success, response = edit_paste_by_hash(hash=short_url_hash, text=new_text, access_token=get_access_token())
if not success:
click.secho(response["message"], err=True, fg="red")
return

click.secho("Paste was successfully edited!", fg="green")
6 changes: 6 additions & 0 deletions florgon_cc_cli/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from pathlib import Path

CC_API_URL = "https://api-cc.florgon.com/v1"
Expand All @@ -7,3 +8,8 @@

CONFIG_DIR = Path.home() / ".config" / "florgon-cc"
CONFIG_FILE = CONFIG_DIR / "config.toml"

if sys.platform == "win32":
TEMP_FILES_DIR = Path.home()
else:
TEMP_FILES_DIR = Path("/tmp")
22 changes: 22 additions & 0 deletions florgon_cc_cli/services/paste.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,25 @@ def clear_paste_stats_by_hash(
if response.status_code == 204:
return (True,)
return try_decode_response_to_json(response)


def edit_paste_by_hash(
hash: str, text: str, access_token: Optional[str] = None
) -> Union[Tuple[Literal[True], Paste], Tuple[Literal[False], Error], NoReturn]:
"""
Edits user's paste text by hash
:param str hash: paste hash
:param str text: new paste text
:param Optional[str] access_token: access token
:return: Tuple with two or one elements.
First is a response status (True if successfully).
Seconds is a response body.
:rtype: Tuple[True, Paste] if successfully edited, Tuple[False, Error] if error occured,
or exit application if cannot decode to json
"""
response = execute_json_api_method(
"PATCH", f"pastes/{hash}/", access_token=access_token, data={"text": text}
)
if "success" in response:
return True, response["success"]["paste"]
return False, response["error"]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "florgon-cc-cli"
version = "0.10.0"
version = "0.11.0"
license = "MIT"
homepage = "https://cc.florgon.com/"
keywords = ["cli", "url shortener", "paste manager"]
Expand Down

0 comments on commit 0e2aad1

Please sign in to comment.