<commit_before>mongoose = require('mongoose')

import Hash from './Hash'
import User from './user'

import calculateHashes from '../hashes/calculateHashes'

import awaitAll from '../../client/lib/awaitAll'
import logger from '../log'

outcomeType = (outcome) ->
    switch outcome
        when "DR" then "DR"
        when "PS" then "PS"
        else "_"

submitsSchema = new mongoose.Schema
    _id: String
    time: Date
    downloadTime: { type: Date, default: new Date(0) }
    user: String
    problem: String
    outcome: String
    source: String
    sourceRaw: String
    language: String
    comments: [String]
    results: mongoose.Schema.Types.Mixed
    force: { type: Boolean, default: false },
    quality: { type: Number, default: 0 },
    hashes: [{window: Number, hash: String, score: Number}]
    testSystemData: mongoose.Schema.Types.Mixed
    
submitsSchema.methods.upsert = () ->
    @update(this, {upsert: true, overwrite: true})

submitsSchema.methods.calculateHashes = () ->
    logger.info("calculating hashes for submit #{@_id}")
    @hashes = calculateHashes((@sourceRaw or @source).toString())
    logger.info("calculating hashes for submit #{@_id}, have #{@hashes.length} hashes")
    for h in @hashes
        if @outcome in ['OK', 'IG']
            h.score *= 2
        if @outcome == 'AC'
            h.score *= 3
        hash = new Hash
            _id: "#{h.hash}:#{@_id}"
            hash: h.hash
            submit: @_id
            user: @user
            problem: @problem
            window: h.window
            score: h.score
        await hash.upsert()
    await @upsert()

submitsSchema.methods.equivalent = (other) ->
    if @comments.length > 0
        return false
    if @outcome == "AC" or @outcome == "IG" or @outcome == "DQ"
        return false
    if @force
        return false
    return @user == other.user \
        and @problem == other.problem \
        and outcomeType(@outcome) == outcomeType(other.outcome) \
        and @source == other.source \
        and (@language == other.language \
             or Math.abs(@time - other.time) < 1500 \
             or Math.abs(Math.abs(@time - other.time) - 3 * 60 * 60 * 1000) < 1500)

submitsSchema.statics.findByUser = (userId) ->
    Submit.find
        user: userId
<commit_msg>Update submit.coffee<commit_after>mongoose = require('mongoose')

import Hash from './Hash'
import User from './user'

import calculateHashes from '../hashes/calculateHashes'

import awaitAll from '../../client/lib/awaitAll'
import logger from '../log'

outcomeType = (outcome) ->
    switch outcome
        when "DR" then "DR"
        when "PS" then "PS"
        else "_"

submitsSchema = new mongoose.Schema
    _id: String
    time: Date
    downloadTime: { type: Date, default: new Date(0) }
    user: String
    problem: String
    outcome: String
    source: String
    sourceRaw: String
    language: String
    comments: [String]
    results: mongoose.Schema.Types.Mixed
    force: { type: Boolean, default: false },
    quality: { type: Number, default: 0 },
    hashes: [{window: Number, hash: String, score: Number}]
    testSystemData: mongoose.Schema.Types.Mixed
    
submitsSchema.methods.upsert = () ->
    @update(this, {upsert: true, overwrite: true})

submitsSchema.methods.calculateHashes = () ->
    logger.info("calculating hashes for submit #{@_id}")
    @hashes = calculateHashes((@sourceRaw or @source).toString())
    logger.info("calculating hashes for submit #{@_id}, have #{@hashes.length} hashes")
    for h in @hashes
        if @outcome in ['OK', 'IG']
            h.score *= 2
        if @outcome == 'AC'
            h.score *= 3
        hash = new Hash
            _id: "#{h.hash}:#{@_id}"
            hash: h.hash
            submit: @_id
            user: @user
            problem: @problem
            window: h.window
            score: h.score
        await hash.upsert()
    await @upsert()

submitsSchema.methods.equivalent = (other) ->
    if @user == "394891"
        loger.log "Compare submits ", @this, other
    if @comments.length > 0
        return false
    if @outcome == "AC" or @outcome == "IG" or @outcome == "DQ"
        return false
    if @force
        return false
    return @user == other.user \
        and @problem == other.problem \
        and outcomeType(@outcome) == outcomeType(other.outcome) \
        and @source == other.source \
        and (@language == other.language \
             or Math.abs(@time - other.time) < 1500 \
             or Math.abs(Math.abs(@time - other.time) - 3 * 60 * 60 * 1000) < 1500)

submitsSchema.statics.findByUser = (userId) ->
    Submit.find
        user: userId

{'fraction_non_alphanumeric': 0.13250161325016133, 'fraction_numerical': 0.010755001075500108, 'mean_word_length': 2.2932011331444757, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '896105', 'n_tokens_mistral': 1481, 'n_tokens_neox': 1434, 'n_words': 405}