Files @ 22285473c090
Branch filter:

Location: C3L-NOC/spaceapi/spaceapi/utils.py

Dennis Fink
Version bump
import json
import os.path
from time import time

from flask import request, current_app

import tweepy


default_json_file = os.path.abspath('default.json')
last_state_file = os.path.abspath('laststate.json')

if not os.path.exists(default_json_file):
    raise RuntimeError('default.json does not exists!')
elif not os.path.isfile(default_json_file):
    raise RuntimeError('default.json is not a file!')


class Singleton:

    def __new__(cls, *args, **kwargs):
        key = str(hash(cls))

        if not hasattr(cls, '_instance_dict'):
            cls._instance_dict = {}

        if key not in cls._instance_dict:
            cls._instance_dict[key] = super().__new__(cls, *args, **kwargs)

        return cls._instance_dict[key]


class ActiveStatus(Singleton, dict):

    def reload(self):

        with open(default_json_file, encoding='utf-8') as f:
            self.update(json.load(f))

        if os.path.exists(last_state_file) and os.path.isfile(last_state_file):
            with open(last_state_file, encoding='utf-8') as f:
                last_state_json = json.load(f)

            self['state'] = last_state_json['state']
            self['sensors'].update(last_state_json['sensors'])

    def save_last_state(self):

        with open(last_state_file, mode='w', encoding='utf-8') as f:
            last_state = {}
            last_state['state'] = self['state']
            last_state['sensors'] = self['sensors']
            json.dump(last_state, f, sort_keys=True)

    def add_user_present(self, username):
        if self['state']['open']:
            if 'people_now_present' not in self['sensors']:
                self['sensors']['people_now_present'] = [{'value': 0}]

            people_now_present = self['sensors']['people_now_present'][0]

            if 'names' in people_now_present and username not in people_now_present['names']:
                people_now_present['value'] += 1

                if username in current_app.config['PEOPLE_NOW_PRESENT_ALLOWED']:
                    people_now_present['names'].append(username)

            elif 'names' not in people_now_present:
                people_now_present['value'] += 1

                if username in current_app.config['PEOPLE_NOW_PRESENT_ALLOWED']:
                    people_now_present['names'] = [username]

            self['sensors']['people_now_present'][0] = people_now_present
        else:
            pass

    def remove_user_present(self, username):
        if self['state']['open'] and 'people_now_present' in self['sensors']:
            people_now_present = self['sensors']['people_now_present'][0]

            if people_now_present['value'] > 0:
                people_now_present['value'] -= 1

            if 'names' in people_now_present:
                if people_now_present['value'] == 0:
                    del people_now_present['names']
                elif username in people_now_present['names']:
                    people_now_present['names'].remove(username)
                    if not people_now_present['names']:
                        del people_now_present['names']
            self['sensors']['people_now_present'][0] = people_now_present
        else:
            pass

    def set_new_state(self, value=None, trigger_person=None, message=None):

        if value is not None:
            self['state']['open'] = value

            if 'TWITTER_CONSUMER_KEY' in current_app.config:
                auth = tweepy.OAuthHandler(
                    current_app.config['TWITTER_CONSUMER_KEY'],
                    current_app.config['TWITTER_CONSUMER_SECRET']
                )
                auth.set_access_token(
                    current_app.config['TWITTER_ACCESS_TOKEN_KEY'],
                    current_app.config['TWITTER_ACCESS_TOKEN_SECRET']
                )
                api = tweepy.API(auth)

                if value:
                    api.update_status('The space is now open!')
                else:
                    api.update_status('The space is now closed!')

            if not value:
                if 'people_now_present' in self['sensors']:
                    self['sensors']['people_now_present'][0]['value'] = 0
                    if 'names' in self['sensors']['people_now_present'][0]:
                        del self['sensors']['people_now_present'][0]['names']

                if 'message' in self['state']:
                    del self['state']['message']

            if trigger_person is None:
                del self['state']['trigger_person']

        if trigger_person is not None:
            self['state']['trigger_person'] = trigger_person

        if message is not None:
            self['state']['message'] = message

        if value is not None or trigger_person is not None or message is not None:
            self['state']['lastchange'] = int(time())


def request_wants_json():
    best = request.accept_mimetypes.best_match(
        ['application/json', 'text/html']
    )
    return best == 'application/json' and \
        request.accept_mimetypes[best] > \
        request.accept_mimetypes['text/html']


def fuzzy_list_find(lst, key, value):

    for i, dic in enumerate(lst):
        if dic[key] == value:
            return i

    raise ValueError


def first(iterable, keys):
    for key in keys:
        if key in iterable:
            return key

    raise ValueError