-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathnews_report.py
200 lines (162 loc) · 7.77 KB
/
news_report.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from fluidity import StateMachine, state, transition
import plivohelper
"""
Sketch of news show.
At most basic, the show consists of making outgoing calls and playing a news report.
Options:
Have news report read live from a location
Have a live reporter reading texts at the end
Have a regional segment following the national
Advertisements in-line
"""
import zmq
from config import *
import redis
from utils import call, init_logging
from zmq.eventloop import ioloop, zmqstream
ioloop.install()
#TODO: Is above just an artifact, should be in station_daemon?
import os,sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from yapsy.IPlugin import IPlugin
import time
# get access to telephony & web database
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from rootio.extensions import db
telephony_server = Flask("ResponseServer")
telephony_server.debug = True
from rootio.telephony.models import *
from rootio.radio.models import *
telephony_server.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db = SQLAlchemy(telephony_server)
logger = init_logging('news_report')
# redis is used for flagging is_master if program is across multiple stations
r = redis.StrictRedis(host='localhost', port=6379, db=0)
class News(StateMachine):
initial_state = 'setup'
def __init__(self, episode_id, station_id):
self.caller_list = "caller_list-{0}".format(episode_id)
self.sound_url = "{}{}{}{}".format(TELEPHONY_SERVER_IP,'/~csik/sounds/programs/',episode_id,'/current.mp3')
self.conference = "plivo" #"news_report_conference-{}".format(episode_id)
testme = db.session.query(Station).filter(Station.id == station_id).first()
logger.info("testme : {} type : {}".format(testme, type(testme)))
self.station = testme
self.episode_id = episode_id
self.is_master = False
self.fnumber = None
super(News, self).__init__()
def setup(self):
logger.info("News_Report: In setup")
logger.info("... for station {}".format(self.station.name))
# Check if this instance should be master
if r.get('is_master_'+str(self.episode_id)) == 'none':
r.set('is_master_'+str(self.episode_id),self.station.id)
self.is_master = True
logger.info("{} is master for news report".format(str(self)))
#check soundfile
import requests
response = requests.head(self.sound_url)
if response.status_code != 200:
logger.error('No sound file available at url:'.format(self.sound_url))
#check to see if this is a simple outgoing gateway or a multi-line one
logger.info('Station name: {}'.format(self.station.name))
try:
top_gateway = self.station.outgoing_gateways[0]
if top_gateway.number_top == 0:
logger.info(str("Looks like the gateway does not need to acquire a line."))
fnumber='3124680992' #make this a database field?
self.fnumber=fnumber
else:
#allocate outgoing line
logger.info(str(r.llen('outgoing_unused'))+" free phone lines available")
fnumber = str(r.rpoplpush('outgoing_unused','outgoing_busy'))
self.fnumber = fnumber
logger.info("Allocating line {}".format(fnumber))
except Exception, e:
logger.debug("Exception: {} -- {}".format(Exception, e))
#place calls
#GATEWAY_PREFIX='951' # This is a hack -- make this part of station or similar db field
logger.info("Trying to get transmitter_phone.raw_number for station {}".format(self.station.name))
try:
logger.info("self.station.transmitter_phone.raw_number = {}".format(self.station.transmitter_phone))
except Exception, e:
logger.info("Failed to get transmitter_phone.raw_number", exc_info = True)
try:
call_result = call( to_number="{}".format(self.station.transmitter_phone.raw_number),
from_number=fnumber,
gateway=top_gateway.sofia_string,
answered='http://127.0.0.1:5000/confer/'+str(self.episode_id)+'/',
#extra_dial_string="bridge_early_media=true,hangup_after_bridge=true,origination_caller_id_name=rootio,caller_name=rootio,origination_caller_id_number="+fnumber,
extra_dial_string=top_gateway.extra_string,
)
except Exception, e:
logger.error('Failed to place call', exc_info=True)
call_result = 'Error'
if call_result !='Error':
if call_result.get('Success') == True:
self.RequestUUID = call_result.get('RequestUUID')
logger.info(str(call_result))
time.sleep(10)
#count successful calls,
#if not successful, plan otherwise
#launch show-wide listeners
def intro(self):
logger.info("News_Report: In intro")
#play music
if self.is_master == True:
logger.info("In INTRO to news report {}".format(self.conference))
#wait until intro music is finished
def report(self):
logger.info("In REPORT of news report {}".format(self.conference))
#play report sound
if self.is_master == True:
logger.info("In conference: {}".format(self.conference))
# Create a REST object
plivo = plivohelper.REST(REST_API_URL, SID, AUTH_TOKEN, API_VERSION)
call_params = {'ConferenceName':'plivo', 'MemberID':'all', 'FilePath':'/home/csik/public_html/sounds/programs/5/current.mp3'}
try:
result = plivo.conference_play(call_params)
logger.info("Result of conference play: {}".format(result))
except Exception, e:
logger.info("Exception in news_report REPORT: {},{}".format(Exception, e))
#check on calls?
#
time.sleep(120)
def outro(self):
logger.info("In OUTRO to news report {}".format(self.conference))
#log
#play outgoing music
# This among all others should be "blocking", i.e. how do we assure it has
# executed before trying another show?
def teardown(self):
logger.info("In TEARDOWN of news report {}".format(self.conference))
#hang up calls if they have not been hung up
plivo = plivohelper.REST(REST_API_URL, SID, AUTH_TOKEN, API_VERSION)
hangup_call_params = {'RequestUUID' : self.RequestUUID} # CallUUID for Hangup
try:
result = plivo.hangup_call(hangup_call_params)
logger.info(str(result))
except Exception, e:
logger.error('Failed to hangup in new_report', exc_info=True)
#clear conference
#clear is_master semaphore
if self.is_master == True:
r.set('is_master_'+str(self.episode_id),'none')
#return numbers to stack
top_gateway = self.station.outgoing_gateways[0]
if top_gateway>0:
logger.info("Returning phone numbers to stack.")
r.lrem('outgoing_busy', 0, self.fnumber) # remove all instances for somenumber
r.rpush('outgoing_unused', self.fnumber) # add them back to the queue
# Set up states
state('setup',enter=setup)
state('intro',enter=intro)
state('report',enter=report)
state('outro',enter=outro)
state('teardown',enter=teardown)
# Set up transitions, note they expect serial progression except for teardown
transition(from_='setup', event='go_intro', to='intro')
transition(from_='intro', event='go_report', to='report')
transition(from_='report', event='go_outro', to='outro')
transition(from_=['outro','report','intro','setup'], event='go_teardown', to='teardown')