<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Listens on PubNub channels for observations and pupulates database.
Configuration file is in ~/.pubnub.json and this should look like:

.. code:: Javascript

    {
      "subscribe_key": "demo",
      "publish_key": "demo",
      "channels": ["ch1", "ch2"],
      "channel_groups": ["cg1", "cg2"],
      "ssl": false,
      "reconnect_policy": "linear",
      "publish_channel": "pubch"
    }

'''

import json
import logging
import os.path
import signal

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

import pubnub
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub, SubscribeListener
from pubnub.enums import PNReconnectionPolicy

from birdseye.default_settings import SQLALCHEMY_DATABASE_URI
import birdseye.models as bm


CONFIG = "~/.pubnub.json"

log = logging.getLogger("pubsub")


def db_session():
    engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode=True)
    Session = sessionmaker(bind=engine)
    return Session()


class PubSubError(RuntimeError):

    pass


class DebugListener(SubscribeListener):

    def status(self, pubnub, status):
        pass

    def message(self, pubnub, message):
        log.info("Received message: {}".format(json.dumps(message.message)))

    def presence(self, pubnub, presence):
        pass


class ObservationsListener(SubscribeListener):

    def status(self, pubnub, status):
        pass

    def message(self, pubnub, message):
        session = db_session()
        data = message.message
        log.debug("Received message {}".format(json.dumps(data)))
        user = bm.User.find_by_credentials(
            data.get('credentials'), data.get('secret'))
        if user:
            try:
                obs = bm.Observation(
                    user, data.get('geometry'), data.get('media'),
                    data.get('properties'), data.get('species'))
                session.add(obs)
                session.commit()
                session.refresh(obs)
                log.debug("Observation added")
            except Exception as e:
                log.exception(e)
        else:
            log.error("User not found.")

    def presence(self, pubnub, presence):
        pass


class PubSub():

    RECONNECT_POLICY = {
        None: PNReconnectionPolicy.NONE,
        "linear": PNReconnectionPolicy.LINEAR,
        "exponential": PNReconnectionPolicy.EXPONENTIAL,
    }<commit_msg>make pubsub a singleton<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Listens on PubNub channels for observations and pupulates database.
Configuration file is in ~/.pubnub.json and this should look like:

.. code:: Javascript

    {
      "subscribe_key": "demo",
      "publish_key": "demo",
      "channels": ["ch1", "ch2"],
      "channel_groups": ["cg1", "cg2"],
      "ssl": false,
      "reconnect_policy": "linear",
      "publish_channel": "pubch"
    }

'''

import json
import logging
import os.path
import signal

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

import pubnub
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub, SubscribeListener
from pubnub.enums import PNReconnectionPolicy

from birdseye.default_settings import SQLALCHEMY_DATABASE_URI
import birdseye.models as bm


CONFIG = "~/.pubnub.json"

log = logging.getLogger("pubsub")


def db_session():
    engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode=True)
    Session = sessionmaker(bind=engine)
    return Session()


class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(
                Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class PubSubError(RuntimeError):

    pass


class DebugListener(SubscribeListener):

    def status(self, pubnub, status):
        pass

    def message(self, pubnub, message):
        log.info("Received message: {}".format(json.dumps(message.message)))

    def presence(self, pubnub, presence):
        pass


class ObservationsListener(SubscribeListener):

    def status(self, pubnub, status):
        pass

    def message(self, pubnub, message):
        session = db_session()
        data = message.message
        log.debug("Received message {}".format(json.dumps(data)))
        user = bm.User.find_by_credentials(
            data.get('credentials'), data.get('secret'))
        if user:
            try:
                obs = bm.Observation(
                    user, data.get('geometry'), data.get('media'),
                    data.get('properties'), data.get('species'))
                session.add(obs)
                session.commit()
                session.refresh(obs)
                log.debug("Observation added")
            except Exception as e:
                log.exception(e)
        else:
            log.error("User not found.")

    def presence(self, pubnub, presence):
        pass


class PubSub(object, metaclass=Singleton):

    RECONNECT_POLICY = {
        None: PNReconnectionPolicy.NONE,
        "linear": PNReconnectionPolicy.LINEAR,
        "exponential": PNReconnectionPolicy.EXPONENTIAL,
    }
{'fraction_non_alphanumeric': 0.11313246162592382, 'fraction_numerical': 0.0018950161076369148, 'mean_word_length': 2.7221438645980256, 'pattern_counts': {'":': 18, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5787022', 'n_tokens_mistral': 1602, 'n_tokens_neox': 1522, 'n_words': 371}