<commit_before>import time
import random
import re
import sys

from BeautifulSoup import BeautifulSoup
from PyQt4 import QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import QWebPage
from anki import notes
from anki.hooks import wrap, addHook
from aqt import mw, editcurrent, addcards
from aqt.reviewer import Reviewer
from aqt.utils import showInfo, tooltip
from aqt.webview import AnkiWebView

import ir.settings
import ir.util

sys.setdefaultencoding('utf8')

IREAD_MODEL_NAME = 'IRead2'

TEXT_FIELD_NAME = 'Text'
SOURCE_FIELD_NAME = 'Source'
TITLE_FIELD_NAME = 'Title'

AFMT = "When do you want to see this card again?"


class IRead2(object):
    def __init__(self, mw):
        self.mw = mw

    def loadPluginData(self):
        self.add_IRead_model()
        mw.settingsManager = ir.settings.SettingsManager()
        self.settings = mw.settingsManager.settings
        addHook('reset', mw.IRead2.adjustZoomAndScroll)

    def savePluginData(self):
        mw.settingsManager.saveSettings()

    def add_IRead_model(self):
        "Only adds model if no model with the same name is present"
        col = mw.col
        mm = col.models
        iread_model = mm.byName(IREAD_MODEL_NAME)
        if iread_model is None:
            iread_model = mm.new(IREAD_MODEL_NAME)
            # Field for title:
            model_field = mm.newField(TITLE_FIELD_NAME)
            mm.addField(iread_model, model_field)
            # Field for text:
            text_field = mm.newField(TEXT_FIELD_NAME)
            mm.addField(iread_model, text_field)
            # Field for source:
            source_field = mm.newField(SOURCE_FIELD_NAME)
            source_field['sticky'] = True
            mm.addField(iread_model, source_field)

            # Add template
            t = mm.newTemplate('IRead2 review')
            t['qfmt'] = '<div class="ir-text">{{%s}}</div>' % (TEXT_FIELD_NAME)
            t['afmt'] = AFMT
            mm.addTemplate(iread_model, t)
            # Add model to collection:
            mm.add(iread_model)
            return iread_model
        else:
            fmap = mm.fieldMap(iread_model)
            title_ord, title_field = fmap[TITLE_FIELD_NAME]
            text_ord, text_field = fmap[TEXT_FIELD_NAME]
            source_ord, source_field = fmap[SOURCE_FIELD_NAME]
            source_field['sticky'] = True


    def extract(self):
        #Copy text or html to clipboard and show (later will create card)
        if(len(mw.web.selectedText()) > 0): mw.web.triggerPageAction(QWebPage.Copy);
        clipboard = QApplication.clipboard();
        mimeData = clipboard.mimeData();
        #Highlight the text in the original document
        self.highlightSelectedText(self.settings['highlightColor'], self.settings['doHighlightFont']);

        card = mw.reviewer.card
        cur_note = card.note()
        col = mw.col
        deckName = col.decks.get(card.did)['name']
        model = col.models.byName(IREAD_MODEL_NAME)
        new_note = notes.Note(col, model)
        new_note.tags = cur_note.tags
        #setField(new_note, TITLE_FIELD_NAME, getField(cur_note, TITLE_FIELD_NAME))
        setField(new_note, TEXT_FIELD_NAME, mimeData.html())
        setField(new_note, SOURCE_FIELD_NAME, getField(cur_note, SOURCE_FIELD_NAME))
        self.editCurrent = editcurrent.EditCurrent(mw)

        self.addCards = addcards.AddCards(mw)
        self.addCards.editor.setNote(new_note)
        self.addCards.deckChooser.deck.setText(deckName)
        self.addCards.modelChooser.models.setText(IREAD_MODEL_NAME)

    def adjustZoomAndScroll(self):
        if mw.reviewer.card and mw.reviewer.card.model()['name'] == IREAD_MODEL_NAME:
            cardID = str(mw.reviewer.card.id)

            if cardID not in self.settings['zoom']:
                self.settings['zoom'][cardID] = 1

            if cardID not in self.settings['scroll']:
                self.settings['scroll'][cardID] = 0

            mw.web.setTextSizeMultiplier(
                    self.settings['zoom'][cardID])

            position = self.settings['scroll'][cardID]
            mw.web.page().mainFrame().setScrollPosition(QPoint(0, position))

    def highlightAllRanges(self):
        # Add python object to take values back from javascript
        pyCallback = IREJavaScriptCallback()
        self.mw.web.page().mainFrame().addToJavaScriptWindowObject("pyCallback", pyCallback)
        initJavaScript()
        mw.web.eval("highlightAllRanges()")

    def highlightSelectedText(self, color, doHighlightFont):
        mw.viewManager.saveScrollPosition()

        # No obvious/easy way to do this with BeautifulSoup
        def removeOuterDiv(html):
            withoutOpenDiv = re.sub('^<div[^>]+>', '', str(html))
            withoutCloseDiv = re.sub('</div>$', '', withoutOpenDiv)
            return withoutCloseDiv

        currentCard = self.mw.reviewer.card
        currentModelName = currentCard.model()['name']
        currentNote = currentCard.note()

        # Need to make this general
        # Limited because of reference to 'Text' field
        if currentCard and currentModelName == IREAD_MODEL_NAME:
            identifier = str(int(time.time() * 10))
            script = "markRange('%s', '%s', '%s');" % (identifier,
                                                       color,
                                                       doHighlightFont)
            script += "highlight('%s', '%s');" % (color, doHighlightFont)
            mw.web.eval(script)

            page = mw.web.page().mainFrame().toHtml()
            soup = BeautifulSoup(page)
            irTextDiv = soup.find('div', {'class': 'ir-text'})

            if irTextDiv:
                withoutDiv = removeOuterDiv(irTextDiv)
                currentNote['Text'] = str(withoutDiv)
                currentNote.flush()
                self.adjustZoomAndScroll()

            self.highlightAllRanges()
            mw.viewManager.setScrollPosition(
                    self.settings['scroll'][str(mw.reviewer.card.id)])

    def highlightText(self):
        self.highlightSelectedText(self.settings['highlightColor'], self.settings['doHighlightFont']);

    def htmlUpdated(self):
        #Called from javascript
        curNote = self.mw.reviewer.card.note();
        curNote['Text'] = mw.web.page().mainFrame().toHtml();
        curNote.flush();
        mw.web.setHtml(curNote['Text']);
        self.adjustZoomAndScroll();

    def showSetHighlightColorDialog(self):
        #Objective is a dialog to set highlight color used with 'h' key
        d = QDialog(self.mw)
        l = QVBoxLayout()
        l.setMargin(0)
        w = AnkiWebView()
        l.addWidget(w)
        #Add python object to take values back from javascript<commit_msg>Fix mistake that broke highlighting<commit_after>import time
import random
import re
import sys

from BeautifulSoup import BeautifulSoup
from PyQt4 import QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import QWebPage
from anki import notes
from anki.hooks import wrap, addHook
from aqt import mw, editcurrent, addcards
from aqt.reviewer import Reviewer
from aqt.utils import showInfo, tooltip
from aqt.webview import AnkiWebView

import ir.settings
import ir.util

sys.setdefaultencoding('utf8')

IREAD_MODEL_NAME = 'IRead2'

TEXT_FIELD_NAME = 'Text'
SOURCE_FIELD_NAME = 'Source'
TITLE_FIELD_NAME = 'Title'

AFMT = "When do you want to see this card again?"


class IRead2(object):
    def __init__(self, mw):
        self.mw = mw

    def loadPluginData(self):
        self.add_IRead_model()
        mw.settingsManager = ir.settings.SettingsManager()
        self.settings = mw.settingsManager.settings
        addHook('reset', mw.IRead2.adjustZoomAndScroll)

    def savePluginData(self):
        mw.settingsManager.saveSettings()

    def add_IRead_model(self):
        "Only adds model if no model with the same name is present"
        col = mw.col
        mm = col.models
        iread_model = mm.byName(IREAD_MODEL_NAME)
        if iread_model is None:
            iread_model = mm.new(IREAD_MODEL_NAME)
            # Field for title:
            model_field = mm.newField(TITLE_FIELD_NAME)
            mm.addField(iread_model, model_field)
            # Field for text:
            text_field = mm.newField(TEXT_FIELD_NAME)
            mm.addField(iread_model, text_field)
            # Field for source:
            source_field = mm.newField(SOURCE_FIELD_NAME)
            source_field['sticky'] = True
            mm.addField(iread_model, source_field)

            # Add template
            t = mm.newTemplate('IRead2 review')
            t['qfmt'] = '<div class="ir-text">{{%s}}</div>' % (TEXT_FIELD_NAME)
            t['afmt'] = AFMT
            mm.addTemplate(iread_model, t)
            # Add model to collection:
            mm.add(iread_model)
            return iread_model
        else:
            fmap = mm.fieldMap(iread_model)
            title_ord, title_field = fmap[TITLE_FIELD_NAME]
            text_ord, text_field = fmap[TEXT_FIELD_NAME]
            source_ord, source_field = fmap[SOURCE_FIELD_NAME]
            source_field['sticky'] = True


    def extract(self):
        #Copy text or html to clipboard and show (later will create card)
        if(len(mw.web.selectedText()) > 0): mw.web.triggerPageAction(QWebPage.Copy);
        clipboard = QApplication.clipboard();
        mimeData = clipboard.mimeData();
        #Highlight the text in the original document
        self.highlightSelectedText(self.settings['highlightColor'], self.settings['doHighlightFont']);

        card = mw.reviewer.card
        cur_note = card.note()
        col = mw.col
        deckName = col.decks.get(card.did)['name']
        model = col.models.byName(IREAD_MODEL_NAME)
        new_note = notes.Note(col, model)
        new_note.tags = cur_note.tags
        #setField(new_note, TITLE_FIELD_NAME, getField(cur_note, TITLE_FIELD_NAME))
        setField(new_note, TEXT_FIELD_NAME, mimeData.html())
        setField(new_note, SOURCE_FIELD_NAME, getField(cur_note, SOURCE_FIELD_NAME))
        self.editCurrent = editcurrent.EditCurrent(mw)

        self.addCards = addcards.AddCards(mw)
        self.addCards.editor.setNote(new_note)
        self.addCards.deckChooser.deck.setText(deckName)
        self.addCards.modelChooser.models.setText(IREAD_MODEL_NAME)

    def adjustZoomAndScroll(self):
        if mw.reviewer.card and mw.reviewer.card.model()['name'] == IREAD_MODEL_NAME:
            cardID = str(mw.reviewer.card.id)

            if cardID not in self.settings['zoom']:
                self.settings['zoom'][cardID] = 1

            if cardID not in self.settings['scroll']:
                self.settings['scroll'][cardID] = 0

            mw.web.setTextSizeMultiplier(
                    self.settings['zoom'][cardID])

            position = self.settings['scroll'][cardID]
            mw.web.page().mainFrame().setScrollPosition(QPoint(0, position))

            self.highlightAllRanges()

    def highlightAllRanges(self):
        # Add python object to take values back from javascript
        pyCallback = IREJavaScriptCallback()
        self.mw.web.page().mainFrame().addToJavaScriptWindowObject("pyCallback", pyCallback)
        initJavaScript()
        mw.web.eval("highlightAllRanges()")

    def highlightSelectedText(self, color, doHighlightFont):
        # No obvious/easy way to do this with BeautifulSoup
        def removeOuterDiv(html):
            withoutOpenDiv = re.sub('^<div[^>]+>', '', str(html))
            withoutCloseDiv = re.sub('</div>$', '', withoutOpenDiv)
            return withoutCloseDiv

        currentCard = self.mw.reviewer.card
        currentModelName = currentCard.model()['name']
        currentNote = currentCard.note()

        # Need to make this general
        # Limited because of reference to 'Text' field
        if currentCard and currentModelName == IREAD_MODEL_NAME:
            identifier = str(int(time.time() * 10))
            script = "markRange('%s', '%s', '%s');" % (identifier,
                                                       color,
                                                       doHighlightFont)
            script += "highlight('%s', '%s');" % (color, doHighlightFont)
            mw.web.eval(script)

            page = mw.web.page().mainFrame().toHtml()
            soup = BeautifulSoup(page)
            irTextDiv = soup.find('div', {'class': 'ir-text'})

            if irTextDiv:
                withoutDiv = removeOuterDiv(irTextDiv)
                currentNote['Text'] = str(withoutDiv)
                currentNote.flush()
                self.adjustZoomAndScroll()

    def highlightText(self):
        self.highlightSelectedText(self.settings['highlightColor'], self.settings['doHighlightFont']);

    def htmlUpdated(self):
        #Called from javascript
        curNote = self.mw.reviewer.card.note();
        curNote['Text'] = mw.web.page().mainFrame().toHtml();
        curNote.flush();
        mw.web.setHtml(curNote['Text']);
        self.adjustZoomAndScroll();

    def showSetHighlightColorDialog(self):
        #Objective is a dialog to set highlight color used with 'h' key
        d = QDialog(self.mw)
        l = QVBoxLayout()
        l.setMargin(0)
        w = AnkiWebView()
        l.addWidget(w)
        #Add python object to take values back from javascript
{'fraction_non_alphanumeric': 0.10551487072186519, 'fraction_numerical': 0.0023912718577193243, 'mean_word_length': 2.425390325057589, 'pattern_counts': {'":': 0, '<': 11, '<?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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1056563', 'n_tokens_mistral': 4063, 'n_tokens_neox': 3899, 'n_words': 832}