<commit_before>import os

import bcrypt
import cherrypy
from pockets import listify
from sqlalchemy import and_, or_
from sqlalchemy.orm import joinedload

from uber.config import c
from uber.custom_tags import humanize_timedelta
from uber.decorators import all_renderable, csrf_protected, csv_file, multifile_zipfile, render, xlsx_file
from uber.errors import HTTPRedirect
from uber.models import AdminAccount, Attendee, Group, IndieGame, IndieGameReview, IndieStudio
from uber.tasks.email import send_email
from uber.utils import check, genpasswd, localized_now


@all_renderable(c.INDIE_ADMIN)
class Root:
    def index(self, session, message=''):
        return {
            'message': message,
            'judges': session.indie_judges().all(),
            'games': [g for g in session.indie_games() if g.video_submitted]
        }

    def studios(self, session, message=''):
        return {
            'message': message,
            'studios': session.query(IndieStudio).all()
        }

    @csv_file
    def social_media(self, out, session):
        out.writerow(['Studio', 'Website', 'Twitter', 'Facebook'])
        for game in session.indie_games():
            if game.confirmed:
                out.writerow([
                    game.studio.name,
                    game.studio.website,
                    game.studio.twitter,
                    game.studio.facebook
                ])

    @csv_file
    def everything(self, out, session):
        out.writerow([
            'Game', 'Studio', 'Studio URL', 'Primary Contact Name', 'Primary Contact Email',
            'Game Website', 'Twitter', 'Facebook', 'Other Social Media',
            'Genres', 'Brief Description', 'Long Description', 'How to Play',
            'Link to Video for Judging', 'Link to Promo Video', 'Link to Game', 'Game Link Password',
            'Game Requires Codes?', 'Code Instructions', 'Build Status', 'Build Notes',
            'Video Submitted', 'Game Submitted', 'Current Status',
            'Registered', 'Accepted', 'Confirmation Deadline',
            'Screenshot Links', 'Average Score', 'Individual Scores'
        ])
        for game in session.indie_games():
            out.writerow([
                game.title,
                game.studio.name,
                '{}/mivs_applications/continue_app?id={}'.format(c.PATH, game.studio.id),
                game.studio.primary_contact.full_name,
                game.studio.primary_contact.email,
                game.link_to_webpage,
                game.twitter,
                game.facebook,
                game.other_social_media,
                ' / '.join(game.genres_labels),
                game.brief_description,
                game.description,
                game.how_to_play,
                game.link_to_video,
                game.link_to_promo_video,
                game.link_to_game,
                game.password_to_game,
                game.code_type_label,
                game.code_instructions,
                game.build_status_label,
                game.build_notes,
                'submitted' if game.video_submitted else 'not submitted',
                'submitted' if game.submitted else 'not submitted',
                'accepted and confirmed' if game.confirmed else game.status_label,
                game.registered.strftime('%Y-%m-%d'),
                'n/a' if not game.accepted else game.accepted.strftime('%Y-%m-%d'),
                'n/a' if not game.accepted else game.studio.confirm_deadline.strftime('%Y-%m-%d'),
                '\n'.join(c.URL_BASE + screenshot.url.lstrip('.') for screenshot in game.screenshots),
                str(game.average_score)
            ] + [str(score) for score in game.scores])

    @csv_file
    def checklist_completion(self, out, session):
        header_row = ['Studio']
        for key, val in c.MIVS_CHECKLIST.items():
            header_row.append(val['name'])
            header_row.append('Past Due?')
        out.writerow(header_row)

        rows = []
        for studio in session.query(IndieStudio).join(IndieStudio.group).join(Group.guest):
            row = [studio.name]
            for key, val in c.MIVS_CHECKLIST.items():
                row.extend([
                    'Not Completed' if getattr(studio, key + "_status", None) is None
                    else getattr(studio, key + "_status"),
                    'No' if localized_now() <= studio.checklist_deadline(key)
                    else humanize_timedelta(studio.past_checklist_deadline(key), granularity='hours'),
                ])
            rows.extend(row)

        out.writerow(rows)

    @xlsx_file
    def accepted_games_xlsx(self, out, session):
        rows = []
        for game in session.query(IndieGame).filter_by(status=c.ACCEPTED):
            screenshots = game.best_screenshot_download_filenames()
            rows.append([
                game.studio.name, game.studio.website,
                game.title, game.brief_description, game.link_to_webpage,
                game.twitter, game.facebook, game.other_social_media,
                game.link_to_promo_video, game.link_to_video, game.link_to_game,<commit_msg>Export MIVS checklist completion as separate rows (#3380)<commit_after>import os

import bcrypt
import cherrypy
from pockets import listify
from sqlalchemy import and_, or_
from sqlalchemy.orm import joinedload

from uber.config import c
from uber.custom_tags import humanize_timedelta
from uber.decorators import all_renderable, csrf_protected, csv_file, multifile_zipfile, render, xlsx_file
from uber.errors import HTTPRedirect
from uber.models import AdminAccount, Attendee, Group, IndieGame, IndieGameReview, IndieStudio
from uber.tasks.email import send_email
from uber.utils import check, genpasswd, localized_now


@all_renderable(c.INDIE_ADMIN)
class Root:
    def index(self, session, message=''):
        return {
            'message': message,
            'judges': session.indie_judges().all(),
            'games': [g for g in session.indie_games() if g.video_submitted]
        }

    def studios(self, session, message=''):
        return {
            'message': message,
            'studios': session.query(IndieStudio).all()
        }

    @csv_file
    def social_media(self, out, session):
        out.writerow(['Studio', 'Website', 'Twitter', 'Facebook'])
        for game in session.indie_games():
            if game.confirmed:
                out.writerow([
                    game.studio.name,
                    game.studio.website,
                    game.studio.twitter,
                    game.studio.facebook
                ])

    @csv_file
    def everything(self, out, session):
        out.writerow([
            'Game', 'Studio', 'Studio URL', 'Primary Contact Name', 'Primary Contact Email',
            'Game Website', 'Twitter', 'Facebook', 'Other Social Media',
            'Genres', 'Brief Description', 'Long Description', 'How to Play',
            'Link to Video for Judging', 'Link to Promo Video', 'Link to Game', 'Game Link Password',
            'Game Requires Codes?', 'Code Instructions', 'Build Status', 'Build Notes',
            'Video Submitted', 'Game Submitted', 'Current Status',
            'Registered', 'Accepted', 'Confirmation Deadline',
            'Screenshot Links', 'Average Score', 'Individual Scores'
        ])
        for game in session.indie_games():
            out.writerow([
                game.title,
                game.studio.name,
                '{}/mivs_applications/continue_app?id={}'.format(c.PATH, game.studio.id),
                game.studio.primary_contact.full_name,
                game.studio.primary_contact.email,
                game.link_to_webpage,
                game.twitter,
                game.facebook,
                game.other_social_media,
                ' / '.join(game.genres_labels),
                game.brief_description,
                game.description,
                game.how_to_play,
                game.link_to_video,
                game.link_to_promo_video,
                game.link_to_game,
                game.password_to_game,
                game.code_type_label,
                game.code_instructions,
                game.build_status_label,
                game.build_notes,
                'submitted' if game.video_submitted else 'not submitted',
                'submitted' if game.submitted else 'not submitted',
                'accepted and confirmed' if game.confirmed else game.status_label,
                game.registered.strftime('%Y-%m-%d'),
                'n/a' if not game.accepted else game.accepted.strftime('%Y-%m-%d'),
                'n/a' if not game.accepted else game.studio.confirm_deadline.strftime('%Y-%m-%d'),
                '\n'.join(c.URL_BASE + screenshot.url.lstrip('.') for screenshot in game.screenshots),
                str(game.average_score)
            ] + [str(score) for score in game.scores])

    @csv_file
    def checklist_completion(self, out, session):
        header_row = ['Studio']
        for key, val in c.MIVS_CHECKLIST.items():
            header_row.append(val['name'])
            header_row.append('Past Due?')
        out.writerow(header_row)

        for studio in session.query(IndieStudio).join(IndieStudio.group).join(Group.guest):
            row = [studio.name]
            for key, val in c.MIVS_CHECKLIST.items():
                row.extend([
                    'Not Completed' if getattr(studio, key + "_status", None) is None
                    else getattr(studio, key + "_status"),
                    'No' if localized_now() <= studio.checklist_deadline(key)
                    else humanize_timedelta(studio.past_checklist_deadline(key), granularity='hours'),
                ])
            out.writerow(row)

    @xlsx_file
    def accepted_games_xlsx(self, out, session):
        rows = []
        for game in session.query(IndieGame).filter_by(status=c.ACCEPTED):
            screenshots = game.best_screenshot_download_filenames()
            rows.append([
                game.studio.name, game.studio.website,
                game.title, game.brief_description, game.link_to_webpage,
                game.twitter, game.facebook, game.other_social_media,
                game.link_to_promo_video, game.link_to_video, game.link_to_game,
{'fraction_non_alphanumeric': 0.10639123266414509, 'fraction_numerical': 0.0003879352148191252, 'mean_word_length': 2.0617577197149646, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '501009', 'n_tokens_mistral': 3085, 'n_tokens_neox': 2880, 'n_words': 654}