Skip to content
This repository was archived by the owner on May 28, 2022. It is now read-only.

Zeroconf support for headless server #648

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ before_install:
- sudo apt-get -qq install gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly
- sudo apt-get -qq install gstreamer0.10-pulseaudio
- sudo apt-get -qq install gstreamer0.10-alsa
- sudo apt-get -qq install python-avahi
- python -c 'import avahi'
- python -c 'import dbus'
# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install:
- pip install -r dev_requirements.txt --use-mirrors
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ oauth<1.1
simplejson<3.4
tabulate==0.7.2
yapsy<1.11
zeroconf<=0.15.1
56 changes: 56 additions & 0 deletions src/freeseer/framework/announcer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# freeseer - vga/presentation capture software
#
# Copyright (C) 2014 Free and Open Source Software Learning Centre
# http://fosslc.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# For support, questions, suggestions or any other inquiries, visit:
# http://wiki.github.com/Freeseer/freeseer/

import avahi
import dbus


class ServiceAnnouncer:
"""ServiceAnnouncer publishes Freeseer service over Zeroconf/Avahi protocol"""
def __init__(self, name, service, port, txt):
"""
Args:
name - instance name i.e Freeseer Host
service - service type i.e _freeseer._tcp
port - port number
txt - List containing strings of information you wish to include.
"""
bus = dbus.SystemBus()
server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
self.group = dbus.Interface(bus.get_object(avahi.DBUS_NAME, server.EntryGroupNew()), avahi.DBUS_INTERFACE_ENTRY_GROUP)
self.service = service
self.name = name
self.port = port
self.txt = txt

def advertise(self):
"""Announces Freeseer service over Zeroconf/Avahi"""
self.group.AddService(avahi.IF_UNSPEC, avahi.PROTO_INET, 0,
self.name, self.service, '', '', self.port,
avahi.string_array_to_txt_array(self.txt))
self.group.Commit()

def unpublish(self):
"""Removes service from Zeroconf/Avahi"""
self.group.Reset()
64 changes: 64 additions & 0 deletions src/freeseer/framework/listener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# freeseer - vga/presentation capture software
#
# Copyright (C) 2014 Free and Open Source Software Learning Centre
# http://fosslc.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# For support, questions, suggestions or any other inquiries, visit:
# http://wiki.github.com/Freeseer/freeseer/

import socket
from time import sleep

from zeroconf import ServiceBrowser, Zeroconf


class Listener(object):

def __init__(self):
self.servers = {}

def removeService(self, zeroconf, type, name):
"""Updates dictionary of available freeseer servers"""
info = zeroconf.getServiceInfo(type, name)
ipaddr = socket.inet_ntoa(info.getAddress())
port = info.getPort()
del self.servers[(ipaddr, port)]

def addService(self, zeroconf, type, name):
"""Updates dictionary of available freeseer servers"""
info = zeroconf.getServiceInfo(type, name)
if info:
ipaddr = socket.inet_ntoa(info.getAddress())
port = info.getPort()
self.servers[(ipaddr, port)] = {
'name': name,
'type': type,
}


def search(timeout):
results = []
zeroconf = Zeroconf(socket.gethostbyname(socket.gethostname()))
listener = Listener()
ServiceBrowser(zeroconf, '_freeseer._tcp.local.', listener)
sleep(timeout)
for (ipaddr, port), value in listener.servers.iteritems():
results.append('{}\t{}:{}'.format(value['name'].split('.')[0], ipaddr, port))
zeroconf.close()
return results
28 changes: 27 additions & 1 deletion src/freeseer/frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import signal
import sys
import textwrap
from time import sleep

import pygst
import yapsy
Expand Down Expand Up @@ -70,6 +71,7 @@ def setup_parser():
setup_parser_report(subparsers)
setup_parser_upload(subparsers)
setup_parser_server(subparsers)
setup_parser_browse(subparsers)
return parser


Expand Down Expand Up @@ -155,7 +157,13 @@ def setup_parser_upload_youtube(subparsers):
def setup_parser_server(subparsers):
"""Setup server command parser"""
parser = subparsers.add_parser("server", help="Setup a freeseer restful server")
parser.add_argument("-f", "--filename", type=unicode, help="file to load recordings")
parser.add_argument("--filename", type=unicode, help="file to load recordings")


def setup_parser_browse(subparsers):
"""Setup browse command parser"""
parsers = subparsers.add_parser('browse', help='Search for freeseer servers on the network')
parsers.add_argument('-t', '--timeout', help='Poll for freeseer servers continually', type=int)


def parse_args(parser, parse_args=None):
Expand Down Expand Up @@ -272,6 +280,13 @@ def parse_args(parser, parse_args=None):
else:
launch_server()

elif args.app == 'browse':
if args.timeout:
timeout = args.timeout
launch_browser(timeout)
else:
launch_browser()


def launch_recordapp():
"""Launch the Recording GUI if no arguments are passed"""
Expand Down Expand Up @@ -341,3 +356,14 @@ def launch_server(storage_file="recording_storage"):
import freeseer.frontend.controller.server as server

server.start_server(storage_file)


def launch_browser(timeout=5):
"""Search for Freeseer hosts on client's network"""
import freeseer.framework.listener as listener

print('Searching for Freeseer Hosts\n')
results = listener.search(max(timeout, 5))
print('Results:')
print('\n'.join(results))
sleep(0.1) # workaround hack. Without sleep(0.1) exception is thrown on shutdown on my ubuntu vm.
16 changes: 14 additions & 2 deletions src/freeseer/frontend/controller/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,33 @@
# http://wiki.github.com/Freeseer/freeseer/

import functools
import signal
import sys

from flask import jsonify

from freeseer.frontend.controller import app
from freeseer.framework.announcer import ServiceAnnouncer


def start_server(storage_file):
def start_server(storage_file, port=7079):
"""Starts the restapi server.

Args:
storage_file - name of storage file to which you are saving recordings
port - the port you wish to broadcast your server on.
"""

app.storage_file_path = storage_file
app.run()
app.service_announcer = ServiceAnnouncer('Freeseer Host', '_freeseer._tcp', port, [])
app.service_announcer.advertise()
signal.signal(signal.SIGTERM, remove)
app.run('::0.0.0.0', port)


def remove(signal, frame):
app.service_announcer.remove_service()
sys.exit(0)


def http_response(status_code):
Expand Down