def log_time(self, delta=None, billable=True, project=None, start=None, end=None, status=None, pause=0, activity=None, user=None): if not user: user = self.user if delta and not end: hours, minutes = delta else: hours = 4 minutes = 0 if not start: start = timezone.now() - relativedelta(hour=0) # In case the default would fall off the end of the billing period if start.day >= 28: start -= relativedelta(days=1) if not end: end = start + relativedelta(hours=hours, minutes=minutes) data = {'user': user, 'start_time': start, 'end_time': end, 'seconds_paused': pause, } if project: data['project'] = project else: data['project'] = factories.BillableProject() if activity: data['activity'] = activity else: if billable: data['activity'] = self.devl_activity else: data['activity'] = self.activity if status: data['status'] = status return factories.Entry(**data)
def testFindEntries(self): """ Given a list of users and a starting point, entries should generate a list of all entries for each user from that time until now. """ start = check_entries.Command().find_start() if start.day == 1: start += relativedelta(days=1) all_users = check_entries.Command().find_users() entries = check_entries.Command().find_entries(all_users, start) # Determine the number of days checked today = timezone.now() - \ relativedelta(hour=0, minute=0, second=0, microsecond=0) diff = today - start days_checked = diff.days total_entries = 0 while True: try: user_entries = next(entries) for entry in user_entries: total_entries += 1 except StopIteration: # Verify that every entry from the start point was returned expected_total = days_checked * len(self.all_users) self.assertEqual(total_entries, expected_total) return
def test_due_not_pending(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today+relativedelta(days=-1), amount=Decimal('1'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) ObjectPaymentPlanInstalmentFactory( due=today+relativedelta(days=-2), state=CheckoutState.objects.fail, amount=Decimal('2'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) ObjectPaymentPlanInstalmentFactory( due=today+relativedelta(days=-3), amount=Decimal('3'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal('1'), Decimal('3')] == result
def get_date(self, line, date): value = None if line.delay in ('net_days', 'end_month'): value = date + relativedelta(days=line.days) if line.delay == 'end_month': value += relativedelta(day=31) return value
def setUp(self): super(CheckEntries, self).setUp() self.user = factories.User() self.user2 = factories.User() self.superuser = factories.Superuser() self.project = factories.Project( type__enable_timetracking=True, status__enable_timetracking=True, point_person=self.user) self.default_data = { 'user': self.user, 'project': self.project, 'seconds_paused': 0, 'status': Entry.VERIFIED, } self.good_start = timezone.now() - relativedelta(days=0, hours=8) self.good_end = timezone.now() - relativedelta(days=0) self.bad_start = timezone.now() - relativedelta(days=1, hours=8) self.bad_end = timezone.now() - relativedelta(days=1) # Create users for the test self.user.first_name = 'first1' self.user.last_name = 'last1' self.user.save() self.user2.first_name = 'first2' self.user2.last_name = 'last2' self.user2.save() self.all_users = [self.user, self.user2, self.superuser] # Create a valid entry for all users on every day since 60 days ago self.make_entry_bulk(self.all_users, 60)
def get_datetime_at_period_ix(self, ix): """ Get the datetime at a given period. :param period: The index of the period. :returns: The datetime. """ if self.timestep_period_duration == TimePeriod.millisecond: return self.start_datetime + timedelta(milliseconds=ix) elif self.timestep_period_duration == TimePeriod.second: return self.start_datetime + timedelta(seconds=ix) elif self.timestep_period_duration == TimePeriod.minute: return self.start_datetime + timedelta(minutes=ix) elif self.timestep_period_duration == TimePeriod.hour: return self.start_datetime + timedelta(hours=ix) elif self.timestep_period_duration == TimePeriod.day: return self.start_datetime + relativedelta(days=ix) elif self.timestep_period_duration == TimePeriod.week: return self.start_datetime + relativedelta(days=ix*7) elif self.timestep_period_duration == TimePeriod.month: return self.start_datetime + relativedelta(months=ix) elif self.timestep_period_duration == TimePeriod.year: return self.start_datetime + relativedelta(years=ix)
def test_due_plan_deposit(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today+relativedelta(days=-1), amount=Decimal('1'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) ObjectPaymentPlanInstalmentFactory( deposit=True, due=today+relativedelta(days=-2), amount=Decimal('2'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) ObjectPaymentPlanInstalmentFactory( due=today+relativedelta(days=-3), amount=Decimal('3'), object_payment_plan=ObjectPaymentPlanFactory( content_object=ContactFactory(), ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal('1'), Decimal('3')] == result
def create_period(cls, fiscalyears, interval=1): ''' Create periods for the fiscal years with month interval ''' Period = Pool().get('account.period') to_create = [] for fiscalyear in fiscalyears: period_start_date = fiscalyear.start_date while period_start_date < fiscalyear.end_date: period_end_date = period_start_date + \ relativedelta(months=interval - 1) + \ relativedelta(day=31) if period_end_date > fiscalyear.end_date: period_end_date = fiscalyear.end_date name = datetime_strftime(period_start_date, '%Y-%m') if name != datetime_strftime(period_end_date, '%Y-%m'): name += ' - ' + datetime_strftime(period_end_date, '%Y-%m') to_create.append({ 'name': name, 'start_date': period_start_date, 'end_date': period_end_date, 'fiscalyear': fiscalyear.id, 'type': 'standard', }) period_start_date = period_end_date + relativedelta(days=1) if to_create: Period.create(to_create)
def init(self, cr, uid=1): """ This view will be used in dashboard The reason writing this code here is, we need to check date range from today to first date of fiscal year. """ pool_obj_fy = self.pool['account.fiscalyear'] today = time.strftime('%Y-%m-%d') fy_id = pool_obj_fy.find(cr, uid, exception=False) LIST_RANGES = [] if fy_id: fy_start_date = pool_obj_fy.read(cr, uid, fy_id, ['date_start'])['date_start'] fy_start_date = datetime.strptime(fy_start_date, '%Y-%m-%d') last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1) while (last_month_date > fy_start_date): LIST_RANGES.append(today + " to " + last_month_date.strftime('%Y-%m-%d')) today = (last_month_date- relativedelta(days=1)).strftime('%Y-%m-%d') last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1) LIST_RANGES.append(today +" to " + fy_start_date.strftime('%Y-%m-%d')) cr.execute('delete from temp_range') for range in LIST_RANGES: self.pool['temp.range'].create(cr, uid, {'name':range}) cr.execute(""" create or replace view report_aged_receivable as ( select id,name from temp_range )""")
def get_interval(self): today = self.get_today_date() weekday = get_weekday_start() start = today + relativedelta(weekday=weekday(-1)) end = start + relativedelta(days=+6) return start, end
def periods_in_range(self, months_per, start, end): one_day = datetime.timedelta(days=1) ends = [] cur_start = start.replace(day=1) # in edge cases (all sids filtered out, start/end are adjacent) # a test will not generate any returns data if len(self.algorithm_returns) == 0: return ends # ensure that we have an end at the end of a calendar month, in case # the return series ends mid-month... the_end = end.replace(day=1) + relativedelta(months=1) - one_day while True: cur_end = cur_start + relativedelta(months=months_per) - one_day if(cur_end > the_end): break cur_period_metrics = RiskMetricsPeriod( start_date=cur_start, end_date=cur_end, returns=self.algorithm_returns, benchmark_returns=self.benchmark_returns ) ends.append(cur_period_metrics) cur_start = cur_start + relativedelta(months=1) return ends
def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, date_begin, context=None): """ Generic method to generate data for bar chart values using SparklineBarWidget. This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field). :param obj: the target model (i.e. crm_lead) :param domain: the domain applied to the read_group :param list read_fields: the list of fields to read in the read_group :param str value_field: the field used to compute the value of the bar slice :param str groupby_field: the fields used to group :return list section_result: a list of dicts: [ { 'value': (int) bar_column_value, 'tootip': (str) bar_column_tooltip, } ] """ date_begin = date_begin.date() section_result = [{'value': 0, 'tooltip': ustr((date_begin + relativedelta.relativedelta(days=i)).strftime('%d %B %Y')), } for i in range(0, self._period_number)] group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) field = obj._fields.get(groupby_field.split(':')[0]) pattern = tools.DEFAULT_SERVER_DATE_FORMAT if field.type == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT for group in group_obj: group_begin_date = datetime.strptime(group['__domain'][0][2], pattern).date() timedelta = relativedelta.relativedelta(group_begin_date, date_begin) section_result[timedelta.days] = {'value': group.get(value_field, 0), 'tooltip': group.get(groupby_field)} return section_result
def archive_month(year, month): calendar_start_month = datetime.date(CALENDAR_START.year, CALENDAR_START.month, 1) first_month_redir = redirect(url_for('archive_month', year=CALENDAR_START.year, month=CALENDAR_START.month)) if year == 0 or month == 0: return first_month_redir date = datetime.date(year, month, 1) if date < calendar_start_month: return first_month_redir today = datetime.datetime.utcnow().date() if date > today: return redirect(url_for('archive_month', year=today.year, month=today.month)) cal = calendar.Calendar() days = list(cal.itermonthdays2(date.year, date.month)) prev = date - relativedelta(months=1) next = date + relativedelta(months=1) prev_disabled = prev < calendar_start_month next_disabled = next > today return render_template('pages/archive_month.html', date=date, days=days, prev=prev, prev_disabled=prev_disabled, next=next, next_disabled=next_disabled, today=today)
def eventsJson(request): month_start = datetime.datetime(timezone.now().year, timezone.now().month, 1, 0) next_month = month_start+relativedelta(months=+1) month_end = next_month+relativedelta(seconds=-1) data = serializers.serialize("json", Event.objects.all()) return HttpResponse(data, content_type="text/plain")
def create_invoices(self, cr, uid, ids, context=None): sale_obj = self.pool.get('sale.order') wizard = self.browse(cr, uid, ids[0], context) sale_ids = context.get('active_ids', []) invoice_obj = self.pool.get('account.invoice') if wizard.advance_payment_method == 'multiple': if len(sale_ids) > 1: raise Warning(_('Can not use multiple invoices in multiple sales orders at once!')) if sale_obj.browse(cr, uid, sale_ids[0], context=context).invoice_ids: raise Warning(_('This sale order has already some invoices created!')) inv_ids = [] for invoice_count in range(wizard.invoice_qty - 1): for sale_id, inv_values in self._prepare_advance_invoice_vals(cr, uid, ids, context=context): first_invoice_date = datetime.strptime(wizard.first_invoice_date, DEFAULT_SERVER_DATE_FORMAT) invoice_date = (first_invoice_date + relativedelta.relativedelta(months=invoice_count)).strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_id = self._create_invoices(cr, uid, inv_values, sale_id, context=context) invoice_obj.write(cr, uid, invoice_id, {'date_invoice':invoice_date}, context=context) inv_ids.append(invoice_id) # create the final invoices of the active sales orders invoice_date = (first_invoice_date + relativedelta.relativedelta(months=wizard.invoice_qty-1)).strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_id = sale_obj.manual_invoice(cr, uid, sale_ids, context).get('res_id',False) invoice_obj.write(cr, uid, invoice_id, {'date_invoice':invoice_date}, context=context) if context.get('open_invoices', False): return sale_obj.action_view_invoice(cr, uid, sale_ids, context=context) return {'type': 'ir.actions.act_window_close'} return super(sale_advance_payment_inv, self).create_invoices(cr, uid, ids, context=context)
def output(date, file_path, bias, cid, name, stock_id, zone, yr): s_end_date = date - relativedelta(days=bias) s_start_date = date - relativedelta(years=yr) fmt = "%b" s_end_date_month_f = s_end_date.strftime(fmt) s_start_date_month_f = s_start_date.strftime(fmt) #print s_end_date, s_start_date startdate = '%s+%s+%s' % (s_start_date_month_f, s_start_date.day, s_start_date.year) enddate = '%s+%s+%s' % (s_end_date_month_f, s_end_date.day, s_end_date.year) print "URL using date end %s, start %s" % (enddate, startdate) num = '200' pg = ['0', '200', '400', '600', '800', '1000'] url_list = [] stock_pg_datalist = {} for i in range(yr+1): url_list.append('https://www.google.com/finance/historical?cid=%s&startdate=%s&enddate=%s&num=%s&start=%s' % (cid, startdate, enddate, num, pg[i])) #print url_list for i in url_list: stock_pg_datalist.update(stock_pg_data(i)) current_value = realtime_data(stock_id) cal_data = calculate_data(current_value, stock_pg_datalist, date) write_data(name, cid, cal_data[0], cal_data[1], cal_data[2], current_value, zone, stock_id, cal_data[3])
def calc_period_prec(self, cr, uid, fiscal_year, context={}): fiscalyear_obj = self.pool['account.fiscalyear'] date_start = ( str(datetime.strptime(fiscal_year.date_start, '%Y-%m-%d') - relativedelta(years=1))[:10]) date_stop = ( str(datetime.strptime(fiscal_year.date_stop, '%Y-%m-%d') - relativedelta(years=1))[:10]) id_fy = fiscalyear_obj.search( cr, uid, [('date_start', '=', date_start), ('date_stop', '=', date_stop)]) if not id_fy: raise osv.except_osv( _('Error!'), _('Not find the previous exercise for period %s - %s' % ( date_start, date_stop))) # Anno Successivo date_start = ( str(datetime.strptime(fiscal_year.date_start, '%Y-%m-%d') + relativedelta(years=1))[:10]) date_stop = ( str(datetime.strptime(fiscal_year.date_stop, '%Y-%m-%d') + relativedelta(years=1))[:10]) id_fy1 = fiscalyear_obj.search( cr, uid, [('date_start', '=', date_start), ('date_stop', '=', date_stop)]) if not id_fy1: raise osv.except_osv( _('Error!'), _('Not find the next exercise for period %s - %s' % ( date_start, date_stop))) return id_fy[0], id_fy1[0]
def calculate_next_run_time(self): if self.last_run_time: start_date = self.from_date if self.repeat_every_minute < 9000: one_week_ago = datetime.datetime.now() - relativedelta(weeks=1) start_date = start_date.replace(one_week_ago.year, one_week_ago.month, one_week_ago.day) extra_days = (self.repeat_every_minute / 1400) + 10 runs = list(rrule(MINUTELY, cache=True, interval=self.repeat_every_minute, until=datetime.date.today() + relativedelta(days=extra_days, weekday=FR(-1)), dtstart=start_date)) for run in runs: if run > self.last_run_time: return run return self.from_date
def test_link_stats_page(self): with mock.patch('django.utils.timezone.now') as mock_now: # register usage thirty-eight days ago mock_now.return_value = self.now - relativedelta(days=38) self.link.register_usage(self.user) # register usage eight days ago mock_now.return_value = self.now - relativedelta(days=8) self.link.register_usage(self.user) # register usage now self.link.register_usage(self.user) stats_url = reverse('link-stats', kwargs={'pk': self.link.pk}) response = self.app.get(stats_url) self.assertEquals( response.html.find(class_='usage-seven-days').text, '1' ) self.assertEquals( response.html.find(class_='usage-thirty-days').text, '2' ) self.assertEquals( response.html.find(class_='usage-total').text, '3' )
def __init__(self, stdabbr, stdoffset=None, dstabbr=None, dstoffset=None, start=None, end=None): global relativedelta if not relativedelta: from dateutil import relativedelta self._std_abbr = stdabbr self._dst_abbr = dstabbr if stdoffset is not None: self._std_offset = datetime.timedelta(seconds=stdoffset) else: self._std_offset = ZERO if dstoffset is not None: self._dst_offset = datetime.timedelta(seconds=dstoffset) elif dstabbr and stdoffset is not None: self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) else: self._dst_offset = ZERO if start is None: self._start_delta = relativedelta.relativedelta( hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) else: self._start_delta = start if end is None: self._end_delta = relativedelta.relativedelta( hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) else: self._end_delta = end
def _interval_schedule_hours(self, intervals, hour, backwards=False): """ Schedule hours in intervals. The last matching interval is truncated to match the specified hours. This method can be applied backwards meaning scheduling hours going in the past. In that case truncating last interval is done accordingly. If number of hours to schedule is greater than possible scheduling in the given intervals, returned result equals intervals. :param list intervals: a list of time intervals :param int/float hours: number of hours to schedule. It will be converted into a timedelta, but should be submitted as an int or float :param boolean backwards: schedule starting from last hour :return list results: a list of time intervals """ if backwards: intervals.reverse() # first interval is the last working interval of the day results = [] res = timedelta() limit = timedelta(hours=hour) for interval in intervals: res += interval[1] - interval[0] if res > limit and not backwards: interval = (interval[0], interval[1] + relativedelta(seconds=(limit - res).total_seconds())) elif res > limit: interval = (interval[0] + relativedelta(seconds=(res - limit).total_seconds()), interval[1]) results.append(interval) if res > limit: break if backwards: results.reverse() # return interval with increasing starting times return results
def get_metric_by_month(self, unique_identifier, metric, from_date, limit=10, **kwargs): """ Returns the ``metric`` for ``unique_identifier`` segmented by month starting from``from_date``. It will retrieve metrics data starting from the 1st of the month specified in ``from_date`` :param unique_identifier: Unique string indetifying the object this metric is for :param metric: A unique name for the metric you want to track :param from_date: A python date object :param limit: The total number of months to retrive starting from ``from_date`` """ conn = kwargs.get("connection", None) first_of_month = datetime.date(year=from_date.year, month=from_date.month, day=1) metric_key_date_range = self._get_weekly_date_range( first_of_month, relativedelta(months=limit)) date_generator = (first_of_month + relativedelta(months=i) for i in itertools.count()) #generate a list of first_of_month's in between the start date and the end date series = list(itertools.islice(date_generator, limit)) metric_keys = [self._get_monthly_metric_name(metric, month_date) for month_date in series] metric_func = lambda conn: [conn.hmget( self._get_weekly_metric_key( unique_identifier, metric_key_date), metric_keys) for metric_key_date in metric_key_date_range] if conn is not None: results = metric_func(conn) else: with self._analytics_backend.map() as conn: results = metric_func(conn) series, results = self._parse_and_process_metrics(series, results) return series, results
def run(self, **kwargs): logger.info("TASK :: alarm_dispatcher") # Select Alarm where date_start_notice >= now() - 60 minutes and <= now() + 5 minutes start_time = datetime.utcnow().replace(tzinfo=utc) + relativedelta(minutes=-60) end_time = datetime.utcnow().replace(tzinfo=utc) + relativedelta(minutes=+5) alarm_list = Alarm.objects.filter(date_start_notice__range=(start_time, end_time), status=ALARM_STATUS.PENDING).order_by('date_start_notice') # Browse all the Alarm found for obj_alarm in alarm_list: # Check if there is an existing Event if obj_alarm.event: obj_alarm.status = ALARM_STATUS.IN_PROCESS obj_alarm.save() second_towait = obj_alarm.get_time_diff() # If second_towait negative then set to 0 to be run directly if second_towait <= 0: perform_alarm.delay(obj_alarm.event, obj_alarm) else: # Call the Alarm in the future perform_alarm.apply_async( args=[obj_alarm.event, obj_alarm], countdown=second_towait) else: logger.error("There is no Event attached to this Alarm: %d" % obj_alarm.id) ## Mark the Alarm as ERROR obj_alarm.status = ALARM_STATUS.FAILURE obj_alarm.save()
def get_period_date_ranges(filters): from dateutil.relativedelta import relativedelta from_date, to_date = getdate(filters.from_date), getdate(filters.to_date) increment = { "Monthly": 1, "Quarterly": 3, "Half-Yearly": 6, "Yearly": 12 }.get(filters.range,1) periodic_daterange = [] for dummy in range(1, 53, increment): if filters.range == "Weekly": period_end_date = from_date + relativedelta(days=6) else: period_end_date = from_date + relativedelta(months=increment, days=-1) if period_end_date > to_date: period_end_date = to_date periodic_daterange.append([from_date, period_end_date]) from_date = period_end_date + relativedelta(days=1) if period_end_date == to_date: break return periodic_daterange
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) date = self.get_date() context['current_month'] = date context['previous_month'] = first_day(date - relativedelta(months=1)) context['next_month'] = first_day(date + relativedelta(months=1)) return context
def test_inv006_warehouse_stock_report(self): """ @case: inv006 @description: Warehouse Stock Report * DOES NOT WORK """ print "\n" import datetime from dateutil.relativedelta import relativedelta #@ToDo: Move these into we2unittest today = datetime.date.today().strftime("%Y-%m-%d") now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") now_1_day = (datetime.datetime.now() + relativedelta( days = +1 )).strftime("%Y-%m-%d %H:%M:%S") now_1_week = (datetime.date.today() + relativedelta( weeks = +1 )).strftime("%Y-%m-%d %H:%M:%S") # Login, if not-already done so self.login(account="normal", nexturl="inv/inv_item/report") # INV006 # Warehouse Stock Report - Using Filter Options # Report by Item self.search( "inv_item_search", "text", "cans")] )
def test_initial_states_with_future(self): """ Test that after the licence has been created some returns has been created according to the return frequency and the licence end date """ # issue licence # use a one year licence with a monthly return start_date = today = date.today() end_date = start_date + timedelta(days=366) licence_data = { 'return_frequency': 1, 'start_date': str(start_date), 'end_date': str(end_date) } licence = self._issue_licence(licence_data) self.assertIsNotNone(licence) # 12 returns should have been created rets = Return.objects.all().order_by('due_date') self.assertEqual(rets.count(), 12) # the first one should be in a month with status 'current' current = rets.first() self.assertEqual(current.status, 'current') next_month = today + relativedelta(months=1) self.assertEqual(current.due_date, next_month) # the next ones should have the status 'future' futures = rets[1:] for i, future in enumerate(futures, start=1): self.assertEqual(future.status, 'future') expected_due_date = next_month + relativedelta(months=i) self.assertEqual(future.due_date, expected_due_date)
def onchange_description(self, cr, uid, ids, description, recurrence_id, next_invoice_date, context={}): txt = tools.ustr(description or '') if not next_invoice_date or not recurrence_id: return { 'value': { 'out_description': txt or '' } } if 'lang' not in context: context = { 'lang': self.pool.get('res.users').browse(cr,uid,uid).context_lang } start_date = datetime.strptime( next_invoice_date, '%Y-%m-%d' ) end_date = start_date recurrence = self.pool.get( 'product.recurrence.unit' ).browse( cr, uid, recurrence_id, context=context ) if recurrence: if recurrence.unit == 'day': end_date = start_date + relativedelta( days=recurrence.value ) elif recurrence.unit == 'month': end_date = start_date + relativedelta( months=recurrence.value ) elif recurrence.unit == 'year': end_date = start_date + relativedelta( years=recurrence.value ) if recurrence.value > 0: end_date -= relativedelta( days=1 ) if txt: if txt != '': txt += ' - ' else: txt = '' txt += start_date.strftime( '%d.%m.%Y' ) + ' ' + _( 'to' ) + ' ' + end_date.strftime( '%d.%m.%Y' ) return { 'value': { 'out_description': txt or '' } }
def get_cached(self, contract, period): end_period_date = datetime.strptime(period, '%Y%m') end_period_date += relativedelta(months=1) end_period_date = datetime(year=end_period_date.year, month=end_period_date.month, day=1) end_period_date -= relativedelta(days=1) end_period = int(end_period_date.strftime('%Y%m%d')) # Set the start period at the begining of the month start_period_date = datetime(year=end_period_date.year, month=end_period_date.month, day=1) start_period = int(start_period_date.strftime('%Y%m%d')) query = {'contractId': contract, 'day': {'$gte': start_period, '$lte': end_period}} res = self._result_collection.find(query).sort('day', 1) cached = [x for x in res] for elem in cached: for hidden_key in self._hidden_keys: if hidden_key in elem: elem.pop(hidden_key) return {"_items": cached}
def sync_month_metric(self, unique_identifier, metric, start_date, end_date): """ Uses the count for each day in the date range to recalculate the counters for the months for the ``metric`` for ``unique_identifier``. Useful for updating the counters for week and month after using set_metric_by_day. The redis backend supports lists for both ``unique_identifier`` and ``metric`` allowing for the setting of multiple metrics for multiple unique_identifiers efficiently. Not all backends may support this. :param unique_identifier: Unique string indetifying the object this metric is for :param metric: A unique name for the metric you want to track :param start_date: Date syncing starts :param end_date: Date syncing end """ metric = [metric] if isinstance(metric, basestring) else metric unique_identifier = [unique_identifier] if not isinstance(unique_identifier, (types.ListType, types.TupleType, types.GeneratorType,)) else unique_identifier num_months = self._num_months(start_date, end_date) first_of_month = datetime.date(year=start_date.year, month=start_date.month, day=1) metric_key_date_range = self._get_weekly_date_range( first_of_month, relativedelta(months=num_months)) month_date_generator = (first_of_month + relativedelta(months=i) for i in itertools.count()) #generate a list of first_of_month's in between the start date and the end date months_to_update = list(itertools.islice(month_date_generator, num_months)) for uid in unique_identifier: for single_metric in metric: for month in months_to_update: _, series_results = self.get_metric_by_day(uid, single_metric, from_date=month, limit=monthrange(month.year, month.month)[1]) month_counter = sum([value for key, value in series_results.items()]) hash_key_monthly = self._get_weekly_metric_key(uid, month) monthly_metric_name = self._get_monthly_metric_name(single_metric, month) with self._analytics_backend.map() as conn: conn.hset(hash_key_monthly, monthly_metric_name, month_counter)
def _default_valid_until(self): return datetime.today() + relativedelta(days=7)
def make_difference_heatmap(df_current, df_prior, race, event, start_date, end_date, save_fig=False): areas = make_areas() if datetime.date.fromisoformat(start_date).year == 2014: prior_start_date = (datetime.date.fromisoformat(start_date) + relativedelta(years=1)).isoformat() prior_end_date = (datetime.date.fromisoformat(end_date) + relativedelta(years=1)).isoformat() else: prior_start_date = (datetime.date.fromisoformat(start_date) - relativedelta(years=1)).isoformat() prior_end_date = (datetime.date.fromisoformat(end_date) - relativedelta(years=1)).isoformat() props_post = make_proportions(df_current, race, start_date, end_date) props_pre = make_proportions(df_prior, race, prior_start_date, prior_end_date) differences = props_post.subtract(props_pre) heat_diff = areas.merge(differences, left_on='serv', right_index=True, how='outer') heat_diff = heat_diff.dissolve(by='serv', aggfunc='first').fillna(0).drop(0) event_y = (datetime.date.fromisoformat(start_date) + relativedelta(months=2)).year cdict = { 'green': ( (0.0, 0.0, 0.0), # no red at 0 (0.5, 1.0, 1.0), # all channels set to 1.0 at 0.5 to create white (1.0, 0.8, 0.8)), # set to 0.8 so its not too bright at 1 'red': ( (0.0, 0.8, 0.8), # set to 0.8 so its not too bright at 0 (0.5, 1.0, 1.0), # all channels set to 1.0 at 0.5 to create white (1.0, 0.0, 0.0)), # no green at 1 'blue': ( (0.0, 0.0, 0.0), # no blue at 0 (0.5, 1.0, 1.0), # all channels set to 1.0 at 0.5 to create white (1.0, 0.0, 0.0)) # no blue at 1 } # Create the colormap using the dictionary GnRd = colors.LinearSegmentedColormap('GnRd', cdict) fig, ax = plt.subplots(1, figsize=(10, 10)) ax.axis('off') ax.set_title( f'Change in Proportion of {race} Drivers Stopped By Service Area\n Event: {event} ({event_y})' .format(race, event, event_y), fontdict={ 'fontsize': '15', 'fontweight': '3' }) heat_diff.plot(column='prop', cmap=GnRd, linewidth=0.8, ax=ax, edgecolor='0.8', vmin=-.5, vmax=.5, legend=True) if save_fig: if not os.path.exists(DATA_OUTPATH): os.makedirs(DATA_OUTPATH, exist_ok=True) fig.savefig(DATA_OUTPATH + '/{r}_{e}_({e_y})'.format( r=race.replace('/', '_'), e=event, e_y=event_y)) return heat_diff
#Stockprice hist = ticker.history(period="max") hist = hist.tail(1) stockprice = hist.iloc[0]["Open"] #Risk free rate risk_free = yf.Ticker("^IRX") hist = risk_free.history() hist = hist.tail(1) r = hist.iloc[0]["Open"]/100 #Dividend approximation based on historic dividend returns. dividend = hist["Dividends"] delta_years_floor = math.floor(time_to_maturity) delta_years_ceil = delta_years_floor + 1 prior_year_t = today - relativedelta(years=1) prior_year_expiration = expiration_datetime - relativedelta(years=delta_years_ceil) dividend_approx = sum(dividend.loc[prior_year_t:today])*delta_years_floor dividend_approx = dividend_approx + sum(dividend.loc[prior_year_t:prior_year_expiration]) #___________________________________________________________________________________ #4. Definition of four functions for different option types def European_Call_Div (S0, K, T, sigma, n): #Calculation of Initial Parameters dt = T/n u = np.exp(sigma*np.sqrt(dt)) d = 1/u DivRate = dividend_approx / S0
def computeFeesInterestPrincipal_ForLoan(dfForLoan): # Over the life of the loan, these are the values to be computed and returned by this function. cumPrincipal, cumInterest, cumFees = 0, 0, 0 # Do some up-front validation that the data takes the form expected. loanID = dfForLoan[_g.ID_COL].iloc[0] if dfForLoan[_g.ORIGINAL_PRINCIPAL_COL].unique().size != 1: raise Exception( f"Column={_g.ORIGINAL_PRINCIPAL_COL} expected to have unique value for loanID={loanID}." ) if dfForLoan[_g.ORIGINATION_DATE_COL].unique().size != 1: raise Exception( f"Column={_g.ORIGINATION_DATE_COL} expected to have unique value for loanID={loanID}." ) if dfForLoan[_g.TERM_COL].unique().size != 1: raise Exception( f"Column={_g.TERM_COL} expected to have unique value for loanID={loanID}." ) if dfForLoan[_g.APR_COL].unique().size != 1: raise Exception( f"Column={_g.APR_COL} expected to have unique value for loanID={loanID}." ) # Get necessary data from dataframe columns. Accessing the data thusly preserves the dtype. originationDate = dfForLoan[_g.ORIGINATION_DATE_COL].iloc[0] termNumMonths = dfForLoan[_g.TERM_COL].iloc[0] apr = dfForLoan[_g.APR_COL].iloc[0] originalPrincipal = dfForLoan[_g.ORIGINAL_PRINCIPAL_COL].iloc[0] numMonthsRemaining = termNumMonths principalLedger = originalPrincipal interestLedger = 0 feesLedger = 0 # Aggregate any rows with the same payment date. paymentTS = dfForLoan.groupby(_g.PAYMENT_DATE_COL).agg( {_g.PAYMENT_AMOUNT_COL: 'sum'}) paymentTS.sort_values( _g.PAYMENT_DATE_COL, inplace=True) # Chronological order, past --> present priorPaymentDate = originationDate paymentDeadlineDate = originationDate + pd.DateOffset( months=1) + pd.DateOffset(days=13) targetMonthlyPayment = principalLedger * (apr / 12 / (1 - (1 + apr / 12)** (-numMonthsRemaining))) paymentLedger = 0 for index, row in paymentTS.iterrows(): # From each row, get the date the payment was made, and the cumulative amount of the payment. paymentDate = row.name paymentAmount = row[_g.PAYMENT_AMOUNT_COL] # Compute the accrued simple interest. This is done on a daily basis, non-compounding. daysSinceLastPayment = (paymentDate - priorPaymentDate).days interestAmountPerDay = apr / 360.0 * principalLedger interestLedger += interestAmountPerDay * daysSinceLastPayment # Need to determine whether to assess fees, and how much to assess. if paymentDate > paymentDeadlineDate: # If *multiple* pay periods have been missed since lass payment, assess a fee for each missed. # Again, EXACT methodology here would need to be determined from reading loan-provider's methodology. monthsPastDeadline = relativedelta.relativedelta( paymentDate, paymentDeadlineDate).months + 1 for missedDeadline in range(monthsPastDeadline): outstandingBalance = principalLedger + interestLedger + feesLedger feesLedger += 0.05 * outstandingBalance if 0.05 * outstandingBalance > 20 else 20 paymentAmountDist = paymentAmount if paymentAmountDist > feesLedger: paymentAmountDist -= feesLedger cumFees += feesLedger feesLedger = 0 if paymentAmountDist > interestLedger: paymentAmountDist -= interestLedger cumInterest += interestLedger interestLedger = 0 if paymentAmountDist > principalLedger: # Register the overpayment as a data anomaly? For now, print to stdout, if overpayment by $5+ if paymentAmountDist - principalLedger >= 5: print( f"!!! Payments for loanID={loanID} went over principal by ${paymentAmountDist-principalLedger:.2f}!!!" ) paymentAmountDist -= principalLedger cumPrincipal += principalLedger principalLedger = 0 break else: principalLedger -= paymentAmountDist cumPrincipal += paymentAmountDist else: interestLedger -= paymentAmountDist cumInterest += paymentAmountDist else: feesLedger -= paymentAmountDist cumFees += paymentAmountDist # At this point in the code, we've registered the fees and interest that may have accrued since our last # payment, we've registered the payment amount, and we've counted the payment amount against any outstanding # (1) fees, (2) interest, (3) principal, in that order. # # Now, we need to address the payment ledger, and the targeted monthly payment. If this payment exceeds # the last recorded payment deadline date, then this payment now counts against a new deadline, with a # new targeted monthly payment. # if paymentDate > paymentDeadlineDate: # Any existing paymentLedger prior to this tardy payment should be wiped clean. paymentLedger = 0 # Need to determine whether *multiple* pay periods have been missed since last payment. monthsPastDeadline = relativedelta.relativedelta( paymentDate, paymentDeadlineDate).months paymentDeadlineDate += pd.DateOffset( months=monthsPastDeadline + 1) numMonthsRemaining -= monthsPastDeadline + 1 if numMonthsRemaining <= 0: break # If the loan has reached full term, break. targetMonthlyPayment = principalLedger * (apr/12 / (1 - (1 + apr/12)**(-numMonthsRemaining))) \ + (interestLedger + feesLedger) / numMonthsRemaining paymentLedger += paymentAmount if paymentLedger >= targetMonthlyPayment: # Our paymentLedger has grown sufficiently large to meet our target monthly payment. Thus, we # zero out the paymentLedger. paymentLedger = 0 paymentDeadlineDate += pd.DateOffset(months=1) numMonthsRemaining -= 1 if numMonthsRemaining <= 0: break # If the loan has reached full term, break. targetMonthlyPayment = principalLedger * (apr/12 / (1 - (1 + apr/12)**(-numMonthsRemaining))) \ + (interestLedger + feesLedger) / numMonthsRemaining # Wind forward the prior payment date to this current payment. priorPaymentDate = paymentDate #--------End of for-loop------------------------------------------------------------- return pd.DataFrame({ _g.ID_COL: [loanID], _g.ORIGINAL_PRINCIPAL_COL: [originalPrincipal], _g.ORIGINATION_DATE_COL: [originationDate], _g.TERM_COL: [termNumMonths], _g.APR_COL: [apr], _g.CUM_PRINCIPAL_COL: [cumPrincipal], _g.CUM_INTEREST_COL: [cumInterest], _g.CUM_FEES_COL: [cumFees] })
def main(args): # Max number of posts max_posts = int(args['<max_posts>']) config_path = args['<config_path>'] # Load configuration file with open(config_path) as config_file: config = json.loads(config_file.read()) # To find go to page's FB page, at the end of URL find username # E.g. http://facebook.com/walmart, walmart is the username list_companies = [config["fb_fanpage_name"]] # Save all comments save_comments = False # The time of last weeks crawl last_crawl = datetime.datetime.now() - relativedelta(years=200) last_crawl = last_crawl.isoformat() # Configure connection and connect db_connection = DBConnection(config["db_user"], config["db_password"], config["hostname"], config["database"]) db_connection.connect() # Simple data pull App Secret and App ID APP_SECRET = config["APP_SECRET"] APP_ID = config["APP_ID"] fc = FacebookScrapper(APP_SECRET, APP_ID) # Get posts already in database db_posts_dict = {} db_posts = db_connection.get_posts() get_db_posts(db_posts_dict, db_posts) # Get last posts url post_url = "" if os.path.isfile('last_post_url.txt'): with open('last_post_url.txt', 'r') as lastpost_file: post_url = lastpost_file.read() for company in list_companies: # Make graph api url with company username page = fc.get_page_info(company) # Insert the data we pulled into db, commit and close connection page_id = db_connection.insert_info(page) db_connection.commit() db_connection.close() posts = [] # Extract post data if post_url == "": post_url = fc.create_post_url(company) print(post_url) fc.scrape_posts_by_date(post_url, last_crawl, posts, company, db_posts_dict, max_posts) # Reconnect db_connection.connect() # Loop through and insert posts for post in posts: print("storing post data......... " + post[0]) post.append(page_id) # Insert post and commit post_id = db_connection.insert_post(post) db_connection.commit() if save_comments: # Retrieving and saving comments comment_url = fc.create_comments_url(post[0]) comments = [] fc.get_comments_data(comment_url, comments, post_id) # Loop through and insert comments for comment in comments: db_connection.insert_comment(comment) db_connection.commit() db_connection.close()
def extract_datetime_pt(text, anchorDate=None, default_time=None): def clean_string(s): # cleans the input string of unneeded punctuation and capitalization # among other things symbols = [".", ",", ";", "?", "!", "º", "ª"] noise_words = [ "o", "os", "a", "as", "do", "da", "dos", "das", "de", "ao", "aos" ] for word in symbols: s = s.replace(word, "") for word in noise_words: s = s.replace(" " + word + " ", " ") s = s.lower().replace("á", "a").replace("ç", "c").replace( "à", "a").replace("ã", "a").replace("é", "e").replace("è", "e").replace( "ê", "e").replace("ó", "o").replace("ò", "o").replace("-", " ").replace("_", "") # handle synonims and equivalents, "tomorrow early = tomorrow morning synonims = { "manha": ["manhazinha", "cedo", "cedinho"], "tarde": ["tardinha", "tarde"], "noite": ["noitinha", "anoitecer"], "todos": ["ao", "aos"], "em": ["do", "da", "dos", "das", "de"] } for syn in synonims: for word in synonims[syn]: s = s.replace(" " + word + " ", " " + syn + " ") # relevant plurals, cant just extract all s in pt wordlist = [ "manhas", "noites", "tardes", "dias", "semanas", "anos", "minutos", "segundos", "nas", "nos", "proximas", "seguintes", "horas" ] for _, word in enumerate(wordlist): s = s.replace(word, word.rstrip('s')) s = s.replace("meses", "mes").replace("anteriores", "anterior") return s def date_found(): return found or \ ( datestr != "" or timeStr != "" or yearOffset != 0 or monthOffset != 0 or dayOffset is True or hrOffset != 0 or hrAbs or minOffset != 0 or minAbs or secOffset != 0 ) if text == "" or not anchorDate: return None found = False daySpecified = False dayOffset = False monthOffset = 0 yearOffset = 0 dateNow = anchorDate today = dateNow.strftime("%w") currentYear = dateNow.strftime("%Y") fromFlag = False datestr = "" hasYear = False timeQualifier = "" words = clean_string(text).split(" ") timeQualifiersList = ['manha', 'tarde', 'noite'] time_indicators = [ "em", "as", "nas", "pelas", "volta", "depois", "estas", "no", "dia", "hora" ] days = [ 'segunda', 'terca', 'quarta', 'quinta', 'sexta', 'sabado', 'domingo' ] months = [ 'janeiro', 'febreiro', 'marco', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ] monthsShort = [ 'jan', 'feb', 'mar', 'abr', 'mai', 'jun', 'jul', 'ag', 'set', 'out', 'nov', 'dec' ] nexts = ["proximo", "proxima"] suffix_nexts = ["seguinte", "subsequente", "seguir"] lasts = ["ultimo", "ultima"] suffix_lasts = ["passada", "passado", "anterior", "antes"] nxts = ["depois", "seguir", "seguida", "seguinte", "proxima", "proximo"] prevs = ["antes", "ante", "previa", "previamente", "anterior"] froms = [ "partir", "em", "para", "na", "no", "daqui", "seguir", "depois", "por", "proxima", "proximo", "da", "do", "de" ] thises = [ "este", "esta", "deste", "desta", "neste", "nesta", "nesse", "nessa" ] froms += thises lists = nxts + prevs + froms + time_indicators for idx, word in enumerate(words): if word == "": continue wordPrevPrev = words[idx - 2] if idx > 1 else "" wordPrev = words[idx - 1] if idx > 0 else "" wordNext = words[idx + 1] if idx + 1 < len(words) else "" wordNextNext = words[idx + 2] if idx + 2 < len(words) else "" wordNextNextNext = words[idx + 3] if idx + 3 < len(words) else "" start = idx used = 0 # save timequalifier for later if word in timeQualifiersList: timeQualifier = word # parse today, tomorrow, yesterday elif word == "hoje" and not fromFlag: dayOffset = 0 used += 1 elif word == "amanha" and not fromFlag: dayOffset = 1 used += 1 elif word == "ontem" and not fromFlag: dayOffset -= 1 used += 1 # "before yesterday" and "before before yesterday" elif (word == "anteontem" or (word == "ante" and wordNext == "ontem")) and not fromFlag: dayOffset -= 2 used += 1 if wordNext == "ontem": used += 1 elif word == "ante" and wordNext == "ante" and wordNextNext == \ "ontem" and not fromFlag: dayOffset -= 3 used += 3 elif word == "anteanteontem" and not fromFlag: dayOffset -= 3 used += 1 # day after tomorrow elif word == "depois" and wordNext == "amanha" and not fromFlag: dayOffset += 2 used = 2 # day before yesterday elif word == "antes" and wordNext == "ontem" and not fromFlag: dayOffset -= 2 used = 2 # parse 5 days, 10 weeks, last week, next week, week after elif word == "dia": if wordNext == "depois" or wordNext == "antes": used += 1 if wordPrev and wordPrev[0].isdigit(): dayOffset += int(wordPrev) start -= 1 used += 1 elif (wordPrev and wordPrev[0].isdigit() and wordNext not in months and wordNext not in monthsShort): dayOffset += int(wordPrev) start -= 1 used += 2 elif wordNext and wordNext[0].isdigit() and wordNextNext not in \ months and wordNextNext not in monthsShort: dayOffset += int(wordNext) start -= 1 used += 2 elif word == "semana" and not fromFlag: if wordPrev[0].isdigit(): dayOffset += int(wordPrev) * 7 start -= 1 used = 2 for w in nexts: if wordPrev == w: dayOffset = 7 start -= 1 used = 2 for w in lasts: if wordPrev == w: dayOffset = -7 start -= 1 used = 2 for w in suffix_nexts: if wordNext == w: dayOffset = 7 start -= 1 used = 2 for w in suffix_lasts: if wordNext == w: dayOffset = -7 start -= 1 used = 2 # parse 10 months, next month, last month elif word == "mes" and not fromFlag: if wordPrev[0].isdigit(): monthOffset = int(wordPrev) start -= 1 used = 2 for w in nexts: if wordPrev == w: monthOffset = 7 start -= 1 used = 2 for w in lasts: if wordPrev == w: monthOffset = -7 start -= 1 used = 2 for w in suffix_nexts: if wordNext == w: monthOffset = 7 start -= 1 used = 2 for w in suffix_lasts: if wordNext == w: monthOffset = -7 start -= 1 used = 2 # parse 5 years, next year, last year elif word == "ano" and not fromFlag: if wordPrev[0].isdigit(): yearOffset = int(wordPrev) start -= 1 used = 2 for w in nexts: if wordPrev == w: yearOffset = 7 start -= 1 used = 2 for w in lasts: if wordPrev == w: yearOffset = -7 start -= 1 used = 2 for w in suffix_nexts: if wordNext == w: yearOffset = 7 start -= 1 used = 2 for w in suffix_lasts: if wordNext == w: yearOffset = -7 start -= 1 used = 2 # parse Monday, Tuesday, etc., and next Monday, # last Tuesday, etc. elif word in days and not fromFlag: d = days.index(word) dayOffset = (d + 1) - int(today) used = 1 if dayOffset < 0: dayOffset += 7 for w in nexts: if wordPrev == w: dayOffset += 7 used += 1 start -= 1 for w in lasts: if wordPrev == w: dayOffset -= 7 used += 1 start -= 1 for w in suffix_nexts: if wordNext == w: dayOffset += 7 used += 1 start -= 1 for w in suffix_lasts: if wordNext == w: dayOffset -= 7 used += 1 start -= 1 if wordNext == "feira": used += 1 # parse 15 of July, June 20th, Feb 18, 19 of February elif word in months or word in monthsShort: try: m = months.index(word) except ValueError: m = monthsShort.index(word) used += 1 datestr = months[m] if wordPrev and wordPrev[0].isdigit(): # 13 maio datestr += " " + wordPrev start -= 1 used += 1 if wordNext and wordNext[0].isdigit(): datestr += " " + wordNext used += 1 hasYear = True else: hasYear = False elif wordNext and wordNext[0].isdigit(): # maio 13 datestr += " " + wordNext used += 1 if wordNextNext and wordNextNext[0].isdigit(): datestr += " " + wordNextNext used += 1 hasYear = True else: hasYear = False elif wordPrevPrev and wordPrevPrev[0].isdigit(): # 13 dia maio datestr += " " + wordPrevPrev start -= 2 used += 2 if wordNext and word[0].isdigit(): datestr += " " + wordNext used += 1 hasYear = True else: hasYear = False elif wordNextNext and wordNextNext[0].isdigit(): # maio dia 13 datestr += " " + wordNextNext used += 2 if wordNextNextNext and wordNextNextNext[0].isdigit(): datestr += " " + wordNextNextNext used += 1 hasYear = True else: hasYear = False if datestr in months: datestr = "" # parse 5 days from tomorrow, 10 weeks from next thursday, # 2 months from July validFollowups = days + months + monthsShort validFollowups.append("hoje") validFollowups.append("amanha") validFollowups.append("ontem") validFollowups.append("anteontem") validFollowups.append("agora") validFollowups.append("ja") validFollowups.append("ante") # TODO debug word "depois" that one is failing for some reason if word in froms and wordNext in validFollowups: if not (wordNext == "amanha" and wordNext == "ontem") and not ( word == "depois" or word == "antes" or word == "em"): used = 2 fromFlag = True if wordNext == "amanha" and word != "depois": dayOffset += 1 elif wordNext == "ontem": dayOffset -= 1 elif wordNext == "anteontem": dayOffset -= 2 elif wordNext == "ante" and wordNextNext == "ontem": dayOffset -= 2 elif (wordNext == "ante" and wordNextNext == "ante" and wordNextNextNext == "ontem"): dayOffset -= 3 elif wordNext in days: d = days.index(wordNext) tmpOffset = (d + 1) - int(today) used = 2 if wordNextNext == "feira": used += 1 if tmpOffset < 0: tmpOffset += 7 if wordNextNext: if wordNextNext in nxts: tmpOffset += 7 used += 1 elif wordNextNext in prevs: tmpOffset -= 7 used += 1 dayOffset += tmpOffset elif wordNextNext and wordNextNext in days: d = days.index(wordNextNext) tmpOffset = (d + 1) - int(today) used = 3 if wordNextNextNext: if wordNextNextNext in nxts: tmpOffset += 7 used += 1 elif wordNextNextNext in prevs: tmpOffset -= 7 used += 1 dayOffset += tmpOffset if wordNextNextNext == "feira": used += 1 if wordNext in months: used -= 1 if used > 0: if start - 1 > 0 and words[start - 1] in lists: start -= 1 used += 1 for i in range(0, used): words[i + start] = "" if start - 1 >= 0 and words[start - 1] in lists: words[start - 1] = "" found = True daySpecified = True # parse time timeStr = "" hrOffset = 0 minOffset = 0 secOffset = 0 hrAbs = None minAbs = None military = False for idx, word in enumerate(words): if word == "": continue wordPrevPrev = words[idx - 2] if idx > 1 else "" wordPrev = words[idx - 1] if idx > 0 else "" wordNext = words[idx + 1] if idx + 1 < len(words) else "" wordNextNext = words[idx + 2] if idx + 2 < len(words) else "" wordNextNextNext = words[idx + 3] if idx + 3 < len(words) else "" # parse noon, midnight, morning, afternoon, evening used = 0 if word == "meio" and wordNext == "dia": hrAbs = 12 used += 2 elif word == "meia" and wordNext == "noite": hrAbs = 0 used += 2 elif word == "manha": if not hrAbs: hrAbs = 8 used += 1 elif word == "tarde": if not hrAbs: hrAbs = 15 used += 1 elif word == "meio" and wordNext == "tarde": if not hrAbs: hrAbs = 17 used += 2 elif word == "meio" and wordNext == "manha": if not hrAbs: hrAbs = 10 used += 2 elif word == "fim" and wordNext == "tarde": if not hrAbs: hrAbs = 19 used += 2 elif word == "fim" and wordNext == "manha": if not hrAbs: hrAbs = 11 used += 2 elif word == "tantas" and wordNext == "manha": if not hrAbs: hrAbs = 4 used += 2 elif word == "noite": if not hrAbs: hrAbs = 22 used += 1 # parse half an hour, quarter hour elif word == "hora" and \ (wordPrev in time_indicators or wordPrevPrev in time_indicators): if wordPrev == "meia": minOffset = 30 elif wordPrev == "quarto": minOffset = 15 elif wordPrevPrev == "quarto": minOffset = 15 if idx > 2 and words[idx - 3] in time_indicators: words[idx - 3] = "" words[idx - 2] = "" else: hrOffset = 1 if wordPrevPrev in time_indicators: words[idx - 2] = "" words[idx - 1] = "" used += 1 hrAbs = -1 minAbs = -1 # parse 5:00 am, 12:00 p.m., etc elif word[0].isdigit(): isTime = True strHH = "" strMM = "" remainder = "" if ':' in word: # parse colons # "3:00 in the morning" stage = 0 length = len(word) for i in range(length): if stage == 0: if word[i].isdigit(): strHH += word[i] elif word[i] == ":": stage = 1 else: stage = 2 i -= 1 elif stage == 1: if word[i].isdigit(): strMM += word[i] else: stage = 2 i -= 1 elif stage == 2: remainder = word[i:].replace(".", "") break if remainder == "": nextWord = wordNext.replace(".", "") if nextWord == "am" or nextWord == "pm": remainder = nextWord used += 1 elif wordNext == "manha": remainder = "am" used += 1 elif wordNext == "tarde": remainder = "pm" used += 1 elif wordNext == "noite": if 0 < int(word[0]) < 6: remainder = "am" else: remainder = "pm" used += 1 elif wordNext in thises and wordNextNext == "manha": remainder = "am" used = 2 elif wordNext in thises and wordNextNext == "tarde": remainder = "pm" used = 2 elif wordNext in thises and wordNextNext == "noite": remainder = "pm" used = 2 else: if timeQualifier != "": military = True if strHH <= 12 and \ (timeQualifier == "manha" or timeQualifier == "tarde"): strHH += 12 else: # try to parse # s without colons # 5 hours, 10 minutes etc. length = len(word) strNum = "" remainder = "" for i in range(length): if word[i].isdigit(): strNum += word[i] else: remainder += word[i] if remainder == "": remainder = wordNext.replace(".", "").lstrip().rstrip() if (remainder == "pm" or wordNext == "pm" or remainder == "p.m." or wordNext == "p.m."): strHH = strNum remainder = "pm" used = 1 elif (remainder == "am" or wordNext == "am" or remainder == "a.m." or wordNext == "a.m."): strHH = strNum remainder = "am" used = 1 else: if (wordNext == "pm" or wordNext == "p.m." or wordNext == "tarde"): strHH = strNum remainder = "pm" used = 1 elif (wordNext == "am" or wordNext == "a.m." or wordNext == "manha"): strHH = strNum remainder = "am" used = 1 elif (int(word) > 100 and (wordPrev == "o" or wordPrev == "oh" or wordPrev == "zero")): # 0800 hours (pronounced oh-eight-hundred) strHH = int(word) / 100 strMM = int(word) - strHH * 100 military = True if wordNext == "hora": used += 1 elif (wordNext == "hora" and word[0] != '0' and (int(word) < 100 and int(word) > 2400)): # ignores military time # "in 3 hours" hrOffset = int(word) used = 2 isTime = False hrAbs = -1 minAbs = -1 elif wordNext == "minuto": # "in 10 minutes" minOffset = int(word) used = 2 isTime = False hrAbs = -1 minAbs = -1 elif wordNext == "segundo": # in 5 seconds secOffset = int(word) used = 2 isTime = False hrAbs = -1 minAbs = -1 elif int(word) > 100: strHH = int(word) / 100 strMM = int(word) - strHH * 100 military = True if wordNext == "hora": used += 1 elif wordNext == "" or (wordNext == "em" and wordNextNext == "ponto"): strHH = word strMM = 00 if wordNext == "em" and wordNextNext == "ponto": used += 2 if wordNextNextNext == "tarde": remainder = "pm" used += 1 elif wordNextNextNext == "manha": remainder = "am" used += 1 elif wordNextNextNext == "noite": if 0 > int(strHH) > 6: remainder = "am" else: remainder = "pm" used += 1 elif wordNext[0].isdigit(): strHH = word strMM = wordNext military = True used += 1 if wordNextNext == "hora": used += 1 else: isTime = False strHH = int(strHH) if strHH else 0 strMM = int(strMM) if strMM else 0 strHH = strHH + 12 if (remainder == "pm" and 0 < strHH < 12) else strHH strHH = strHH - 12 if (remainder == "am" and 0 < strHH >= 12) else strHH if strHH > 24 or strMM > 59: isTime = False used = 0 if isTime: hrAbs = strHH * 1 minAbs = strMM * 1 used += 1 if used > 0: # removed parsed words from the sentence for i in range(used): words[idx + i] = "" if wordPrev == "em" or wordPrev == "ponto": words[words.index(wordPrev)] = "" if idx > 0 and wordPrev in time_indicators: words[idx - 1] = "" if idx > 1 and wordPrevPrev in time_indicators: words[idx - 2] = "" idx += used - 1 found = True # check that we found a date if not date_found: return None if dayOffset is False: dayOffset = 0 # perform date manipulation extractedDate = dateNow extractedDate = extractedDate.replace(microsecond=0, second=0, minute=0, hour=0) if datestr != "": en_months = [ 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december' ] en_monthsShort = [ 'jan', 'feb', 'mar', 'apr', 'may', 'june', 'july', 'aug', 'sept', 'oct', 'nov', 'dec' ] for idx, en_month in enumerate(en_months): datestr = datestr.replace(months[idx], en_month) for idx, en_month in enumerate(en_monthsShort): datestr = datestr.replace(monthsShort[idx], en_month) temp = datetime.strptime(datestr, "%B %d") if not hasYear: temp = temp.replace(year=extractedDate.year) if extractedDate < temp: extractedDate = extractedDate.replace( year=int(currentYear), month=int(temp.strftime("%m")), day=int(temp.strftime("%d"))) else: extractedDate = extractedDate.replace( year=int(currentYear) + 1, month=int(temp.strftime("%m")), day=int(temp.strftime("%d"))) else: extractedDate = extractedDate.replace( year=int(temp.strftime("%Y")), month=int(temp.strftime("%m")), day=int(temp.strftime("%d"))) if timeStr != "": temp = datetime(timeStr) extractedDate = extractedDate.replace(hour=temp.strftime("%H"), minute=temp.strftime("%M"), second=temp.strftime("%S")) if yearOffset != 0: extractedDate = extractedDate + relativedelta(years=yearOffset) if monthOffset != 0: extractedDate = extractedDate + relativedelta(months=monthOffset) if dayOffset != 0: extractedDate = extractedDate + relativedelta(days=dayOffset) if (hrAbs or 0) != -1 and (minAbs or 0) != -1: if hrAbs is None and minAbs is None and default_time: hrAbs = default_time.hour minAbs = default_time.minute extractedDate = extractedDate + relativedelta(hours=hrAbs or 0, minutes=minAbs or 0) if (hrAbs or minAbs) and datestr == "": if not daySpecified and dateNow > extractedDate: extractedDate = extractedDate + relativedelta(days=1) if hrOffset != 0: extractedDate = extractedDate + relativedelta(hours=hrOffset) if minOffset != 0: extractedDate = extractedDate + relativedelta(minutes=minOffset) if secOffset != 0: extractedDate = extractedDate + relativedelta(seconds=secOffset) resultStr = " ".join(words) resultStr = ' '.join(resultStr.split()) resultStr = _pt_pruning(resultStr) return [extractedDate, resultStr]
if len(open_cases) > 0: case_numbers = ",".join([case.case_number for case in open_cases]) self.record.errors += [ f"All charges are ineligible because there is one or more open case: {case_numbers}. Open cases with valid dispositions are still included in time analysis. Otherwise they are ignored, so time analysis may be inaccurate for other charges." ] self.record.errors += self._build_disposition_errors(self.record.charges) for charge in self.analyzable_charges: eligibility_dates: List[Tuple[date, str]] = [] other_charges = [c for c in self.analyzable_charges if c != charge] dismissals, convictions = Expunger._categorize_charges(other_charges) most_recent_blocking_dismissal = Expunger._most_recent_different_case_dismissal(charge, dismissals) most_recent_blocking_conviction = Expunger._most_recent_convictions(convictions) if charge.convicted(): eligibility_dates.append( (charge.disposition.date + relativedelta(years=3), "Time-ineligible under 137.225(1)(a)") ) if charge.disposition.status == DispositionStatus.NO_COMPLAINT: eligibility_dates.append( (charge.disposition.date + relativedelta(years=1), "Time-ineligible under 137.225(1)(b)") ) if most_recent_blocking_conviction: eligibility_dates.append( ( most_recent_blocking_conviction.disposition.date + relativedelta(years=10), "Time-ineligible under 137.225(7)(b)", ) )
def mip(self): keys = list(self.borrowers.keys()) for i in range(len(self.data)): # self.data.to_csv(self.params['DATA'], sep=';', index=False) self.data.loc[i, 'mip'] = insurance.mip(self.data.loc[i, 'balance'], self.signature, keys[0].birth, self.signature + relativedelta(months=i), keys[1].birth if keys[1] else None, self.borrowers[keys[0]], self.borrowers[keys[1]] if keys[1] else None)
def avg_annualised_return(input_df, output_log=False): ''' This function takes price paid data and returns the average length of a holding period and the annualised change in value between the purchase and sale, grouped by the year a holding period ends and the property type. ''' from dateutil import relativedelta # Creating a separate field for that combined the house number, flat number # and postcode to ensure multiple properties with the same postcode are treated as separate. data = input_df.copy() data['Date'] = pd.to_datetime(data['Date']) data['Year'] = data['Date'].dt.year data['num_postcode'] = data['PAON'] + data['SAON'].astype(str) + data['Postcode'] data['num_postcode'] = data['num_postcode'].astype(str) data = data.sort_values('Date', ascending=True) working_df = pd.DataFrame(columns=['year', 'type', 'hold_period', 'annualised_return']) # For each for address in data['num_postcode']: current = data.loc[data['num_postcode'] == address] appearances = len(current) # don't add to new dataset if there is no holding period if appearances < 2: continue # annualized_return=((1 + total_return)**(months))-1 if appearances > 1: for period in range(appearances-1): if period == appearances-1: break new_type = current['Type'].iloc[period] total_return = (current['Price'].iloc[period+1] - current['Price'].iloc[period]) / current['Price'].iloc[period] # calculation plus 1 to avoid divide by zero error. For properties sold in the first month (0), it is treated as month = 1 hold_period = float(relativedelta.relativedelta(current['Date'].iloc[period+1], current['Date'].iloc[period]).months)+1 # year of the sale (next period) year = current['Year'].iloc[period+1] ann_return = (((1 + total_return)**(12/hold_period))-1)*100 new_row = {'year': year, 'type': new_type, 'hold_period': hold_period, 'annualised_return': ann_return} working_df = working_df.append(new_row, ignore_index=True) # I used this for checking / debugging if output_log == True: print('---New holding period ---\n') print(new_row) print(hold_period) print('Sale Price: ' + str(current['Price'].iloc[period+1]) + ' Buy Price: ' + str(current['Price'].iloc[period]) + '\n\n') return working_df.set_index(['year', 'type']).groupby(level=[0,1]).mean()
def days_from_now(n): now = datetime.datetime.now() delta = relativedelta(days=n) return (now + delta).strftime('%Y-%m-%d')
def survey_submit(self, survey_token, answer_token, **post): """ Submit a page from the survey. This will take into account the validation errors and store the answers to the questions. If the time limit is reached, errors will be skipped, answers will be ignored and survey state will be forced to 'done'""" # Survey Validation access_data = self._get_access_data(survey_token, answer_token, ensure_token=True) if access_data['validity_code'] is not True: return {'error': access_data['validity_code']} survey_sudo, answer_sudo = access_data['survey_sudo'], access_data[ 'answer_sudo'] if answer_sudo.state == 'done': return {'error': 'unauthorized'} questions, page_or_question_id = survey_sudo._get_survey_questions( answer=answer_sudo, page_id=post.get('page_id'), question_id=post.get('question_id')) if not answer_sudo.test_entry and not survey_sudo._has_attempts_left( answer_sudo.partner_id, answer_sudo.email, answer_sudo.invite_token): # prevent cheating with users creating multiple 'user_input' before their last attempt return {'error': 'unauthorized'} if answer_sudo.survey_time_limit_reached or answer_sudo.question_time_limit_reached: if answer_sudo.question_time_limit_reached: time_limit = survey_sudo.session_question_start_time + relativedelta( seconds=survey_sudo.session_question_id.time_limit) time_limit += timedelta(seconds=3) else: time_limit = answer_sudo.start_datetime + timedelta( minutes=survey_sudo.time_limit) time_limit += timedelta(seconds=10) if fields.Datetime.now() > time_limit: # prevent cheating with users blocking the JS timer and taking all their time to answer return {'error': 'unauthorized'} errors = {} # Prepare answers / comment by question, validate and save answers for question in questions: inactive_questions = request.env[ 'survey.question'] if answer_sudo.is_session_answer else answer_sudo._get_inactive_conditional_questions( ) if question in inactive_questions: # if question is inactive, skip validation and save continue answer, comment = self._extract_comment_from_answers( question, post.get(str(question.id))) errors.update(question.validate_question(answer, comment)) if not errors.get(question.id): answer_sudo.save_lines(question, answer, comment) if errors and not (answer_sudo.survey_time_limit_reached or answer_sudo.question_time_limit_reached): return {'error': 'validation', 'fields': errors} if not answer_sudo.is_session_answer: answer_sudo._clear_inactive_conditional_answers() if answer_sudo.survey_time_limit_reached or survey_sudo.questions_layout == 'one_page': answer_sudo._mark_done() elif 'previous_page_id' in post: # Go back to specific page using the breadcrumb. Lines are saved and survey continues return self._prepare_question_html(survey_sudo, answer_sudo, **post) else: vals = {'last_displayed_page_id': page_or_question_id} if not answer_sudo.is_session_answer: next_page = survey_sudo._get_next_page_or_question( answer_sudo, page_or_question_id) if not next_page: answer_sudo._mark_done() answer_sudo.write(vals) return self._prepare_question_html(survey_sudo, answer_sudo)
def get_phone_records(self): """ 获取通话记录 :param postsms: :return: """ for _ in range(0, 7): # 最近半年, 可以查询7个月记录 last = datetime.date.today() - relativedelta(months=+_) month = last.strftime("%Y%m") queryBillDetailNum_url = 'http://sd.189.cn/selfservice/bill/queryBillDetailNum?tag=iframe_rnval' headers = { "Accept": "application/json", "Content-Type": "application/json", "Host": "sd.189.cn", "Origin": "http://sd.189.cn", "Referer": "http://sd.189.cn/selfservice/IframeBill/iframeSimple?tag=monthlyDetail", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36" } queryBillDetailNum_data = { "accNbr": self.phoneNumber, "billingCycle": month, "ticketType": "0" } queryBillDetailNum_res = self.session.post( url=queryBillDetailNum_url, headers=headers, json=queryBillDetailNum_data, cookies=self.cookies) queryBillDetailNum_j = queryBillDetailNum_res.json() if queryBillDetailNum_j.get('resultMsg') == '成功': records = int( queryBillDetailNum_j.get('records')) # 通话记录条数,每页为20条记录 if records == 0: print('{}无通话记录'.format(month)) continue else: pages = records // 20 if records % 20 == 0 else records // 20 + 1 try: for pageNo in range(pages): queryBillDetail_url = 'http://sd.189.cn/selfservice/bill/queryBillDetail' queryBillDetail_data = { "accNbr": self.phoneNumber, "billingCycle": month, "pageRecords": "20", "pageNo": str(pageNo + 1), "qtype": "0", "totalPage": "1", "queryType": "6" } queryBillDetail_res = self.session.post( url=queryBillDetail_url, headers=headers, json=queryBillDetail_data, cookies=self.cookies) queryBillDetail_j = queryBillDetail_res.json() if queryBillDetail_j.get( "ruleId") == '1': # 身份认证未通过的情况,重新认证 self.second_selfservice() elif queryBillDetail_j.get( "resultMsg") == "服务忙,请稍后再试": self.get_phone_records() elif queryBillDetail_j.get("resultMsg") == "成功": callDetailRecord = [] # print(queryBillDetail_j) items = jsonpath.jsonpath( queryBillDetail_j, "$..items")[0] for _ in items: txxiangDanModel = dict() txxiangDanModel['startTime'] = _.get( 'startTime') # 本次通话发生时间 txxiangDanModel['commPlac'] = _.get( 'position') # 本次通话发生地点 txxiangDanModel['commMode'] = _.get( 'callType') # 本次通话方式,主叫/被叫 txxiangDanModel['anotherNm'] = _.get( 'calledNbr') # 本次通话对方号码 txxiangDanModel['commTime'] = _.get( 'duration') # 本次通话时长(秒) txxiangDanModel['commType'] = _.get( 'eventType') # 本次通话类型 ,无通讯费用 txxiangDanModel['commFee'] = _.get( 'charge') # 本次通话通信费(元) callDetailRecord.append(txxiangDanModel) print(callDetailRecord) except Exception as e: print(e) return self.second_selfservice() else: return self.get_phone_records()
def test_humanize_delta_handle_high_units(self): """humanize_delta should be able to handle very high units.""" # Very high maximum units, but it only ever iterates over # each value the relativedelta might have. self.assertEqual(time.humanize_delta(relativedelta(days=2, hours=2), 'hours', 20), '2 days and 2 hours')
def main(): # 引数の処理 argvs = sys.argv _type = "" # ダウンロードするデータのタイプ(日ごと、1時間ごと、10分ごと) _force = False # 既にhtmlファイル(中身はチェックしない)があるかどうかに関わらず新規にダウンロードする場合はTrue if len(argvs) >= 2: _type = argvs[1] if _type not in "daily hourly 10min real-time": # 引数ミスのチェック print("please set argv. e.g. daily, hourly, 10min, real-time.") exit() if "-f" in argvs: _force = True else: print("please set argv. e.g. daily, hourly, 10min, real-time.") exit() amedas_nodes = get_amedas_nodes() # ダウンロードの対象となっている期間とアメダスの一覧をファイルから読み込む target = [] with open("AMEDAS.ini", "r", encoding="utf-8-sig") as fr: lines = fr.readlines() start_date = dt.strptime(lines[0], "start=%Y,%m,%d\n") end_date = dt.strptime(lines[1], "stop=%Y,%m,%d\n") for i in range(3, len(lines)): line = lines[i] line = line.rstrip() line = line.lstrip() if len(line) == 0: continue if "#" in line: continue field = re.split(r"\t|,|\s+", line) print(field) block_no, name = field while True: # Excelで編集した際に文字列先頭の0を無くしちゃうことがあるが、面倒なのでコードで対応 if len(block_no) >= 4: break block_no = "0" + block_no target.append(block_no) # もし、最新データが必要であれば設定ファイルの内容を無視して、現時点の時刻データに置き換える if _type == "real-time": start_date = dt.now() end_date = start_date # 観測データをダウンロードして保存する t = start_date while t <= end_date: for val in target: node = amedas_nodes[val] isaccess = node.save(_type, t, force=_force) if isaccess: time.sleep(0.2) if _type == "10min" or _type == "hourly" or _type == "real-time": t += td(days=1) elif _type == "daily": t += relativedelta(months=1) """
def get_month(off): today = date.today() d = today - relativedelta(months=off) return date(d.year, d.month, 1)
def update(self): self.data.update() waste_data = self.data.data try: if waste_data: if self.type in waste_data: collection_date = datetime.strptime( waste_data[self.type], "%Y-%m-%d" ).date() # Date in date format "%Y-%m-%d" self._year_month_day_date = str(collection_date) if collection_date: # Set the values of the sensor self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M") # Is the collection date today? self._is_collection_date_today = date.today() == collection_date # Days until collection date delta = collection_date - date.today() self._days_until_collection_date = delta.days # Only show the value if the date is lesser than or equal to (today + timespan_in_days) if collection_date <= date.today() + relativedelta(days=int(self.timespan_in_days)): #if the date does not contain a named day or month, return the date as normal if (self.date_format.find('a') == -1 and self.date_format.find('A') == -1 and self.date_format.find('b') == -1 and self.date_format.find('B') == -1): self._state = collection_date.strftime(self.date_format) #else convert the named values to the locale names else: edited_date_format = self.date_format.replace('%a', 'EEE') edited_date_format = edited_date_format.replace('%A', 'EEEE') edited_date_format = edited_date_format.replace('%b', 'MMM') edited_date_format = edited_date_format.replace('%B', 'MMMM') #half babel, half date string... something like EEEE 04-MMMM-2020 half_babel_half_date = collection_date.strftime(edited_date_format) #replace the digits with qquoted digits 01 --> '01' half_babel_half_date = re.sub(r"(\d+)", r"'\1'", half_babel_half_date) #transform the EEE, EEEE etc... to a real locale date, with babel locale_date = format_date(collection_date, half_babel_half_date, locale=self.locale) self._state = locale_date else: self._hidden = True else: raise ValueError() else: raise ValueError() else: raise ValueError() except ValueError: self._state = None self._hidden = True self._days_until_collection_date = None self._year_month_day_date = None self._is_collection_date_today = False self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")
def account_detail(request, id): template_name = 'retirement_401k/account_detail.html' account = get_object_or_404(Account401K, id=id) acct = dict() acct['id'] = account.id acct['company'] = account.company acct['start_date'] = account.start_date acct['end_date'] = account.end_date acct['employee_contribution'] = account.employee_contribution acct['employer_contribution'] = account.employer_contribution acct['total'] = account.total acct['notes'] = account.notes acct['as_on_date'] = account.nav_date acct['lv_dollar'] = round(account.units*account.nav, 2) acct['units'] = account.units acct['latest_value'] = account.latest_value if account.goal: acct['goal'] = get_goal_name_from_id(account.goal) acct['user'] = get_user_name_from_id(account.user) acct['roi'] = account.roi acct['nav'] = account.nav chart_data = get_yearly_contribution(id) acct['years'] = chart_data['years'] acct['er_vals'] = chart_data['er'] acct['em_vals'] = chart_data['em'] acct['in_vals'] = chart_data['int'] acct['total_vals'] = chart_data['total'] acct['nav_history'] = NAVHistory.objects.filter(account=account) #{{fund_vals|safe}}, {{voo_vals|safe}}, {{chart_labels|safe}} fund_vals = list() spy_vals = list() chart_labels = list() for nav in NAVHistory.objects.filter(account=account).order_by('nav_date'): chart_labels.append(nav.nav_date.strftime('%Y-%m-%d')) fund_vals.append(float(nav.nav_value)) val = None if nav.comparision_nav_value and nav.comparision_nav_value != 0: val = float(nav.comparision_nav_value) else: response = YahooFinance2('SPY').get_historical_value(nav.nav_date, nav.nav_date+relativedelta(days=5)) val_date = None for k,v in response.items(): if not val: val = v val_date = k else: if val_date > k: val_date = k val = v if val: nav.comparision_nav_value = round(val, 2) nav.save() else: val = 0 spy_vals.append(val) acct['fund_vals'] = fund_vals acct['chart_labels'] = chart_labels acct['spy_vals'] = spy_vals acct['curr_module_id'] = 'id_401k_module' return render(request, template_name, acct)
def test_humanize_delta_handle_unknown_units(self): """humanize_delta should be able to handle unknown units, and will not abort.""" # Does not abort for unknown units, as the unit name is checked # against the attribute of the relativedelta instance. self.assertEqual(time.humanize_delta(relativedelta(days=2, hours=2), 'elephants', 2), '2 days and 2 hours')
def create(self, vals): vals['next_run_date'] = date.today() + relativedelta(days=3) return super(Digest, self).create(vals)
def homepage(request): date_now = datetime.date.today() katastimata = [ 'Σκάλα', 'Μολάοι Κεντρικό', 'Μολάοι Παιδικό', 'MyModa', 'Boom' ] search_pro = request.POST.get('search_pro', None) try: picked_date = request.session['date_now'] except: picked_date = None request.session['date_now'] = None #stats per month start_year = datetime.datetime(datetime.datetime.now().year, 1, 1) months_list = [] month = 1 months = diff_month(start_year, date_now) while month <= months + 1: months_list.append( datetime.datetime(datetime.datetime.now().year, month, 1).month) month += 1 title = 'Try' incomes = AddEsoda.objects.all().filter( title__month=date_now.month, title__year=date_now.year).order_by('-title') incomes_initial = AddEsoda.objects.all().filter( title__range=[start_year, date_now]) date_pick = request.POST.get('date_pick') if search_pro: incomes = AddEsoda.objects.filter(comments__icontains=search_pro) try: date_range = date_pick.split('-') date_range[0] = date_range[0].replace(' ', '') date_range[1] = date_range[1].replace(' ', '') date_start = datetime.datetime.strptime(date_range[0], '%m/%d/%Y') date_end = datetime.datetime.strptime(date_range[1], '%m/%d/%Y') incomes = AddEsoda.objects.all() start_next_year = date_start end_next_year = date_end start_last_year = date_start end_last_year = date_end start_next_year = start_next_year + relativedelta( year=start_next_year.year + 1) end_next_year = end_next_year + relativedelta(year=end_next_year.year + 1) #start_next_year = datetime.datetime.strptime(start_next_year, '%m/%d/%Y') #end_next_year = datetime.datetime.strptime(end_last_year,'%m/%d/%Y') incomes_next_year = incomes.filter( title__range=[start_next_year, end_next_year]).order_by('-title') start_last_year = start_last_year + relativedelta( year=start_last_year.year - 1) end_last_year = end_last_year + relativedelta(year=end_last_year.year - 1) incomes_last_year = incomes.filter( title__range=[start_last_year, end_last_year]).order_by('-title') incomes = incomes.filter( title__range=[date_start, date_end]).order_by('-title') print(date_end, date_start, start_next_year, end_next_year) except: date_pick = None #get next year reports try: all_retail_next = incomes_next_year.aggregate(Sum('sinolo_fisikon')) all_retail_next = all_retail_next['sinolo_fisikon__sum'] all_retail_avg_next = incomes_next_year.aggregate( Avg('sinolo_fisikon')) all_retail_avg_next = all_retail_avg_next['sinolo_fisikon__avg'] except: all_retail_next = 0 all_retail_avg_next = 0 try: all_incomes_next = incomes_next_year.aggregate(Sum('sinolo_olon')) all_incomes_next = all_incomes_next['sinolo_olon__sum'] all_incomes_avg_next = incomes_next_year.aggregate(Avg('sinolo_olon')) all_incomes_avg_next = all_incomes_avg_next['sinolo_olon__avg'] except: all_incomes_next = 0 all_incomes_avg_next = 0 try: pediko_total_next = incomes_next_year.aggregate(Sum('pediko')) pediko_total_next = pediko_total_next['pediko__sum'] pediko_total_avg_next = incomes_next_year.aggregate(Avg('pediko')) pediko_total_avg_next = pediko_total_avg_next['pediko__avg'] except: pediko_total_next = 0 pediko_total_avg_next = 0 try: topiko_next = incomes_next_year.aggregate(Sum('topiko_katastima')) topiko_next = topiko_next['topiko_katastima__sum'] topiko_avg_next = incomes_next_year.aggregate(Avg('topiko_katastima')) topiko_avg_next = topiko_avg_next['topiko_katastima__avg'] except: topiko_next = 0 topiko_avg_next = 0 try: skala_next = incomes_next_year.aggregate(Sum('skala')) skala_next = skala_next['skala__sum'] skala_avg_next = incomes_next_year.aggregate(Avg('skala')) skala_avg_next = skala_avg_next['skala__avg'] except: skala_next = 0 skala_avg_next = 0 try: my_moda_next = incomes_next_year.aggregate(Sum('mymoda')) my_moda_next = my_moda_next['mymoda__sum'] my_moda_avg_next = incomes_next_year.aggregate(Avg('mymoda')) my_moda_avg_next = my_moda_avg_next['mymoda__avg'] except: my_moda_next = 0 my_moda_avg_next = 0 #get last year reports try: all_retail_last = incomes_last_year.aggregate(Sum('sinolo_fisikon')) all_retail_last = all_retail_last['sinolo_fisikon__sum'] all_retail_avg_last = incomes_last_year.aggregate( Avg('sinolo_fisikon')) all_retail_avg_last = all_retail_avg_last['sinolo_fisikon__avg'] except: all_retail_last = 0 all_retail_avg_last = 0 try: all_incomes_last = incomes_last_year.aggregate(Sum('sinolo_olon')) all_incomes_last = all_incomes_last['sinolo_olon__sum'] all_incomes_avg_last = incomes_last_year.aggregate(Avg('sinolo_olon')) all_incomes_avg_last = all_incomes_avg_last['sinolo_olon__avg'] except: all_incomes_last = 0 all_incomes_avg_last = 0 try: pediko_total_last = incomes_last_year.aggregate(Sum('pediko')) pediko_total_last = pediko_total_last['pediko__sum'] pediko_total_avg_last = incomes_last_year.aggregate(Avg('pediko')) pediko_total_avg_last = pediko_total_avg_last['pediko__avg'] except: pediko_total_last = 0 pediko_total_avg_last = 0 try: topiko_last = incomes_last_year.aggregate(Sum('topiko_katastima')) topiko_last = topiko_last['topiko_katastima__sum'] topiko_avg_last = incomes_last_year.aggregate(Avg('topiko_katastima')) topiko_avg_last = topiko_avg_last['topiko_katastima__avg'] except: topiko_last = 0 topiko_avg_last = 0 try: skala_last = incomes_last_year.aggregate(Sum('skala')) skala_last = skala_last['skala__sum'] skala_avg_last = incomes_last_year.aggregate(Avg('skala')) skala_avg_last = skala_avg_last['skala__avg'] except: skala_last = 0 skala_avg_last = 0 try: my_moda_last = incomes_last_year.aggregate(Sum('mymoda')) my_moda_last = my_moda_last['mymoda__sum'] my_moda_avg_last = incomes_last_year.aggregate(Avg('mymoda')) my_moda_avg_last = my_moda_avg_last['mymoda__avg'] except: my_moda_last = 0 my_moda_avg_last = 0 #get reports try: all_retail = incomes.aggregate(Sum('sinolo_fisikon')) all_retail = all_retail['sinolo_fisikon__sum'] all_retail_avg = incomes.aggregate(Avg('sinolo_fisikon')) all_retail_avg = all_retail_avg['sinolo_fisikon__avg'] except: all_retail = 0 all_retail_avg = 0 try: all_incomes = incomes.aggregate(Sum('sinolo_olon')) all_incomes = all_incomes['sinolo_olon__sum'] all_incomes_avg = incomes.aggregate(Avg('sinolo_olon')) all_incomes_avg = all_incomes_avg['sinolo_olon__avg'] except: all_incomes = 0 all_incomes_avg = 0 try: pediko_total = incomes.aggregate(Sum('pediko')) pediko_total = pediko_total['pediko__sum'] pediko_total_avg = incomes.aggregate(Avg('pediko')) pediko_total_avg = pediko_total_avg['pediko__avg'] except: pediko_total = 0 pediko_total_avg = 0 try: topiko = incomes.aggregate(Sum('topiko_katastima')) topiko = topiko['topiko_katastima__sum'] topiko_avg = incomes.aggregate(Avg('topiko_katastima')) topiko_avg = topiko_avg['topiko_katastima__avg'] except: topiko = 0 topiko_avg = 0 try: skala = incomes.aggregate(Sum('skala')) skala = skala['skala__sum'] skala_avg = incomes.aggregate(Avg('skala')) skala_avg = skala_avg['skala__avg'] except: skala = 0 skala_avg = 0 try: my_moda = incomes.aggregate(Sum('mymoda')) my_moda = my_moda['mymoda__sum'] my_moda_avg = incomes.aggregate(Avg('mymoda')) my_moda_avg = my_moda_avg['mymoda__avg'] except: my_moda = 0 my_moda_avg = 0 try: boom = incomes.aggregate( Sum('boom'))['boom__sum'] if incomes.aggregate(Sum('boom')) else 0 boom_avg = incomes.aggregate( Avg('boom'))['boom__avg'] if incomes.aggregate(Avg('boom')) else 0 except: boom = 0 boom_avg = 0 try: boom_last = incomes_last_year.aggregate( Sum('boom'))['boom__sum'] if incomes_last_year.aggregate( Sum('boom')) != None else 0 boom_avg_last = incomes_last_year.aggregate( Avg('boom'))['boom__avg'] if incomes_last_year.aggregate( Avg('boom')) else 0 boom_next = incomes_next_year.aggregate( Sum('boom'))['boom__sum'] if incomes_next_year.aggregate( Sum('boom')) else 0 boom_avg_next = incomes_next_year.aggregate( Avg('boom'))['boom__avg'] if incomes_next_year.aggregate( Avg('boom')) else 0 except: boom_last = 0 boom_avg_last = 0 boom_next = 0 boom_avg_next = 0 total_per_month = [] for num in months_list: month = datetime.datetime.now() - relativedelta(months=num - 1) boom_sum = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate( Sum('boom'))['boom__sum'] if incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate( Sum('boom'))['boom__sum'] else 0 try: sum_paidiko = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('pediko')) sum_paidiko = sum_paidiko['pediko__sum'] except: sum_paidiko = 0 try: sum_kenriko = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('topiko_katastima')) sum_kenriko = sum_kenriko['topiko_katastima__sum'] except: sum_kenriko = 0 try: sum_skala = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('skala')) sum_skala = sum_skala['skala__sum'] except: sum_skala = 0 try: sum_my_moda = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('mymoda')) sum_my_moda = sum_my_moda['mymoda__sum'] except: sum_my_moda = 0 try: sum_fisikon = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('sinolo_fisikon')) sum_fisikon = sum_fisikon['sinolo_fisikon__sum'] except: sum_fisikon = 0 try: sum_total = incomes_initial.filter( title__month=month.month, title__year=month.year).aggregate(Sum('sinolo_olon')) sum_total = sum_total['sinolo_olon__sum'] except: sum_total = 0 total_per_month.append((month, sum_paidiko, sum_kenriko, sum_skala, sum_fisikon, sum_my_moda, sum_total, boom_sum)) #the section of total sum per katastima katastima_name = request.POST.get('vendor_name') or None month_analysis = [] this_year = date_now years = [] year_initial = datetime.datetime.now().today().year ele = 1 all_months = [ ('January', '1'), ('February', '2'), ('March', '3'), ('April', '4'), ('May', '5'), ('June', '6'), ('July', '7'), ('August', '8'), ('September', '9'), ('October', '10'), ('November', '11'), ('December', '12'), ] try: jk = YearMeter.objects.get(id=1).title except: jk = 5 if katastima_name: while ele < jk + 1: years.append(year_initial) year_initial -= 1 ele += 1 if katastima_name == 'Σκάλα': incomes_initial = AddEsoda.objects.all() for month in all_months: year_analysis = [] for yeara in years: try: sum_skala = incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate(Sum('skala')) sum_skala = sum_skala['skala__sum'] except: sum_skala = 0 year_analysis.append(sum_skala) month_analysis.append((month[0], year_analysis)) final_data = [] for month in month_analysis: final_data.append(month[0]) try: print(month[1][0] - month[1][1]) except: print(month[1][0]) print(final_data) if katastima_name == 'Μολάοι Κεντρικό': incomes_initial = AddEsoda.objects.all() for month in all_months: year_analysis = [] for yeara in years: try: sum_skala = incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate(Sum('topiko_katastima')) sum_skala = sum_skala['topiko_katastima__sum'] except: sum_skala = 0 year_analysis.append(sum_skala) month_analysis.append((month[0], year_analysis)) if katastima_name == 'Μολάοι Παιδικό': incomes_initial = AddEsoda.objects.all() for month in all_months: year_analysis = [] for yeara in years: try: sum_skala = incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate(Sum('pediko')) sum_skala = sum_skala['pediko__sum'] except: sum_skala = 0 year_analysis.append(sum_skala) month_analysis.append((month[0], year_analysis)) if katastima_name == 'MyModa': incomes_initial = AddEsoda.objects.all() for month in all_months: year_analysis = [] for yeara in years: try: sum_skala = incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate(Sum('mymoda')) sum_skala = sum_skala['mymoda__sum'] except: sum_skala = 0 year_analysis.append(sum_skala) month_analysis.append((month[0], year_analysis)) if katastima_name == 'Boom': incomes_initial = AddEsoda.objects.all() for month in all_months: year_analysis = [] for yeara in years: sum_boom = incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate( Sum('boom'))['boom__sum'] if incomes_initial.filter( title__month=month[1], title__year=yeara).aggregate( Sum('boom'))['boom__sum'] else 0 year_analysis.append(sum_boom) month_analysis.append((month[0], year_analysis)) if pediko_total == None: pediko_total = 0 pediko_total_last = pediko_total_last if pediko_total_last else 0 topiko_last = topiko_last if topiko_last else 0 skala_last = skala_last if skala_last else 0 my_moda_last = my_moda_last if my_moda_last else 0 all_retail_last = all_retail_last if all_retail_last else 0 all_incomes_last = all_incomes_last if all_incomes_last else 0 boom_last = boom_last if boom_last else 0 if topiko == None: topiko = 0 if skala == None: skala = 0 if my_moda == None: my_moda = 0 if all_retail == None: all_retail = 0 if all_incomes == None: all_incomes = 0 if boom == None: boom = 0 diff_bewetween_years = [ pediko_total - pediko_total_last, topiko - topiko_last, skala - skala_last, my_moda - my_moda_last, all_retail - all_retail_last, all_incomes - all_incomes_last, boom - boom_last, ] context = { 'title': title, 'kat_name': katastima_name, 'total_per_month': total_per_month, 'all_esoda': incomes, 'vendors': katastimata, #next year_analysis 'all_retail_next': all_retail_next, 'all_retail_avg_next': all_retail_avg_next, 'all_incomes_next': all_incomes_next, 'all_incomes_avg_next': all_incomes_avg_next, 'pediko_total_next': pediko_total_next, 'pediko_avg_next': pediko_total_avg_next, 'topiko_next': topiko_next, 'topiko_avg_next': topiko_avg_next, 'skala_next': skala_next, 'skala_avg_next': skala_avg_next, 'my_moda_next': my_moda_next, 'my_moda_avg_next': my_moda_avg_next, #last year_analysis 'all_retail_last': all_retail_last, 'all_retail_avg_last': all_retail_avg_last, 'all_incomes_last': all_incomes_last, 'all_incomes_avg_last': all_incomes_avg_last, 'pediko_total_last': pediko_total_last, 'pediko_avg_last': pediko_total_avg_last, 'topiko_last': topiko_last, 'topiko_avg_last': topiko_avg_last, 'skala_last': skala_last, 'skala_avg_last': skala_avg_last, 'my_moda_last': my_moda_last, 'my_moda_avg_last': my_moda_avg_last, #current target 'all_retail': all_retail, 'all_retail_avg': all_retail_avg, 'all_incomes': all_incomes, 'all_incomes_avg': all_incomes_avg, 'pediko_total': pediko_total, 'pediko_avg': pediko_total_avg, 'topiko': topiko, 'topiko_avg': topiko_avg, 'skala': skala, 'skala_avg': skala_avg, 'my_moda': my_moda, 'my_moda_avg': my_moda_avg, 'date_pick': date_pick, 'month_ana': month_analysis, 'years': years, 'picked_date': picked_date, 'year_meter': jk, 'diff_be': diff_bewetween_years, 'boom': boom, 'boom_avg': boom_avg, 'boom_next': boom_next, 'boom_last': boom_last, 'boom_avg_next': boom_avg_next, 'boom_avg_last': boom_avg_last, } return render(request, 'katastimata_esoda/homepage.html', context)
self.delete_delivery_token_in_charon() # implemented self.send_email() # not implemented return 'DELIVERED' elif mover_status == 'FAILED': self.update_delivery_status('FAILED') # implemented self.delete_delivery_token_in_charon() # implemented # todo: to implement this self.send_email() # not implemented return 'FAILED' elif mover_status == 'IN_PROGRESS': # this is not in Charon yet, talk to Denis delivery_started = parser.parse(self.db_entry().get('delivery_started')) # alternative way: checking when the folder was created # delivery_started = datetime.datetime.fromtimestamp(os.path.getctime(path)) today = datetime.datetime.now() if delivery_started + relativedelta(days=7) >= today: logger.warning('Delivery has been ongoing for more than 7 days. Project will be marked as "FAILED"') self.update_delivery_status('FAILED') self.delete_delivery_token_in_charon() # todo: to implement this self.send_email() return 'FAILED' else: # do nothing return 'IN_PROGRESS' def deliver_project(self): """ Deliver all samples in a project to grus :returns: True if all samples were delivered successfully, False if
from datetime import datetime from dateutil.relativedelta import relativedelta from operator import itemgetter from traceback import format_exception from sys import exc_info from openerp.tools.safe_eval import safe_eval as eval import re from openerp.addons.decimal_precision import decimal_precision as dp from openerp import api from openerp.osv import fields, osv from openerp.report import render_report from openerp.tools.translate import _ _intervalTypes = { 'hours': lambda interval: relativedelta(hours=interval), 'days': lambda interval: relativedelta(days=interval), 'months': lambda interval: relativedelta(months=interval), 'years': lambda interval: relativedelta(years=interval), } DT_FMT = '%Y-%m-%d %H:%M:%S' class marketing_campaign(osv.osv): _name = "marketing.campaign" _description = "Marketing Campaign" def _count_segments(self, cr, uid, ids, field_name, arg, context=None): res = {} try:
class ContactFormPurpose(AbstractPurpose): name = "retain due to mailing campaign" slug = CONTACT_FORM_SLUG expiration_timedelta = relativedelta(months=1) fields = "__ALL__"
def get_start_date(self): """ Find the nearest Monday preceding the start date given on input. """ return (parse(self.request.input.start) + relativedelta(weekday=MO(-1))).strftime('%Y-%m-%d')
def decode_relativedelta(var: Dict[str, Any]) -> relativedelta.relativedelta: if 'weekday' in var: var['weekday'] = relativedelta.weekday(*var['weekday']) # type: ignore return relativedelta.relativedelta(**var)
class FirstNLastNamePurpose(AbstractPurpose): """Store First & Last name for 10 years.""" name = "retain due to internet archive" slug = FIRST_AND_LAST_NAME_SLUG expiration_timedelta = relativedelta(years=10) fields = ("first_name", "last_name")
def get_year_of(date): begin = (datetime_to_midnight(date) - relativedelta(months=(date.month - 1), days=(date.day - 1))) return begin, begin + relativedelta(years=1)
def render_html(self, data=None): report_obj = self.env['report'] report = report_obj._get_report_from_name( 'hr_attendance_report.print_attendance') docs = [] employee_attendance = {} totals = {} for employee in self.env[report.model].browse(data['ids']): employee_attendance[employee.id] = [] docs.append(employee) from_date_s = data.get('form', {}).get('from_date', '') to_date_s = data.get('form', {}).get('to_date', '') from_date = datetime.strptime(from_date_s, '%Y-%m-%d').date() to_date = datetime.strptime(to_date_s, '%Y-%m-%d').date() while from_date <= to_date: from_date_1 = datetime.strftime(from_date, "%Y-%m-%d %H:%M:%S") from_date_2 = datetime.strftime(from_date, "%Y-%m-%d 23:59:59") attendances = self.env['hr.attendance'].search( [('employee_id', '=', employee.id), ('name', '>=', from_date_1), ('name', '<=', from_date_2)], order='name asc') day_attendances = {'ord_hours': 0, 'in_out_str': '', 'day': from_date_1[8:10]} used_ids = [] while len(attendances) - len(used_ids) >= 2: in_attr = attendances.filtered( lambda r: r.id not in used_ids and r.action == 'sign_in')[0] out_attr = attendances.filtered( lambda r: r.id not in used_ids and r.action == 'sign_out')[0] in_time = fields.Datetime.context_timestamp( self, datetime.strptime(in_attr.name, "%Y-%m-%d %H:%M:%S")) out_time = fields.Datetime.context_timestamp( self, datetime.strptime(out_attr.name, "%Y-%m-%d %H:%M:%S")) day_attendances['ord_hours'] += out_attr.worked_hours fields.Datetime.context_timestamp( self, datetime.strptime(attendances[0].name, "%Y-%m-%d %H:%M:%S")) day_attendances['in_out_str'] += \ '%02d:%02d-%02d:%02d | ' % (in_time.hour, in_time.minute, out_time.hour, out_time.minute) used_ids.append(in_attr.id) used_ids.append(out_attr.id) if day_attendances['in_out_str']: day_attendances['in_out_str'] = \ day_attendances['in_out_str'][:-3] if day_attendances['ord_hours']: employee_attendance[employee.id].append(day_attendances) from_date += relativedelta(days=1) totals[employee.id] = { 'total': sum(x['ord_hours'] for x in employee_attendance[employee.id]), 'ordinary': sum(x['ord_hours'] for x in employee_attendance[employee.id]), 'complementary': 0, 'extra': 0 } docargs = { 'doc_ids': data['ids'], 'doc_model': report.model, 'docs': docs, 'attendances': employee_attendance, 'data': data, 'totals': totals } return report_obj.render('hr_attendance_report.print_attendance', docargs)
def get_quarter_of(date): begin = (datetime_to_midnight(date) - relativedelta(months=(date.month % 3) - 1, days=(date.day - 1))) return begin, begin + relativedelta(months=3)
def main(): # Silence upload.py. rietveld.upload.verbosity = 0 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) parser.add_option('-u', '--user', metavar='<email>', default=os.environ.get('USER'), help='Filter on user, default=%default') parser.add_option('-b', '--begin', metavar='<date>', help='Filter issues created after the date (mm/dd/yy)') parser.add_option('-e', '--end', metavar='<date>', help='Filter issues created before the date (mm/dd/yy)') quarter_begin, quarter_end = get_quarter_of(datetime.today() - relativedelta(months=2)) parser.add_option( '-Q', '--last_quarter', action='store_true', help='Use last quarter\'s dates, i.e. %s to %s' % (quarter_begin.strftime('%Y-%m-%d'), quarter_end.strftime('%Y-%m-%d'))) parser.add_option('-Y', '--this_year', action='store_true', help='Use this year\'s dates') parser.add_option('-w', '--week_of', metavar='<date>', help='Show issues for week of the date (mm/dd/yy)') parser.add_option( '-W', '--last_week', action='count', help='Show last week\'s issues. Use more times for more weeks.') parser.add_option( '-a', '--auth', action='store_true', help='Ask to authenticate for instances with no auth cookie') parser.add_option('-d', '--deltas', action='store_true', help='Fetch deltas for changes.') parser.add_option( '--no-referenced-issues', action='store_true', help='Do not fetch issues referenced by owned changes. Useful in ' 'combination with --changes-by-issue when you only want to list ' 'issues that have also been modified in the same time period.') parser.add_option( '--skip-own-issues-without-changes', action='store_true', help='Skips listing own issues without changes when showing changes ' 'grouped by referenced issue(s). See --changes-by-issue for more ' 'details.') activity_types_group = optparse.OptionGroup( parser, 'Activity Types', 'By default, all activity will be looked up and ' 'printed. If any of these are specified, only ' 'those specified will be searched.') activity_types_group.add_option('-c', '--changes', action='store_true', help='Show changes.') activity_types_group.add_option('-i', '--issues', action='store_true', help='Show issues.') activity_types_group.add_option('-r', '--reviews', action='store_true', help='Show reviews.') activity_types_group.add_option( '--changes-by-issue', action='store_true', help='Show changes grouped by referenced issue(s).') parser.add_option_group(activity_types_group) output_format_group = optparse.OptionGroup( parser, 'Output Format', 'By default, all activity will be printed in the ' 'following format: {url} {title}. This can be ' 'changed for either all activity types or ' 'individually for each activity type. The format ' 'is defined as documented for ' 'string.format(...). The variables available for ' 'all activity types are url, title and author. ' 'Format options for specific activity types will ' 'override the generic format.') output_format_group.add_option( '-f', '--output-format', metavar='<format>', default=u'{url} {title}', help='Specifies the format to use when printing all your activity.') output_format_group.add_option( '--output-format-changes', metavar='<format>', default=None, help='Specifies the format to use when printing changes. Supports the ' 'additional variable {reviewers}') output_format_group.add_option( '--output-format-issues', metavar='<format>', default=None, help='Specifies the format to use when printing issues. Supports the ' 'additional variable {owner}.') output_format_group.add_option( '--output-format-reviews', metavar='<format>', default=None, help='Specifies the format to use when printing reviews.') output_format_group.add_option( '--output-format-heading', metavar='<format>', default=u'{heading}:', help='Specifies the format to use when printing headings.') output_format_group.add_option( '--output-format-no-url', default='{title}', help='Specifies the format to use when printing activity without url.') output_format_group.add_option( '-m', '--markdown', action='store_true', help='Use markdown-friendly output (overrides --output-format ' 'and --output-format-heading)') output_format_group.add_option( '-j', '--json', action='store_true', help='Output json data (overrides other format options)') parser.add_option_group(output_format_group) auth.add_auth_options(parser) parser.add_option('-v', '--verbose', action='store_const', dest='verbosity', default=logging.WARN, const=logging.INFO, help='Output extra informational messages.') parser.add_option('-q', '--quiet', action='store_const', dest='verbosity', const=logging.ERROR, help='Suppress non-error messages.') parser.add_option( '-o', '--output', metavar='<file>', help='Where to output the results. By default prints to stdout.') # Remove description formatting parser.format_description = (lambda _: parser.description) # pylint: disable=no-member options, args = parser.parse_args() options.local_user = os.environ.get('USER') if args: parser.error('Args unsupported') if not options.user: parser.error('USER is not set, please use -u') options.user = username(options.user) logging.basicConfig(level=options.verbosity) # python-keyring provides easy access to the system keyring. try: import keyring # pylint: disable=unused-import,unused-variable,F0401 except ImportError: logging.warning('Consider installing python-keyring') if not options.begin: if options.last_quarter: begin, end = quarter_begin, quarter_end elif options.this_year: begin, end = get_year_of(datetime.today()) elif options.week_of: begin, end = (get_week_of( datetime.strptime(options.week_of, '%m/%d/%y'))) elif options.last_week: begin, end = ( get_week_of(datetime.today() - timedelta(days=1 + 7 * options.last_week))) else: begin, end = (get_week_of(datetime.today() - timedelta(days=1))) else: begin = dateutil.parser.parse(options.begin) if options.end: end = dateutil.parser.parse(options.end) else: end = datetime.today() options.begin, options.end = begin, end if options.markdown: options.output_format_heading = '### {heading}\n' options.output_format = ' * [{title}]({url})' options.output_format_no_url = ' * {title}' logging.info('Searching for activity by %s', options.user) logging.info('Using range %s to %s', options.begin, options.end) my_activity = MyActivity(options) my_activity.show_progress('Loading data') if not (options.changes or options.reviews or options.issues or options.changes_by_issue): options.changes = True options.issues = True options.reviews = True # First do any required authentication so none of the user interaction has to # wait for actual work. if options.changes or options.changes_by_issue: my_activity.auth_for_changes() if options.reviews: my_activity.auth_for_reviews() logging.info('Looking up activity.....') try: if options.changes or options.changes_by_issue: my_activity.get_changes() if options.reviews: my_activity.get_reviews() if options.issues or options.changes_by_issue: my_activity.get_issues() if not options.no_referenced_issues: my_activity.get_referenced_issues() except auth.AuthenticationError as e: logging.error('auth.AuthenticationError: %s', e) my_activity.show_progress('\n') my_activity.print_access_errors() output_file = None try: if options.output: output_file = open(options.output, 'w') logging.info('Printing output to "%s"', options.output) sys.stdout = output_file except (IOError, OSError) as e: logging.error('Unable to write output: %s', e) else: if options.json: my_activity.dump_json() else: if options.changes: my_activity.print_changes() if options.reviews: my_activity.print_reviews() if options.issues: my_activity.print_issues() if options.changes_by_issue: my_activity.print_changes_by_issue( options.skip_own_issues_without_changes) finally: if output_file: logging.info('Done printing to file.') sys.stdout = sys.__stdout__ output_file.close() return 0