def complete_splitwise_auth(self, state): # code = self.keychain.get_secret(state) # redirect_uri = self.homepage # # Mock splitwise implementation # data = "client_id=%s&client_secret=%s&grant_type=authorization_code&code=%s&redirect_uri=%s" % ( # CONSUMER_KEY, CONSUMER_SECRET, code, redirect_uri) # OAUTH_BASE_URL = "https://www.splitwise.com/" # OAUTH2_TOKEN_URL = OAUTH_BASE_URL + "oauth/" \ # "token" # url = Splitwise.OAUTH2_TOKEN_URL # method = 'POST' # auth = None # from requests import Request, sessions # requestObj = Request(method=method, url=url, data=data, auth=auth, files=None) # prep_req = requestObj.prepare() # with sessions.Session() as session: # response = session.send(prep_req) # Instantiate Splitwise client CONSUMER_KEY, CONSUMER_SECRET = self.keychain.get_api_credentials( "splitwise") sw_client = Splitwise(CONSUMER_KEY, CONSUMER_SECRET) # Get access token access_token = sw_client.getOAuth2AccessToken(state, self.homepage) sw_client.setOAuth2AccessToken(access_token) print("Access Token: {}".format(access_token))
class SplitwiseWrapper: def __init__(self, config_file="data/splitwise.ini"): # Get key and secret from config file config = configparser.ConfigParser() config.read(config_file) if "App" not in config: raise ValueError( "Please provide app key and secret for Splitwise in config file." ) self._consumer_key = config["App"].get('key') self._consumer_secret = config["App"].get('secret') if self._consumer_key is None or self._consumer_secret is None: raise ValueError( "Please provide app key and secret for Splitwise in config file." ) # Create user section if it does not exist yet if "User" not in config: config.add_section("User") # Save config for later access self._config = config self._config_file = config_file # Init splitwise self._s = Splitwise( consumer_key=self._consumer_key, consumer_secret=self._consumer_secret, ) if self._access_token is not None: self._s.setOAuth2AccessToken(self._access_token) # Cache for logged in user self._user: User = User() @property def _access_token(self): token = self._config['User'].get('token', "") token_type = self._config['User'].get('token_type', "") if token == "" or token_type == "": return None else: return {"access_token": token, "token_type": token_type} def set_access_token(self, token): """ Set O-Auth token and write to file. :token: { "access_token": str, "token_type": str } """ self._config['User']['token'] = token['access_token'] self._config['User']['token_type'] = token['token_type'] with open(self._config_file, 'w') as f: self._config.write(f) self._s.setOAuth2AccessToken(token) @property def s(self): return self._s @property def user(self) -> User: if self._user.getId() is None: self._user = self.s.getCurrentUser() return self._user def pay_bill(self, paying_user_id: int, bill: CoffeeBill) -> str: """ Pay a bill by creating an expense for `paying_user` with respect to logged in splitwise user. :param paying_user_id: Splitwise id of paying user :param bill: CoffeeBill to be payed :return: Splitwise transaction id """ # Convert amount to string amount_str = f"{bill.sum:.2f}" # User which will pay money paying_user = ExpenseUser() paying_user.setId(paying_user_id) paying_user.setOwedShare(amount_str) # User which will receive money my_user = ExpenseUser() my_user.setId(self.user.getId()) my_user.setPaidShare(amount_str) # Create Expense/Transaction expense = Expense() expense.setCost(amount_str) expense.setDescription(f"CoffeeTracker, Rechnung {bill.id}") expense.addUser(paying_user) expense.addUser(my_user) # Execute transaction expense_response, errors = self.s.createExpense(expense) if errors is not None: raise RuntimeError( "An error occured while processing the transaction with Splitwise: " f"{errors.errors}") return f"{expense_response.getId()}"
config = read_config(CONFIG_PATH) client_id = config['oauth']['client_id'] client_secret = config['oauth']['client_secret'] redirect_uri = config['oauth']['redirect_uri'] server_addr = config['server']['addr'] server_port = config.getint('server', 'port') server_debug = config.getboolean('server', 'debug') # TODO: initiate the oauth from a route instead of CLI to make this a web app s = Splitwise(client_id, client_secret) # see if we already have an access token, otherwise initialize the OAuth flow if config.has_option('oauth', 'access_token'): access_token = json.loads(config['oauth']['access_token']) s.setOAuth2AccessToken(access_token) else: print("No access token found. Initiating Splitwise integration") server_thread = threading.Thread(target=app.run, args=(server_addr, server_port, server_debug)) server_thread.start() # TODO: use url_for in 'with app.app_context():'. requires setting SERVER_NAME env var redirect_uri = redirect_uri + '/authorized' url, state = s.getOAuth2AuthorizeURL(redirect_uri) webbrowser.open_new_tab(url) server_thread.join() with open(EXPENSE_PATH) as fp: exp_data = json.load(fp) # print(s.getCurrentUser().getId()) add_group_expense(exp_data)