Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #41 from hughrun/poetry
Browse files Browse the repository at this point in the history
Pre-release for PyPi
  • Loading branch information
hughrun authored Feb 13, 2021
2 parents fd699d8 + f919464 commit 4305de3
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 128 deletions.
10 changes: 3 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
settings.yaml
logo/
# Setuptools distribution folder.
/dist/

# Python egg metadata, regenerated from source files by setuptools.
/*.egg-info
/*.egg
settings.yaml
dev_settings.yaml
pypi.md
64 changes: 37 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,31 @@

`pocketsnack` is a command line application offering various commands to make your [Pocket](https://getpocket.com) account more manageable. You can de-duplicate your list, purge unwanted tags, and hide your enormous 'to be read' list in a special archive so that looking at your list doesn't become paralysing.

This is the version 3 documentation. If you don't want to upgrade you can still read the [version 2 README](v2_README.md) or [version 1 README](v1_README.md).
This is the version 3.x documentation. If you prefer to use an older version you can still read the [version 2 README](v2_README.md) or [version 1 README](v1_README.md).

## A note on version 3

Version 3 introduces a new YAML format for the settings file. This approach also allows for changes to the settings file without having to re-install `pocketsnack`, which was an unintended side effect of the previous approach of simply importing the file. Additional documentation on the settings file can be found below.

## Getting started
## tl;dr

1. make sure you have installed Python version 3.x (preferably 3.7 or higher)
2. download `pocketsnack` using git or the download link in [releases](releases)
3. move into the top `pocketsnack` directory (i.e. `cd pocketsnack`)
4. `pip install .` or if pip points to Python2, `pip3 install .`
5. Add Pocket consumer key to `settings/settings.yaml`
6. `pocketsnack --authorise`
7. You are now ready to enjoy using pocketsnack from any directory
2. `pip install pocketsnack` (you may need to use `pip3` instead)
3. `pocketsnack --config`
4. Add your Pocket API consumer key to the config file
5. `pocketsnack --authorise`
6. You are now ready to enjoy using pocketsnack from any directory

### Installing Python 3
## Getting started

You will need Python 3.x installed. On MacOS the easiest thing to do is to [install Python 3 using Homebrew](https://docs.brew.sh/Homebrew-and-Python): `brew install python`.
### Creating a Pocket consumer key for your app

### Settings
1. Log in to Pocket in a web browser
2. Go to [`https://getpocket.com/developer`](https://getpocket.com/developer) and click 'CREATE NEW APP'
3. Complete the form: you will need all permissions, and the platform should be _Desktop (other)_ or _Mac_.
4. Your new app will show a **consumer key**, which you need to paste into the first line in your configuration file.

You will need to copy `settings/settings-example.yaml` to a new file - `settings/settings.yaml` before you start. You can do this however you like, but from the command line you could use:
```shell
cp settings/settings-example.py settings/settings.yaml
```
## Creating a configuration file

Then edit it with a text editor like `nano`, Atom or VS Code, but any text editor will do the job - you could even use TextEdit or Notepad.
Before you can use `pocketsnack` you need to create a configuration file. If you run any command (including simply `pocketsnack` without an argument) when your configuration file doesn't exist, a new file will be created and will open in your default application for editing `yaml` files. You *must* copy in the consumer key referred to above, and *may* adjust any other settings.

You can adjust most settings, but the defaults in `settings-example.yaml` should be sensible for most users.
You can adjust most settings, but the defaults should be sensible for most users if you just want to get started.

| setting | type | description |
| :------------------- | :---: | :------------------------------------ |
Expand All @@ -48,12 +43,7 @@ You can adjust most settings, but the defaults in `settings-example.yaml` should
| num_longreads | integer | how many long reads (if there are long reads in your list) should be included in each `--lucky_dip`. This is a subset of `item_per_cycle`, not in addition to the total. The definition of a long read is determined by `longreads_wordcount`|
| pocket_access_token | string | access token required to interact with the Pocket API. This will be updated when you run `--authorise` and should not be edited manually.|

### Creating a Pocket consumer key for your app

1. Log in to Pocket in a web browser
2. Go to [`https://getpocket.com/developer`](https://getpocket.com/developer) and click 'CREATE NEW APP'
3. Complete the form: you will need all permissions, and the platform should be _Desktop (other)_
4. Your new app will show a **consumer key**, which you need to paste into the first line in `settings.yaml`
Save and close when you're done. You can edit this file again at any time by running `pocketsnack --config`.

### Authorising your app with a Pocket access token

Expand Down Expand Up @@ -81,8 +71,16 @@ This command has an 's', not a 'z', and the short version is a 'u', not an 'a'.

You need this to authorise your app. Everything else works exclusively on the command line, but _authorise_ needs to open a browser to complete the authorisation process, so you need to run this on a machine with a web browser. It will authorise your app with your user, wait for you to confirm that you have completed the authorisation (by typing 'done') and then add the token to `settings.yaml`. You also need to run `--authorise` if you want to change the Pocket account you are using with `pocketsnack`.

## -v, --version

Prints the current version number to screen.

## action commands

### -c, --config

Create or edit your config file stored at `~/.pocketsnack_conf.yml`.

### --dedupe

Removes duplicates from your List, TBR archive, full Archive, or everything, depending on the flag you use with it. This is an extension of the functionality provided by [pickpocket](https://github.com/hughrun/pickpocket).
Expand All @@ -91,6 +89,10 @@ Removes duplicates from your List, TBR archive, full Archive, or everything, dep

Returns items with the archive tag from the archive to the list, and removes the archive tag. The number of items returned is determined by `items_per_cycle` in `settings.yaml`. Note that if `num_videos` and `num_images` add up to more than `items_per_cycle`, then `--lucky_dip` will only return the total specified in `items_per_cycle`. Videos take precedence.

### -i, --info LOCATION

Get information on items in a list (if LOCATION is `-l`) or TBR items in your archive (if LOCATION is `-a`).

### -p, --purge

You can use `--purge` to clear all tags in your List, TBR achive, full Archive, or everything - excluding the `archive_tag` and any `retain_tags`. This is useful if you've been using the _Aus GLAM Blogs_ Pocket tool or anything else that retains the original tags from articles.
Expand Down Expand Up @@ -141,6 +143,10 @@ The Pocket API does not store a value for the date an items was first added. The

## examples

Find out how many `TBR` items are in the archive:

`pocketsnack --info -a`

Stash only items updated in the last 2 days:

`pocketsnack --stash -n 2`
Expand All @@ -161,6 +167,10 @@ Run lucky_dip but only choose from items last updated longer ago than one week:

`pocketsnack -d -o 7`

## A note on version 3

Version 3.x introduces a new YAML format for the settings file. This approach also allows for changes to the settings file without having to re-install `pocketsnack`, which was an unintended side effect of the previous approach.

## Uninstalling or moving v1 script to a new directory

### If you installed with pip
Expand Down
Binary file added dist/pocketsnack-3.1.0a0-py3-none-any.whl
Binary file not shown.
Binary file added dist/pocketsnack-3.1.0a0.tar.gz
Binary file not shown.
File renamed without changes.
181 changes: 110 additions & 71 deletions bin/pocketsnack → pocketsnack/pocketsnack.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,85 +23,23 @@
# ----------------

from argparse import ArgumentParser
import yaml

# bundled with Python
import os
import pkg_resources
import subprocess

# local modules
from lib import toolkit as pt
import yaml
configyaml = open('settings/settings.yaml', 'r')
for S in yaml.safe_load_all(configyaml):

# ----------------
# Settings
# ----------------

# assign short variable names from the settings file
access_token = S['pocket_access_token']
consumer_key = S['pocket_consumer_key']
archive_tag = S['archive_tag']
ignore_tags = set(S['ignore_tags'])
retain_tags = set(S['retain_tags'])
from pocketsnack import toolkit as pt

# ----------------
# argparser arguments
# What happens with each command?
# ----------------

parser = ArgumentParser(description='\033[1;36mpocketsnack: KonMari your Pocket tsundoku from the command line.\033[1;m')
admin = parser.add_argument_group('admin commands')
actions = parser.add_argument_group('action commands')
mex = parser.add_mutually_exclusive_group()
timers = parser.add_mutually_exclusive_group()

mex.add_argument(
"-a", "--archive", action="store_true", help="get information on TBR items in archive (with -i) or purge tags in archive (with -p)"
)
mex.add_argument(
"-b", "--all", action="store_true", help="purge all tags in both list and archive (with -p)"
)
actions.add_argument(
"-d", "--lucky_dip", action="store_true", help="move random items tagged 'tbr' from archive to list, depending on settings"
)
actions.add_argument(
"--dedupe", action="store_true", help="de-duplicate list (-l), archive (-a), tbr items (--tbr) or all (-b)- defaults to list"
)
actions.add_argument(
"-i", "--info", action="store_true", help="get information on items in list or TBR items in archive"
)
mex.add_argument(
"-l", "--list", action="store_true", help="get information on items in list (with -i) or purge tags in list (with -p)"
)
timers.add_argument(
"-n", "--since", type=int, help="only act on items where last activity is newer than a given number of days. Use with any action command"
)
timers.add_argument(
"-o", "--before", type=int, help="only act on items where last activity is older than a given number of days. Use with any action command"
)
actions.add_argument(
"-p", "--purge", action="store_true", help="remove all tags from list, archive, or both, depending on the second argument provided and excepting tags listed in 'retain_tags' in settings"
)
actions.add_argument(
"-s", "--stash", action="store_true", help="add 'tbr' tag to all items in user list and archive them, with exceptions as per settings"
)
admin.add_argument(
"-t", "--test", action="store_true", help="test whether API call returns data"
)
mex.add_argument(
"--tbr", action="store_true", help="used in conjuction with --dedupe to dedupe only items in the tbr archive."
)
admin.add_argument(
"-u", "--authorise", action="store_true", help="authorise app to connect to a Pocket account"
)

options = parser.parse_args()
def main():

# ----------------
# What happens with each combination?
# ----------------

if __name__ == '__main__':
try:

# Find all args that have a value other than False
# This helps with error messages for optional args
Expand All @@ -112,7 +50,11 @@
if vars(options)[x]:
true_vars.append(x)

if options.authorise:
if options.config:
conf = pt.config()
print(conf)

elif options.authorise:
# Run authorise once first to retrieve a pocket_access_token
auth = pt.authorise(consumer_key)
print(auth)
Expand All @@ -127,7 +69,7 @@

location = tag if tag else state if state != 'unread' else 'list'
print(' \033[46;97mChecking for duplicates in ' + location + '\033[0;m')
dd = pt.dedupe(state, tag, consumer_key, access_token)
pt.dedupe(state, tag, consumer_key, access_token)

elif options.lucky_dip:
print(' \033[46;97mRunning lucky dip...\033[0;m')
Expand Down Expand Up @@ -256,9 +198,106 @@ def print_info(response, collection):
elif options.test:
result = pt.test(consumer_key, access_token)
print(result)

elif options.version:
# version number from package info
vnum = pkg_resources.require("pocketsnack")[0].version
print(vnum)

elif set(true_vars).intersection(orphans):
print('\n That command cannot be used by itself. Check \033[46;97mpocketsnack --help\033[0;m for more information\n')

else:
print(' \033[46;97mpocketsnack\033[0;m requires commands and/or flags to do anything useful. Try \033[46;97mpocketsnack -h\033[0;m for more information')
print(' \033[46;97mpocketsnack\033[0;m requires commands and/or flags to do anything useful. Try \033[46;97mpocketsnack -h\033[0;m for more information')

except NameError:
# this happens when there is no config file
# since we already provide an error message below
# we do nothing here
pass

# -----------------------------------
# Parse commands (the action is here)
# -----------------------------------
try:
config_file = os.path.expanduser('~/.pocketsnack_conf.yml')
configyaml = open(config_file, 'r')
for S in yaml.safe_load_all(configyaml):

# ----------------
# Settings
# ----------------

# assign short variable names from the config file
access_token = S['pocket_access_token']
consumer_key = S['pocket_consumer_key']
archive_tag = S['archive_tag']
ignore_tags = set(S['ignore_tags'])
retain_tags = set(S['retain_tags'])

# ----------------
# argparser arguments
# ----------------

parser = ArgumentParser(description='\033[1;36mpocketsnack: KonMari your Pocket tsundoku from the command line.\033[1;m')
admin = parser.add_argument_group('admin commands')
actions = parser.add_argument_group('action commands')
mex = parser.add_mutually_exclusive_group()
timers = parser.add_mutually_exclusive_group()

mex.add_argument(
"-a", "--archive", action="store_true", help="get information on TBR items in archive (with -i) or purge tags in archive (with -p)"
)
mex.add_argument(
"-b", "--all", action="store_true", help="purge all tags in both list and archive (with -p)"
)
actions.add_argument(
"-c", "--config", action="store_true", help="create or edit your config file stored at ~/.pocketsnack_conf.yml"
)
actions.add_argument(
"-d", "--lucky_dip", action="store_true", help="move random items tagged 'tbr' from archive to list, depending on config"
)
actions.add_argument(
"--dedupe", action="store_true", help="de-duplicate list (-l), archive (-a), tbr items (--tbr) or all (-b)- defaults to list"
)
actions.add_argument(
"-i", "--info", action="store_true", help="get information on items in list or TBR items in archive"
)
mex.add_argument(
"-l", "--list", action="store_true", help="get information on items in list (with -i) or purge tags in list (with -p)"
)
timers.add_argument(
"-n", "--since", type=int, help="only act on items where last activity is newer than a given number of days. Use with any action command"
)
timers.add_argument(
"-o", "--before", type=int, help="only act on items where last activity is older than a given number of days. Use with any action command"
)
actions.add_argument(
"-p", "--purge", action="store_true", help="remove all tags from list, archive, or both, depending on the second argument provided and excepting tags listed in 'retain_tags' in config"
)
actions.add_argument(
"-s", "--stash", action="store_true", help="add 'tbr' tag to all items in user list and archive them, with exceptions as per config"
)
admin.add_argument(
"-t", "--test", action="store_true", help="test whether API call returns data"
)
mex.add_argument(
"--tbr", action="store_true", help="used in conjuction with --dedupe to dedupe only items in the tbr archive"
)
admin.add_argument(
"-u", "--authorise", action="store_true", help="authorise app to connect to a Pocket account"
)
admin.add_argument(
"-v", "--version", action="store_true", help="print the current version number to screen"
)

options = parser.parse_args()

if __name__ == '__main__':

main()

except FileNotFoundError:
print(' \033[46;97mpocketsnack\033[0;m needs a config file!')
conf = pt.config()
print(conf)
Loading

0 comments on commit 4305de3

Please sign in to comment.