def init_app(app): app.config['SECRET_KEY'] = config.get('SECRET_KEY') app.config['SQLALCHEMY_DATABASE_URI'] = config.get('db_path') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False Bootstrap(app) logging.log_init(app) mail.init_app(app)
def __init__(self): # Theme theme_name = config.get('visual', 'theme') self.theme = Theme(theme_name) self.status = FadeLabel() self.revision_status = gtk.Label() # Main window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_name('PyRoom') self.window.set_title("PyRoom") self.window.connect('delete_event', self.delete_event) self.window.connect('destroy', self.destroy) self.textbox = gtk.TextView() self.textbox.connect('scroll-event', self.scroll_event) self.textbox.set_wrap_mode(gtk.WRAP_WORD) self.fixed = gtk.Fixed() self.vbox = gtk.VBox() self.align = gtk.Alignment() self.align.add(self.vbox) self.window.add(self.align) self.hbox2 = gtk.HBox() self.hbox2.set_spacing(12) self.hbox2.pack_end(self.revision_status, True, True, 0) self.vbox.pack_start(self.hbox2, False, False, 0) self.revision_status.modify_font(pango.FontDescription("Monospace 12")) self.revision_status.set_alignment(0.0, 0.5) self.revision_status.set_justify(gtk.JUSTIFY_LEFT) self.revision_status.set_text("") self.boxout = gtk.EventBox() self.boxout.set_border_width(1) self.boxin = gtk.EventBox() self.boxin.set_border_width(1) self.vbox.pack_start(self.boxout, True, True, 1) self.boxout.add(self.boxin) self.scrolled = gtk.ScrolledWindow() self.boxin.add(self.scrolled) self.scrolled.add(self.textbox) self.scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER) self.scrolled.show() self.scrolled.set_property('resize-mode', gtk.RESIZE_PARENT) self.textbox.set_property('resize-mode', gtk.RESIZE_PARENT) self.vbox.set_property('resize-mode', gtk.RESIZE_PARENT) self.vbox.show_all() # Status self.hbox = gtk.HBox() self.hbox.set_spacing(12) self.hbox.pack_end(self.status, True, True, 0) self.vbox.pack_end(self.hbox, False, False, 0) self.status.set_alignment(0.0, 0.5) self.status.set_justify(gtk.JUSTIFY_LEFT) self.apply_theme()
def toggle_indent(self, widget): """toggle textbox indent""" if config.get('visual', 'indent') == '1': config.set('visual', 'indent', '0') else: config.set('visual', 'indent', '1') state['gui'].apply_theme()
def show_info(self): """ Display buffer information on status label for 5 seconds """ buf = self.buffers[self.current] if buf.modified: status = _(' (modified)') else: status = '' self.status.set_text( _('Buffer %(buffer_id)d: %(buffer_name)s\ %(status)s, %(char_count)d character(s), %(word_count)d word(s)\ , %(lines)d line(s)') % { 'buffer_id': self.current + 1, 'buffer_name': buf.filename if int(config.get('visual', 'showpath')) else os.path.split(buf.filename)[1], 'status': status, 'char_count': buf.get_char_count(), 'word_count': self.word_count(buf), 'lines': buf.get_line_count(), }, 5000)
def post(self): post = request.form tel = post.get("tel") if not tel: return success(res={'r': 1, 'error_code': 4006, 'msg': '手机号不能为空'}) if not AdminAccount.objects(tel=tel): return success(res={'r': 1, 'error_code': 4006, 'msg': '用户不存在'}) key = model.CHECKCODE_KEY.format(tel=tel) code = cache.get(key) if not code: code = random.randint(100000, 999999) cache.incr(key, code) cache.expire(key, 300) if config.get("DEBUG"): print code, "CODEEE" ret = True else: ret = alidayu_tool.send_code(phone=tel, num=str(code)) if ret: return success(res={}) else: return success(res={'error_code': 4001, 'msg': u'验证码发送失败'})
def events_calendar(year): form = EventCalendarListForm() form.populate_calendar_event_list(int(year)) csv = render_template('admin/event_calendar.txt', event_calendar_list=form.event_calendar_list) csv = csv.replace('\n\n', '\n').replace('\n\n', '\n') file = os.path.join(config.get('locations')['output'], 'calendar_' + year + '.csv') write_file(file, csv) flash('Calendar published as ' + file, 'success') return redirect(url_for_admin('list_events', year=year))
def save(self, member_id): file = path_join(config.get('locations')['export'], 'b_details.csv') # if not file_exists(file): # create_data_file(file, ['member_id', 'name', 'number', 'sort']) name = self.account_name.data number = self.account_number.data sort = self.account_sort.data rec = '\r' + ','.join([str(member_id), name, number, sort]) append_file(file, rec) return get_member(member_id)
def my_open(filename, mode, access_all=False): if mode == 'w': fh = open(filename, mode, encoding="latin-1", newline="\n") else: fh = open(filename, mode, encoding="latin-1") op_sys = config.get("OS") if op_sys == 'Unix': if mode == 'w': if access_all: os.chmod(filename, 0o666) else: os.chmod(filename, 0o664) return fh
def fill_pref_dialog(self): """load config into the dialog""" self.custom_font_preference.set_font_name( config.get('visual', 'custom_font')) parse_color = lambda x: gtk.gdk.color_parse(state['gui'].theme[x]) self.colorpreference.set_color(parse_color('foreground')) self.textboxbgpreference.set_color(parse_color('textboxbg')) self.bgpreference.set_color(parse_color('background')) self.borderpreference.set_color(parse_color('border')) self.paddingpreference.set_value(float(state['gui'].theme['padding'])) self.widthpreference.set_value( float(state['gui'].theme['width']) * 100) self.heightpreference.set_value( float(state['gui'].theme['height']) * 100)
def __init__(self): # Theme theme_name = config.get('visual', 'theme') self.theme = Theme(theme_name) self.status = FadeLabel() # Main window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_name('PyRoom') self.window.set_title("PyRoom") self.window.connect('delete_event', self.delete_event) self.window.connect('destroy', self.destroy) self.textbox = gtk.TextView() self.textbox.connect('scroll-event', self.scroll_event) self.textbox.set_wrap_mode(gtk.WRAP_WORD) self.fixed = gtk.Fixed() self.vbox = gtk.VBox() self.align = gtk.Alignment() self.align.add(self.vbox) self.window.add(self.align) self.boxout = gtk.EventBox() self.boxout.set_border_width(1) self.boxin = gtk.EventBox() self.boxin.set_border_width(1) self.vbox.pack_start(self.boxout, True, True, 1) self.boxout.add(self.boxin) self.scrolled = gtk.ScrolledWindow() self.boxin.add(self.scrolled) self.scrolled.add(self.textbox) self.scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER) self.scrolled.show() self.scrolled.set_property('resize-mode', gtk.RESIZE_PARENT) self.textbox.set_property('resize-mode', gtk.RESIZE_PARENT) self.vbox.set_property('resize-mode', gtk.RESIZE_PARENT) self.vbox.show_all() # Status self.hbox = gtk.HBox() self.hbox.set_spacing(12) self.hbox.pack_end(self.status, True, True, 0) self.vbox.pack_end(self.hbox, False, False, 0) self.status.set_alignment(0.0, 0.5) self.status.set_justify(gtk.JUSTIFY_LEFT) self.apply_theme()
def init_app(app, create=False, multi_thread=True): app.config['SECRET_KEY'] = config.get('SECRET_KEY') app.config['SQLALCHEMY_DATABASE_URI'] = db_path + ( '' if multi_thread else '?check_same_thread=False') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False Bootstrap(app) CSRFProtect(app) logging.log_init(app) mail.init_app(app) db.init_app(app) if create: db.create_all(app=app)
def populate_event_list(self, year): self.editable.data = is_event_editable(year) override = config.get('override') for event in get_events_for_year(year): event_type = event.type item_form = EventItemForm() item_form.event_id = event.id item_form.date = fmt_date(event.date) item_form.event = event.trophy.name if event.trophy else '' item_form.venue = event.venue.name item_form.event_type = event_type item_form.result = override or ( event.date <= datetime.date.today() and event.type in [ EventType.wags_vl_event, EventType.non_vl_event, EventType.wags_tour ]) self.event_list.append_entry(item_form)
def show_info(self): """ Display buffer information on status label for 5 seconds """ buf = self.buffers[self.current] if buf.modified: status = _(' (modified)') else: status = '' self.status.set_text(_('Buffer %(buffer_id)d: %(buffer_name)s\ %(status)s, %(char_count)d character(s), %(word_count)d word(s)\ , %(lines)d line(s)') % { 'buffer_id': self.current + 1, 'buffer_name': buf.filename if int(config.get('visual', 'showpath')) else os.path.split(buf.filename)[1], 'status': status, 'char_count': buf.get_char_count(), 'word_count': self.word_count(buf), 'lines': buf.get_line_count(), }, 5000)
def season_tickets(): file_name = path.join( config.get('locations')['import'], 'season tickets.csv') print('Importing ' + file_name) result = [] with open(file_name, 'r', encoding='latin-1') as in_file: reader = csv.DictReader(in_file, delimiter=file_delimiter(file_name)) count = 0 for row in reader: count += 1 if count % 50 == 0: if 'dt id' in row.keys(): print('Processing ' + row['dt id']) message = update_member_season_ticket(row) if len(message) > 0: result.append('***' + row['dt id'] + ': ' + '\n'.join(message)) if len(result) > 0: return '\n'.join(result) else: return '{} records processed'.format(count)
def log_init(app): # initialize the log handler log_path = config.get('locations')['logs'] + '/info.log' log_handler = RotatingFileHandler(log_path, maxBytes=1000000, backupCount=1) # set the log handler level log_handler.setLevel(logging.INFO) formatter = logging.Formatter( "%(asctime)s - %(levelname)s - %(name)s - %(message)s") log_handler.setFormatter(formatter) # set the app logger level app.logger.setLevel(logging.INFO) app.logger.addHandler(log_handler) return
def fill_pref_dialog(self): """load config into the dialog""" self.custom_font_preference.set_font_name( config.get('visual', 'custom_font') ) parse_color = lambda x: gtk.gdk.color_parse( state['gui'].theme[x] ) self.colorpreference.set_color(parse_color('foreground')) self.textboxbgpreference.set_color(parse_color('textboxbg')) self.bgpreference.set_color(parse_color('background')) self.borderpreference.set_color(parse_color('border')) self.paddingpreference.set_value(float( state['gui'].theme['padding']) ) self.widthpreference.set_value( float(state['gui'].theme['width']) * 100 ) self.heightpreference.set_value( float(state['gui'].theme['height']) * 100 )
def renew_paid(payment_method, save=True): file_name = path.join( config.get('locations')['import'], 'paypal_apply.txt' if payment_method == 'cc' else 'dd_apply.txt') payment_method = PaymentMethod.cc if payment_method == 'cc' else PaymentMethod.dd print('Importing ' + file_name) result = [] with open(file_name, 'r', encoding='latin-1') as in_file: reader = csv.DictReader(in_file, delimiter=file_delimiter(file_name)) count = 0 for row in reader: count += 1 if count % 50 == 0: if 'id' in row.keys(): print('Processing ' + row['id']) message = update_member_payment(row, payment_method, save) if len(message) > 0: result.append('***' + row['id'] + ': ' + '\n'.join(message)) if len(result) > 0: return '\n'.join(result) else: return '{} records processed'.format(count)
def send_mail(to, sender, cc=None, subject=None, message=None): #in order to get this to work, had to change the libraries as follows: #/home/admin/wagsv_python/venv/lib/python3.5/site-packages/flask_sendmail/connection.py[23] # sm.stdin.write(str.encode(message.dump())) #/usr/lib/python3.5/email/mime/text.py[17] # def __init__(self, _text, _subtype='plain', _charset='utf-8'): to = force_list(to) msg = Message(subject) msg.sender = sender msg.recipients = to msg.cc = force_list(cc) msg.body = '\n'.join(force_list(message)) app = current_app._get_current_object() if config.get('send_mail'): #send_async_email(app, msg) mail.send(msg) else: out = [ 'Email:', 'from: ' + sender, 'to: ' + ', '.join(to), 'subject: ' + subject, 'message:' ] print('\n'.join(out + force_list(message)))
def is_event_result_editable(event): override = config.get('override') return override or (datetime.date.today() >= event.date) and (datetime.date.today().year == event.date.year)
process_etl(import_path, 'states.txt', session, state_etl) process_etl(import_path, 'countries.txt', session, country_etl) process_etl(import_path, 'members.txt', session, member_etl) process_etl(import_path, 'payments.txt', session, payment_etl) process_etl(import_path, 'donations.txt', session, donation_etl) process_etl(import_path, 'comments.txt', session, comment_etl) process_etl(import_path, 'users.txt', session, user_etl) def import_season_tickets(): process_etl(import_path, 'season tickets.csv', session, season_ticket_etl) if __name__ == '__main__': args = sys.argv db_path = config.get('db_path') import_path = config.get('locations')['import'] engine = create_engine(db_path, echo=False) Session = sessionmaker(bind=engine) session = Session() if 'test' in args: print('Database test') if 'delete' in args or 'all' in args: delete_tables() if 'create' in args or 'all' in args: create_tables() if 'etl' in args or 'all' in args: import_all() if 'season_ticket' in args: import_season_tickets()
from flask_sqlalchemy import SQLAlchemy from flask_bootstrap import Bootstrap from flask_wtf import CSRFProtect from flask_sendmail import Mail from globals import logging, config db_path = config.get('db_path') db = SQLAlchemy() mail = Mail() def init_app(app, create=False, multi_thread=True): app.config['SECRET_KEY'] = config.get('SECRET_KEY') app.config['SQLALCHEMY_DATABASE_URI'] = db_path + ( '' if multi_thread else '?check_same_thread=False') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False Bootstrap(app) CSRFProtect(app) logging.log_init(app) mail.init_app(app) db.init_app(app) if create: db.create_all(app=app)
def has_reserve_list(self): return self.id in config.get('event_has_reserve_list')
def apply_theme(self): """immediately apply the theme given in configuration this has changed from previous versions! Takes no arguments! Only uses configuration!""" # text cursor gtkrc_string = """\ style "pyroom-colored-cursor" { GtkTextView::cursor-color = '%s' bg_pixmap[NORMAL] = "<none>" } class "GtkWidget" style "pyroom-colored-cursor" """ % self.theme['foreground'] gtk.rc_parse_string(gtkrc_string) padding = int(self.theme['padding']) self.textbox.set_border_width(padding) # Screen geometry screen = gtk.gdk.screen_get_default() root_window = screen.get_root_window() mouse_x, mouse_y, mouse_mods = root_window.get_pointer() current_monitor_number = screen.get_monitor_at_point(mouse_x, mouse_y) monitor_geometry = screen.get_monitor_geometry(current_monitor_number) (screen_width, screen_height) = (monitor_geometry.width, monitor_geometry.height) width_percentage = float(self.theme['width']) height_percentage = float(self.theme['height']) # Sizing self.vbox.set_size_request(int(width_percentage * screen_width), int(height_percentage * screen_height)) parse_color = lambda x: gtk.gdk.color_parse(self.theme[x]) # Colors self.window.modify_bg(gtk.STATE_NORMAL, parse_color('background')) self.boxout.modify_bg(gtk.STATE_NORMAL, parse_color('border')) self.status.active_color = self.theme['foreground'] self.status.inactive_color = self.theme['background'] self.textbox.modify_bg(gtk.STATE_NORMAL, parse_color('textboxbg')) self.textbox.modify_base(gtk.STATE_NORMAL, parse_color('textboxbg')) self.textbox.modify_base(gtk.STATE_SELECTED, parse_color('foreground')) self.textbox.modify_text(gtk.STATE_NORMAL, parse_color('foreground')) self.textbox.modify_text(gtk.STATE_SELECTED, parse_color('textboxbg')) self.textbox.modify_fg(gtk.STATE_NORMAL, parse_color('foreground')) # Border if not int(config.get('visual', 'showborder')): self.boxin.set_border_width(0) self.boxout.set_border_width(0) else: self.boxin.set_border_width(1) self.boxout.set_border_width(1) # Fonts if config.get('visual', 'use_font_type') == 'custom' or\ not state['gnome_fonts']: new_font = config.get('visual', 'custom_font') else: font_type = config.get('visual', 'use_font_type') new_font = state['gnome_fonts'][font_type] self.textbox.modify_font(pango.FontDescription(new_font)) tab_width = pango.TabArray(1, False) tab_width.set_tab(0, pango.TAB_LEFT, calculate_real_tab_width(self.textbox, 4)) self.textbox.set_tabs(tab_width) # Indent if config.get('visual', 'indent') == '1': pango_context = self.textbox.get_pango_context() current_font_size = pango_context.\ get_font_description().\ get_size() / 1024 self.textbox.set_indent(current_font_size * 2) else: self.textbox.set_indent(0) # linespacing linespacing = config.getint('visual', 'linespacing') self.textbox.set_pixels_below_lines(linespacing) self.textbox.set_pixels_above_lines(linespacing) self.textbox.set_pixels_inside_wrap(linespacing) # alignment self.align.set(xalign=0.5, yalign=ORIENTATION[config.get('visual', 'alignment')], xscale=0, yscale=0)
def __init__(self): gladefile = os.path.join(state['absolute_path'], "preferences.glade") builder = gtk.Builder() builder.add_from_file(gladefile) # Defining widgets needed self.window = builder.get_object("dialog-preferences") self.colorpreference = builder.get_object("colorbutton") self.textboxbgpreference = builder.get_object("textboxbgbutton") self.bgpreference = builder.get_object("bgbutton") self.borderpreference = builder.get_object("borderbutton") self.paddingpreference = builder.get_object("paddingtext") self.heightpreference = builder.get_object("heighttext") self.heightpreference.set_range(5, 95) self.widthpreference = builder.get_object("widthtext") self.widthpreference.set_range(5, 95) self.presetscombobox = builder.get_object("presetscombobox") self.showborderbutton = builder.get_object("showborder") self.showpathbutton = builder.get_object("showpath") self.autosave = builder.get_object("autosavetext") self.autosave_spinbutton = builder.get_object("autosavetime") self.linespacing_spinbutton = builder.get_object("linespacing") self.indent_check = builder.get_object("indent_check") if config.get('visual', 'indent') == '1': self.indent_check.set_active(True) self.save_custom_button = builder.get_object("save_custom_theme") self.custom_font_preference = builder.get_object("fontbutton1") if not config.get('visual', 'use_font_type') == 'custom': self.custom_font_preference.set_sensitive(False) self.font_radios = { 'document':builder.get_object("radio_document_font"), 'monospace':builder.get_object("radio_monospace_font"), 'custom':builder.get_object("radio_custom_font") } self.orientation_radios = { 'top':builder.get_object('orientation_top'), 'center':builder.get_object('orientation_center'), } for widget in self.font_radios.values(): if not widget.get_name() == 'radio_custom_font': widget.set_sensitive(bool(state['gnome_fonts'])) # Setting up config parser self.customfile = FailsafeConfigParser() self.customfile.read(os.path.join( state['themes_dir'], 'custom.theme') ) if not self.customfile.has_section('theme'): self.customfile.add_section('theme') # Getting preferences from conf file active_style = config.get("visual", "theme") self.autosave.set_active(config.getint('editor', 'autosave')) # Set up pyroom from conf file self.linespacing_spinbutton.set_value(int( config.get('visual', 'linespacing') )) self.autosave_spinbutton.set_value(float( config.get('editor', 'autosavetime'))) self.showborderbutton.set_active( config.getint('visual', 'showborder') ) self.showpathbutton.set_active( config.getint('visual', 'showpath') ) font_type = config.get('visual', 'use_font_type') self.font_radios[font_type].set_active(True) self.orientation_radios[ config.get('visual', 'alignment') ].set_active(True) self.toggleautosave(self.autosave) self.window.set_transient_for(state['gui'].window) self.stylesvalues = {'custom': 0} startingvalue = 1 state['gui'].theme = Theme(config.get('visual', 'theme')) # Add themes to combobox for i in get_themes_list(): self.stylesvalues['%s' % (i)] = startingvalue startingvalue += 1 current_loading_theme = Theme(i) theme_name = current_loading_theme['name'] self.presetscombobox.append_text(theme_name) if active_style == 'custom': self.save_custom_button.set_sensitive(True) self.presetscombobox.set_active(self.stylesvalues[active_style]) self.fill_pref_dialog() # Connecting interface's signals dic = { "on_MainWindow_destroy": self.QuitEvent, "on_button-ok_clicked": self.set_preferences, "on_close": self.kill_preferences } builder.connect_signals(dic) self.showborderbutton.connect('toggled', self.toggleborder) self.showpathbutton.connect('toggled', self.togglepath) self.autosave.connect('toggled', self.toggleautosave) self.autosave_spinbutton.connect('value-changed', self.toggleautosave) self.linespacing_spinbutton.connect( 'value-changed', self.changelinespacing ) self.indent_check.connect( 'toggled', self.toggle_indent ) self.presetscombobox.connect('changed', self.presetchanged) self.colorpreference.connect('color-set', self.customchanged) self.textboxbgpreference.connect('color-set', self.customchanged) self.bgpreference.connect('color-set', self.customchanged) self.borderpreference.connect('color-set', self.customchanged) self.paddingpreference.connect('value-changed', self.customchanged) self.heightpreference.connect('value-changed', self.customchanged) self.widthpreference.connect('value-changed', self.customchanged) self.save_custom_button.connect('clicked', self.save_custom_theme) for widget in self.font_radios.values(): widget.connect('toggled', self.change_font) for widget in self.orientation_radios.values(): widget.connect('toggled', self.change_orientation) self.custom_font_preference.connect('font-set', self.change_font)
def apply_theme(self): """immediately apply the theme given in configuration this has changed from previous versions! Takes no arguments! Only uses configuration!""" # text cursor gtkrc_string = """\ style "pyroom-colored-cursor" { GtkTextView::cursor-color = '%s' bg_pixmap[NORMAL] = "<none>" } class "GtkWidget" style "pyroom-colored-cursor" """ % self.theme['foreground'] gtk.rc_parse_string(gtkrc_string) padding = int(self.theme['padding']) self.textbox.set_border_width(padding) # Screen geometry screen = gtk.gdk.screen_get_default() root_window = screen.get_root_window() mouse_x, mouse_y, mouse_mods = root_window.get_pointer() current_monitor_number = screen.get_monitor_at_point(mouse_x, mouse_y) monitor_geometry = screen.get_monitor_geometry(current_monitor_number) (screen_width, screen_height) = (monitor_geometry.width, monitor_geometry.height) width_percentage = float(self.theme['width']) height_percentage = float(self.theme['height']) # Sizing self.vbox.set_size_request( int(width_percentage * screen_width), int(height_percentage * screen_height) ) parse_color = lambda x: gtk.gdk.color_parse(self.theme[x]) # Colors self.window.modify_bg(gtk.STATE_NORMAL, parse_color('background')) self.boxout.modify_bg(gtk.STATE_NORMAL, parse_color('border')) self.status.active_color = self.theme['foreground'] self.status.inactive_color = self.theme['background'] self.textbox.modify_bg(gtk.STATE_NORMAL, parse_color('textboxbg')) self.textbox.modify_base(gtk.STATE_NORMAL, parse_color('textboxbg')) self.textbox.modify_base(gtk.STATE_SELECTED, parse_color('foreground')) self.textbox.modify_text(gtk.STATE_NORMAL, parse_color('foreground')) self.textbox.modify_text(gtk.STATE_SELECTED, parse_color('textboxbg')) self.textbox.modify_fg(gtk.STATE_NORMAL, parse_color('foreground')) # Border if not int(config.get('visual', 'showborder')): self.boxin.set_border_width(0) self.boxout.set_border_width(0) else: self.boxin.set_border_width(1) self.boxout.set_border_width(1) # Fonts if config.get('visual', 'use_font_type') == 'custom' or\ not state['gnome_fonts']: new_font = config.get('visual', 'custom_font') else: font_type = config.get('visual', 'use_font_type') new_font = state['gnome_fonts'][font_type] self.textbox.modify_font(pango.FontDescription(new_font)) tab_width = pango.TabArray(1, False) tab_width.set_tab(0, pango.TAB_LEFT, calculate_real_tab_width(self.textbox, 4) ) self.textbox.set_tabs(tab_width) # Indent if config.get('visual', 'indent') == '1': pango_context = self.textbox.get_pango_context() current_font_size = pango_context.\ get_font_description().\ get_size() / 1024 self.textbox.set_indent(current_font_size * 2) else: self.textbox.set_indent(0) # linespacing linespacing = config.getint('visual', 'linespacing') self.textbox.set_pixels_below_lines(linespacing) self.textbox.set_pixels_above_lines(linespacing) self.textbox.set_pixels_inside_wrap(linespacing) # alignment self.align.set( xalign=0.5, yalign=ORIENTATION[config.get('visual', 'alignment')], xscale=0, yscale=0 )
from back_end.data_utilities import mean, first_or_default, fmt_date, normalise_name, gen_to_list from back_end.table import Table from front_end.form_helpers import get_elements_from_html from globals.enumerations import MemberStatus, PlayerStatus, EventType, Function, UserRole from models.wags_db import Event, Score, Course, CourseData, Trophy, Player, Venue, Handicap, Member, Contact, \ Schedule, Booking, User, Committee, Role from globals.app_setup import db from sqlalchemy import text, and_, func from globals import config from back_end.file_access import get_records, update_html_elements, get_file_contents, create_data_file db_session = db.session # region text files data_location = config.get('locations')['data'] html_location = config.get('locations')['html'] def accounts_file(year): path = os.path.join(html_location, 'reports', str(year)) if not os.path.exists(path): os.mkdir(path, 755) fields = ['Member', 'Date', 'Item', 'Debit', 'Credit'] create_data_file(os.path.join(path, 'accounts.tab'), fields) return os.path.join(path, 'accounts.tab') def news_file(): return os.path.join(html_location, 'news/news.htm')
class TestData: data_location = config.get('locations')['data'] events_data = r'2017\events.tab' shots_data = r'shots.tab' events_file = os.path.join(data_location, events_data) shots_file = os.path.join(data_location, shots_data) handicaps_file = os.path.join(data_location, 'hcaps.tab') trophies_file = os.path.join(data_location, 'trophies.txt') venues_file = os.path.join(data_location, 'venue_info.txt') example_event_record = { 'num': '4', 'date': 'Monday 22 May', 'venue': 'West Surrey', 'event': 'The Shutes Shot-Glass', 'course': 'West Surrey', 'address': 'Enton Green,Godalming,Surrey', 'post_code': 'GU8 5AF', 'phone': '01483 421275', 'member_price': '60', 'guest_price': '70', 'schedule': '10.30 Coffee and bacon rolls,11.16 Tee off 18 holes,16.30 1 Course Meal', 'organiser': 'Anthony Shutes', 'directions': 'Whether travelling from Guildford or Portsmouth, turn off the A3 at Milford Junction. At the roundabout take the exit onto the A283 (signposted Milford). At the traffic signals turn left onto Portsmouth Road - A3100 (signposted Godalming). At the mini roundabout, turn right onto Church Road - A286 (signposted Midhurst) then immediately turn left onto Station Lane (signposted Milford Station). At Milford Station, go over the rail crossing and carry on for about 800 yards. At Enton Green, proceed straight on and the entrance to the West Surrey Golf Club is immediately on your right.', 'note': '', 'dinner_price': '', 'dinner_incl': '', 'jacket': '', 'url': 'www.wsgc.co.uk/', 'deadline': 'Thursday 18 May', 'booking_start': '', 'max': '24', 'type': '1' } example_event_record_updated = { 'num': '4', 'date': 'Monday 22 May', 'venue': 'West Surrey', 'event': 'The Shutes Shot-Glass', 'address': 'Enton Green,Godalming,Surrey', 'post_code': 'GU8 5AF', 'phone': '01483 421275', 'member_price': '25.00', 'guest_price': '70.00', 'schedule': '10.30 Coffee and bacon rolls,11.15 Tee off 18 holes,16.00 Buffet', 'organiser': 'Anthony Shutes', 'directions': 'Whether travelling from Guildford or Portsmouth, turn off the A3 at Milford Junction. At the roundabout take the exit onto the A283 (signposted Milford). At the traffic signals turn left onto Portsmouth Road - A3100 (signposted Godalming). At the mini roundabout, turn right onto Church Road - A286 (signposted Midhurst) then immediately turn left onto Station Lane (signposted Milford Station). At Milford Station, go over the rail crossing and carry on for about 800 yards. At Enton Green, proceed straight on and the entrance to the West Surrey Golf Club is immediately on your right.', 'note': '*** New note ***', 'dinner_price': '', 'dinner_incl': '', 'jacket': '', 'url': 'www.wsgc.co.uk/', 'deadline': 'Saturday 20 May', 'max': '24', 'type': '1' } example_event_record_empty = { 'num': None, 'date': None, 'venue': None, 'event': None, 'address': None, 'post_code': None, 'phone': None, 'member_price': None, 'guest_price': None, 'schedule': None, 'organiser': None, 'directions': None, 'note': None, 'dinner_price': None, 'dinner_incl': None, 'jacket': None, 'url': None, 'deadline': None, 'max': None, 'type': None, 'course': None, 'booking_start': None } example_event = { 'num': '4', 'date': datetime.date(2017, 5, 22), 'venue': 'West Surrey', 'event': 'Shutes Shot-Glass', 'course': 'West Surrey', 'address': 'Enton Green\nGodalming\nSurrey', 'post_code': 'GU8 5AF', 'phone': '01483 421275', 'member_price': Decimal("60"), 'guest_price': Decimal("70"), 'schedule': [{ 'time': datetime.time(10, 30), 'text': 'Coffee and bacon rolls' }, { 'time': datetime.time(11, 16), 'text': 'Tee off 18 holes' }, { 'time': datetime.time(16, 30), 'text': '1 Course Meal' }, { 'time': datetime.time(0, 0), 'text': None }, { 'time': datetime.time(0, 0), 'text': None }, { 'time': datetime.time(0, 0), 'text': None }], 'organiser': 'Anthony Shutes', 'directions': 'Whether travelling from Guildford or Portsmouth, turn off the A3 at Milford Junction. At the roundabout take the exit onto the A283 (signposted Milford). At the traffic signals turn left onto Portsmouth Road - A3100 (signposted Godalming). At the mini roundabout, turn right onto Church Road - A286 (signposted Midhurst) then immediately turn left onto Station Lane (signposted Milford Station). At Milford Station, go over the rail crossing and carry on for about 800 yards. At Enton Green, proceed straight on and the entrance to the West Surrey Golf Club is immediately on your right. If you are using Satellite Navigation, do not turn into Water Lane where there is no access to the club. The main entrance to the club is directly off Station Road.', 'dinner_price': '', 'dinner_incl': '', 'jacket': '', 'url': 'www.wsgc.co.uk/', 'booking_start': '', 'max': '24', 'end_booking': datetime.date(2017, 5, 18), 'start_booking': datetime.date(2017, 5, 22), 'deadline': 'Thursday 18 May', 'note': '', 'type': '1', 'event_type': EventType.wags_vl_event } example_event_cards = { '260': ('99', '99', '4', '8', '5', '6', '6', '6', '4', '5', '6', '6', '3', '7', '5', '6', '3', '99'), '160': ('6', '5', '3', '6', '3', '7', '7', '5', '4', '5', '6', '6', '4', '5', '4', '6', '3', '6'), '93': ('5', '5', '3', '6', '4', '4', '5', '5', '4', '6', '6', '5', '5', '7', '6', '99', '99', '7'), '316': ('5', '4', '4', '6', '4', '8', '5', '4', '5', '5', '5', '6', '4', '4', '6', '99', '3', '4'), '162': ('6', '5', '5', '8', '6', '7', '6', '6', '4', '7', '6', '4', '4', '6', '6', '6', '4', '99'), '294': ('5', '5', '5', '6', '5', '7', '6', '4', '5', '4', '7', '4', '4', '3', '6', '6', '4', '6'), '129': ('5', '5', '4', '5', '5', '6', '6', '6', '5', '7', '7', '5', '4', '5', '4', '5', '4', '6'), '178': ('6', '4', '4', '8', '5', '7', '6', '6', '99', '7', '7', '4', '5', '5', '7', '7', '4', '5'), '24': ('99', '6', '99', '7', '99', '6', '6', '7', '5', '6', '7', '99', '4', '6', '99', '7', '4', '99'), '12': ('8', '4', '6', '7', '7', '6', '8', '7', '4', '8', '9', '99', '5', '7', '6', '8', '5', '8'), '3': ('7', '4', '3', '7', '5', '4', '5', '4', '4', '6', '6', '5', '4', '5', '99', '4', '4', '99'), '222': ('6', '4', '3', '6', '5', '6', '6', '5', '5', '99', '5', '5', '4', '5', '3', '4', '3', '6'), '28': ('7', '6', '4', '5', '5', '5', '6', '5', '4', '5', '6', '3', '4', '6', '5', '4', '5', '7'), '290': ('99', '6', '3', '6', '4', '6', '6', '99', '4', '5', '99', '4', '99', '99', '6', '6', '4', '6'), '384': ('4', '4', '3', '7', '5', '7', '5', '7', '5', '5', '6', '5', '3', '5', '6', '6', '3', '7'), '225': ('5', '4', '4', '6', '5', '99', '99', '5', '4', '5', '6', '6', '4', '4', '99', '4', '3', '5') } example_event_result = \ [{'id': '287', 'name': 'Mike Gardner', 'handicap': '18.2', 'strokes': 89, 'points': 36, 'position': 1, 'guest': ''}, {'id': '129', 'name': 'Graham Hansen', 'handicap': '12.9', 'strokes': 90, 'points': 30, 'position': 2, 'guest': ''}, {'id': '385', 'name': 'David Dunn', 'handicap': '10', 'strokes': 89, 'points': 28, 'position': 3, 'guest': ''}, {'id': '3', 'name': 'Mike Dearden', 'handicap': '20.3', 'strokes': 99, 'points': 28, 'position': 4, 'guest': ''}, {'id': '2', 'name': 'Peter Berring', 'handicap': '19.9', 'strokes': 102, 'points': 27, 'position': 5, 'guest': ''}, {'id': '222', 'name': 'Bob Hill', 'handicap': '14.2', 'strokes': 98, 'points': 24, 'position': 6, 'guest': ''}, {'id': '269', 'name': 'John Quilter', 'handicap': '21.1', 'strokes': 104, 'points': 24, 'position': 7, 'guest': ''}, {'id': '1', 'name': 'Fred Berring', 'handicap': '10.6', 'strokes': 94, 'points': 24, 'position': 8, 'guest': ''}, {'id': '225', 'name': 'Anthony Shutes', 'handicap': '11.9', 'strokes': 98, 'points': 21, 'position': 9, 'guest': ''}, {'id': '319', 'name': 'Richard Poole', 'handicap': '26.2', 'strokes': 113, 'points': 20, 'position': 10, 'guest': ''}] example_event_field = [ 'Richard Trinick', 'Gerry Robinson', 'John Stembridge', 'Anthony Shutes', 'Richard Latham', 'Richard Latham', 'Richard Latham', 'Richard Latham', 'Mike Dearden', 'Mike Wells', 'Steve Shaw', 'Bob Hill', 'Quintin Heaney', 'Martin Dilke-Wing', 'Andy Burn', 'Peter Berring', 'Gerry McGuffie', 'Rhod James', '', '', 'Andy Burn' ] example_venues_fields = [('1', 'West Byfleet'), ('2', 'Wimbledon Common'), ('3', 'Chartham Park'), ('4', 'West Surrey'), ('5', 'Portugal'), ('5.1', 'Lisbon Sports Club'), ('5.2', 'Golf Do Estoril'), ('5.3', 'Penha Longa'), ('6', 'Mill Ride'), ('7', 'Betchworth'), ('8', 'The Dyke'), ('9', 'Seaford Head'), ('10', 'The Richmond'), ('11', 'Moor Park'), ('12', ''), ('13', 'Malden'), ('14', 'Worplesdon'), ('15', 'Pine Ridge'), ('16', 'Burhill'), ('12.1', 'Enmore Park'), ('12.2', 'Oake Manor'), ('12.3', 'Taunton & Pickeridge')] example_course_data_1 = { 'course': '4', 'year': '3000', 'sss': '70', 'si1': '9', 'si2': '15', 'si3': '3', 'si4': '7', 'si5': '17', 'si6': '1', 'si7': '13', 'si8': '5', 'si9': '11', 'si10': '12', 'si11': '18', 'si12': '2', 'si13': '16', 'si14': '8', 'si15': '4', 'si16': '14', 'si17': '6', 'si18': '10', 'par': '70', 'par1': '4', 'par2': '3', 'par3': '4', 'par4': '3', 'par5': '4', 'par6': '4', 'par7': '3', 'par8': '5', 'par9': '4', 'par10': '3', 'par11': '4', 'par12': '4', 'par13': '4', 'par14': '3', 'par15': '5', 'par16': '4', 'par17': '5', 'par18': '4' } example_course_data_2 = { 'course': '4', 'year': '1997', 'sss': '69', 'si1': '2', 'si2': '16', 'si3': '4', 'si4': '12', 'si5': '18', 'si6': '8', 'si7': '14', 'si8': '10', 'si9': '6', 'si10': '15', 'si11': '17', 'si12': '7', 'si13': '9', 'si14': '13', 'si15': '11', 'si16': '1', 'si17': '5', 'si18': '3', 'par': '70', 'par1': '4', 'par2': '3', 'par3': '4', 'par4': '3', 'par5': '4', 'par6': '4', 'par7': '3', 'par8': '5', 'par9': '4', 'par10': '3', 'par11': '4', 'par12': '4', 'par13': '4', 'par14': '3', 'par15': '5', 'par16': '4', 'par17': '5', 'par18': '4' } example_course_data_3 = { 'course': '21', 'year': '3000', 'sss': '69', 'si1': '6', 'si2': '12', 'si3': '4', 'si4': '14', 'si5': '16', 'si6': '2', 'si7': '8', 'si8': '18', 'si9': '10', 'si10': '11', 'si11': '1', 'si12': '9', 'si13': '5', 'si14': '7', 'si15': '17', 'si16': '3', 'si17': '15', 'si18': '13', 'par': '71', 'par1': '4', 'par2': '5', 'par3': '3', 'par4': '4', 'par5': '3', 'par6': '4', 'par7': '4', 'par8': '3', 'par9': '5', 'par10': '5', 'par11': '4', 'par12': '4', 'par13': '4', 'par14': '4', 'par15': '3', 'par16': '5', 'par17': '3', 'par18': '4' } example_venue = { 'id': '4', 'name': 'Gatton Manor', 'address': 'Standon Lane\nOckley\nNr.Dorking\nSurrey', 'post_code': 'RH5 5PQ', 'phone': '01306 627555', 'url': 'www.gattonmanor.co.uk/golf.html', 'directions': "From Dorking, south on the A24 in the direction of Horsham. Go past sign for Beare Green and continue to the large roundabout (Dukes Head Hotel on left) turn right onto the A29 (signposted Ockley, Bognor Regis). Continue through Ockley (approx 3 miles) and at the far end of Ockley village on the right hand side is a restaurant called 'Bryces -The Old School House', 200 yards past this turn right into Cat Hill Lane. Continue to follow the signs and you will turn left into Standon Lane. This is a narrow country lane, please travel at a slow pace and continue for approx 1 mile and you will find the main entrance to Gatton Manor on the right." } example_tour_events = [{ 'num': '5.1', 'date': datetime.date(2017, 6, 9), 'course': 'Lisbon Sports Club', 'venue': 'Lisbon Sports Club' }, { 'num': '5.2', 'date': datetime.date(2017, 6, 10), 'course': 'Golf Do Estoril', 'venue': 'Golf Do Estoril' }, { 'num': '5.3', 'date': datetime.date(2017, 6, 11), 'course': 'Penha Longa', 'venue': 'Penha Longa' }, { 'num': None, 'date': None, 'course': None, 'venue': None }, { 'num': None, 'date': None, 'course': None, 'venue': None }, { 'num': None, 'date': None, 'course': None, 'venue': None }] event_result_return = \ [ {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 38, 'guest': '', 'player_id': '3', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '21.8', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 34, 'guest': '', 'player_id': '222', 'strokes_return': '88', 'guest_return': '', 'handicap_return': '14.3', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 32, 'guest': '', 'player_id': '28', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '16', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 31, 'guest': '', 'player_id': '384', 'strokes_return': '93', 'guest_return': 'guest', 'handicap_return': '16', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '93', 'strokes_return': '96', 'guest_return': '', 'handicap_return': '16.3', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '160', 'strokes_return': '91', 'guest_return': '', 'handicap_return': '11.8', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '260', 'strokes_return': '103', 'guest_return': '', 'handicap_return': '23.1', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '225', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '12.4', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '316', 'strokes_return': '89', 'guest_return': '', 'handicap_return': '8.1', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '162', 'strokes_return': '104', 'guest_return': '', 'handicap_return': '23.5', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '294', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '11.9', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '290', 'strokes_return': '104', 'guest_return': 'guest', 'handicap_return': '24', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 27, 'guest': '', 'player_id': '129', 'strokes_return': '94', 'guest_return': '', 'handicap_return': '12.5', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 23, 'guest': '', 'player_id': '178', 'strokes_return': '103', 'guest_return': '', 'handicap_return': '18.1', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 20, 'guest': '', 'player_id': '24', 'strokes_return': '116', 'guest_return': '', 'handicap_return': '28', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 16, 'guest': '', 'player_id': '12', 'strokes_return': '121', 'guest_return': '', 'handicap_return': '28', 'csrf_token': ''}, {'num': None, 'position': None, 'player': '', 'handicap': None, 'strokes': None, 'points': 0, 'guest': '', 'player_id': '2', 'strokes_return': '0', 'guest_return': '', 'handicap_return': '19.7', 'csrf_token': ''} ] event_result_sorted = \ [ {'num': None, 'position': 1, 'player': '', 'handicap': None, 'strokes': None, 'points': 38, 'guest': '', 'player_id': '3', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '21.8', 'csrf_token': '', 'sort': 38161006.0}, {'num': None, 'position': 2, 'player': '', 'handicap': None, 'strokes': None, 'points': 34, 'guest': '', 'player_id': '222', 'strokes_return': '88', 'guest_return': '', 'handicap_return': '14.3', 'csrf_token': '', 'sort': 34191507.0}, {'num': None, 'position': 3, 'player': '', 'handicap': None, 'strokes': None, 'points': 32, 'guest': '', 'player_id': '28', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '16', 'csrf_token': '', 'sort': 32170904.0}, {'num': None, 'position': 4, 'player': '', 'handicap': None, 'strokes': None, 'points': 31, 'guest': '', 'player_id': '384', 'strokes_return': '93', 'guest_return': 'guest', 'handicap_return': '16', 'csrf_token': '', 'sort': 31161004.0}, {'num': None, 'position': 5, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '225', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '12.4', 'csrf_token': '', 'sort': 29171308.0}, {'num': None, 'position': 6, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '260', 'strokes_return': '103', 'guest_return': '', 'handicap_return': '23.1', 'csrf_token': '', 'sort': 29171105.0}, {'num': None, 'position': 7, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '160', 'strokes_return': '91', 'guest_return': '', 'handicap_return': '11.8', 'csrf_token': '', 'sort': 29151105.0}, {'num': None, 'position': 8, 'player': '', 'handicap': None, 'strokes': None, 'points': 29, 'guest': '', 'player_id': '93', 'strokes_return': '96', 'guest_return': '', 'handicap_return': '16.3', 'csrf_token': '', 'sort': 29080301.0}, {'num': None, 'position': 9, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '294', 'strokes_return': '92', 'guest_return': '', 'handicap_return': '11.9', 'csrf_token': '', 'sort': 28161004.0}, {'num': None, 'position': 10, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '162', 'strokes_return': '104', 'guest_return': '', 'handicap_return': '23.5', 'csrf_token': '', 'sort': 28150904.0}, {'num': None, 'position': 11, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '316', 'strokes_return': '89', 'guest_return': '', 'handicap_return': '8.1', 'csrf_token': '', 'sort': 28140905.0}, {'num': None, 'position': 12, 'player': '', 'handicap': None, 'strokes': None, 'points': 28, 'guest': '', 'player_id': '290', 'strokes_return': '104', 'guest_return': 'guest', 'handicap_return': '24', 'csrf_token': '', 'sort': 28130706.0}, {'num': None, 'position': 13, 'player': '', 'handicap': None, 'strokes': None, 'points': 27, 'guest': '', 'player_id': '129', 'strokes_return': '94', 'guest_return': '', 'handicap_return': '12.5', 'csrf_token': '', 'sort': 27141205.0}, {'num': None, 'position': 14, 'player': '', 'handicap': None, 'strokes': None, 'points': 23, 'guest': '', 'player_id': '178', 'strokes_return': '103', 'guest_return': '', 'handicap_return': '18.1', 'csrf_token': '', 'sort': 23120805.0}, {'num': None, 'position': 15, 'player': '', 'handicap': None, 'strokes': None, 'points': 20, 'guest': '', 'player_id': '24', 'strokes_return': '116', 'guest_return': '', 'handicap_return': '28', 'csrf_token': '', 'sort': 20100703.0}, {'num': None, 'position': 16, 'player': '', 'handicap': None, 'strokes': None, 'points': 16, 'guest': '', 'player_id': '12', 'strokes_return': '121', 'guest_return': '', 'handicap_return': '28', 'csrf_token': '', 'sort': 16050502.0}, {'num': None, 'position': 17, 'player': '', 'handicap': None, 'strokes': None, 'points': 0, 'guest': '', 'player_id': '2', 'strokes_return': '0', 'guest_return': '', 'handicap_return': '19.7', 'csrf_token': '', 'sort': 0.0} ]
def current_year_end(): date = config.get('next_renewal_date') return parse_date(date, reverse=True)
def setUp(self): db_path = config.get('db_path') self.engine = create_engine(db_path, echo=True) Session = sessionmaker(bind=self.engine) self.session = Session()
def render_html(template, **kwargs): import jinja2 env = jinja2.Environment(loader=jinja2.FileSystemLoader( searchpath=config.get('locations')['templates'])) template = env.get_template(template) return template.render(url_for=url_for, **kwargs)
try: os.mkdir('resume_file/{0}/{1}'.format(year, month)) except OSError, e: pass try: os.mkdir('resume_file/{0}/{1}/{2}'.format(year, month, day)) except OSError, e: pass img_f = os.path.join( 'resume_file/{0}/{1}/{2}/'.format(year, month, day), img_time) with open(img_f, 'wb+') as f: f.write(data) # ResizeImage(filein=img_f, fileout=out_f, width=1193, height=570, i_type=imgType) qiniu_config = config.get("QINIU") a_key = qiniu_config.get('access_key') s_key = qiniu_config.get("secret_key") bucket_name = qiniu_config.get("bucket_name") q = Auth(access_key=a_key, secret_key=s_key) key = img_f token = q.upload_token(bucket_name, key) localfile = img_f name_url = qiniu_config.get("url") ret, info = put_file(token, key, localfile) if ret.get("key") == key: url = '{0}/{1}'.format(name_url, key) # url = get_photo(key=key, size='small') return success(res={'url': url, 'file_key': key})
def is_latest_event(event): last = get_latest_event() override = config.get('override') return override or event.id == last.id
import os from globals import config from globals.config import url_for_html from back_end.data_utilities import fmt_date, parse_date, force_list from globals.enumerations import MinutesType minutes_location = config.get('locations')['minutes'] class Minutes: def __init__(self, type=None, date=None, file_type='pdf'): self.type = type self.date = date self.file_type = file_type def file_name(self): meeting_date = fmt_date(self.date).replace('/', ' ') meeting_type = Minutes.map_type_to_file(self.type) return meeting_type + ' ' + meeting_date + '.' + self.file_type def file_link(self, draft=False): draft = 'drafts' if draft else '' return url_for_html('minutes', draft, self.file_name()) def full_type(self): if self.type == MinutesType.Committee: return 'Committee meeting' if self.type == MinutesType.AGM: return 'AGM'
def is_event_editable(year): override = config.get('override') return override or year >= datetime.date.today().year