def action(self): config_obj = ApplicationConfig.get_current_config() cleaning_time_presence = int(config_obj.cleaning_time_presence) today = datetime.datetime.now().date() date = today - datetime.timedelta(days=cleaning_time_presence) end_date = datetime.datetime.combine(date, day_end) start_date = end_date - datetime.timedelta(days=cleaning_time_presence * 3) cleaned = DBSession.execute( """ WITH minq as ( SELECT MIN(p1.id) FROM presence_entry as p1 WHERE p1.ts >= :start_date AND p1.ts <= :end_date GROUP BY p1.user_id, date_trunc('day', p1.ts) ), maxq as ( SELECT MAX(p2.id) FROM presence_entry as p2 WHERE p2.ts >= :start_date AND p2.ts <= :end_date GROUP BY p2.user_id, date_trunc('day', p2.ts) ) DELETE FROM presence_entry as p WHERE p.ts >= :start_date AND p.ts <= :end_date AND p.id NOT IN (SELECT * FROM minq) AND p.id NOT IN (SELECT * FROM maxq); """, params={"start_date": start_date, "end_date": end_date}, ).rowcount LOG(u"Cleaned %s entries" % (cleaned,)) return Response(self._(u"Cleaned ${num} entries", num=cleaned))
def send_html(cls, to, topic, message): config = ApplicationConfig.get_current_config() email = MIMEMultipart('alternative') email['Subject'] = topic email['From'] = config.google_user_email email['To'] = to email.attach(MIMEText(message,'html', 'utf-8')) formatted_mail = email.as_string() messageFile = StringIO(formatted_mail) resultDeferred = Deferred() senderFactory = ESMTPSenderFactory( config.google_user_email, # user config.google_user_password, # secret config.google_user_email, # from to, # to messageFile, # message resultDeferred, # deferred contextFactory=cls.contextFactory) reactor.connectTCP(cls.SMTP_SERVER, cls.SMTP_PORT, senderFactory) return resultDeferred
def dispatch(self): subpage = self.request.GET.get('subpage', 'general') if subpage not in ['general', 'reports', 'spreadsheets', 'access']: return HTTPForbidden() config_obj = ApplicationConfig.get_current_config(allow_empty=True) FormRef = getattr(config_forms, "%sForm" % subpage.title()) if config_obj is not None: LOG(u"Found config object from %s" % (config_obj.date, )) form = FormRef(self.request.POST, obj=config_obj) else: LOG(u"Config object not found") form = FormRef(self.request.POST) if self.request.method == 'POST' and form.validate(): if config_obj is None: config_obj = ApplicationConfig() # Add/Edit data if subpage == 'general': config_obj.office_ip = form.office_ip.data config_obj.google_user_email = form.google_user_email.data config_obj.google_user_password = form.google_user_password.data config_obj.cleaning_time_presence = form.cleaning_time_presence.data config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None config_obj.monthly_late_limit = form.monthly_late_limit.data config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data elif subpage == 'reports': config_obj.reports_project_ids = [ int(id) for id in form.reports_project_ids.data ] config_obj.reports_omit_user_ids = [ int(id) for id in form.reports_omit_user_ids.data ] config_obj.reports_without_ticket_project_ids = [ int(id) for id in form.reports_without_ticket_project_ids.data ] config_obj.reports_without_ticket_omit_user_ids = [ int(id) for id in form.reports_without_ticket_omit_user_ids.data ] elif subpage == 'spreadsheets': config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data config_obj.hours_employee_project = form.hours_employee_project.data config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None elif subpage == "access": config_obj.freelancers = form.freelancers.data self.session.add(config_obj) config_obj.invalidate_office_ip() LOG(u"Config object saved") self.flash(self._(u'Application Config saved'), klass='success') return HTTPFound( location=self.request.url_for('/config/view', subpage=subpage)) return dict(form=form, subpage=subpage)
def action(self): config_obj = ApplicationConfig.get_current_config() cleaning_time_presence = int(config_obj.cleaning_time_presence) today = datetime.datetime.now().date() date = today - datetime.timedelta(days=cleaning_time_presence) date = datetime.datetime.combine(date, day_end) cleaned = self.session.execute(""" DELETE FROM presence_entry as p WHERE p.ts <= :date AND p.ts > ( SELECT MIN(a.ts) FROM presence_entry a WHERE date_trunc('day', a.ts) = date_trunc('day', p.ts) AND a.user_id = p.user_id ) AND p.ts < ( SELECT MAX(b.ts) FROM presence_entry b WHERE date_trunc('day', b.ts) = date_trunc('day', p.ts) AND b.user_id = p.user_id ); """, params={ 'date': date }).rowcount LOG(u"Cleaned %s entries" % (cleaned, )) return Response(self._(u"Cleaned ${num} entries", num=cleaned))
def send_with_file(cls, to, topic, message, file_path): config = ApplicationConfig.get_current_config() email = MIMEMultipart() email['Subject'] = topic email['From'] = config.google_user_email email['To'] = to part = MIMEBase('application', "octet-stream") part.set_payload(open(file_path, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % file_path.split('/')[-1]) email.attach(part) email.attach(MIMEText(message)) formatted_mail = email.as_string() messageFile = StringIO(formatted_mail) resultDeferred = Deferred() senderFactory = ESMTPSenderFactory( config.google_user_email, # user config.google_user_password, # secret config.google_user_email, # from to, # to messageFile, # message resultDeferred, # deferred contextFactory=cls.contextFactory) reactor.connectTCP(cls.SMTP_SERVER, cls.SMTP_PORT, senderFactory) return resultDeferred
def action(self): config_obj = ApplicationConfig.get_current_config() cleaning_time_presence = int(config_obj.cleaning_time_presence) today = datetime.datetime.now().date() date = today - datetime.timedelta(days=cleaning_time_presence) end_date = datetime.datetime.combine(date, day_end) start_date = end_date - datetime.timedelta( days=cleaning_time_presence * 3, ) cleaned = DBSession.execute(""" WITH minq as ( SELECT MIN(p1.id) FROM presence_entry as p1 WHERE p1.ts >= :start_date AND p1.ts <= :end_date GROUP BY p1.user_id, date_trunc('day', p1.ts) ), maxq as ( SELECT MAX(p2.id) FROM presence_entry as p2 WHERE p2.ts >= :start_date AND p2.ts <= :end_date GROUP BY p2.user_id, date_trunc('day', p2.ts) ) DELETE FROM presence_entry as p WHERE p.ts >= :start_date AND p.ts <= :end_date AND p.id NOT IN (SELECT * FROM minq) AND p.id NOT IN (SELECT * FROM maxq); """, params={ 'start_date': start_date, 'end_date': end_date }).rowcount LOG(u"Cleaned %s entries" % (cleaned, )) return Response(self._(u"Cleaned ${num} entries", num=cleaned))
def _annually_report(self, year): year_start = datetime.date(year, 1, 1) year_end = datetime.date(year, 12, 31) excuses_error = None config_obj = ApplicationConfig.get_current_config() query = DBSession.query('uid', 'date', 'presence').from_statement(""" SELECT p.user_id as "uid", date_trunc('day', p.ts) as "date", MIN(p.ts) as "presence" FROM presence_entry p WHERE p.ts >= :year_start AND p.ts <= :year_end GROUP BY p.user_id, date_trunc('day', p.ts) """).params(year_start=year_start, year_end=year_end) data = query.all() users = User.query.filter(User.is_active==True)\ .filter(User.is_not_client())\ .filter(User.is_not_freelancer())\ .order_by(User.name).all() _excuses = excuses.presence() data = self._group_by_user_monthly(data, _excuses) stats = self._prepare_statistics(data) return dict( data=data, users=users, stats=stats, today=datetime.datetime.today(), year_start=year_start, deltazero=deltazero, late_limit=config_obj.monthly_late_limit, excuses_error=excuses_error, )
def action(self): date = datetime.date.today() - relativedelta(days=1) config_obj = ApplicationConfig.get_current_config() self._today_hours_without_ticket( date, config_obj.reports_without_ticket_project_ids, config_obj.reports_without_ticket_omit_user_ids ) return Response("ok")
def __init__(self): config = ApplicationConfig.get_current_config() user = config.google_user_email secret = config.google_user_password self.user, self.secret = user, secret self.server = smtplib.SMTP(self.HOST, self.PORT) self.server.ehlo() self.server.starttls() self.server.login(user, secret)
def action(self): date = datetime.date.today() - relativedelta(days=1) config_obj = ApplicationConfig.get_current_config() self._today_hours_without_ticket( date, config_obj.reports_without_ticket_project_ids, config_obj.reports_without_ticket_omit_user_ids, ) return Response('ok')
def callback(request): code = request.params.get('code', '') try: credentials = flow.step2_exchange(code) except FlowExchangeError: raise HTTPForbidden data = requests.get(USER_INFO_URI % credentials.access_token, verify=False) google_profile = data.json email = google_profile['email'] EXTRA_EMAILS = request.registry.settings.get('GOOGLE_EXTRA_EMAILS', '').split('\n') config = ApplicationConfig.get_current_config(allow_empty=True) freelancers = config.get_freelancers() clients_emails = Client.get_emails() if email.endswith('@%s' % request.registry.settings['COMPANY_DOMAIN']) or email in EXTRA_EMAILS: group = 'user' elif email in freelancers: group = 'freelancer' elif email in clients_emails: group = 'client' else: WARN_LOG(u"Forbidden acccess for profile:\n%s\n client's emails:\n%s\nfreelancer's emails:\n%s" % (google_profile, clients_emails, freelancers)) return HTTPForbidden() session = request.db_session user = session.query(User).filter(User.email==email).first() if user is not None: if credentials.refresh_token: DEBUG(u'Adding refresh token %s for user %s' % ( credentials.refresh_token, user.name, )) user.refresh_token = credentials.refresh_token session.add(user) DEBUG(u'Signing in existing user %s' % (user.name, )) else: LOG(u'Creating new user with name %s and email %s, group: %s' % (google_profile['name'], google_profile['email'], group)) user = User( name=google_profile['name'], email=email, refresh_token=credentials.refresh_token or '', groups=[group], ) session.add(user) session.flush() headers = remember(request, user.id) DEBUG(u'User %s set' % user.name) if group == 'client': location = request.url_for('/scrum/sprint/list') else: location = '/' return HTTPFound( location=location, headers=headers, )
def _fetch_bugs_titles(self, tracker_ticket): query = self.session.query config_obj = ApplicationConfig.get_current_config() user = query(User).filter( User.id == config_obj.hours_ticket_user_id).first() tracker_creds = query(Tracker.id, Tracker, TrackerCredentials)\ .filter(TrackerCredentials.tracker_id==Tracker.id)\ .filter(TrackerCredentials.user_id==User.id)\ .filter(User.id==config_obj.hours_ticket_user_id) tracker_creds = groupby(tracker_creds, lambda x: x[0], lambda x: x[1:]) fetchers = {} for tracker_id, ticket_ids in tracker_ticket.iteritems(): ticket_ids = [ticket_id for ticket_id in ticket_ids if ticket_id] if not tracker_id in tracker_creds: continue tracker, creds = tracker_creds[tracker_id][0] mapping = {creds.login.lower(): user} for i, portion in enumerate( partition(ticket_ids, MAX_TICKETS_PER_REQUEST)): fetcher = get_fetcher(tracker, creds, mapping) fetcher.fetch_bug_titles_and_depends_on(portion) fetchers[(tracker.name, i)] = fetcher ticket_titles = {} start = time() while len(fetchers): for key, fetcher in fetchers.iteritems(): if fetcher.isReady(): if fetcher.error: ERROR(u"Fetcher for tracker %s failed with %r" % (key[0], fetcher.error)) del fetchers[key] break # continue ignoring exception - titles and depends_on will be empty #raise fetcher.error for bug_id, bug in fetcher.bugs.iteritems(): if type(bug['title']) == str: ticket_titles['%s_%s' % (fetcher.tracker.id, bug_id )] = bug['title'].decode('utf-8') else: ticket_titles['%s_%s' % (fetcher.tracker.id, bug_id)] = bug['title'] del fetchers[key] break else: # no fetcher is ready yet if time() - start > MAX_TIMEOUT: ERROR(u'%s requests timed-out' % len(fetchers)) break # continue without exception - titles and depends_on will be empty # raise FetchException(u'%s requests timed-out for tracker %s' % (len(fetchers), tracker.name)) else: sleep(0.1) return ticket_titles
def __call__(self, *args, **kwargs): config = ApplicationConfig.get_current_config(allow_empty=True) if config is None: WARN(u'Application config not found, emails cannot be checked') return trackers = dict( (tracker.mailer, tracker) for tracker in Tracker.query.filter(Tracker.mailer != None).filter(Tracker.mailer != '') ) if not len(trackers): WARN(u'No trackers have mailers configured, email will not be checked') return username = config.google_user_email.encode('utf-8') password = config.google_user_password.encode('utf-8') # TODO logins_mappings = dict( (tracker.id, TrackerCredentials.get_logins_mapping(tracker)) for tracker in trackers.itervalues() ) selector_mappings = dict( (tracker.id, SelectorMapping(tracker)) for tracker in trackers.itervalues() ) # find all projects connected to the tracker projects = dict( (project.id, project) for project in Project.query.all() ) # all pre-conditions should be checked by now # start fetching fetcher = MailFetcher( username, password, ) # ok, we have all mails, lets create timeentries from them extractor = TimeEntryMailExtractor( trackers, logins_mappings, projects, selector_mappings, ) for msg in fetcher: timeentry = extractor.get(msg) if timeentry: DBSession.add(timeentry) transaction.commit()
def dispatch(self): subpage = self.request.GET.get('subpage', 'general') if subpage not in ['general', 'reports', 'spreadsheets', 'access']: return HTTPForbidden() config_obj = ApplicationConfig.get_current_config(allow_empty=True) FormRef = getattr(config_forms, "%sForm"% subpage.title()) if config_obj is not None: LOG(u"Found config object from %s" % (config_obj.date, )) form = FormRef(self.request.POST, obj=config_obj) else: LOG(u"Config object not found") form = FormRef(self.request.POST) if self.request.method == 'POST' and form.validate(): if config_obj is None: config_obj = ApplicationConfig() # Add/Edit data if subpage == 'general': config_obj.office_ip = form.office_ip.data config_obj.google_user_email = form.google_user_email.data config_obj.google_user_password = form.google_user_password.data config_obj.cleaning_time_presence = form.cleaning_time_presence.data config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None config_obj.monthly_late_limit = form.monthly_late_limit.data config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data elif subpage == 'reports': config_obj.reports_project_ids = [int(id) for id in form.reports_project_ids.data] config_obj.reports_omit_user_ids = [int(id) for id in form.reports_omit_user_ids.data] config_obj.reports_without_ticket_project_ids = [int(id) for id in form.reports_without_ticket_project_ids.data] config_obj.reports_without_ticket_omit_user_ids = [int(id) for id in form.reports_without_ticket_omit_user_ids.data] elif subpage == 'spreadsheets': config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data config_obj.hours_employee_project = form.hours_employee_project.data config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None elif subpage == "access": config_obj.freelancers = form.freelancers.data DBSession.add(config_obj) config_obj.invalidate_office_ip() LOG(u"Config object saved") self.flash(self._(u'Application Config saved'), klass='success') return HTTPFound(location=self.request.url_for('/config/view', subpage=subpage)) return dict( form=form, subpage=subpage )
def _fetch_bugs_titles(self, tracker_ticket): query = self.session.query config_obj = ApplicationConfig.get_current_config() user = query(User).filter(User.id == config_obj.hours_ticket_user_id).first() tracker_creds = ( query(Tracker.id, Tracker, TrackerCredentials) .filter(TrackerCredentials.tracker_id == Tracker.id) .filter(TrackerCredentials.user_id == User.id) .filter(User.id == config_obj.hours_ticket_user_id) ) tracker_creds = groupby(tracker_creds, lambda x: x[0], lambda x: x[1:]) fetchers = {} for tracker_id, ticket_ids in tracker_ticket.iteritems(): ticket_ids = [ticket_id for ticket_id in ticket_ids if ticket_id] if not tracker_id in tracker_creds: continue tracker, creds = tracker_creds[tracker_id][0] mapping = {creds.login.lower(): user} for i, portion in enumerate(partition(ticket_ids, MAX_TICKETS_PER_REQUEST)): fetcher = get_fetcher(tracker, creds, mapping) fetcher.fetch_bug_titles_and_depends_on(portion) fetchers[(tracker.name, i)] = fetcher ticket_titles = {} start = time() while len(fetchers): for key, fetcher in fetchers.iteritems(): if fetcher.isReady(): if fetcher.error: ERROR(u"Fetcher for tracker %s failed with %r" % (key[0], fetcher.error)) del fetchers[key] break # continue ignoring exception - titles and depends_on will be empty # raise fetcher.error for bug_id, bug in fetcher.bugs.iteritems(): if type(bug["title"]) == str: ticket_titles["%s_%s" % (fetcher.tracker.id, bug_id)] = bug["title"].decode("utf-8") else: ticket_titles["%s_%s" % (fetcher.tracker.id, bug_id)] = bug["title"] del fetchers[key] break else: # no fetcher is ready yet if time() - start > MAX_TIMEOUT: ERROR(u"%s requests timed-out" % len(fetchers)) break # continue without exception - titles and depends_on will be empty # raise FetchException(u'%s requests timed-out for tracker %s' % (len(fetchers), tracker.name)) else: sleep(0.1) return ticket_titles
def __call__(self, *args, **kwargs): config = ApplicationConfig.get_current_config(allow_empty=True) if config is None: WARN(u'Application config not found, emails cannot be checked') return trackers = dict( (tracker.mailer, tracker) for tracker in Tracker.query.filter( Tracker.mailer != None).filter(Tracker.mailer != '')) if not len(trackers): WARN( u'No trackers have mailers configured, email will not be checked' ) return username = config.google_user_email.encode('utf-8') password = config.google_user_password.encode('utf-8') # TODO logins_mappings = dict( (tracker.id, TrackerCredentials.get_logins_mapping(tracker)) for tracker in trackers.itervalues()) selector_mappings = dict((tracker.id, SelectorMapping(tracker)) for tracker in trackers.itervalues()) # find all projects connected to the tracker projects = dict( (project.id, project) for project in Project.query.all()) # all pre-conditions should be checked by now # start fetching fetcher = MailFetcher( username, password, ) # ok, we have all mails, lets create timeentries from them extractor = TimeEntryMailExtractor( trackers, logins_mappings, projects, selector_mappings, ) for msg in fetcher: timeentry = extractor.get(msg) if timeentry: DBSession.add(timeentry) transaction.commit()
def action(self): config_obj = ApplicationConfig.get_current_config() client = SpreadsheetConnector(config_obj.google_user_email, config_obj.google_user_password) worksheet = client.get_worksheet(config_obj.holidays_spreadsheet, 6) data = worksheet.FindRecords("") dates_new = set([datetime.datetime.strptime(d.content["data"], "%Y-%m-%d").date() for d in data]) dates_old = set(Holiday.all(cache=False)) dates_diff = dates_new.difference(dates_old) if dates_diff: holidays = [Holiday(date=date) for date in dates_diff] self.session.add_all(holidays) INFO(u"%s Holidays added: %s" % (len(dates_diff), dates_diff)) return Response("ok")
def action(self): config_obj = ApplicationConfig.get_current_config() client = SpreadsheetConnector(config_obj.google_user_email, config_obj.google_user_password) worksheet = client.get_worksheet(config_obj.holidays_spreadsheet, 6) data = worksheet.GetRecords(1, 99999) # Magic Constant dates_new = set([ datetime.datetime.strptime(d.content['data'], '%Y-%m-%d').date() for d in data ]) dates_old = set(Holiday.all(cache=False)) dates_diff = dates_new.difference(dates_old) if dates_diff: holidays = [ Holiday(date=date) for date in dates_diff ] DBSession.add_all(holidays) INFO(u'%s Holidays added: %s' % (len(dates_diff), dates_diff)) return Response('ok')
def _synchronize_client_hours(self): LOG(u"Client Hours synchronization starts") entries = self.session.query("month", "email", "client", "time").from_statement( """ SELECT date_trunc('month', t.date) as "month", u.email as "email", c.name as client, COALESCE(SUM(t.time), 0) as "time" FROM time_entry t, project p, "user" u, client c WHERE t.deleted = FALSE AND t.project_id = p.id AND p.client_id = c.id AND t.user_id = u.id GROUP BY u.email, c.name, date_trunc('month', t.date) ORDER BY "month", "email", "client" """ ) rows = [ (month.strftime("%Y-%m-%d"), client, email, (u"%.2f" % time).replace(".", ",")) for month, email, client, time in entries ] config_obj = ApplicationConfig.get_current_config() h.trier( partial( gdocs.insert_or_replace_worksheet, config_obj.google_user_email, config_obj.google_user_password, config_obj.hours_employee_project, "DB-CLIENT", [u"Miesiac", u"Klient", u"Osoba", u"Liczba przepracowanych godzin", u"Miesiac (import)"], rows, ), doc=u"Client hours synchronization", ) return u"Synchronized"
def _synchronize_client_hours(self): LOG(u"Client Hours synchronization starts") entries = self.session.query('month', 'email', 'client', 'time').from_statement(""" SELECT date_trunc('month', t.date) as "month", u.email as "email", c.name as client, COALESCE(SUM(t.time), 0) as "time" FROM time_entry t, project p, "user" u, client c WHERE t.deleted = FALSE AND t.project_id = p.id AND p.client_id = c.id AND t.user_id = u.id GROUP BY u.email, c.name, date_trunc('month', t.date) ORDER BY "month", "email", "client" """) rows = [ (month.strftime('%Y-%m-%d'), client, email, (u'%.2f' % time).replace('.', ',')) for month, email, client, time in entries ] config_obj = ApplicationConfig.get_current_config() h.trier( partial( gdocs.insert_or_replace_worksheet, config_obj.google_user_email, config_obj.google_user_password, config_obj.hours_employee_project, 'DB-CLIENT-test', [u'Miesiac', u'Klient', u'Osoba', u'Liczba przepracowanych godzin', u'Miesiac (import)'], rows ), doc=u"Client hours synchronization" ) return u"Synchronized"
def _annually_report(self, year): year_start = datetime.date(year, 1, 1) year_end = datetime.date(year, 12, 31) excuses_error = None config_obj = ApplicationConfig.get_current_config() entries = DBSession.query('user_id', 'date').from_statement(""" SELECT date_trunc('day', s.date) as date, s.user_id as user_id FROM time_entry s WHERE DATE(s.modified_ts) > s.date AND s.date >= :year_start AND s.date <= :year_end GROUP BY date_trunc('day', s.date), s.user_id """).params(year_start=year_start, year_end=year_end) users = User.query.filter(User.is_active==True)\ .filter(User.is_not_client())\ .order_by(User.is_freelancer(), User.name) entries_grouped = {} _excuses = excuses.wrongtime() for user_id, date in entries: month = date.month - 1 entry = entries_grouped.setdefault(user_id, [0] * 12) if date.strftime('%Y-%m-%d') not in _excuses.get(user_id, {}).keys(): entry[month] += 1 stats = {} for user_id, entry in entries_grouped.iteritems(): stats_entry = stats.setdefault(user_id, [0]) stats_entry[0] = sum(entry) return dict( entries=entries_grouped, stats=stats, users=users, year_start=year_start, limit=config_obj.monthly_incorrect_time_record_limit, excuses_error=excuses_error, )
def send(cls, to, topic, message, sender_name=None, cc=None, replay_to=None): """ Send an email with message to given address. This is an asynchronous call. @return: deferred """ config = ApplicationConfig.get_current_config() user = config.google_user_email email_addr = user if sender_name: email_addr = formataddr((sender_name, email_addr)) secret = config.google_user_password SenderFactory = ESMTPSenderFactory email = MIMEText(message, _charset='utf-8') email['Subject'] = topic email['From'] = email_addr email['To'] = to if cc: email['Cc'] = cc if replay_to: email['Reply-To'] = replay_to formatted_mail = email.as_string() messageFile = StringIO(formatted_mail) resultDeferred = Deferred() senderFactory = SenderFactory( user, # user secret, # secret user, # from to, # to messageFile, # message resultDeferred, # deferred contextFactory=cls.contextFactory) reactor.connectTCP(cls.SMTP_SERVER, cls.SMTP_PORT, senderFactory) return resultDeferred
def _annually_report(self, year): year_start = datetime.date(year, 1, 1) year_end = datetime.date(year, 12, 31) excuses_error = None config_obj = ApplicationConfig.get_current_config() entries = DBSession.query('user_id', 'date').from_statement(""" SELECT date_trunc('day', s.date) as date, s.user_id as user_id FROM time_entry s WHERE DATE(s.modified_ts) > s.date AND s.date >= :year_start AND s.date <= :year_end GROUP BY date_trunc('day', s.date), s.user_id """).params(year_start=year_start, year_end=year_end) users = User.query.filter(User.is_active==True)\ .filter(User.is_not_client())\ .order_by(User.is_freelancer(), User.name) entries_grouped = {} _excuses = excuses.wrongtime() for user_id, date in entries: month = date.month - 1 entry = entries_grouped.setdefault(user_id, [0]*12) if date.strftime('%Y-%m-%d') not in _excuses.get(user_id, {}).keys(): entry[month] += 1 stats = {} for user_id, entry in entries_grouped.iteritems(): stats_entry = stats.setdefault(user_id, [0]) stats_entry[0] = sum(entry) return dict( entries=entries_grouped, stats=stats, users=users, year_start=year_start, limit=config_obj.monthly_incorrect_time_record_limit, excuses_error=excuses_error, )
def _run(self): config = ApplicationConfig.get_current_config(allow_empty=True) if config is None: WARN(u'Application config not found, emails cannot be checked') return self.mark_not_busy() trackers = dict( (tracker.mailer, tracker) for tracker in Tracker.query.filter(Tracker.mailer != None).filter(Tracker.mailer != '') ) if not len(trackers): WARN(u'No trackers have mailers configured, email will not be checked') return self.mark_not_busy() username = config.google_user_email.encode('utf-8') password = config.google_user_password.encode('utf-8') # TODO logins_mappings = dict( (tracker.id, TrackerCredentials.get_logins_mapping(tracker)) for tracker in trackers.itervalues() ) selector_mappings = dict( (tracker.id, SelectorMapping(tracker)) for tracker in trackers.itervalues() ) # find all projects connected to the tracker projects = dict( (project.id, project) for project in Project.query.all() ) # all pre-conditions should be checked by now # start fetching f = CustomClientFactory(username, password, self.mark_not_busy, trackers, logins_mappings, projects, selector_mappings) f.protocol = MailerPOP3Client reactor.connectSSL(self.POP3_SERVER, self.POP3_PORT, f, self.context_factory)
def action(self): config_obj = ApplicationConfig.get_current_config() cleaning_time_presence = int(config_obj.cleaning_time_presence) today = datetime.datetime.now().date() date = today - datetime.timedelta(days=cleaning_time_presence) date = datetime.datetime.combine(date, day_end) cleaned = self.session.execute(""" DELETE FROM presence_entry as p WHERE p.ts <= :date AND p.ts > ( SELECT MIN(a.ts) FROM presence_entry a WHERE date_trunc('day', a.ts) = date_trunc('day', p.ts) AND a.user_id = p.user_id ) AND p.ts < ( SELECT MAX(b.ts) FROM presence_entry b WHERE date_trunc('day', b.ts) = date_trunc('day', p.ts) AND b.user_id = p.user_id ); """, params= {'date': date}).rowcount LOG(u"Cleaned %s entries" % (cleaned, )) return Response(self._(u"Cleaned ${num} entries", num=cleaned))
def _annually_report(self, year): year_start = datetime.date(year, 1, 1) year_end = datetime.date(year, 12, 31) excuses_error = None config_obj = ApplicationConfig.get_current_config() query = self.session.query('uid', 'date', 'presence').from_statement(""" SELECT p.user_id as "uid", date_trunc('day', p.ts) as "date", MIN(p.ts) as "presence" FROM presence_entry p WHERE p.ts >= :year_start AND p.ts <= :year_end GROUP BY p.user_id, date_trunc('day', p.ts) """).params(year_start=year_start, year_end=year_end) data = query.all() users = User.query.filter(User.is_active==True)\ .filter(User.is_not_client())\ .filter(User.freelancer==False)\ .order_by(User.name).all() _excuses = excuses.presence() data = self._group_by_user_monthly(data, _excuses) stats = self._prepare_statistics(data) return dict( data=data, users=users, stats=stats, today=datetime.datetime.today(), year_start=year_start, deltazero=deltazero, late_limit=config_obj.monthly_late_limit, excuses_error=excuses_error, )
def _fetch_bugs(self, sprint): config_obj = ApplicationConfig.get_current_config() user = User.query.get(config_obj.hours_ticket_user_id) bugs = Bugs(self.request, user).get_sprint(sprint) return bugs
def callback(request): code = request.params.get('code', '') try: credentials = flow.step2_exchange(code) except FlowExchangeError: raise HTTPForbidden data = requests.get(USER_INFO_URI % credentials.access_token, verify=False) google_profile = data.json email = google_profile['email'] EXTRA_EMAILS = request.registry.settings.get('GOOGLE_EXTRA_EMAILS', '').split('\n') config = ApplicationConfig.get_current_config(allow_empty=True) freelancers = config.get_freelancers() clients_emails = Client.get_emails() if email.endswith('@%s' % request.registry.settings['COMPANY_DOMAIN'] ) or email in EXTRA_EMAILS: group = 'user' elif email in freelancers: group = 'freelancer' elif email in clients_emails: group = 'client' else: WARN_LOG( u"Forbidden acccess for profile:\n%s\n client's emails:\n%s\nfreelancer's emails:\n%s" % (google_profile, clients_emails, freelancers)) return HTTPForbidden() session = request.db_session user = session.query(User).filter(User.email == email).first() if user is not None: if credentials.refresh_token: DEBUG(u'Adding refresh token %s for user %s' % ( credentials.refresh_token, user.name, )) user.refresh_token = credentials.refresh_token session.add(user) DEBUG(u'Signing in existing user %s' % (user.name, )) else: LOG(u'Creating new user with name %s and email %s, group: %s' % (google_profile['name'], google_profile['email'], group)) user = User( name=google_profile['name'], email=email, refresh_token=credentials.refresh_token or '', groups=[group], ) session.add(user) session.flush() headers = remember(request, user.id) DEBUG(u'User %s set' % user.name) if group == 'client': location = request.url_for('/scrum/sprint/list') else: location = '/' return HTTPFound( location=location, headers=headers, )