├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README.rst
├── imgur_uploader.py
├── requirements.txt
├── setup.cfg
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project-specific
2 | .env
3 |
4 | # Byte-compiled / optimized / DLL files
5 | __pycache__/
6 | *.py[cod]
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *,cover
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 |
56 | # Sphinx documentation
57 | docs/_build/
58 |
59 | # PyBuilder
60 | target/
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Andrew T. Baker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.rst LICENSE requirements.txt
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | imgur-uploader
2 | ==============
3 |
4 | A simple command line client for uploading files to Imgur.
5 |
6 | Created for my `PyCon US 2015 Docker tutorial
7 | `_ so that students using
8 | my cloud servers can see the gifs they create at the end of exercise 1.
9 |
10 | This tool is open source under the `MIT License `_.
11 |
12 | Quickstart
13 | ----------
14 |
15 | Getting Imgur API credentials
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17 |
18 | Go to https://api.imgur.com/oauth2/addclient and register a new Imgur API
19 | client. You will need an Imgur account to do this.
20 |
21 | You can put it any valid URL for the callback URL - we won't be using it.
22 |
23 | Installing imgur-uploader
24 | ^^^^^^^^^^^^^^^^^^^^^^^^^
25 |
26 | Installing imgur-uploader is easy. It runs on versions of Python >=2.7 or >=3.3.
27 |
28 | If you just want to use imgur-uploader, you can just ``pip install
29 | imgur-uploader``.
30 |
31 | If you want to tweak or enhance imgur-uploader, follow these instructions:
32 |
33 | #. Clone this repository
34 | #. Install the tool with ``pip install -e .``
35 |
36 | Using imgur-uploader
37 | ^^^^^^^^^^^^^^^^^^^^
38 |
39 | First, create a file called ``~/.config/imgur_uploader/uploader.cfg``, with the
40 | following contents (substitute your credentials)::
41 |
42 | [imgur]
43 | id = 9354da9ecdcfae3
44 | secret = 8387eca75687ecad9876ead47786edac0875dc0d
45 |
46 | Otherwise, set the ``IMGUR_API_ID`` and ``IMGUR_API_SECRET`` environment
47 | variables in your terminal session, using your client's credentials.
48 |
49 | Upload an image by running ``imgur-uploader path/to/my.gif``
50 |
51 | The tool will return a shortened link to your uploaded gif upon completion::
52 |
53 | Uploading file my.gif
54 | ...
55 | File uploaded - see your gif at http://i.imgur.com/6WsQPpw.gif
56 |
57 | If you want your images to appear in your account, you additionally need to
58 | get a refresh token. See the `Imgur API `
59 | for information on how to obtain this. Then, add a ``refresh_token`` line in
60 | your config file::
61 |
62 | [imgur]
63 | id = 9354da9ecdcfae3
64 | secret = 8387eca75687ecad9876ead47786edac0875dc0d
65 | refresh_token = 9812398ab1b2cc98de9fa982bacd31cb312c6194
66 |
--------------------------------------------------------------------------------
/imgur_uploader.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import click
4 | from imgurpython import ImgurClient
5 |
6 | try:
7 | import ConfigParser
8 | except ImportError:
9 | import configparser as ConfigParser
10 |
11 |
12 | def get_config():
13 | client_id = os.environ.get("IMGUR_API_ID")
14 | client_secret = os.environ.get("IMGUR_API_SECRET")
15 | refresh_token = os.environ.get("IMGUR_REFRESH_TOKEN")
16 |
17 | config = ConfigParser.ConfigParser()
18 | config.read([os.path.expanduser("~/.config/imgur_uploader/uploader.cfg")])
19 |
20 | try:
21 | imgur = dict(config.items("imgur"))
22 | except:
23 | imgur = {}
24 |
25 | client_id = client_id or imgur.get("id")
26 | client_secret = client_secret or imgur.get("secret")
27 | refresh_token = refresh_token or imgur.get("refresh_token", "")
28 |
29 | if not (client_id and client_secret):
30 | return {}
31 |
32 | data = {"id": client_id, "secret": client_secret}
33 | if refresh_token:
34 | data["refresh_token"] = refresh_token
35 | return data
36 |
37 |
38 | @click.command()
39 | @click.argument("images", type=click.Path(exists=True), nargs=-1)
40 | def upload_image(images):
41 | """Uploads image files to Imgur"""
42 |
43 | config = get_config()
44 |
45 | if not config:
46 | click.echo(
47 | "Cannot upload - could not find IMGUR_API_ID or " "IMGUR_API_SECRET environment variables or config file"
48 | )
49 | return
50 |
51 | if "refresh_token" in config:
52 | client = ImgurClient(config["id"], config["secret"], refresh_token=config["refresh_token"])
53 | anon = False
54 | else:
55 | client = ImgurClient(config["id"], config["secret"])
56 | anon = True
57 |
58 | links = []
59 | copylink = True
60 |
61 | try:
62 | import pyperclip
63 | except ImportError:
64 | copylink = False
65 |
66 | for image in images:
67 | click.echo("Uploading file {}".format(click.format_filename(image)))
68 |
69 | response = client.upload_from_path(image, anon=anon)
70 |
71 | click.echo("File uploaded - see your image at {}".format(response["link"]))
72 |
73 | if copylink:
74 | # add individual link to clipboard
75 | links.append(response["link"])
76 | pyperclip.copy(response["link"])
77 |
78 | if copylink:
79 | # add all links to the clipboard
80 | # useful if user does not have a clipboard manager with history
81 | pyperclip.copy("\n".join(links))
82 | else:
83 | print("pyperclip not found. To enable clipboard functionality, please install it.")
84 |
85 |
86 | if __name__ == "__main__":
87 | upload_image()
88 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | click==4.0
2 | imgurpython==1.1.5
3 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [wheel]
2 | universal = 1
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from setuptools import setup
4 |
5 |
6 | def read(*paths):
7 | """Build a file path from *paths* and return the contents."""
8 | with open(os.path.join(*paths), 'r') as f:
9 | return f.read()
10 |
11 | setup(
12 | name='imgur-uploader',
13 | version='0.3.0',
14 | description='A simple command line client for uploading files to Imgur.',
15 | long_description=read('README.rst'),
16 | url='https://github.com/atbaker/imgur-uploader',
17 | license='MIT',
18 | author='Andrew Tork Baker',
19 | author_email='andrew@atbaker.me',
20 | py_modules=['imgur_uploader'],
21 | include_package_data=True,
22 | install_requires=[
23 | 'click',
24 | 'pyperclip',
25 | 'imgurpython'
26 | ],
27 | entry_points='''
28 | [console_scripts]
29 | imgur-uploader=imgur_uploader:upload_image
30 | imgur=imgur_uploader:upload_image
31 | ''',
32 | classifiers=[
33 | 'Development Status :: 5 - Production/Stable',
34 | 'Intended Audience :: Developers',
35 | 'Natural Language :: English',
36 | 'License :: OSI Approved :: MIT License',
37 | 'Operating System :: OS Independent',
38 | 'Programming Language :: Python',
39 | 'Programming Language :: Python :: 2',
40 | 'Programming Language :: Python :: 2.7',
41 | 'Programming Language :: Python :: 3',
42 | 'Programming Language :: Python :: 3.3',
43 | 'Programming Language :: Python :: 3.4',
44 | 'Topic :: Utilities',
45 | ]
46 | )
47 |
--------------------------------------------------------------------------------