123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- # -*- coding: utf-8 -*-
- # Natural Language Toolkit: Twitter client
- #
- # Copyright (C) 2001-2019 NLTK Project
- # Author: Ewan Klein <ewan@inf.ed.ac.uk>
- # Lorenzo Rubio <lrnzcig@gmail.com>
- # URL: <http://nltk.org/>
- # For license information, see LICENSE.TXT
- """
- Authentication utilities to accompany :module:`twitterclient`.
- """
- from __future__ import print_function
- import os
- import pprint
- from twython import Twython
- def credsfromfile(creds_file=None, subdir=None, verbose=False):
- """
- Convenience function for authentication
- """
- return Authenticate().load_creds(
- creds_file=creds_file, subdir=subdir, verbose=verbose
- )
- class Authenticate(object):
- """
- Methods for authenticating with Twitter.
- """
- def __init__(self):
- self.creds_file = 'credentials.txt'
- self.creds_fullpath = None
- self.oauth = {}
- try:
- self.twitter_dir = os.environ['TWITTER']
- self.creds_subdir = self.twitter_dir
- except KeyError:
- self.twitter_dir = None
- self.creds_subdir = None
- def load_creds(self, creds_file=None, subdir=None, verbose=False):
- """
- Read OAuth credentials from a text file.
- ::
- File format for OAuth 1
- =======================
- app_key=YOUR_APP_KEY
- app_secret=YOUR_APP_SECRET
- oauth_token=OAUTH_TOKEN
- oauth_token_secret=OAUTH_TOKEN_SECRET
- ::
- File format for OAuth 2
- =======================
- app_key=YOUR_APP_KEY
- app_secret=YOUR_APP_SECRET
- access_token=ACCESS_TOKEN
- :param str file_name: File containing credentials. ``None`` (default) reads\
- data from `TWITTER/'credentials.txt'`
- """
- if creds_file is not None:
- self.creds_file = creds_file
- if subdir is None:
- if self.creds_subdir is None:
- msg = (
- "Supply a value to the 'subdir' parameter or"
- + " set the TWITTER environment variable."
- )
- raise ValueError(msg)
- else:
- self.creds_subdir = subdir
- self.creds_fullpath = os.path.normpath(
- os.path.join(self.creds_subdir, self.creds_file)
- )
- if not os.path.isfile(self.creds_fullpath):
- raise OSError('Cannot find file {}'.format(self.creds_fullpath))
- with open(self.creds_fullpath) as infile:
- if verbose:
- print('Reading credentials file {}'.format(self.creds_fullpath))
- for line in infile:
- if '=' in line:
- name, value = line.split('=', 1)
- self.oauth[name.strip()] = value.strip()
- self._validate_creds_file(verbose=verbose)
- return self.oauth
- def _validate_creds_file(self, verbose=False):
- """Check validity of a credentials file."""
- oauth1 = False
- oauth1_keys = ['app_key', 'app_secret', 'oauth_token', 'oauth_token_secret']
- oauth2 = False
- oauth2_keys = ['app_key', 'app_secret', 'access_token']
- if all(k in self.oauth for k in oauth1_keys):
- oauth1 = True
- elif all(k in self.oauth for k in oauth2_keys):
- oauth2 = True
- if not (oauth1 or oauth2):
- msg = 'Missing or incorrect entries in {}\n'.format(self.creds_file)
- msg += pprint.pformat(self.oauth)
- raise ValueError(msg)
- elif verbose:
- print('Credentials file "{}" looks good'.format(self.creds_file))
- def add_access_token(creds_file=None):
- """
- For OAuth 2, retrieve an access token for an app and append it to a
- credentials file.
- """
- if creds_file is None:
- path = os.path.dirname(__file__)
- creds_file = os.path.join(path, 'credentials2.txt')
- oauth2 = credsfromfile(creds_file=creds_file)
- app_key = oauth2['app_key']
- app_secret = oauth2['app_secret']
- twitter = Twython(app_key, app_secret, oauth_version=2)
- access_token = twitter.obtain_access_token()
- tok = 'access_token={}\n'.format(access_token)
- with open(creds_file, 'a') as infile:
- print(tok, file=infile)
- def guess_path(pth):
- """
- If the path is not absolute, guess that it is a subdirectory of the
- user's home directory.
- :param str pth: The pathname of the directory where files of tweets should be written
- """
- if os.path.isabs(pth):
- return pth
- else:
- return os.path.expanduser(os.path.join("~", pth))
|