コード例 #1
0
 def testDateTimeComponentsToArrowLocalDate(self):
     zhArrowDateTimeObj_begOfDay = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
         30, 9, 2017, 2, 0, 0, 'Europe/Zurich')
     self.assertEqual(1506729600, zhArrowDateTimeObj_begOfDay.timestamp())
     self.assertEqual(
         "2017/09/30 02:00:00 +02:00",
         zhArrowDateTimeObj_begOfDay.format(US_DATE_TIME_FORMAT_TZ_ARROW))
コード例 #2
0
    def testExecuteHistoricalPriceNoYear(self):
        testDayStr = '1'
        testMonthStr = '1'
        testHourStr = '01'
        testMinuteStr = '15'
        testTimeZoneStr = 'Europe/Zurich'

        self.commandPrice.parsedParmData[self.commandPrice.CRYPTO] = 'btc'
        self.commandPrice.parsedParmData[self.commandPrice.FIAT] = 'usd'
        self.commandPrice.parsedParmData[
            self.commandPrice.EXCHANGE] = 'bittrex'
        self.commandPrice.parsedParmData[self.commandPrice.DAY] = testDayStr
        self.commandPrice.parsedParmData[
            self.commandPrice.MONTH] = testMonthStr
        #self.commandPrice.parsedParmData[self.commandPrice.YEAR] = '2017'
        self.commandPrice.parsedParmData[self.commandPrice.HOUR] = testHourStr
        self.commandPrice.parsedParmData[
            self.commandPrice.MINUTE] = testMinuteStr

        resultData = self.commandPrice.execute()

        now = DateTimeUtil.localNow(testTimeZoneStr)
        fourDigitYear = now.year
        nowYear = fourDigitYear - 2000
        nowYearStr = str(nowYear)

        testDateTime = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
            int(testDayStr), int(testMonthStr), fourDigitYear,
            int(testHourStr), int(testMinuteStr), 0, testTimeZoneStr)

        self.assertEqual(resultData.getValue(resultData.RESULT_KEY_ERROR_MSG),
                         None)
        self.assertEqual(resultData.getValue(resultData.RESULT_KEY_CRYPTO),
                         'BTC')
        self.assertEqual(resultData.getValue(resultData.RESULT_KEY_FIAT),
                         'USD')
        self.assertEqual(resultData.getValue(resultData.RESULT_KEY_EXCHANGE),
                         'BitTrex')

        if DateTimeUtil.isDateOlderThan(testDateTime, 7):
            self.assertEqual(
                resultData.getValue(resultData.RESULT_KEY_PRICE_TYPE),
                resultData.PRICE_TYPE_HISTO_DAY)
            self.assertEqual(
                resultData.getValue(
                    resultData.RESULT_KEY_PRICE_DATE_TIME_STRING),
                '01/01/{} 00:00'.format(nowYearStr))
        else:
            self.assertEqual(
                resultData.getValue(resultData.RESULT_KEY_PRICE_TYPE),
                resultData.PRICE_TYPE_HISTO_MINUTE)
            self.assertEqual(
                resultData.getValue(
                    resultData.RESULT_KEY_PRICE_DATE_TIME_STRING),
                '01/01/{} {}:{}'.format(nowYearStr, testHourStr,
                                        testMinuteStr))
コード例 #3
0
    def _buildFullDateAndTimeStrings(self, commandDic, timezoneStr):
        '''
        This method ensures that the full command string is unified whatever the completness of the
        dated/time components specified in the request by the user.

        Ex: btc usd 1/1 bitfinex or btc usd 1/01/18 bitfinex or btc usd 1/1 12:23 bitfinex all return
            a full commaand of btc usd 01/01/18 00:00 bitfinex, btc usd 01/01/18 12:23 bitfinex
            respectively.

        This is important since the ful command string is what is stored in the command history list, with
        no duplicates. Otherwxise, btc usd 1/1 00:00 bitfinex and btc usd 01/01/18 00:00 bitfinex would
        be stored as 2 entries !

        :param commandDic:
        :param timezoneStr:
        :seqdiag_return requestDateDMY, requestDateHM
        :return:
        '''
        dayInt = int(commandDic[CommandPrice.DAY])
        monthInt = int(commandDic[CommandPrice.MONTH])
        year = commandDic[CommandPrice.YEAR]

        if year == None:
            now = DateTimeUtil.localNow(timezoneStr)
            yearInt = now.year
        else:
            yearInt = int(year)

        hour = commandDic[CommandPrice.HOUR]
        minute = commandDic[CommandPrice.MINUTE]

        if hour != None and minute != None:
            # hour can not exist without minute and vice versa !
            hourInt = int(hour)
            minuteInt = int(minute)
        else:
            hourInt = 0
            minuteInt = 0

        requestArrowDate = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
            dayInt, monthInt, yearInt, hourInt, minuteInt, 0, timezoneStr)
        dateTimeComponentSymbolList, separatorsList, dateTimeComponentValueList = DateTimeUtil.getFormattedDateTimeComponents(
            requestArrowDate, self.configurationMgr.dateTimeFormat)
        dateSeparator = separatorsList[0]
        timeSeparator = separatorsList[1]
        requestDateDMY = dateTimeComponentValueList[0] + dateSeparator + dateTimeComponentValueList[1] + dateSeparator + \
                         dateTimeComponentValueList[2]
        requestDateHM = dateTimeComponentValueList[
            3] + timeSeparator + dateTimeComponentValueList[4]

        from seqdiagbuilder import SeqDiagBuilder
        SeqDiagBuilder.recordFlow()

        return requestDateDMY, requestDateHM
コード例 #4
0
ファイル: commandprice.py プロジェクト: ychaim/cryptopricer
    def execute(self):
        '''

        :seqdiag_return ResultData or False
        :return:
        '''
        resultPriceOrBoolean = self._validateMandatoryData()

        if resultPriceOrBoolean != True:
            return resultPriceOrBoolean

        localTimezone = self.configManager.localTimeZone
        localNow = DateTimeUtil.localNow(localTimezone)

        resultPriceOrBoolean = self._validateDateTimeData(localNow)

        if resultPriceOrBoolean != True:
            return resultPriceOrBoolean

        cryptoUpper = self.parsedParmData[self.CRYPTO].upper()
        fiatUpper = self.parsedParmData[self.FIAT].upper()
        exchange = self.parsedParmData[self.EXCHANGE]

        dayStr = self.parsedParmData[self.DAY]

        if dayStr != None:
            day = int(dayStr)
        else:
            day = 0

        monthStr = self.parsedParmData[self.MONTH]

        if monthStr != None:
            month = int(monthStr)
        else:
            month = localNow.month

        yearStr = self.parsedParmData[self.YEAR]

        if yearStr != None:
            if len(yearStr) == 2:
                year = 2000 + int(yearStr)
            elif len(yearStr) == 4:
                year = int(yearStr)
            elif yearStr == '0':  # user entered -d0 !
                year = 0
        else:
            year = localNow.year

        hourStr = self.parsedParmData[self.HOUR]

        if hourStr != None:
            hour = int(hourStr)
        else:
            hour = 0

        minuteStr = self.parsedParmData[self.MINUTE]

        if minuteStr != None:
            minute = int(minuteStr)
        else:
            minute = 0

        #storing the parsed parm gata dicèionary before it
        #may be modified in case the user requested a RT
        #price. The initial dictionary wiLl be added to the
        #returned resultData so the client can have access
        #to the full command request, even if only a partial
        #request like -d or -c was entered. This is necessary
        #bcecause if the client is a GUI, it stores the list
        #of requests in order to be able to replay them !
        initialParsedParmDataDic = self.parsedParmData.copy()

        wasDateInFutureSetToLastYear = False
        localRequestDateTime = None

        if day + month + year == 0:
            # asking for RT price here. Current date is stored in parsed parm data for possible
            # use in next request
            self._storeDateTimeDataForNextPartialRequest(localNow)
        else:
            try:
                localRequestDateTime = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
                    day, month, year, hour, minute, 0, localTimezone)
            except ValueError as e:
                # is the when the user specify only the day if he enters 31 and the current month
                # has no 31st or if he enters 30 or 29 and we are on February
                result = ResultData()
                result.setValue(
                    ResultData.RESULT_KEY_ERROR_MSG,
                    "ERROR - {}: day {}, month {}".format(str(e), day, month))
                return result

            if DateTimeUtil.isAfter(localRequestDateTime, localNow):
                # request date is in the future ---> invalid. This happens for example in case
                # btc usd 31/12 bittrex entered sometime before 31/12. Then the request year is
                # forced to last year and a warning will be displayed.
                year = localNow.year - 1
                wasDateInFutureSetToLastYear = True

        priceValueSymbol = self.parsedParmData[self.PRICE_VALUE_SYMBOL]
        priceValueAmount = self.parsedParmData[self.PRICE_VALUE_AMOUNT]

        if priceValueSymbol:
            priceValueSymbol = priceValueSymbol.upper()

        if priceValueAmount:
            priceValueAmount = float(priceValueAmount)

        priceValueSaveFlag = self.parsedParmData[self.PRICE_VALUE_SAVE]
        result = self.receiver.getCryptoPrice(cryptoUpper, fiatUpper, exchange,
                                              day, month, year, hour, minute,
                                              priceValueSymbol,
                                              priceValueAmount,
                                              priceValueSaveFlag,
                                              self.requestInputString)

        #the command components	denoting the user request will be used to recreate
        #a full command request which will be stored in the command history list.
        #The historry list can be replayed, stored on disk, edited ...
        result.setValue(ResultData.RESULT_KEY_INITIAL_COMMAND_PARMS,
                        initialParsedParmDataDic)

        result.setValue(ResultData.RESULT_KEY_PRICE_VALUE_SAVE,
                        priceValueSaveFlag)

        if wasDateInFutureSetToLastYear:
            result.setWarning(
                ResultData.WARNING_TYPE_FUTURE_DATE,
                "Warning - request date {} can not be in the future and was shifted back to last year"
                .format(
                    localRequestDateTime.format(
                        self.configManager.dateTimeFormat)))

        unsupportedCommand = self.parsedParmData[self.UNSUPPORTED_COMMAND]

        if unsupportedCommand:
            result.setWarning(
                ResultData.WARNING_TYPE_UNSUPPORTED_COMMAND,
                "Warning - unsupported command {}{} in request {}".format(
                    unsupportedCommand,
                    self.parsedParmData[self.UNSUPPORTED_COMMAND_DATA],
                    self.requestInputString))

        return result
コード例 #5
0
ファイル: commandprice.py プロジェクト: ychaim/cryptopricer
    def _validateDateTimeData(self, localNow):
        '''
        Ensures that date/time info contained in the parsedParmData dic are valid and in
        a right format. If everything is ok, returns True.

        ['1', '10', '0', '2', '58'] #btc usd 1/10/0 2:58
        [None, None, None, '2', '57'] # btc usd 1 2:57
        ['11', '10', None, None, None] # neo btc 11/10
        :param localNow:
        :return: True if date/time values stored in the parsedParmData dic are valid. If an
                 error was detected, a new ResultData with a meaningfull error msg is
                 returned.
        '''

        dtFormatDic = DateTimeUtil.getDateAndTimeFormatDictionary(
            self.configManager.dateTimeFormat)

        dateShortFormat = dtFormatDic[DateTimeUtil.SHORT_DATE_FORMAT_KEY]
        dateLongFormat = dtFormatDic[DateTimeUtil.LONG_DATE_FORMAT_KEY]
        timeFormat = dtFormatDic[DateTimeUtil.TIME_FORMAT_KEY]

        resultData = True

        dayStr = self.parsedParmData[self.DAY]
        monthStr = self.parsedParmData[self.MONTH]
        yearStr = self.parsedParmData[self.YEAR]
        hourStr = self.parsedParmData[self.HOUR]
        minuteStr = self.parsedParmData[self.MINUTE]

        if (yearStr == '0' and monthStr == '0' and dayStr == '0'):
            # RT price asked
            return True
        else:
            # Here, the three date components are not all equal to 0 !
            if (yearStr == None and monthStr == None and dayStr == None
                    and hourStr != None and minuteStr != None):
                # Here, only time was specified in the full request, which is now possible.
                # Current day, month and year are fornatted into the parsed parm data
                # and True is returned
                self.parsedParmData[self.DAY] = localNow.format('DD')
                self.parsedParmData[self.MONTH] = localNow.format('MM')
                self.parsedParmData[self.YEAR] = localNow.format('YYYY')
                return True
            elif (yearStr == None and monthStr == None and dayStr != None
                  and hourStr != None and minuteStr != None):
                # Here, only day and time were specified in the full request, which is now possible.
                # Current month and year are fornatted into the parsed parm data
                # and True is returned
                self.parsedParmData[self.MONTH] = localNow.format('MM')
                self.parsedParmData[self.YEAR] = localNow.format('YYYY')
                return True
            elif (yearStr == '0' or
                  # yearStr is None when only day/month specified -> valid !
                  monthStr == '0' or monthStr == None or dayStr == '0'
                  or dayStr == None):
                # only when user enters -d0 for RT price,
                # is yearStr equal to '0' since 0 is put
                # by Requesèer into day, month and year !
                resultData = ResultData()
                resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG,
                                    "ERROR - date not valid")
                return resultData
            elif len(monthStr) > 2:
                resultData = ResultData()
                resultData.setValue(
                    ResultData.RESULT_KEY_ERROR_MSG,
                    "ERROR - {} not conform to accepted month format (MM or M)"
                    .format(monthStr))
                return resultData
            elif yearStr != None:
                yearStrLen = len(yearStr)
                if yearStrLen != 2 and yearStrLen != 4:
                    resultData = ResultData()
                    resultData.setValue(
                        ResultData.RESULT_KEY_ERROR_MSG,
                        "ERROR - {} not conform to accepted year format (YYYY, YY or '')"
                        .format(yearStr))

                    # avoiding that invalid year will pollute next price requests
                    self.parsedParmData[self.YEAR] = None
                    return resultData

            # validating full date. Catch inval day or inval month,
            # like day == 123 or day == 32 or month == 31
            if yearStr == None:
                yearStr = str(localNow.year)

            if hourStr == None:
                hourStr = str(localNow.hour)

            if minuteStr == None:
                minuteStr = str(localNow.minute)

            dateTimeTupleList = [('day', dayStr, dateShortFormat),
                                 ('month', monthStr, dateShortFormat),
                                 ('year', yearStr, dateLongFormat),
                                 ('hour', hourStr, timeFormat),
                                 ('minute', minuteStr, timeFormat)]

            try:
                for name, value, format in dateTimeTupleList:
                    int(value)
            except ValueError as e:
                resultData = ResultData()
                resultData.setValue(
                    ResultData.RESULT_KEY_ERROR_MSG,
                    "ERROR - invalid value: {} violates format for {} ({})".
                    format(value, name, format))
                return resultData

            try:
                date = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
                    int(dayStr), int(monthStr), int(yearStr), int(hourStr),
                    int(minuteStr), 0, self.configManager.localTimeZone)
            except ValueError as e:
                resultData = ResultData()
                resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG,
                                    "ERROR - " + str(e))

        return resultData
コード例 #6
0
    def _handleDateTimeRequestParms(self):
        '''
		Complete missing request date elements with current date values and validate
		request date and time elements format. Then converts or computes date and time
		elements to int.
		
		In case the resulting date is in the future, its year is reduced by one and
		the returned localRequestDateTime is not None !
		
		:return: day, month, year, hour, minute
				 localRequestDateTime None, except if the (effective or completed)
									  request date is in the future
				 resultPriceOrBoolean
		'''
        day = None
        month = None
        year = None
        hour = None
        minute = None
        localRequestDateTime = None

        localTimezone = self.configManager.localTimeZone
        localNow = DateTimeUtil.localNow(localTimezone)

        resultPriceOrBoolean = self._completeAndValidateDateTimeData(localNow)

        # storing the parsed parm data dictionary before it
        # may be modified in case the user requested a RT
        # price. The initial dictionary wiLl be added to the
        # returned resultData so the client can have access
        # to the full command request, even if only a partial
        # request like -d or -c was entered. This is necessary
        # because if the client is a GUI, it stores the list
        # of requests in order to be able to replay them !
        initialParsedParmDataDic = self.parsedParmData.copy()

        if resultPriceOrBoolean == True:
            dayStr = self.parsedParmData[self.DAY]
            day = int(dayStr)

            monthStr = self.parsedParmData[self.MONTH]

            if monthStr != None:
                month = int(monthStr)
            else:
                month = localNow.month

            yearStr = self.parsedParmData[self.YEAR]

            if yearStr != None:
                if len(yearStr) == 2:
                    year = 2000 + int(yearStr)
                elif len(yearStr) == 4:
                    year = int(yearStr)
                elif yearStr == '0':  # user entered -d0 !
                    year = 0
            else:
                year = localNow.year

            hourStr = self.parsedParmData[self.HOUR]

            if hourStr != None:
                hour = int(hourStr)
            else:
                hour = 0

            minuteStr = self.parsedParmData[self.MINUTE]

            if minuteStr != None:
                minute = int(minuteStr)
            else:
                minute = 0

            localRequestDateTime = None

            if day + month + year == 0:
                # asking for RT price here. Current date is stored in parsed parm data for possible
                # use in next request
                self._storeDateTimeDataForNextPartialRequest(localNow)
            else:
                try:
                    localRequestDateTime = DateTimeUtil.dateTimeComponentsToArrowLocalDate(
                        day, month, year, hour, minute, 0, localTimezone)
                except ValueError as e:
                    # is the case when the user specify only the day if he enters 31 and the current month
                    # has no 31st or if he enters 30 or 29 and we are on February
                    resultPriceOrBoolean = ResultData()
                    resultPriceOrBoolean.setError(
                        "ERROR - {}: day {}, month {}.".format(
                            str(e), day, month))

                if resultPriceOrBoolean == True:
                    if DateTimeUtil.isAfter(localRequestDateTime, localNow):
                        # request date is in the future ---> invalid. This happens for example in case
                        # btc usd 31/12 bittrex entered sometime before 31/12. Then the request year is
                        # forced to last year and a warning will be displayed.
                        year = localNow.year - 1
                    else:
                        localRequestDateTime = None

        return day, month, year, hour, minute, localRequestDateTime, resultPriceOrBoolean, initialParsedParmDataDic