示例#1
0
 def __init__(self):
     self.parameter_manager = ParameterManager()
     self.config = self._get_config()
     if not all(k in self.config for k in ("email", "password")):
         raise ConfigError("""Please put the following paths and their 
         values in the aws parameter store
         
         /endomondo/email
         /endomondo/password
         """)
     self._authenticate()
示例#2
0
# 'https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.weight:com.google.android.gms:merge_weight/datasets/0-1443194884000000000'
import os
import time
import rollbar

from managers.parameter import ParameterManager
from managers.s3 import S3Manager
from managers.google_fit import GoogleFitManager

from models.body import WeightEntry, Weights

HEALTH_DATA_BUCKET_NAME = os.environ.get('HEALTH_DATA_BUCKET_NAME')
MINIMUM_NANOS = os.environ.get('MINIMUM_NANOS', '1528917191000000000')
PARAMETER_MANAGER = ParameterManager()

rollbar_key = PARAMETER_MANAGER.get('/rollbar/key')
rollbar.init(rollbar_key, __file__)


@rollbar.lambda_function
def handler(event, context):
    s3_manager = S3Manager(HEALTH_DATA_BUCKET_NAME, 'weights.csv', WeightEntry)
    min_nanos = int(MINIMUM_NANOS)

    if s3_manager.has_entries_online():
        min_nanos = s3_manager.get_max_int(column_name='startTimeNanos')

    google_fit_manager = GoogleFitManager()
    google_fit_manager.authenticate()

示例#3
0
class EndomondoService():
    def __init__(self):
        self.parameter_manager = ParameterManager()
        self.config = self._get_config()
        if not all(k in self.config for k in ("email", "password")):
            raise ConfigError("""Please put the following paths and their 
            values in the aws parameter store
            
            /endomondo/email
            /endomondo/password
            """)
        self._authenticate()

    def _get_config(self):
        return self.parameter_manager.get_multiple('/endomondo/')

    def _authenticate(self):
        auth_key = self.config.get("auth_key")
        if not auth_key:
            auth_key = self._get_key()
            self.parameter_manager.store('/endomondo/auth_key', auth_key)

    def _get_key(self) -> str:
        url = 'https://api.mobile.endomondo.com/mobile/auth'
        # taken from https://github.com/isoteemu/sports-tracker-liberator/blob/master/endomondo/endomondo.py
        params = {
            'os': platform.system(),
            'model': platform.python_implementation(),
            'osVersion': platform.release(),
            'vendor': 'github/kreusen',
            'appVariant': 'endomondo-api',
            'country': 'GB',
            'v': '2.4',
            'appVersion': '0.1',
            'deviceId':
            str(uuid.uuid5(uuid.NAMESPACE_DNS, socket.gethostname())),
            "action": "pair",
            "email": self.config.get("email"),
            "password": self.config.get("password")
        }
        r = requests.get(url, params=params)

        lines = r.text.split("\n")
        if lines[0] != "OK":
            raise AuthenticationError(
                f"Could not authenticate with Endomondo, Expected 'OK', got '{lines[0]}'"
            )

        for line in lines[1:]:
            key, value = line.split("=")
            if key == "authToken":
                return value

    def get_runs(self, maxresults: int = 25) -> List[Run]:
        url = f"https://api.mobile.endomondo.com/mobile/api/workouts?authToken={self.config.get('auth_key')}&maxResults={maxresults}&fields=basic"
        r = requests.get(url)
        response = r.json()

        runs = []
        for workout in response["data"]:
            # only get runs
            if workout["sport"] == 0 and workout["live"] == False:
                run = create_model_from_dict(Run, workout)
                runs.append(run)

        return runs
 def __init__(self):
     self.parameter_manager = ParameterManager()
     self.access_token = None
class GoogleFitManager():
    def __init__(self):
        self.parameter_manager = ParameterManager()
        self.access_token = None
    
    def authenticate(self):
        if self.access_token is None:
            credentials = self._get_credentials()
            self.access_token = credentials.get("access_token")

    def _get_credentials(self) -> dict:
        """ Authenticates with google fit and returns a dictionary with
        the most recent valid credentials """
        online_credentials = self.parameter_manager.get_multiple('/google_fit/')
        credentials = GoogleCredentials(**online_credentials, token_expiry=None, user_agent=None)

        http = credentials.authorize(httplib2.Http())
        credentials.refresh(http)

        credentials_dict = json.loads(credentials.to_json())
        self.access_token = credentials_dict.get("access_token")
        self._store_credentials_online(credentials_dict)

        return credentials_dict        

    def _store_credentials_online(self, credentials_dict: dict):
        keys_to_store = ["access_token", "client_secret", "client_id", "refresh_token", "token_uri"]
        for key in keys_to_store:
            if key in credentials_dict:
                path = f'/google_fit/{key}'
                value = credentials_dict.get(key)
                self.parameter_manager.store(path, value)
    
    def get_weights(self, min_nanos: int, max_nanos: Optional[int] = None) -> Optional[List[WeightEntry]]:
        if max_nanos is None:
            max_nanos = get_current_nanos()
        
        base_url = 'https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.weight:com.google.android.gms:merge_weight/datasets'
        
        # batch requests pe

    def batch_requests(self, base_url: str, min_nanos: int, max_nanos: int, batch_per_n_nanos: int = 8640000000):
        pass


    def build_url(self, base_url: str, min_nanos: int, max_nanos: int) -> str:
        return os.path.join(base_url, f'{min_nanos}-{max_nanos}')

    def make_request(self, url: str):
        headers = {
            "Authorization": f"Bearer {self.access_token}"
        }
        r = requests.get(url, headers=headers)
        response = r.json()
        if "error" in response:
            raise GoogleFitError(response)
        return response

    def extract_values(self, response: dict) -> List[dict]:
        point = response.get("point")
        extracted_values = []
        if point:
            for p in point:
                extracted_value = {
                    "startTimeNanos": p.get("startTimeNanos"),
                    "value": p["value"][0]["fpVal"]
                }
                extracted_values.append(extracted_value)
        
        return extracted_values
 def __init__(self):
     self.parameter_manager = ParameterManager()
class BunqService():
    def __init__(self):
        self.parameter_manager = ParameterManager()

    def authenticate(self):
        if self.parameter_manager.exists("/bunq/api_context"):
            self.api_context = self._get_api_context_from_aws()
            self._ensure_active_session()
        else:
            self.api_context = self._create_api_context()

        BunqContext.load_api_context(self.api_context)

    def _get_api_context_from_aws(self) -> ApiContext:
        json_string = self.parameter_manager.get("/bunq/api_context")
        return ApiContext.from_json(json_string)

    def _create_api_context(self) -> ApiContext:
        api_key = self.parameter_manager.get('/bunq/api_key')
        api_context = ApiContext(ApiEnvironmentType.PRODUCTION, api_key,
                                 'runs-to-gadgetfund')
        self._update_remote_api_context(api_context)
        return api_context

    def _ensure_active_session(self):
        if not self.api_context.is_session_active():
            self.api_context.reset_session()
            self._update_remote_api_context(self.api_context)

    def _update_remote_api_context(self, api_context: object):
        self.parameter_manager.store("/bunq/api_context",
                                     api_context.to_json())

    def make_payment(self, PaymentInfo: object):
        recipient = Pointer('IBAN', PaymentInfo.to_iban, "bunq")
        endpoint.Payment.create(
            amount=Amount(PaymentInfo.amount_string, 'EUR'),
            counterparty_alias=recipient,
            description=PaymentInfo.description,
            monetary_account_id=self._get_monetary_account_id_from_iban(
                PaymentInfo.from_iban))

    def _get_monetary_account_id_from_iban(self,
                                           from_iban: str) -> Optional[int]:
        all_accounts = self._get_all_active_monetary_accounts()
        account_ids_by_iban = {}
        for account in all_accounts:
            for alias in account["alias"]:
                if alias["type"] == "IBAN":
                    iban = alias["value"]
                    continue
            account_id = account["id"]
            account_ids_by_iban[iban] = account_id

        return account_ids_by_iban.get(from_iban)

    def _get_all_active_monetary_accounts(self):
        pagination = Pagination()
        pagination.count = 100

        all_monetary_account_bank = endpoint.MonetaryAccountBank.list(
            pagination.url_params_count_only).value
        all_monetary_account_bank_active = []

        for monetary_account_bank in all_monetary_account_bank:
            if monetary_account_bank.status == "ACTIVE":
                account_to_append = json.loads(monetary_account_bank.to_json())
                all_monetary_account_bank_active.append(account_to_append)

        return all_monetary_account_bank_active