Skip to content

Commit

Permalink
Merge pull request #38 from PTschaikner/attempts-tries
Browse files Browse the repository at this point in the history
New Full Logbook
  • Loading branch information
lemeryfertitta authored Jun 21, 2024
2 parents a92c3c5 + 87f338a commit 802fb23
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 110 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,28 @@ All [Aurora Climbing](https://auroraclimbing.com/) based boards (Kilter, Tension

To download your logbook entries for a given board:

`boardlib logbook <board_name> --username=<username> --output=<output_file_name>.csv --grade-type="hueco"`
`boardlib logbook <board_name> --username=<username> --output=<output_file_name>.csv --grade-type="hueco" --database=<local_database_file>`

This outputs a CSV file with the following fields:

```json
["board", "angle", "name", "date", "grade", "tries", "is_mirror"]
["board", "angle", "climb_name", "date", "logged_grade", "displayed_grade", "difficulty", "tries", "is_mirror", "sessions_count", "tries_total", "is_repeat", "is_ascent", "comment"]
```

For example, the command

`boardlib moon2017 --username="Luke EF" --output="moon2017.csv" --grade-type="hueco"`
`boardlib tension --username="Luke EF" --output="tension.csv" --grade-type="hueco" --database="tension.db"`

would output a file named `moon2017.csv` with the following contents:
would output a file named `tension.csv` with the following contents:

```
board,angle,name,date,grade,tries, is_mirror
moon2017,40,C3PO,2021-07-13,V5,1, False
moon2017,40,LITTLE BLACK SUBMARINE,2021-07-13,V5,2, False
moon2017,40,MOUNTAIN GOAT HARD,2021-07-13,V5,1, False
board,angle,climb_name,date,logged_grade,displayed_grade,difficulty,tries,is_mirror,sessions_count,tries_total,is_repeat,is_ascent,comment
tension,40,trash bag better,2024-06-17 16:21:23,V3,V3,16.0,3,False,1,3,False,True,
tension,40,Bumble,2024-06-17 16:28:23,V3,V3,16.0,1,True,1,1,False,True,
tension,40,sender2,2024-06-17 16:38:06,V5,V5,20.0,2,False,1,2,False,True,
...
```

When no local database is provided, displayed_grade and difficulty remain empty.
See `boardlib --help` for a full list of supported board names and feature flags.

#### Supported Boards 🛹
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = ["bs4", "requests"]
dependencies = ["bs4", "requests", "pandas"]

[project.scripts]
boardlib = "boardlib.__main__:main"
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
beautifulsoup4
requests
requests
pandas
48 changes: 25 additions & 23 deletions src/boardlib/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import boardlib.api.moon
import boardlib.db.aurora

LOGBOOK_FIELDS = ("board", "angle", "name", "date", "grade", "tries", "is_mirror")

LOGBOOK_FIELDS = ("board", "angle", "climb_name", "date", "logged_grade", "displayed_grade", "difficulty", "tries", "is_mirror", "sessions_count", "tries_total", "is_repeat", "is_ascent", "comment")


def logbook_entries(board, username, password, grade_type="font", database=None):
Expand All @@ -27,29 +28,14 @@ def logbook_entries(board, username, password, grade_type="font", database=None)
raise ValueError(f"Unknown board {board}")


def write_entries(output_file, entries, no_headers=False):
writer = csv.DictWriter(output_file, LOGBOOK_FIELDS)

def write_entries(output_file, entries, no_headers=False, fields=LOGBOOK_FIELDS):
writer = csv.DictWriter(output_file, fieldnames=fields)
if not no_headers:
writer.writeheader()

writer.writerows(entries)


def handle_logbook_command(args):
env_var = f"{args.board.upper()}_PASSWORD"
password = os.environ.get(env_var)
if not password:
password = getpass.getpass("Password: ")
entries = logbook_entries(args.board, args.username, password, args.grade_type, args.database)

if args.output:
with open(args.output, "w", encoding="utf-8") as output_file:
write_entries(output_file, entries, args.no_headers)
else:
sys.stdout.reconfigure(encoding="utf-8")
write_entries(sys.stdout, entries, args.no_headers)


def handle_database_command(args):
if not args.database_path.exists():
args.database_path.parent.mkdir(parents=True, exist_ok=True)
Expand All @@ -62,6 +48,21 @@ def handle_database_command(args):
print(f"Synchronized {row_count} rows in {table_name}")


def handle_logbook_command(args):
env_var = f"{args.board.upper()}_PASSWORD"
password = os.environ.get(env_var)
if not password:
password = getpass.getpass("Password: ")
entries = boardlib.api.aurora.logbook_entries(args.board, args.username, password, args.grade_type, args.database)

if args.output:
with open(args.output, "w", encoding="utf-8") as output_file:
write_entries(output_file, entries.to_dict(orient="records"), args.no_headers, fields=LOGBOOK_FIELDS)
else:
sys.stdout.reconfigure(encoding="utf-8")
write_entries(sys.stdout, entries.to_dict(orient="records"), args.no_headers, fields=LOGBOOK_FIELDS)


def add_database_parser(subparsers):
database_parser = subparsers.add_parser(
"database", help="Download and sync the database"
Expand All @@ -82,10 +83,10 @@ def add_database_parser(subparsers):
)
database_parser.set_defaults(func=handle_database_command)


def add_logbook_parser(subparsers):
logbook_parser = subparsers.add_parser(
"logbook", help="Download logbook entries to CSV"
"logbook", help="Download full logbook entries (ascents and bids) to CSV"
)
logbook_parser.add_argument(
"board",
Expand All @@ -110,12 +111,12 @@ def add_logbook_parser(subparsers):
logbook_parser.add_argument(
"-d",
"--database",
help="Path to the local database (optional). Using a local database can significantly speed up the logbook generation. Create a local database with the 'boardlib database' command.",
help="Path to the local database (optional). Using a local database will significantly speed up the logbook generation and is required to retrieve 'displayed_grade' and 'difficulty'. Create a local database with the 'database' command.",
type=pathlib.Path,
required=False,
)
logbook_parser.set_defaults(func=handle_logbook_command)


def main():
parser = argparse.ArgumentParser()
Expand All @@ -126,5 +127,6 @@ def main():
args.func(args)



if __name__ == "__main__":
main()
Loading

0 comments on commit 802fb23

Please sign in to comment.