Пример #1
0
def auto_posting(current_time):
    today = datetime.now()
    week_type = (today.isocalendar()[1] +
                 int(config.get('bot', 'WEEK_TYPE'))) % 2

    if datetime.weekday(today) == 6:
        today += timedelta(days=1)
        week_type = (week_type + 1) % 2

    day = helpers.daysOfWeek[datetime.weekday(today)]

    # Выборка пользователей из базы у которых установлена отправка расписания на текущий день
    with ScheduleDB() as db:
        users = db.find_users_where(auto_posting_time=current_time,
                                    is_today=True)

    send_schedule(users, current_time, day, week_type)

    # Выборка пользователей из базы у которых установлена отправка расписания на завтрашний день,
    # если сегодня воскресенье, то расписание будет отправляться на понедельник.
    if datetime.weekday(datetime.now()) != 6:
        today += timedelta(days=1)

    day = helpers.daysOfWeek[datetime.weekday(today)]

    with ScheduleDB() as db:
        users = db.find_users_where(auto_posting_time=current_time,
                                    is_today=False)

    send_schedule(users, current_time, day, week_type)
Пример #2
0
def command_auto_posting_off(m):
    # Статистика
    if config['STATISTIC_TOKEN'] != '':
        track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'auto_posting_off')
    else:
        logger.info('auto_posting_off')

    cid = m.chat.id

    try:
        db = ScheduleDB(config)
        user = db.find_user(cid)
        if not user:
            bot.send_message(
                cid,
                "Вас ещё нет в базе данных, поэтому пройдите простую процедуру регистрации"
            )
            command_registration(m)
            return

        if db.set_auto_post_time(cid, None, None):
            bot.send_message(
                cid, "Автоматическая отправка расписания успешно отключена")
        else:
            bot.send_message(
                cid,
                "Случилось что то странное, попробуйте ввести команду заново",
                reply_markup=get_date_keyboard())

    except BaseException as e:
        logger.warning('command auto_posting_off: {0}'.format(str(e)))
        bot.send_message(
            cid, "Случилось что то странное, попробуйте ввести команду заново")
Пример #3
0
def command_start(m):
    # Статистика
    if config['STATISTIC_TOKEN'] != '':
        track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'start')
    else:
        logger.info('start')

    cid = m.chat.id
    command_help(m)

    try:
        with ScheduleDB(config) as db:
            user = db.find_user(cid)
        if user and user[0] is not None:
            bot.send_message(cid,
                             "Вы уже добавлены в базу данных",
                             reply_markup=get_date_keyboard())
        else:
            bot.send_message(
                cid,
                "Вас ещё нет в базе данных, поэтому пройдите простую процедуру регистрации"
            )
            command_registration(m)
    except BaseException as e:
        logger.warning('command start: {0}'.format(str(e)))
        bot.send_message(
            cid,
            "Случилось что то странное, попробуйте ввести команду заново",
            reply_markup=get_date_keyboard())
Пример #4
0
def add_organization():
    if not request.is_json:
        return "incorrect request", 403

    try:
        content = request.get_json()

        if content['key'] != config["TOKEN"]:
            return "invalid api key", 403

        data = content['data']

        answer = {'ok': [], 'failed': []}

        with ScheduleDB(config) as db:
            for org_data in data:
                # Обязательные параметры запроса
                organization = org_data['organization']
                group = org_data['group']

                # Необязательные параметры
                faculty = org_data['faculty'] if 'faculty' in org_data else ''

                tag = db.add_organization(organization, faculty, group)
                json_data = {'tag': tag, 'data': org_data}

                if tag is not None:
                    answer['ok'].append(json_data)
                else:
                    answer['failed'].append(json_data)

        return jsonify(answer), 200
    except KeyError as e:
        return 'key not found: {}'.format(str(e)), 403
Пример #5
0
def command_send_report(m):
    # Статистика
    if config['STATISTIC_TOKEN'] != '':
        track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'report')
    else:
        logger.info('report')

    cid = m.chat.id
    data = m.text.split("/send_report")

    if data[1] != '':
        report = data[1]
        with ScheduleDB(config) as db:
            if db.add_report(cid, report):
                bot.send_message(cid, "Сообщение принято")
            else:
                bot.send_message(
                    cid,
                    "Случилось что то странное, попробуйте ввести команду заново",
                    reply_markup=get_date_keyboard())
    else:
        bot.send_message(
            cid,
            "Вы отправили пустую строку. Пример: /send_report <сообщение>",
            reply_markup=get_date_keyboard())
Пример #6
0
def command_registration(m):
    cid = m.chat.id

    # Процедура регистрации проходит в четрые этапа:
    # 1 этап: выбор учебного заведения <--
    # 2 этап: выбор факультета
    # 3 этап: выбор группы
    # 4 этап: добавление данных о принадлежности пользователя к учебному заведению в БД
    try:
        # Статистика
        if config['STATISTIC_TOKEN'] != '':
            track(config['STATISTIC_TOKEN'], cid, 'stage 1',
                  'registration-stage-1')

        keyboard = types.InlineKeyboardMarkup()

        with ScheduleDB(config) as db:
            result = db.get_organizations()
        for row in result:
            callback_button = types.InlineKeyboardButton(
                text=str(row[0]),
                callback_data="reg:stage 2:{0}".format(
                    str(row[1])[:organization_field_length]))
            keyboard.add(callback_button)

        bot.send_message(cid, "Выберите университет:", reply_markup=keyboard)
    except BaseException as e:
        logger.warning('Registration problem: {0}'.format(str(e)))
        bot.send_message(
            cid,
            "Случилось что-то странное, попробуйте начать сначала, введя команду /registration"
        )
Пример #7
0
def command_auto_posting_on(m):
    # Статистика
    if config['STATISTIC_TOKEN'] != '':
        track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'auto_posting_on')
    else:
        logger.info('auto_posting_on')

    cid = m.chat.id

    try:
        data = m.text.split("/auto_posting_on")[1].strip()
        if re.match(data, r'\d{1,2}:\d\d'):
            raise BaseException
    except:
        bot.send_message(
            cid,
            "Вы отправили пустую строку или строку неправильного формата. Правильный формат ЧЧ:ММ",
            reply_markup=get_date_keyboard())
        return None

    try:
        db = ScheduleDB(config)
        user = db.find_user(cid)
        if user and user[0] is not None:
            keyboard = types.InlineKeyboardMarkup()
            callback_button = types.InlineKeyboardButton(
                text="На Сегодня", callback_data="ap:{0}:1".format(data))
            keyboard.add(callback_button)
            callback_button = types.InlineKeyboardButton(
                text="На Завтра", callback_data="ap:{0}:0".format(data))
            keyboard.add(callback_button)

            bot.send_message(
                cid,
                "Выберите день на который будет приходить расписание:",
                reply_markup=keyboard)
        else:
            bot.send_message(
                cid,
                "Вас ещё нет в базе данных, поэтому пройдите простую процедуру регистрации"
            )
            command_registration(m)
    except BaseException as e:
        logger.warning('command auto_posting_on: {0}'.format(str(e)))
        bot.send_message(
            cid, "Случилось что то странное, попробуйте ввести команду заново")
Пример #8
0
def exams(m):
    cid = m.chat.id

    # Статистика
    track(config['STATISTIC_TOKEN'], cid, m.text, 'exams')

    # Если пользователя нет в базе, то ему выведет предложение зарегистрироваться
    try:
        with ScheduleDB(config) as db:
            user = db.find_user(cid)
        if not user or user[0] is None:
            message = "Вас ещё нет в базе данных, поэтому пройдите простую процедуру регистрации:\n"
            message += 'Введите команду(без кавычек):\n\nрегистрация "название вуза" "факультет" "группа"\n\n'
            message += 'Если вы допустите ошибку, то просто наберите команду заново.\n'

            bot.send_message(cid, message, reply_markup=get_date_keyboard())
    except BaseException as e:
        bot.send_message(
            cid,
            'Случилось что то странное, попробуйте ввести команду заново',
            reply_markup=get_date_keyboard())

    try:
        with ScheduleDB(config) as db:
            exams_list = db.get_exams(user[0])

        message = ''
        for exam in exams_list:
            message += exam[0].strftime('%d.%m.%Y') + ":\n"

            title = ' '.join(str(exam[1]).split())
            lecturer = ' '.join(str(exam[2]).split())
            classroom = ' '.join(str(exam[3]).split())

            message += title + ' | ' + lecturer + ' | ' + classroom + "\n"
            message += "------------\n"
        if len(message) == 0:
            message = 'Похоже расписания экзаменов для вашей группы нет в базе'

    except BaseException as e:
        message = "Случилось что то странное, попробуйте ввести команду заново"

    bot.send_message(cid, message, reply_markup=get_date_keyboard())
Пример #9
0
 def __init__(self,log=None):
     # super(Schedule,self).__init__()
     self.logg=log
     appdir=os.path.expanduser("~/.epgdb")
     eitdb=os.path.join(appdir,"database.db")
     scheddb=os.path.join(appdir,"cristel.db")
     self.debug("starting eit db at %s" % eitdb)
     self.eit=EITDatabase(eitdb,log)
     self.debug("starting scheddb at %s" % scheddb)
     self.sch=ScheduleDB(scheddb,log)
     self.debug("scheduler class started")
Пример #10
0
def callback_registration(call):
    cid = call.message.chat.id

    # Парсинг сообщения указывающего стадию регистрации
    # reg : stage : tag
    callback_data = re.split(r':', call.data)

    # Процедура регистрации проходит в четрые этапа:
    # 1 этап: выбор учебного заведения
    # 2 этап: выбор факультета
    # 3 этап: выбор группы
    # 4 этап: добавление данных о принадлежности пользователя к учебному заведению в БД <--
    try:
        # Статистика
        if config['STATISTIC_TOKEN'] != '':
            track(config['STATISTIC_TOKEN'], cid, 'stage 4',
                  'registration-stage-4')

        group_id = callback_data[2]

        db = ScheduleDB(config)

        row = db.get_group(group_id)
        user = db.find_user(cid)

        if user:
            db.update_user(cid, call.message.chat.first_name,
                           call.message.chat.username, str(row[0][1]))
        else:
            db.add_user(cid, call.message.chat.first_name,
                        call.message.chat.username, str(row[0][1]))

        bot.send_message(
            cid,
            "Отлично, вы зарегистрировались, ваша группа: " + row[0][0] +
            "\nЕсли вы ошиблись, то просто введиде команду /registration и измените данные",
            reply_markup=get_date_keyboard())
        bot.send_message(
            cid,
            "Теперь вы можете настроить автоматическую отправку расписания в заданное вами время,"
            " введя команду /auto_posting_on <время>, "
            "где <время> должно иметь формат ЧЧ:ММ")

    except BaseException as e:
        logger.warning('Registration problem: {0}'.format(str(e)))
        bot.send_message(
            cid,
            "Случилось что-то странное, попробуйте начать сначала, введя команду /registration"
        )
Пример #11
0
def create_schedule_text(tag, day, week_type):
    schedule = ""
    is_empty = True
    try:
        with ScheduleDB() as db:
            data = db.get_schedule(tag, day, week_type)

        schedule += "🔎 | {}: {}\n\n".format(
            helpers.daysOfWeek_rus[day], print_week_type(week_type))
        index = 0
        while index < len(data):
            is_empty = False
            row = data[index]

            title = ' '.join(str(row[1]).split())
            classroom = ' '.join(str(row[2]).split())

            schedule += '⏳ | {} пара: '.format(str(row[0]))
            # Этот блок нужен для вывода тех занятий, где занятия по числителю и знамнателю различаются
            if index != len(data) - 1:
                # Сравнивается порядковый номер занятия данной и следующей строки и если они равны,
                # то они выводятся вместе
                if data[index + 1][0] == row[0]:
                    schedule += '{0} {1} {2}\n'.format(title, classroom, print_type(row[3], week_type))

                    index += 1
                    row = data[index]
                    title = ' '.join(str(row[1]).split())
                    classroom = ' '.join(str(row[2]).split())

                    schedule += '&#12288;&#10;&#12288;' \
                                '&#12288;&#10;&#12288;' \
                                '&#12288;&#10;{0} {1} {2}\n\n'.format(title, classroom, print_type(row[3], week_type))
                else:
                    schedule += '{0} {1} {2}\n\n'.format(title, classroom, print_type(row[3], week_type))
            else:
                schedule += '{0} {1} {2}\n\n'.format(title, classroom, print_type(row[3], week_type))

            index += 1
        return schedule, is_empty
    except:
        return '', True
Пример #12
0
def callback_auto_posting(call):
    cid = call.message.chat.id

    try:
        callback_data = re.split(r':', call.data)

        # Проверка на соответствие введённых пользователем данных принятому формату
        if len(callback_data) != 4:
            bot.send_message(
                cid,
                "Вы отправили пустую строку или строку неправильного формата. Правильный формат ЧЧ:ММ",
                reply_markup=get_date_keyboard())
            return

        hour = ''.join(filter(lambda x: x.isdigit(), callback_data[1]))
        minutes = ''.join(filter(lambda x: x.isdigit(), callback_data[2]))
        is_today = callback_data[3]

        # Проверка на соответствие введённых пользователем данных принятому формату
        if not hour.isdigit() or not minutes.isdigit():
            bot.send_message(
                cid,
                "Вы отправили пустую строку или строку неправильного формата. Правильный формат ЧЧ:ММ",
                reply_markup=get_date_keyboard())
            return

        with ScheduleDB(config) as db:
            if db.set_auto_post_time(cid,
                                     (hour + ":" + minutes + ":" + "00").rjust(
                                         8, '0'), is_today):
                bot.send_message(cid,
                                 "Время установлено",
                                 reply_markup=get_date_keyboard())
            else:
                bot.send_message(
                    cid,
                    "Случилось что то странное, попробуйте ввести команду заново",
                    reply_markup=get_date_keyboard())
    except BaseException as e:
        logger.warning('callback_auto_posting: {0}'.format(str(e)))
        bot.send_message(
            cid, "Случилось что то странное, попробуйте ввести команду заново")
Пример #13
0
def callback_registration(call):
    cid = call.message.chat.id

    # Парсинг сообщения указывающего стадию регистрации
    # reg : stage : tag
    callback_data = re.split(r':', call.data)

    # Процедура регистрации проходит в четрые этапа:
    # 1 этап: выбор учебного заведения
    # 2 этап: выбор факультета <--
    # 3 этап: выбор группы
    # 4 этап: добавление данных о принадлежности пользователя к учебному заведению в БД
    try:
        # Статистика
        if config['STATISTIC_TOKEN'] != '':
            track(config['STATISTIC_TOKEN'], cid, 'stage 2',
                  'registration-stage-2')

        keyboard = types.InlineKeyboardMarkup()

        organization_id = callback_data[2]

        with ScheduleDB(config) as db:
            result = db.get_faculty(organization_id)

        for row in result:
            callback_button = types.InlineKeyboardButton(
                text=str(row[0]),
                callback_data="reg:stage 3:{0}".format(
                    str(row[1])[:organization_field_length +
                                faculty_field_length]))
            keyboard.add(callback_button)

        bot.send_message(cid, "Выберите факультет:", reply_markup=keyboard)
    except BaseException as e:
        logger.warning('Registration problem: {0}'.format(str(e)))
        bot.send_message(
            cid,
            "Случилось что-то странное, попробуйте начать сначала, введя команду /registration"
        )
Пример #14
0
def add_schedule():
    if not request.is_json:
        return "incorrect request", 403

    try:
        content = request.get_json()

        if content['key'] != config["TOKEN"]:
            return "invalid api key", 403

        data = content['data']

        answer = {'failed': []}
        with ScheduleDB(config) as db:
            for lecture in data:
                # Обязательные параметры запроса
                tag = lecture['tag']
                day = lecture['day']
                number = lecture['number']
                week_type = lecture['week_type']
                title = lecture['title']
                classroom = lecture['classroom']

                # Необязательные параметры
                time_start = lecture[
                    'time_start'] if 'time_start' in lecture else None
                time_end = lecture[
                    'time_end'] if 'time_end' in lecture else None
                lecturer = lecture[
                    'lecturer'] if 'lecturer' in lecture else None

                if not db.add_lesson(tag, day, number, week_type, time_start,
                                     time_end, title, classroom, lecturer):
                    answer['failed'].append(lecture)
        return jsonify(answer), 200
    except KeyError as e:
        return 'key not found: {}'.format(str(e)), 403
Пример #15
0
def response_msg(m):
    cid = m.chat.id
    if m.text in ScheduleType:
        # Статистика
        if config['STATISTIC_TOKEN'] != '':
            track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'schedule')
        else:
            logger.info('message: {0}'.format(m.text))

        # По умолчанию week_type равен -1 и при таком значении будут выводится все занятия,
        # т.е и для чётных и для нечётных недель
        week_type = -1

        if m.text == "Вся неделя":
            days = ScheduleType[m.text]
        elif m.text == "Сегодня":
            today = datetime.now()
            # Если запрашивается расписание на сегодняшний день,
            # то week_type равен остатку от деления на 2 номера недели в году, т.е он определяет чётная она или нечётная
            week_type = get_week_type(today)

            # Если сегодня воскресенье, то показывается расписание на понедельник следующей недели
            # Также в этом случае, как week_type используется тип следующей недели
            if datetime.weekday(today) == 6:
                today += timedelta(days=1)
                week_type = (week_type + 1) % 2

            days = [daysOfWeek[datetime.weekday(today)]]
        elif m.text == 'Завтра':
            tomorrow = datetime.now()
            tomorrow += timedelta(days=1)
            # Если запрашивается расписание на сегодняшний день,
            # то week_type равен остатку от деления на 2 номера недели в году, т.е он определяет чётная она или нечётная
            week_type = get_week_type(tomorrow)

            # Если сегодня воскресенье, то показывается расписание на понедельник следующей недели
            # Также в этом случае, как week_type используется тип следующей недели
            if datetime.weekday(tomorrow) == 6:
                tomorrow += timedelta(days=1)
                week_type = (week_type + 1) % 2

            days = [daysOfWeek[datetime.weekday(tomorrow)]]
        else:
            days = [ScheduleType[m.text]]

        for day in days:
            try:
                with ScheduleDB(config) as db:
                    user = db.find_user(cid)
                if user and user[0] is not None:
                    result = create_schedule_text(user[0], day, week_type)
                    for schedule in result:
                        bot.send_message(cid,
                                         schedule,
                                         reply_markup=get_date_keyboard())
                else:
                    bot.send_message(
                        cid,
                        "Вас ещё нет в базе данных, поэтому пройдите простую процедуру регистрации"
                    )
                    command_registration(m)
            except BaseException as e:
                logger.warning('response_msg: {0}'.format(str(e)))
                bot.send_message(
                    cid,
                    "Случилось что то странное, попробуйте ввести команду заново"
                )
    else:
        # Статистика
        if config['STATISTIC_TOKEN'] != '':
            track(config['STATISTIC_TOKEN'], m.chat.id, m.text, 'unknown')
        else:
            logger.info('unknown message: {0}'.format(m.text))

        bot.send_message(cid,
                         "Неизвестная команда",
                         reply_markup=get_date_keyboard())
Пример #16
0
class Schedule(CristelLog):
    # should be instance vars, not class vars
    # eit=None
    # sch=None

    def __init__(self,log=None):
        # super(Schedule,self).__init__()
        self.logg=log
        appdir=os.path.expanduser("~/.epgdb")
        eitdb=os.path.join(appdir,"database.db")
        scheddb=os.path.join(appdir,"cristel.db")
        self.debug("starting eit db at %s" % eitdb)
        self.eit=EITDatabase(eitdb,log)
        self.debug("starting scheddb at %s" % scheddb)
        self.sch=ScheduleDB(scheddb,log)
        self.debug("scheduler class started")

    def completeevent(self,event):
        self.debug("completing event: %s" % str(event))
        chan=self.sch.getchannel(event["source"])
        self.debug("channel: %s" % str(chan))
        try:
            event["cname"]=chan["name"]
            event["muxid"]=chan["muxid"]
            event["visible"]=chan["visible"]
            event["favourite"]=chan["favourite"]
            event["priority"]=chan["priority"]
            event["logicalid"]=chan["logicalid"]
            self.debug("event completed %s" % str(event))
            return event
        except (IndexError,TypeError):
            self.warn("No channel for source %s" % event["source"])
            return False

    def makeschedule(self):
        self.sch.dosearches()

    def getschedule(self):
        return self.sch.getschedule()
    
    def getnextschedule(self):
        return self.sch.getnextschedule()

    def getcurrentrecordings(self):
        return self.sch.getcurrentrecordings()

    def filldatabase(self):
        now=int(time.time())
        chans=self.sch.getvisiblechannels()
        cn=len(chans)
        self.debug("%d visible channels" % cn)
        for chan in chans:
            name=chan["name"]
            self.info("getting programmes for channel %s" % name)
            source=chan["source"]
            progs=self.eit.getchannelevents(source,now)
            cn=len(progs)
            self.info("%d programmes for channel %s" % (cn,name))
            inserted=0
            unchanged=0
            for prog in progs:
                prog["cname"]=chan["name"]
                prog["muxid"]=chan["muxid"]
                prog["visible"]=chan["visible"]
                prog["favourite"]=chan["favourite"]
                prog["priority"]=chan["priority"]
                prog["logicalid"]=chan["logicalid"]
                if self.sch.updateschedule(prog):
                    inserted=inserted+1
                else:
                    unchanged=unchanged+1
            self.info("{} new programmes inserted, {} unchanged for {}".format(inserted,unchanged,chan["name"]))
        n24=now-(24*60*60)
        self.sch.reapschedule(n24)
        self.makeschedule()
Пример #17
0
        }

sfn="/home/chris/.epgdb/cristel.db"
muxmove=0
sourcemove=0
newchan=0
unchanged=0

if not isdvbstreamerrunning():
    log.info("starting dvbstreamer")
    startdvbstreamer(1,"tvc","tvc")
    log.debug("giving dvbstreamer 5 seconds to start")
    time.sleep(5)

if isdvbstreamerrunning():
    sch=ScheduleDB(sfn,log)
    s=DvbSession("127.0.0.1",0,"tvc","tvc",log)
    for freq in freqs:
        s.scannet("T " + freq + " " + freqs[freq])

    lcns=s.logicalnames()
    log.info("updating channels")
    muxes=s.lsmuxes()
    for mux in muxes:
        log.debug("reading services for mux: " + mux)
        services=s.servicesformux(mux)
        cn=len(services)
        log.info("mux: %s has %s services" % (mux,cn))
        for svc in services:
            si=s.serviceinfo(svc)
            row=sch.getname(svc)
Пример #18
0
unchanged=0

log=logging.getLogger("cristel")

if __name__ == '__main__':
    log.setLevel(logging.DEBUG)
    handler=logging.handlers.SysLogHandler(address = '/dev/log', facility=logging.handlers.SysLogHandler.LOG_DAEMON)
    log.addHandler(handler)
    prog=os.path.basename(__file__)
    appdir=os.path.expanduser("~/.epgdb")
    sdbfn=os.path.join(appdir,"cristel.db")
    adapters=readadapters(appdir)
    startdvbstreamer(adapters)
    (ip,na,username,password) = adapters[0]
    s=DvbSession(host="%s" % ip, adaptor=na, username="******" % username, password="******" % password, logg=log)
    sdb=ScheduleDB(sdbfn,log)
    lcnames=s.logicalnames()
    services=s.lsservices()
    for svc in services:
        updatechannel=0
        si=s.serviceinfo(svc)
        row=sdb.getname(svc)
        cn=0
        try:
            cn=len(row)
        except:
            pass
        if cn>0:
            if si["ID"] == "233a.4083.4440":
                log.error("martian channel is: %s at %s, %s" % (si["Name"],si["ID"],si["Multiplex UID"]))
            if si["ID"] != row[0]:
Пример #19
0
else:
    log.debug("dvbstreamer is running")

if dvb.isdvbstreamerrunning():
    log.debug("starting session")
    s=DvbSession(host="%s" % ip, adaptor=na, username="******" % username, password="******" % password, logg=log)
    log.debug("reading logical channel numbers")
    lcn=s.logicalchannels()
    log.debug("closing session")
    s.close()
    tlcn=()
    for cn,name in lcn.iteritems():
        t=(int(cn),name)
        tlcn+=t,

    sdb=ScheduleDB(scheddb,log)
    log.debug("updating logical channel numbers")
    sdb.updatelogical(tlcn)

    log.debug("starting session")
    s=DvbSession(host="%s" % ip, adaptor=na, username="******" % username, password="******" % password, logg=log)
    log.debug("reading muxes")
    muxes=s.lsmuxes()
    tsvcs=()
    for mux in muxes:
        log.debug("reading services for mux: %s" % mux)
        svcs=s.servicesformux(mux)
        for svc in svcs:
            t=(mux,svc)
            tsvcs+=t,