def run(d): global out if isinstance(d, list): for k in d: if isinstance(k, dict): run(k) else: for k, v in d.items(): if isinstance(v, dict) or isinstance(v, list): run(v) if isinstance(v, str) and v.startswith("#"): # v = v.lstrip("#") c = Color(v[:7]) out += c.get_hex_l() if 0 < c.saturation < 1: if c.luminance > 0.3: c.luminance = np.clip(c.luminance + 0.1, 0, 1) if c.saturation > 0: c.saturation = np.clip(c.saturation + 0.2, 0, 1) elif c.saturation == 0: if c.luminance > 0.5: c.luminance = np.clip(c.luminance + 0.2, 0, 1) else: ... # c.luminance = np.clip(c.luminance + 0.05, 0, 1) # out = ( # "#" # + "".join([format(int(v), "02x") for v in colorsys.hls_to_rgb(*u)]) # + v[6:] # ) out += "\t" + c.get_hex_l() + "\n" d[k] = c.get_hex_l() + v[7:]
def get_play_colors(play_id: str) -> Tuple[str, str]: """ Generate two colors (in hex) for a given play: the main color and the color to use as a font color :param play_id :return: """ picked_color = Color(pick_for=play_id, luminance=0.4) play_font_color = "#ffffff" return picked_color.get_hex_l(), play_font_color
def get_play_colors(play): """ Return two colors (in hex) for a given play: the main color and the color to use as a font color :return: """ # TODO: Check the if the picked color is (almost) white. We can't see a white edge on the graph picked_color = Color(pick_for=play) play_font_color = "#000000" if picked_color.get_luminance( ) > 0.6 else "#ffffff" return picked_color.get_hex_l(), play_font_color
def get_color_thumbnail(color: Color) -> Path: """ Retrieve the thumbnail of the given color. The output name will be the corresponding hex strings. If the corresponding file does not exist, it will create it. """ fname = data_path / (str(color.get_hex_l()[1:]) + ".png") if fname.exists(): if fname.is_file(): return fname else: raise FileNotFoundError(f"Thumbnail file exists but it's not a file -> {fname}") # file not there - cache it thumbnail_size = (5, 5) rgb_triad = np.array([c * 255 for c in color.get_rgb()], dtype=np.uint8) mat = np.zeros((*thumbnail_size, 3), dtype=np.uint8) + rgb_triad plt.imsave(fname, mat) return fname
def match_color(self, color, convert2discord=True): color = color.lower() if color in self._color_names: rgb = self._color_names[color] if not convert2discord: return rgb['hex'] rgb = rgb['rgb'] rgb = tuple(map(lambda c: c / 255.0, rgb)) else: try: rgb = Colour(color) if not convert2discord: return rgb.get_hex_l() rgb = rgb.rgb except: return return self.check_rgb(rgb)
def generate_page(): form = BlinkieForm() filename = None if form.validate_on_submit(): if form.errors: app.logger.warning(form.errors) text = form.text.data gif_background_color = tuple( int(x * 255) for x in form.background_color.data.rgb) gif_text_color = tuple(int(x * 255) for x in form.text_color.data.rgb) gif_blink_color = tuple( int(x * 255) for x in form.blink_color.data.rgb) filename = make_gif(text, gif_background_color, gif_text_color, gif_blink_color) app.logger.info(filename) background_color = form.background_color.data.get_hex_l() text_color = form.text_color.data.get_hex_l() blink_color = form.blink_color.data.get_hex_l() else: text_color = '#000000' blink_color = '#ffffff' background_color = Color() background_color.red = random.random() background_color.green = random.random() background_color.blue = random.random() background_color = background_color.get_hex_l() return render_template('generate.html', form=form, filename=filename, text_color=text_color, blink_color=blink_color, background_color=background_color)
def _marks_to_excel(data): """ :type discipline: students.models.Discipline :type group: students.models.Group """ from students.models.group import Group # data = json.loads(json.loads(DisciplineMarksCache.get(discipline.pk, group.pk))) lessons = data['lessons'] students = data['students'] mark_types = data['mark_types'] lesson_types = data['lesson_types'] group = None if len(students) > 0: group = Group.objects.filter(pk=students[0]['group']).first() else: return '' students.sort(key=lambda s: s['sum'], reverse=True) # Create an in-memory output file for the new workbook. output = io.BytesIO() workbook = xlsxwriter.Workbook(output, {'in_memory': True}) frmt_student = workbook.add_format() frmt_student.set_border() frmt_student.set_align('center') frmt_student.set_align('vcenter') frmt_student.set_rotation(90) frmt_student.set_text_wrap() frmt_header = workbook.add_format() frmt_header.set_border() frmt_header.set_align('center') frmt_header.set_align('vcenter') frmt_header.set_text_wrap() worksheet = workbook.add_worksheet(u"{}".format(group.title if group else u'студенты')) bg_colors = { # Mark.MARK_ABSENT: "#ffeeee", Mark.MARK_NORMAL: "#aef28c", Mark.MARK_GOOD: "#aef28c", Mark.MARK_EXCELLENT: "#4bb814", Mark.MARK_AWESOME: "#388a0f", Mark.MARK_FANTASTIC: "#255c0a", Mark.MARK_INCREDIBLE: "#3a4408", Mark.MARK_BLACK_HOLE: "black", Mark.MARK_SHINING: "yellow", } mark_formats = {} lesson_formts = {} # Подготовка стилей for lt in lesson_types: frmt = workbook.add_format() frmt.set_align('center') frmt.set_align('vcenter') frmt.set_text_wrap() frmt.set_border() if lt['id'] >= 2: bg_color = Color(bg_colors[Mark.MARK_NORMAL]) bg_color.set_hue({ 2: 0.15, 3: 0.5, 4: 0.6, 5: 0.8 }.get(lt['id'], bg_color.get_hue())) frmt.set_bg_color(bg_color.get_hex_l()) lesson_formts[lt['id']] = frmt for mt in mark_types: if mark_formats.get(lt['id']) is None: mark_formats[lt['id']] = {} frmt = workbook.add_format() frmt.set_align('center') frmt.set_align('vcenter') frmt.set_border() bg_color = bg_colors.get(mt['k'], 'white') color = { Mark.MARK_BLACK_HOLE: 'white', Mark.MARK_AWESOME: 'white', Mark.MARK_EXCELLENT: 'white', Mark.MARK_FANTASTIC: 'white', Mark.MARK_INCREDIBLE: 'white', }.get(mt['k'], 'black') bg_color = Color(bg_color) color = Color(color) if mt['k'] > 0: if lt['id'] == 2: bg_color.set_hue(0.15) bg_color.set_luminance(min(bg_color.get_luminance() * 1.4, 0.9)) elif lt['id'] == 3: bg_color.set_hue(0.5) bg_color.set_luminance(min(bg_color.get_luminance() * 1.1, 0.9)) elif lt['id'] == 4: bg_color.set_hue(0.6) bg_color.set_luminance(min(bg_color.get_luminance() * 1.1, 0.9)) elif lt['id'] == 5: bg_color.set_hue(0.8) bg_color.set_luminance(min(bg_color.get_luminance() * 1.1, 0.9)) else: bg_color.set_hue(0.25) bg_color = { Mark.MARK_SHINING: Color(bg_colors[Mark.MARK_SHINING]), Mark.MARK_BLACK_HOLE: Color(bg_colors[Mark.MARK_BLACK_HOLE]), }.get(mt['k'], bg_color) frmt.set_bg_color(bg_color.get_hex_l()) frmt.set_color(color.get_hex_l()) mark_formats[lt['id']][mt['k']] = frmt # заполнение строки занятий worksheet.set_row(0, 90) for r, l in enumerate(lessons, 2): worksheet.write(r, 0, l['dn_raw'].strip(), lesson_formts[l['lt']]) h = 20 * max(1, l['dn_raw'].strip().count("\n") + 1) worksheet.set_row(r, h) # заполнение таблицы оценок max_width = 1 for c, s in enumerate(students, 1): name = "%s %s" % (s['second_name'], s['name']) score = Discipline.compute_percents(s['marks'], lessons=lessons) score = "{score} / {percents}%".format(**{ 'percents': int(score * 100), 'score': s['sum'], }) # ячейка имени worksheet.write(0, c, name, frmt_student) worksheet.write(1, c, score, frmt_header) # заполняем оценки marks = s['marks'] for r, m in enumerate(marks, 2): if m['m'] is not None: if abs(m['m']) > Mark.MARK_SPECIAL: mark = { Mark.MARK_BLACK_HOLE: u'∅', Mark.MARK_SHINING: u'∞', Mark.MARK_MERCY: u'○', Mark.MARK_KEEP: u'=', }.get(m['m'], '') else: mark = u'н' if m['m'] == -2 else m['m'] else: mark = '' lt = lessons[r - 2]['lt'] worksheet.write(r, c, mark, mark_formats[lt].get(0 if m['m'] is None else m['m'], None)) if len(name) > max_width: max_width = len(name) # декоративные улучшения worksheet.set_column(0, 0, max_width) worksheet.merge_range('A1:A2', group.title, frmt_header) # print setup if len(lessons) < len(students): worksheet.set_landscape() worksheet.fit_to_pages(1, 1) # Close the workbook before streaming the data. workbook.close() # Rewind the buffer. output.seek(0) return output
async def stand_gen(self, ctx, stand, user, image=None, advanced=None): """Generate a stand card. Arguments are stand name, user name and an image Image can be an attachment or a link. Passing -advanced as the last argument will enable advanced mode which gives the ability to tune some numbers. Use quotes for names that have spaces e.g. {prefix}{name} "Star Platinum" "Jotaro Kujo" [image] """ author = ctx.author name = author.name channel = ctx.channel stand = self._standify_text(stand, 2) user = '******' + user stand = '[STAND NAME]\n' + stand size = (1100, 700) shift = 800 if advanced is None and image == '-advanced': image = None advanced = True elif advanced is not None: advanced = advanced.strip() == '-advanced' if advanced: await ctx.send('`{}` Advanced mode activated'.format(name), delete_after=20) image_ = await get_image_from_message(ctx, image) img = await image_from_url(image_, self.bot.aiohttp_client) if img is None: image = image_ if image is None else image return await ctx.send( '`{}` Could not extract image from {}. Stopping command'. format(name, image)) m_, msg = await self.subcommand( ctx, '`{}` Give the stand **stats** in the given order ranging from **A** to **E** ' 'separated by **spaces**.\nDefault value is E\n`{}`'.format( name, '` `'.join(POWERS)), delete_after=120, author=author, channel=channel) await m_.delete() if msg is None: await ctx.send('{} cancelling stand generation'.format(author.name) ) return stats = msg.content.split(' ') stats = dict(zip_longest(POWERS, stats[:6])) m_, msg = await self.subcommand( ctx, '`{}` Use a custom background by uploading a **picture** or using a **link**. ' 'Posting something other than an image will use the **generated background**' .format(name), delete_after=120, author=author, channel=channel) bg = get_picture_from_msg(msg) await m_.delete() if bg is not None: try: bg = bg.strip() bg = await image_from_url(bg, self.bot.aiohttp_client) dominant_color = get_color(bg) color = Color(rgb=list(map(lambda c: c / 255, dominant_color))) bg = resize_keep_aspect_ratio(bg, size, True) except Exception: logger.exception('Failed to get background') await ctx.send( '`{}` Failed to use custom background. Using generated one' .format(name), delete_after=60.0) bg = None if bg is None: color = None pattern = random.choice(GeoPattern.available_generators) m_, msg = await self.subcommand( ctx, "`{}` Generating background. Select a **pattern** and **color** separated by space. " "Otherwise they'll will be randomly chosen. Available patterns:\n" '{}'.format(name, '\n'.join(GeoPattern.available_generators)), delete_after=120, channel=channel, author=author) await m_.delete() if msg is None: await ctx.send('`{}` Selecting randomly'.format(name), delete_after=20) if msg is not None: msg = msg.content.split(' ') pa, c = None, None if len(msg) == 1: pa = msg[0] elif len(msg) > 1: pa, c = msg[:2] if pa in GeoPattern.available_generators: pattern = pa else: await ctx.send( '`{}` Pattern {} not found. Selecting randomly'.format( name, pa), delete_after=20) try: color = Color(c) except: await ctx.send('`{}` {} not an available color'.format( name, c), delete_after=20) bg, color = create_geopattern_background(size, stand + user, generator=pattern, color=color) if advanced: m_, msg = await self.subcommand( ctx, '`{}` Input color value change as an **integer**. Default is {}. ' 'You can also input a **color** instead of the change value. ' 'The resulting color will be used in the stats circle'.format( name, shift), delete_after=120, channel=channel, author=author) try: shift = int(msg.content.split(' ')[0]) except ValueError: try: color = Color(msg.content.split(' ')[0]) shift = 0 except: await ctx.send( '`{}` Could not set color or color change int. Using default values' .format(name), delete_after=15) await m_.delete() bg_color = Color(color) shift_color( color, shift ) # Shift color hue and saturation so it's not the same as the bg fig, _ = self.create_stats_circle(color=color.get_hex_l(), bg_color=bg_color, **stats) path = os.path.join(IMAGES_PATH, 'stats.png') with self.stat_lock: try: fig.savefig(path, transparent=True) stat_img = Image.open(path) except: logger.exception('Could not create image') return await ctx.send( '`{}` Could not create picture because of an error.'. format(name)) plt.close(fig) stat_img = stat_img.resize( (int(stat_img.width * 0.85), int(stat_img.height * 0.85)), Image.BILINEAR) full = Image.new('RGBA', size) x, y = (-60, full.height - stat_img.height) stat_corner = (x + stat_img.width, y + stat_img.height) full.paste(stat_img, (x, y, *stat_corner)) font = ImageFont.truetype(os.path.join('M-1c', 'mplus-1c-bold.ttf'), 40) text = create_glow( create_shadow( create_text(stand, font, '#FFFFFF', (int(full.width * 0.75), int(y * 0.8)), (10, 10)), 80, 3, 2, 4), 3).convert('RGBA') full.paste(text, (20, 20), text) text2 = create_glow( create_shadow( create_text(user, font, '#FFFFFF', (int( (full.width - stat_corner[0]) * 0.8), int( full.height * 0.7)), (10, 10)), 80, 3, 2, 4), 3).convert('RGBA') text2.load() if img is not None: im = trim_image(img) m_, msg = await self.subcommand( ctx, '`{}` Try to automatically remove background (y/n)? ' 'This might f**k the picture up and will take a moment'.format( name), author=author, channel=channel, delete_after=120, check=y_n_check) await m_.delete() if msg and msg.content.lower() in ['y', 'yes']: kwargs = {} if advanced: m_, msg = await self.subcommand( ctx, '`{}` Change the arguments of background removing. Available' ' arguments are `blur`, `canny_thresh_1`, `canny_thresh_2`, ' '`mask_dilate_iter`, `mask_erode_iter`. ' 'Accepted values are integers.\nArguments are added like this ' '`-blur 30 -canny_thresh_2 50`. All arguments are optional' .format(name), channel=channel, author=author, delete_after=140) await m_.delete() await channel.trigger_typing() if msg is not None: try: kwargs = self.parser.parse_known_args( msg.content.split(' '))[0].__dict__ except: await ctx.send( '`{}` Could not get arguments from {}'.format( name, msg.content), delete_after=20) try: im = await self.bot.loop.run_in_executor( self.bot.threadpool, partial(remove_background, im, **kwargs)) except Exception: logger.exception('Failed to remove bg from image') await ctx.send( '`{}` Could not remove background because of an error'. format(name), delete_after=30) box = (500, 600) im = resize_keep_aspect_ratio(im, box, can_be_bigger=False) im = create_shadow(im, 70, 3, -22, -7).convert('RGBA') full.paste( im, (full.width - im.width, int( (full.height - im.height) / 2)), im) await channel.trigger_typing() full.paste(text2, (int( (full.width - stat_corner[0]) * 0.9), int(full.height * 0.7)), text2) bg.paste(full, (0, 0), full) file = BytesIO() bg.save(file, format='PNG') file.seek(0) await ctx.send(file=discord.File(file, filename='stand_card.png'))
def results(request, JobID, JobType='hgspeci'): # if the job hasn't been started, start the job. # if the job is running, check every 5 seconds. # if the job has finished, display the results. item = get_object_or_404(HgSpeciJob, JobID=JobID) if item.CurrentStatus == '0': clientStatistics(request) # the job is 'to be start', submit the job and jump to '1' # change the status in the database item.CurrentStatus = '1' item.Successful = True item.FailedReason = '' item.save() # redirect to the result page return redirect('/hgspeci/results/%d' % int(item.JobID)) if item.CurrentStatus == '1': # a function to start the job #### call some function here #### # a. generate input file # b. submit the job # prepare the necessary file for phreeqc jobmanger = JobManagement() jobmanger.HgspeciJobPrepare(obj=item, JobType=JobType) # run the calculations in background Exec_thread = threading.Thread(target=jobmanger.JobExec, kwargs={"obj": item, 'JobType': JobType}) Exec_thread.start() # the job is 'running', keep checking the status return render(request, 'hgspeci/results_jobrunning.html', {'JobID': JobID, 'Item': item}) if item.CurrentStatus == '2': clientStatistics(request) # the job is finished, display the results. if str(item.SPUserDefinedInput) != '': return render(request, 'hgspeci/results_userdefine.html', {'JobID': JobID, 'Item': item}) # get data for plotting the results job_dir = get_job_dir(JobID) csv = '%s/speciation-molality.csv' % job_dir try: df = pd.DataFrame.from_csv(csv) df = df[df.Species != 'H2O'] df.index = range(len(df)) except: item.Successful = False item.FailedReason = 'Could not find file %s' % os.path.basename(csv) return render(request, 'hgspeci/results_error.html', {'JobID': JobID, 'Item': item}) # get species and pH values species = [str(i) for i in df.Species.values] pHs = [float(i) for i in df.columns.values[1:]] chartType = 'line' if len(pHs) == 1: chartType = 'bar' # generate color does red = Color("red") blue = Color("blue") try: # generate color gradient colors = [blue.get_hex_l(), red.get_hex_l()] + [i.get_hex_l() for i in list(blue.range_to(red, len(species)-2))] #colors = [i.get_hex_l() for i in list(blue.range_to(red, len(species)))] ## sort the color according to charges charges = [getCharge(m) for m in species] sp_ch = sorted(zip(species, charges), key=lambda x: x[1]) sp_color = dict(zip([i[0] for i in sp_ch], colors)) colors = [sp_color[i] for i in species] except: # generate a random color code colors = ['#'+''.join(np.random.permutation([i for i in '0123456789ABCDEF'])[:6]) for i in range(len(df))] # generate a random color code colors = ['#'+''.join(np.random.permutation([i for i in '0123456789ABCDEF'])[:6]) for i in range(len(df))] # for molality data_molality = [] for idx in range(len(df)): di = {'name': df.ix[idx].values[0], 'data':['%.2E' % Decimal(float(i)) for i in df.ix[idx].values[1:]]} di['color'] = colors[idx] data_molality.append(di) # for activity csv = '%s/speciation-activity.csv' % job_dir try: df = pd.DataFrame.from_csv(csv) df = df[df.Species != 'H2O'] df.index = range(len(df)) except: pass data_activity = [] for idx in range(len(df)): di = {'name': df.ix[idx].values[0], 'data':['%.2E' % Decimal(float(i)) for i in df.ix[idx].values[1:]]} di['color'] = colors[idx] data_activity.append(di) # for logmolality csv = '%s/speciation-logmolality.csv' % job_dir try: df = pd.DataFrame.from_csv(csv) df = df[df.Species != 'H2O'] df.index = range(len(df)) except: pass data_logmolality = [] for idx in range(len(df)): di = {'name': df.ix[idx].values[0], 'data':['%.2E' % Decimal(float(i)) for i in df.ix[idx].values[1:]]} di['color'] = colors[idx] data_logmolality.append(di) # for logactivity csv = '%s/speciation-logactivity.csv' % job_dir try: df = pd.DataFrame.from_csv(csv) df = df[df.Species != 'H2O'] df.index = range(len(df)) except: pass data_logactivity = [] for idx in range(len(df)): di = {'name': df.ix[idx].values[0], 'data':['%.2E' % Decimal(float(i)) for i in df.ix[idx].values[1:]]} di['color'] = colors[idx] data_logactivity.append(di) # for gamma csv = '%s/speciation-gamma.csv' % job_dir try: df = pd.DataFrame.from_csv(csv) df = df[df.Species != 'H2O'] df.index = range(len(df)) except: pass data_gamma = [] for idx in range(len(df)): di = {'name': df.ix[idx].values[0], 'data':['%.2E' % Decimal(float(i)) for i in df.ix[idx].values[1:]]} di['color'] = colors[idx] data_gamma.append(di) return render(request, 'hgspeci/results.html', {'JobID': JobID, 'Item': item, 'species': species, 'pHs': pHs, 'chartType': chartType, 'data_molality': data_molality, 'data_activity': data_activity, 'data_logmolality': data_logmolality, 'data_logactivity': data_logactivity, 'data_gamma': data_gamma, }) if item.CurrentStatus == '3': clientStatistics(request) # there is some error in the job, display the error message. return render(request, 'hgspeci/results_error.html', {'JobID': JobID, 'Item': item})