Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ojii committed Apr 18, 2012
0 parents commit 1339595
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.pyc
dist
.*
*.egg-info
htmlcov
/env/
!.gitignore
1 change: 1 addition & 0 deletions leftronicd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '1.0'
4 changes: 4 additions & 0 deletions leftronicd/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

IDLE = 1
RUNNING = 2
Empty file added leftronicd/contrib/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions leftronicd/contrib/github.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from twisted.python import log
import json
import requests

def repo_metric(repo, metric, username=None, password=None):
auth = None
if username and password:
auth = (username, password)
log.msg('[github.repo_metric] Using authentication')
else:
log.msg('[github.repo_metric] No authentication')
url = 'https://api.github.com/repos/%s' % repo
log.msg('[github.repo_metric] Sending request to %s' % url)
response = requests.get(url, auth=auth)
log.msg('[github.repo_metric] Got response: %s' % response.status_code)
response.raise_for_status()
log.msg('[github.repo_metric] Loading data')
data = json.loads(response.content)
log.msg('[github.repo_metric] Returning value')
return data[metric]
20 changes: 20 additions & 0 deletions leftronicd/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from importlib import import_module
import datetime

def load(method_path):
module_name, method_name = method_path.rsplit('.', 1)
module = import_module(module_name)
return getattr(module, method_name)

def td2s(td):
return (td.days * 24 * 3600) + td.seconds

def intervalify(name):
return {
'daily': datetime.timedelta(days=1),
'hourly': datetime.timedelta(hours=1),
}[name]

def get_interval(name):
return td2s(intervalify(name))
103 changes: 103 additions & 0 deletions leftronicd/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
from leftronic import Leftronic
from leftronicd.constants import IDLE, RUNNING
from leftronicd.helpers import get_interval, load
from twisted.internet import task, reactor
from twisted.python import log
from twisted.web.client import getPage
import json
import sys
import yaml


class TwistedLeftronic(Leftronic):
def postData(self, parameters):
""" Makes an HTTP POST to the API URL. """
log.msg('[TwistedLeftronic.postData] Preparing to post %s' % parameters)
# add the access key
parameters['accessKey'] = self.accessKey

if self.cryptoKey:
self.encryptStreams(parameters)

# Convert to JSON
data = json.dumps(parameters)
log.msg('[TwistedLeftronic.postData] Posting %s to %s' % (data, self.apiUrl))
deferred = getPage(self.apiUrl, method='POST', postdata=data)
def log_success(value):
log.msg('[TwistedLeftronic.postData] Post of %s to %s was successful' % (data, self.apiUrl))
def log_error(value):
log.err('[TwistedLeftronic.postData] Post of %s to %s failed' % (data, self.apiUrl))
deferred.addCallback(log_success)
deferred.addErrback(log_error)


class Stream(object):
"""
A leftronic stream
"""
def __init__(self, daemon, config):
self.daemon = daemon
self.interval = get_interval(config.pop('interval'))
self.method_path = config.pop('method')
self.method = load(self.method_path)
self.name = config.pop('name')
self.verbosename = config.pop('verbosename')
self.type = config.pop('type')
self.kwargs = config
self.state = IDLE

def get_interval(self):
return self.interval

def execute(self):
log.msg("[Stream(%s).execute]" % self.name)
if self.state != IDLE:
log.msg("[Stream(%s).execute] Not idle, ignoring..." % self.name)
return
log.msg("[Stream(%s).execute] Calling %s(**%s)" % (self.name, self.method_path, self.kwargs))
self.callback(self.method(**self.kwargs))
self.state = RUNNING

def callback(self, value):
log.msg("[Stream(%s).callback] Got value: %s" % (self.name, value))
method = getattr(self.daemon.leftronic, 'push%s' % self.type.capitalize())
method(self.name, value)
self.state = IDLE


class LeftronicDaemon(object):
"""
The daemon
"""
def __init__(self, config):
self.leftronic = TwistedLeftronic(config['accesskey'])
self.loops = []
self.streams = []
for streamconf in config['streams']:
stream = Stream(self, streamconf)
self.streams.append(stream)
log.msg("[LeftronicDaemon.run] Initialized with %s streams" % len(self.streams))

def run(self):
log.msg("[LeftronicDaemon.run] Starting...")
for stream in self.streams:
loop = task.LoopingCall(stream.execute)
loop.start(stream.get_interval())
self.loops.append(loop)
reactor.run()

def cli():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('configfile', type=argparse.FileType('r'))
parser.add_argument('-v', '--verbose', action='store_true', default=False, dest='verbose')
args = parser.parse_args()
config = yaml.load(args.configfile)
if args.verbose:
log.startLogging(sys.stdout)
daemon = LeftronicDaemon(config)
daemon.run()

if __name__ == '__main__':
cli()
9 changes: 9 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PyYAML==3.10
Twisted==12.0.0
certifi==0.0.8
chardet==1.0.1
leftronic==1.4
pyOpenSSL==0.13
requests==0.11.1
wsgiref==0.1.2
zope.interface==3.8.0
42 changes: 42 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from leftronicd import __version__
from setuptools import setup, find_packages


with open('requirements.txt') as fobj:
INSTALL_REQUIRES = [line.strip() for line in fobj.readlines() if line.strip()]

try:
import json
except ImportError:
INSTALL_REQUIRES.append('simplejson')

CLASSIFIERS = [
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Topic :: Software Development',
]

setup(
name='leftronicd',
version=__version__,
description='A twisted based daemon to send metrics to leftronic.com',
author='Jonas Obrist',
author_email='[email protected]',
url='https://github.com/ojii/leftronicd',
packages=find_packages(),
license='BSD',
platforms=['OS Independent'],
install_requires=INSTALL_REQUIRES,
entry_points="""
[console_scripts]
leftronicd = leftronic.main:cli
""",
)

0 comments on commit 1339595

Please sign in to comment.