[
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n.python-version\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*,cover\n.hypothesis/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n#Ipython Notebook\n.ipynb_checkpoints\n\n.DS_Store\n.\\#*\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Rakan Alhneiti\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "Pocket CLI\n==========\n\nPocket-CLI is an application for reading / listing and managing your GetPocket.com articles from the terminal.\n\nNote: This app is based on my [Pocket-API](https://github.com/rakanalh/pocket-api) package.\n\nFeatures\n--------\n\n* Retrieves and indexes all of your articles and saves them into a CSV file in your home directory for quicker response.\n* Enables you to specify your reading speed to calculate the amount of time each article requires. You can estimate your reading speed from online tests such as [Speed Reading Online Test](http://www.readingsoft.com/)\n* Able to sort articles by reading time (default) and Article ID\n* Enables you to search articles by keywords, tags and sort by [GetPocket's sorting params](https://getpocket.com/developer/docs/v3/retrieve). This will perform a request to Pocket.\n* Automated app configuration through `pocket-cli configure` command.\n* Uses LESS to list article for easy navigation.\n* Multiple `fetch` command calls will retrieve articles since last fetch.\n\n\nNote: This application has been tested on Python 2.7.10 and 3.5.0.\n\nInstallation\n------------\n\n    pip install pocket-cli\n\nConfiguration\n-------------\n\n If you already have a Pocket API consumer key, skip to step 2.\n\n 1. Generate a Pocket API consumer key at https://getpocket.com/developer/apps/new. Here's an example:\n\n ![](/docs/create_consumer_key.png?raw=true)\n\n 2. Run `pocket-cli configure` and enter the consumer key generated in step 1 when prompted.\n 3. Next, you will be prompted for a sort order and your estimated reading speed. You may visit http://www.readingsoft.com/ to estimate your reading speed.\n 4. After you have finished selecting configurations for `pocket-cli`, a browser window will open requesting access to your Pocket account. Log in to Pocket (if you are not already logged in) and click **Authorize** to accept and complete the configuration of `pocket-cli`.\n\n\nUsage\n-----\n\n    Usage: pocket-cli [OPTIONS] COMMAND [ARGS]...\n\n    Options:\n        --help  Show this message and exit.\n\n    Commands:\n        add\n        archive\n        configure\n        fetch\n        list\n        random\n        read\n        search\n\n\nCommands\n--------\n\nTo configure the app (for first time use)\n\n    pocket-cli configure\n\nTo add a new article URL with additional params.\n\n    pocket-cli add --url <URL> --title <title> --tags <tag1> --tags <tag2>\n\n\nMark a specific article as read.\n\n    pocket-cli archive <ID>\n\n\nTo fetch all articles / or articles added since last fetch\n\n    pocket-cli fetch\n\nTo list your articles\n\n    pocket-cli list --limit 10 --order [asc|desc]\n\nTo select a random article for you to read\n\n    pocket-cli random --archive --browser\n\n    --archive will mark this article as read\n    --browser will open the article in your default browser\n\nTo read an article\n\n    pocket-cli random --open-origin --archive\n\n    --archive will mark this article as read\n    --open-origin will open the article's original URL rather than Pocket's.\n\nTo search for specific articles\n\n    pocket-cli --state [unread|archive|all] --sort [newest|oldest|title|site] --tag <search_by_tag> <Search Term>\n\n\nCronjob\n-------\n\nYou can add `/path/to/pocket-cli fetch` to your crontab to let the app fetch new articles every once and a while. For example, to fetch every 3 hours, execute crontab -e and add the following line:\n\n    * */3 * * * /usr/local/bin/pocket-cli fetch\n\nContribution\n------------\n\nContributions are welcome! Fork the repository, create a branch, implement your changes and create a pull request and i'll be happy to review and merge your features / changes.\n\nLicense\n-------\n\nThe MIT License (MIT)\n\nCopyright (c) 2016 Rakan Alhneiti\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "manifest.in",
    "content": "include README.md\ninclude LICENSE\n"
  },
  {
    "path": "pocket_cli/__init__.py",
    "content": ""
  },
  {
    "path": "pocket_cli/app.py",
    "content": "from __future__ import division\nfrom future.utils import raise_from\n\nimport math\nimport time\nfrom datetime import datetime\nfrom operator import itemgetter\n\nfrom pocket import (\n    Pocket,\n    PocketException,\n    PocketAutException\n)\n\nfrom progress.spinner import Spinner\n\nfrom .config import Configs\nfrom .exceptions import AppException, AppNotConfigured\nfrom .storage import Storage\n\n\nclass PocketApp:\n    DEFAULT_WORDS_PER_MINUTE = 180\n    REDIRECT_URL = 'http://www.google.com'\n\n    def __init__(self):\n        self._configs = Configs()\n        self._storage = Storage()\n\n        self._pocket = Pocket(\n            self._configs.get('consumer_key'),\n            self._configs.get('access_token')\n        )\n\n    def configure(self, consumer_key, access_token,\n                  words_per_minute, sort_field):\n        self._configs.set('consumer_key', consumer_key)\n        self._configs.set('access_token', access_token)\n        self._configs.set('words_per_minute', words_per_minute)\n        self._configs.set('sort_field', sort_field)\n        self._configs.set('last_fetch', 0)\n        self._configs.write()\n\n        self._storage.clear()\n\n        self._pocket = Pocket(\n            consumer_key,\n            access_token\n        )\n\n    def init_consumer_key(self, consumer_key):\n        self._pocket = Pocket(consumer_key)\n\n    def get_request_token(self):\n        return self._pocket.get_request_token(\n            self.REDIRECT_URL\n        )\n\n    def get_access_token(self, request_token):\n        return self._pocket.get_access_token(\n            request_token\n        )\n\n    def add_article(self, url, title=None, tags=None):\n        if isinstance(tags, tuple):\n            tags = ','.join(list(tags))\n\n        try:\n            return self._pocket.add(url, title, tags)\n        except PocketException as e:\n            raise_from(self._check_exception(e), e)\n\n    def get_articles(self, limit=None, order=None):\n        if self._storage.is_empty():\n            self.fetch_articles(True)\n\n        articles = self._storage.read(limit, order)\n        sort_field = self._configs.get('sort_field')\n        if not sort_field:\n            sort_field = 'reading_time'\n\n        articles = sorted(articles,\n                          key=itemgetter(sort_field))\n        return articles\n\n    def search(self, search, state, tag, sort):\n        try:\n            articles = self._pocket.retrieve(search=search,\n                                             state=state,\n                                             tag=tag,\n                                             sort=sort)\n            return self._get_articles_index(articles)\n        except PocketException as e:\n            raise_from(self._check_exception(e), e)\n\n    def archive_article(self, item_id):\n        try:\n            self._pocket.archive(int(item_id)).commit()\n        except PocketException as e:\n            raise_from(self._check_exception(e), e)\n\n    def find_article(self, item_id):\n        index = self._storage.read()\n\n        for article in index:\n            if str(article['id']) == str(item_id):\n                return article\n\n        return None\n\n    def fetch_articles(self, output_progress=False):\n        spinner = None\n        if output_progress:\n            spinner = Spinner('Loading articles ')\n\n        articles_index = []\n\n        last_fetch = self._configs.get('last_fetch')\n\n        offset = 0\n        count = 20\n        while(True):\n            try:\n                articles = self._pocket.retrieve(\n                    state='unread',\n                    count=count,\n                    offset=offset,\n                    since=last_fetch\n                )\n            except PocketException as e:\n                spinner.finish()\n                raise_from(self._check_exception(e), e)\n\n            if not articles['list']:\n                break\n\n            articles_index.extend(self._get_articles_index(articles))\n\n            offset += count\n            if spinner:\n                spinner.next()\n\n        if spinner:\n            spinner.finish()\n\n        sort_field = self._configs.get('sort_field')\n        if not sort_field:\n            sort_field = 'reading_time'\n\n        articles_index = sorted(articles_index,\n                                key=itemgetter(sort_field))\n        self._storage.write(articles_index)\n\n        self._configs.set('last_fetch', self._get_timestamp(datetime.now()))\n        self._configs.write()\n\n    def _get_articles_index(self, articles):\n        wpm = self._configs.get('words_per_minute')\n        if not wpm:\n            wpm = self.DEFAULT_WORDS_PER_MINUTE\n        wpm = int(wpm)\n\n        articles_index = []\n\n        articles_list = articles['list']\n        if isinstance(articles_list, list) and len(articles_list) == 0:\n            return articles_index\n\n        for article in articles_list.values():\n            word_count = int(article.get('word_count', 0))\n            if word_count == 0:\n                reading_time = -1\n            else:\n                reading_time = int(math.ceil(word_count / wpm))\n\n            title = article.get('resolved_title', None)\n            if not title:\n                title = article['given_title']\n\n            url = article.get('resolved_url', None)\n            if not url:\n                url = article['given_url']\n\n            index = {\n                'id': article['item_id'],\n                'title': title,\n                'url': url,\n                'word_count': word_count,\n                'reading_time': reading_time\n            }\n\n            articles_index.append(index)\n\n        return articles_index\n\n    def _get_timestamp(self, date):\n        return int(time.mktime(date.timetuple()))\n\n    def _check_exception(self, e):\n        if isinstance(e, PocketAutException):\n            raise AppNotConfigured('Application is not configured')\n\n        raise AppException(e.message)\n"
  },
  {
    "path": "pocket_cli/cli.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nfrom builtins import input\n\nimport random\nimport subprocess\nimport sys\nimport six\nimport webbrowser\n\nimport click\n\nfrom .app import PocketApp\nfrom .exceptions import AppNotConfigured, AppException\nfrom .utils import format_article\n\n\npocket_app = PocketApp()\n\nWORDS_PER_MINUTE = 180\n\n\nCONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])\n\n\n@click.group(context_settings=CONTEXT_SETTINGS)\n@click.version_option()\ndef main():\n    pass\n\n\n@click.command()\n@click.option('--consumer-key', '-k',\n              prompt='Please provide your consumer key')\n@click.option('--sort_field', '-s',\n              type=click.Choice(['id', 'reading_time']),\n              default='reading_time',\n              prompt='Please provide your preferred sort field\\n'\n                     '\\tAvailable options are [id, reading_time]\\n'\n                     '\\tdefault:')\n@click.option('--words-per-minute', '-wpm',\n              type=click.INT,\n              default=180,\n              prompt='Please specify your reading speed in words per minute\\n'\n                     '\\tYou can use this URL to estimate your reading time\\n'\n                     '\\thttp://www.readingsoft.com/\\n'\n                     '\\tdefault:',\n              help='Used in calculating reading time for each article')\ndef configure(consumer_key, sort_field, words_per_minute):\n    pocket_app.init_consumer_key(consumer_key)\n\n    request_token = pocket_app.get_request_token()\n\n    if not request_token:\n        print('Could not obtain request_token')\n        return\n\n    url = 'http://getpocket.com/auth/authorize?request_token={0}' \\\n          '&redirect_uri={1}'.format(request_token, 'http://www.google.com')\n\n    print('You will have to authorize the application to access your articles')\n    print('Enter any key once you\\'re redirected to google.com')\n    print('Or open this link in browser manually:')\n    print(url);\n    webbrowser.open_new_tab(url)\n    input()\n\n    access_token = pocket_app.get_access_token(request_token)\n\n    if not access_token:\n        print('Could not obtain access token')\n        return\n\n    pocket_app.configure(consumer_key, access_token,\n                         words_per_minute, sort_field)\n    print('The application is ready to use')\n\n\n@click.command(name='add')\n@click.option('--url', '-u',\n              help='The URL to be added')\n@click.option('--title', '-t',\n              help='The article\\'s title')\n@click.option('--tags', '-g', multiple=True,\n              help='Tags to be associated. '\n                   'Can be multiple tags --tags=tag1, --tags=tag2')\ndef add_article(url, title, tags):\n    response = pocket_app.add_article(url, title, tags)\n    if response and response['status'] == 1:\n        pocket_app.fetch_articles(False)\n        print('URL has been added')\n\n\n@click.command(name='list')\n@click.option('--limit', '-l', default=10,\n              help='Number of items to list')\n@click.option('--order', '-o', default='asc',\n              type=click.Choice(['asc', 'desc']),\n              help='Order of items to return')\ndef list_articles(limit, order):\n    try:\n        articles = pocket_app.get_articles(limit, order)\n    except AppNotConfigured:\n        app_not_configured()\n        return\n    except AppException as e:\n        exception_occured(e)\n        return\n\n    if not articles:\n        print('Articles index is empty,'\n              'run pocket-cli fetch to index your articles')\n        return\n\n    output_articles(articles)\n\n\n@click.command()\n@click.argument('search')\n@click.option('--state', '-s',\n              type=click.Choice(['unread', 'archive', 'all']),\n              default='unread')\n@click.option('--tag', '-t')\n@click.option('--sort', '-o',\n              type=click.Choice(['newest', 'oldest', 'title', 'site']),\n              default='newest')\ndef search(search, state, tag, sort):\n    try:\n        articles = pocket_app.search(search, state, tag, sort)\n    except AppNotConfigured:\n        app_not_configured()\n    except AppException as e:\n        exception_occured(e)\n\n    output_articles(articles)\n\n\n@click.command()\n@click.argument('item_id')\n@click.option('--open-origin', '-o', is_flag=True,\n              default=False,\n              help='Open original URL not the pocket one')\n@click.option('--archive', '-a', is_flag=True,\n              default=False,\n              help='Archive article')\ndef read(item_id, open_origin, archive):\n    article = pocket_app.find_article(item_id)\n\n    if not article:\n        print('Article with this ID was not found.')\n\n    url = 'https://getpocket.com/a/read/{}'.format(article['id'])\n\n    print(format_article(article, header='Selected Article'))\n\n    if open_origin:\n        url = article['url']\n\n    webbrowser.open_new_tab(url)\n\n    if archive:\n        pocket_app.archive_article(article['id'])\n\n\n@click.command(name='random')\n@click.option('--archive', '-a', is_flag=True,\n              default=False,\n              help='Archive article')\n@click.option('--browser', '-b', is_flag=True,\n              default=False,\n              help='Open in browser')\ndef random_article(browser, archive):\n    articles = pocket_app.get_articles()\n    article = random.choice(articles)\n\n    print(format_article(article, header='Selected Article', line=True))\n\n    if browser:\n        webbrowser.open_new_tab(article['url'])\n\n    if archive:\n        pocket_app.archive_article(article['id'])\n\n\n@click.command()\ndef fetch():\n    try:\n        pocket_app.fetch_articles(True)\n    except AppNotConfigured:\n        app_not_configured()\n    except AppException as e:\n        exception_occured(e)\n\n\n@click.command(name='archive')\n@click.argument('article_id')\ndef archive_article(article_id):\n    try:\n        pocket_app.archive_article(int(article_id))\n    except AppNotConfigured:\n        app_not_configured()\n    except AppException as e:\n        exception_occured(e)\n\n\ndef output_articles(articles):\n    if len(articles) == 0:\n        print('No articles found')\n        return\n\n    try:\n        pager = subprocess.Popen(['less'],\n                                 stdin=subprocess.PIPE,\n                                 stdout=sys.stdout)\n        for article in articles:\n            if int(article['reading_time']) <= 0:\n                article['reading_time'] = 'Unknown'\n            content = format_article(article, line=True)\n\n            if six.PY3:\n                content = bytearray(content, 'utf-8')\n\n            pager.stdin.write(content)\n\n        pager.stdin.close()\n        pager.wait()\n    except (KeyboardInterrupt, ValueError):\n        pass\n\n\ndef app_not_configured():\n    print('App is not configured')\n    print('Run `pocket-cli configure` to be able to use the app')\n\n\ndef exception_occured(exception):\n    print('An error occured while '\n          'trying to perform requested action: {}'.format(\n              exception.message\n          ))\n\n\nmain.add_command(configure)\nmain.add_command(add_article)\nmain.add_command(list_articles)\nmain.add_command(search)\nmain.add_command(random_article)\nmain.add_command(fetch)\nmain.add_command(read)\nmain.add_command(archive_article)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "pocket_cli/config.py",
    "content": "import os\nimport configparser\n\n\nclass Configs:\n    _section_name = 'pocket'\n\n    def __init__(self):\n        path = self._get_file_path()\n\n        self._config_parser = configparser.ConfigParser()\n\n        if not os.path.exists(path):\n            return\n\n        self._config_parser.readfp(open(path))\n\n    def get(self, name):\n        try:\n            value = self._config_parser.get(self._section_name, name)\n        except (configparser.NoSectionError, configparser.NoOptionError):\n            value = None\n\n        return value\n\n    def set(self, name, value):\n        if not self._config_parser.has_section(self._section_name):\n            self._config_parser.add_section(self._section_name)\n        self._config_parser.set(self._section_name, name, str(value))\n\n    def write(self):\n        self._config_parser.write(open(self._get_file_path(), 'w'))\n\n    def _get_file_path(self):\n        return '{}/.pocket-config'.format(os.path.expanduser('~'))\n"
  },
  {
    "path": "pocket_cli/exceptions.py",
    "content": "class AppNotConfigured(Exception):\n    def __init__(self, message):\n        super().__init__(message)\n\n\nclass AppException(Exception):\n    def __init__(self, message):\n        super().__init__(message)\n"
  },
  {
    "path": "pocket_cli/storage.py",
    "content": "from __future__ import unicode_literals\n\nimport csv\nimport os\nimport six\n\n\nclass Storage:\n    def __init__(self):\n        self._filename = '{}/.pocket-index'.format(\n            os.path.expanduser('~'))\n\n    def is_empty(self):\n        if not os.path.exists(self._filename):\n            return True\n\n        if os.stat(self._filename).st_size == 0:\n            return True\n\n        return False\n\n    def write(self, data):\n        if not data:\n            return\n\n        write_header = False\n        if self.is_empty():\n            write_header = True\n\n        mode = 'a+b'\n        if six.PY3:\n            mode = 'a+t'\n\n        with open(self._filename, mode) as csv_file:\n            dict_writer = csv.DictWriter(csv_file, data[0].keys())\n            if write_header:\n                dict_writer.writeheader()\n\n            dict_writer.writerows(self._encode_data(data))\n\n    def read(self, limit=10, order='asc'):\n        index = []\n\n        if not os.path.exists(self._filename):\n            return index\n\n        mode = 'rb'\n        if six.PY3:\n            mode = 'r'\n\n        row_counter = 0\n        with open(self._filename, mode) as csv_file:\n            reader = csv.DictReader(csv_file)\n            for row in reader:\n                index.append(row)\n\n                if order == 'asc':\n                    row_counter += 1\n\n                if row_counter == limit:\n                    break\n\n        if order == 'desc':\n            index = index[::-1]\n\n        return index[0:limit]\n\n    def clear(self):\n        if os.path.exists(self._filename):\n            os.remove(self._filename)\n\n    def _encode_data(self, data):\n        if six.PY3:\n            return data\n\n        for index, item in enumerate(data):\n            for key, value in item.items():\n                if isinstance(value, six.string_types):\n                    data[index][key] = value.encode('utf-8')\n        return data\n"
  },
  {
    "path": "pocket_cli/utils.py",
    "content": "import os\n\ntry:\n    from shutil import get_terminal_size\nexcept ImportError:\n    def get_terminal_size():\n        def ioctl_GWINSZ(fd):\n            try:\n                import fcntl\n                import termios\n                import struct\n                cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,\n                                                     '1234'))\n            except:\n                return None\n            return cr\n        cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)\n        if not cr:\n            try:\n                fd = os.open(os.ctermid(), os.O_RDONLY)\n                cr = ioctl_GWINSZ(fd)\n                os.close(fd)\n            except:\n                pass\n        if not cr:\n            try:\n                cr = (os.env['LINES'], os.env['COLUMNS'])\n            except:\n                cr = (25, 80)\n        return int(cr[1]), int(cr[0])\n\n\ndef format_article(article, header=None, footer=None, line=False):\n    content = ''\n    if header:\n        content = '{}\\n'.format(header)\n    if line:\n        content += '{}\\n'.format('=' * (get_terminal_size()[0]-1))\n\n    content += '{} - {}\\nReading Time: {} Mins\\nURL: {}\\n'.format(\n        article['id'],\n        article['title'] if article['title'] else '(No Title)',\n        article['reading_time'],\n        article['url']\n    )\n\n    if footer:\n        content += footer\n\n    return content\n"
  },
  {
    "path": "requirements.txt",
    "content": "click==6.2\npocket-api\nrequests==2.9.1\nprogress==1.2\nfuture==0.15.2\nsix==1.10.0\n"
  },
  {
    "path": "setup.py",
    "content": "from setuptools import setup, find_packages\n\nsetup(\n    name='pocket-cli',\n    version='0.1.6',\n    author='Rakan Alhneiti',\n    author_email='rakan.alhneiti@gmail.com',\n    url='https://github.com/rakanalh/pocket-api',\n\n    license='LICENSE',\n    description='A terminal application for Pocket',\n    long_description=open('README.md').read(),\n\n    packages=find_packages(),\n    include_package_data=True,\n\n    install_requires=[\n        'click==6.2',\n        'requests==2.9.1',\n        'progress==1.2',\n        'future==0.15.2',\n        'six==1.10.0',\n        'pocket-api'\n    ],\n    entry_points={\n        'console_scripts': [\n            'pocket-cli=pocket_cli.cli:main'\n        ]\n    },\n)\n"
  }
]