# How to dump all your GitHub issues into Todournament

**URL:** <https://forum.beeminder.com/t/how-to-dump-all-your-github-issues-into-todournament/11543>\
**Category:** Tech\
**Created:** [April 13, 2024, 7:21pm UTC](https://forum.beeminder.com/t/how-to-dump-all-your-github-issues-into-todournament/11543 "2024-04-13T19:21:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dreev](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/dreev/32/4311_2.png) [@dreev](https://forum.beeminder.com/u/dreev)\
**Post date:** [April 13, 2024, 7:21pm UTC](https://forum.beeminder.com/t/how-to-dump-all-your-github-issues-into-todournament/11543/1 "2024-04-13T19:21:14Z")

</div>

I’m a fan of [Todournament](http://alltom.github.io/todournament/) by @alltom. It’s a simple to-do list that elegantly sorts your tasks by having you make binary comparisons. Do you want to _Take Out Garbage_ first or _File TPS Report_ first? Click which one you’re more inspired by, repeat until Todournament has enough data to put something at the top of your list, et voila. It’s a bit like the [Mark Forster method](https://doc.beeminder.com/fv "Still languishing as a draft guest post!"). Here’s what the top of my current stack looks like:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/beeminder/original/2X/2/2dcd27e71da1773fb15f8ffae42cc3b1878d9a49.png)

(putting this in the forum is today’s [mustdo](https://blog.beeminder.com/mustdo "HT Alys as usual") so that’s part of “Saturday beemergencies” at the top of my list!)

Another thing I’ve been liking a lot lately is my personal private GitHub repo I call omnitask where I drop in as a GitHub issue (gissue) any crazy ideas I have. I have a [freshening goal](https://blog.beeminder.com/freshen "Nerd version; see also the normal-human version, linked as a sequel post by Nicky") to keep it from being a black hole where ideas go to die. It’s great.

But I really wanted to combine it with Todournament to help things from omnitask bubble up to the top of my list. So here’s a hacky way to do that that I thought I’d share:

```bash
#!/bin/bash
# Fetch the titles of all open gissues and put them in macOS's clipboard

TOKE="REPLACE_ME_WITH_GITHUB_PERSONAL_ACCESS_TOKEN"
USER="REPLACE_ME_WITH_GITHUB_USERNAME"
REPO="REPLACE_ME_WITH_GITHUB_REPOSITORY_NAME"
GURL="https://api.github.com/repos"
PURL="$GURL/$USER/$REPO/issues?per_page=100&page=1"
FILE=$(mktemp)
HEAD=$(mktemp)
TITC=0 # to count how many titles we fetch

while [-n "$PURL"]; do
  echo "Fetching $PURL"
  resp=$(curl -L -s -D $HEAD \
    -H "Accept: application/vnd.github+json" \
    -H "Authorization: Bearer $TOKE" \
    -H "X-GitHub-Api-Version: 2022-11-28" \
    $PURL) 
  titles=$(echo $resp | jq -r '.[] | .title')
  if [$? -ne 0]; then
    echo "Error processing JSON"
  fi
  echo "$titles" >> $FILE
  if [-n "$titles"]; then
    x=$(echo "$titles" | wc -l)
    TITC=$((TITC + x))
  fi
  # Extract next page URL from Link header
  PURL=$(sed -n -e 's/.*<\(.*\)>; rel="next".*/\1/p' $HEAD)
done

cat $FILE | pbcopy
rm $FILE
rm $HEAD
echo "Voila, extracted $TITC gissue titles to your copy/paste buffer!"

```

(I’m not the most fluent in bash scripting and the above took me a couple hours going back and forth with GPT4 but it seems solid now. In retrospect maybe bash was a poor language choice but I was fixated on the part where it sends the tasks straight to your copy/paste buffer which seemed like a job for bash.)

Just put that in a file called omnifetch.sh, fill in your GitHub API key, and run it. Then go to Todournament and hit paste. You now have all your gissues in your task list. 🎉

---

<div class="post-metadata">

**Author:** ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)\
**Post date:** [April 14, 2024, 12:17pm UTC](https://forum.beeminder.com/t/how-to-dump-all-your-github-issues-into-todournament/11543/2 "2024-04-14T12:17:21Z")

</div>

This has inspired me to pull together a less-hacky python version. Here’s a script to fetch all your github issues in a particular repo:

```python
#!/usr/bin/env python

import argparse
import requests
import json
import os

def fetch_issues(repo, token):
    github_api_url = f"https://api.github.com/repos/{repo}/issues"
    params = {'per_page': 100, 'page': 1}
    headers = {
        'Accept': 'application/vnd.github+json',
        'Authorization': f'Bearer {token}',
        'X-GitHub-Api-Version': '2022-11-28'
    }

    while True:
        response = requests.get(github_api_url, headers=headers, params=params)
        response.raise_for_status()

        issues = response.json()

        yield from issues

        if 'next' in response.links:
            github_api_url = response.links['next']['url']
            params = {}
        else:
            break

if __name__ == " __main__":
    parser = argparse.ArgumentParser(description="Fetch all open GitHub issues for a specified repository and output them as NDJSON.")
    parser.add_argument('repo', help="The repository to query, formatted as 'username/repository'.")
    args = parser.parse_args()

    token = os.getenv('GITHUB_ACCESS_TOKEN')
    if not token:
        raise EnvironmentError("GITHUB_ACCESS_TOKEN is not set.")

    for issue in fetch_issues(args.repo, token):
        print(json.dumps(issue))

```

Feel free to edit it to hardcode your token if you’d like, or set hte env variable. You can then run it in one line of bash as `./github-issues.py USER/REPO | jq -r .title | pbcopy`.

Or edit the script to use the `pyperclip` library and use it to copy the titles to the clipboard. But I actually like it that this script follows the unix philosophy of composablity.

---

<div class="post-metadata">

**Author:** ![dreev](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/dreev/32/4311_2.png) [@dreev](https://forum.beeminder.com/u/dreev)\
**Post date:** [April 14, 2024, 9:49pm UTC](https://forum.beeminder.com/t/how-to-dump-all-your-github-issues-into-todournament/11543/3 "2024-04-14T21:49:46Z")

</div>

Ah, a million times better; thank you so much!
