forked from ospalh/anki-addons
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplay_button.py
121 lines (94 loc) · 3.83 KB
/
play_button.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# -*- mode: Python ; coding: utf-8 -*-
#
# Copyright © 2013–14 Roland Sieker <ospalh@gmail.com>
#
# License: GNU AGPL, version 3 or later;
# http://www.gnu.org/copyleft/agpl.html
"""Add-on for Anki 2 to add AnkiDroid-style replay buttons."""
import os
import re
import shutil
from BeautifulSoup import BeautifulSoup
from PyQt4.QtCore import QUrl
from PyQt4.QtGui import QDesktopServices
from anki.hooks import addHook, wrap
from anki.sound import play
from aqt import mw
from aqt.browser import Browser
from aqt.browser import DataModel
from aqt.clayout import CardLayout
from aqt.reviewer import Reviewer
__version__ = "1.5.0"
sound_re = ur"\[sound:(.*?)\]"
original_arrow_name = 'replay.png'
collection_arrow_name = '_inline_replay_button.png'
hide_class_name = u'browserhide'
def play_button_filter(
qa_html, qa_type, dummy_fields, dummy_model, dummy_data, dummy_col):
u"""
Filter the questions and answers to add play buttons.
"""
def add_button(sound):
u"""
Add img link after the match.
Add an img link after the match to replay the audio. The title
is set to "Replay" on the question side to hide information or
to the file name on the answer.
"""
if 'q' == qa_type:
title = u"Replay"
else:
title = sound.group(1)
return u"""{orig}<a href='javascript:py.link("ankiplay{fn}");' \
title="{ttl}" class="replaybutton browserhide"><span><img src="{ip}" \
alt="play" style="max-width: 32px; max-height: 1em; min-height:8px;" />\
</span></a><span style="display: none;">[sound:{fn}]</span>""".format(
orig=sound.group(0), fn=sound.group(1), ip=collection_arrow_name,
ttl=title)
# The [ ] are the square brackets that we want to
# appear as brackets and not trigger the playing of the
# sound. The span inside the a around the img is to bring this
# closer in line with AnkiDroid.
return re.sub(sound_re, add_button, qa_html)
def review_link_handler_wrapper(reviewer, url):
u"""Play the sound or call the original link handler."""
if url.startswith("ankiplay"):
play(url[8:])
else:
original_review_link_handler(reviewer, url)
def simple_link_handler(url):
u"""Play the file."""
if url.startswith("ankiplay"):
play(url[8:])
else:
QDesktopServices.openUrl(QUrl(url))
def add_clayout_link_handler(clayout, dummy_t):
u"""Make sure we play the files from the card layout window."""
clayout.forms[-1]['pform'].frontWeb.setLinkHandler(simple_link_handler)
clayout.forms[-1]['pform'].backWeb.setLinkHandler(simple_link_handler)
def add_preview_link_handler(browser):
u"""Make sure we play the files from the preview window."""
browser._previewWeb.setLinkHandler(simple_link_handler)
def reduce_format_qa(self, text):
u"""Remove elements with a given class before displaying."""
soup = BeautifulSoup(text)
for hide in soup.findAll(True, {'class': re.compile(
'\\b' + hide_class_name + '\\b')}):
hide.extract()
return original_format_qa(self, unicode(soup))
def copy_arrow():
u"""Copy the image file to the collection."""
if not os.path.exists(os.path.join(
mw.col.media.dir(), collection_arrow_name)):
shutil.copy(
os.path.join(mw.pm.addonFolder(), 'color_icons',
original_arrow_name),
collection_arrow_name)
original_review_link_handler = Reviewer._linkHandler
Reviewer._linkHandler = review_link_handler_wrapper
original_format_qa = DataModel.formatQA
DataModel.formatQA = reduce_format_qa
addHook("mungeQA", play_button_filter)
Browser._openPreview = wrap(Browser._openPreview, add_preview_link_handler)
CardLayout.addTab = wrap(CardLayout.addTab, add_clayout_link_handler)
addHook("profileLoaded", copy_arrow)