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:]
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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'))
Exemplo n.º 9
0
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})