Last active
April 3, 2025 18:18
-
-
Save bkbilly/3f824ee42e72b95ce9addcbc1f81f3e0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| ''' This application returns the the remaining minutes in the asterisk format | |
| ex: the 326 minutes are returned as 300 20 6''' | |
| import csv | |
| import re | |
| import datetime | |
| import logging | |
| import sys | |
| import click | |
| logging.basicConfig( | |
| format='%(asctime)s - %(levelname)s - %(message)s', | |
| level=logging.WARNING | |
| ) | |
| class AsteriskShowLimit(): | |
| def __init__(self, sipFilter='vodafone', freeTime=18000, startDay=1, extraTime=15, cliMatch="69[0-9]+"): | |
| self.totalFreeTime = freeTime # Free seconds given by provider | |
| self.startDay = startDay # The Month Day that starts counting from | |
| self.extraTime = extraTime # Extra time to compensate the lack of answer detection | |
| self.cliMatch = cliMatch # Filters only for mobiles | |
| self.sipFilter = sipFilter # Filters the sip that is calling | |
| self.countDuration = self.getCurrentDuration() | |
| self.remainingTime = self.getRemainingTime() | |
| asteriskPrint = self.getAsteriskPrint() | |
| print(asteriskPrint) | |
| def getStartDateTime(self): | |
| # Current Date | |
| nowDay = datetime.datetime.now().day | |
| nowMonth = datetime.datetime.now().month | |
| nowYear = datetime.datetime.now().year | |
| if nowMonth != 1: | |
| if datetime.datetime(nowYear, nowMonth, self.startDay) <= datetime.datetime.now(): | |
| startDatetime = datetime.datetime(nowYear, nowMonth, self.startDay) | |
| elif datetime.datetime(nowYear, nowMonth-1, self.startDay) <= datetime.datetime.now(): | |
| startDatetime = datetime.datetime(nowYear, nowMonth-1, self.startDay) | |
| else: | |
| if datetime.datetime(nowYear, nowMonth, self.startDay) <= datetime.datetime.now(): | |
| startDatetime = datetime.datetime(nowYear, nowMonth, self.startDay) | |
| elif datetime.datetime(nowYear-1, 12, self.startDay) <= datetime.datetime.now(): | |
| startDatetime = datetime.datetime(nowYear-1, 12, self.startDay) | |
| return startDatetime | |
| def getCurrentDuration(self): | |
| # Read the csv log of asterisk into a list of lists | |
| with open('/var/log/asterisk/cdr-csv/Master.csv', 'r') as f: | |
| reader = csv.reader(f) | |
| asteriskLog = list(reader) | |
| asteriskLog.reverse() # Read log botton up | |
| countDuration = 0 | |
| for callLog in asteriskLog: | |
| log_from = callLog[1] | |
| log_to = callLog[2] | |
| dialplan = callLog[3] | |
| log_duration = int(callLog[13]) | |
| sip = re.findall(r".*\/(.*)-.*", callLog[6]) | |
| if len(sip) == 1: | |
| sip = sip[0] | |
| # Calculate the duration | |
| if log_duration > self.extraTime: | |
| log_duration -= self.extraTime | |
| log_date = datetime.datetime.strptime(callLog[9], '%Y-%m-%d %H:%M:%S') | |
| # Read until the specified date | |
| if log_date < self.getStartDateTime(): | |
| break | |
| # Calculate on specified phone number | |
| if sip == self.sipFilter and log_duration > 0 and re.match(self.cliMatch, log_to): | |
| logging.info(callLog) | |
| logging.info('dialplan: %s' % (dialplan)) | |
| logging.info('sip: %s' % (sip)) | |
| logging.info('countDuration: %s' % (countDuration)) | |
| if (log_duration % 60) == 0: | |
| logging.info('log_duration: %s' % (log_duration)) | |
| countDuration += log_duration | |
| else: | |
| logging.info('log_duration: %s' % (log_duration - (log_duration % 60) + 60)) | |
| countDuration += log_duration - (log_duration % 60) + 60 | |
| return countDuration | |
| def getRemainingTime(self): | |
| # Charge per minute | |
| remainingTime = (self.totalFreeTime - self.countDuration)/60 | |
| if remainingTime < 0: | |
| remainingTime = 0 | |
| return remainingTime | |
| # For asterisk to read each number | |
| def calcDec(self, dectime): | |
| numCategory = 10 | |
| while True: | |
| if (dectime // numCategory) == 0: | |
| numCategory = int(numCategory / 10) | |
| break | |
| else: | |
| numCategory = numCategory * 10 | |
| if dectime >= numCategory and dectime > 20: | |
| return 'digits/' + str((dectime // numCategory) * numCategory) + " " + str(self.calcDec(dectime % numCategory)) | |
| else: | |
| return 'digits/' + str(dectime) | |
| def getAsteriskPrint(self): | |
| asteriskRemaining = self.calcDec(int(str(self.remainingTime).split('.')[0])) | |
| if self.remainingTime > 0: | |
| asteriskPrint = '&'.join(('prepaid-you-have', asteriskRemaining, 'minutes')).replace(' ', '&') | |
| else: | |
| asteriskPrint = 'prepaid-zero-balance' | |
| return asteriskPrint | |
| # Constants for DialPlan | |
| #try: | |
| # # Read the freeminutes from a text file every day. This requres | |
| # # an other application to write everyday the free minutes to a | |
| # # file "freemin.txt" and start counting only for today's minutes. | |
| # with open('freemin.txt', 'r') as f: | |
| # result_from_nova = int(f.readline()) * 60 | |
| # totalFreeTime = result_from_nova #Free seconds given by provider | |
| # startDay = nowDay # The Month Day that starts counting from | |
| @click.command() | |
| @click.option('--sipfilter', default='vodafone', help='The SIP to filter') | |
| @click.option('--freetime', default=18000, help='The free time provided by the provider') | |
| @click.option('--startday', default=1, help='Start of the billing cycle') | |
| @click.option('--extratime', default=15, help='Extra time to compensate the lack of answer detection') | |
| @click.option('--climatch', default="69[0-9]+", help='The CLI to filter (RegExpr)') | |
| def main(sipfilter, freetime, startday, extratime, climatch): | |
| """ Shows the remaining time based on the Master.csv file of Asterisk """ | |
| AsteriskShowLimit(sipFilter=sipfilter, freeTime=freetime, startDay=startday, extraTime=extratime, cliMatch=climatch) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment