1# encoding:utf-8
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program; if not, write to the Free Software Foundation, Inc.,
15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17import logging
18import os
19import urllib.error
20import urllib.parse
21
22from gi.repository import Gtk
23from gi.repository import GLib
24
25from xl import common, event, providers, settings
26from xl.nls import gettext as _
27from xlgui import panel
28
29from . import preferences
30
31import gi
32
33gi.require_version('WebKit2', '4.0')
34from gi.repository import WebKit2
35
36
37log = logging.getLogger(__name__)
38
39# fmt: off
40LANGUAGES = ["ab", "aa", "af", "ak", "sq", "am", "ar", "an", "hy", "as", "av",
41             "ae", "ay", "az", "bm", "ba", "eu", "be", "bn", "bh", "bi", "bs", "br", "bg",
42             "my", "ca", "ch", "ce", "ny", "cv", "kw", "co", "cr", "hr", "cs", "da", "dv",
43             "nl", "dz", "en", "eo", "et", "ee", "fo", "fj", "fi", "fr", "ff", "gl", "ka",
44             "de", "el", "gn", "gu", "ht", "ha", "he", "hz", "hi", "ho", "hu", "ia", "id",
45             "ie", "ga", "ig", "ik", "io", "is", "it", "iu", "jv", "kl", "kn", "kr", "kk",
46             "km", "ki", "rw", "ky", "kv", "kg", "kj", "la", "lb", "lg", "li", "ln", "lo",
47             "lt", "lv", "gv", "mk", "mg", "ml", "mt", "mi", "mr", "mh", "mn", "na", "nv",
48             "nb", "nd", "ne", "ng", "nn", "no", "ii", "nr", "oc", "oj", "cu", "om", "or",
49             "os", "pi", "fa", "pl", "ps", "pt", "qu", "rm", "rn", "ro", "ru", "sa", "sc",
50             "se", "sm", "sg", "sr", "gd", "sn", "si", "sk", "sl", "so", "st", "es", "su",
51             "sw", "ss", "sv", "ta", "te", "th", "ti", "bo", "tk", "tl", "tn", "to", "tr",
52             "ts", "tw", "ty", "uk", "ur", "ve", "vi", "vk", "vo", "wa", "cy", "wo", "fy",
53             "xh", "yi", "yo", "za", "zu"]
54# fmt: on
55
56
57class WikipediaPlugin:
58
59    __exaile = None
60    __wiki_panel = None
61
62    def enable(self, exaile):
63        self.__exaile = exaile
64
65    def disable(self, _exaile):
66        providers.unregister('main-panel', self.__wiki_panel)
67        self.__wiki_panel.destroy()
68        self.__exaile = None
69        self.__wiki_panel = None
70
71    def on_gui_loaded(self):
72        user_agent = self.__exaile.get_user_agent_string('wikipedia')
73        self.__wiki_panel = WikiPanel(self.__exaile.gui.main.window, user_agent)
74        providers.register('main-panel', self.__wiki_panel)
75
76    def get_preferences_pane(self):
77        return preferences
78
79
80plugin_class = WikipediaPlugin
81
82
83class BrowserPage(WebKit2.WebView):
84    def __init__(self, builder, user_agent):
85        WebKit2.WebView.__init__(self)
86
87        self.hometrack = None
88        self.__user_agent = user_agent
89
90        builder.connect_signals(self)
91        event.add_callback(self.on_playback_start, 'playback_track_start')
92
93    def destroy(self):
94        event.remove_callback(self.on_playback_start, 'playback_track_start')
95
96    def on_playback_start(self, type, player, track):
97        self.hometrack = track
98        self.load_wikipedia_page(track)
99
100    def on_home_button_clicked(self, button):
101        if self.hometrack is not None:
102            self.load_wikipedia_page(self.hometrack)
103
104    def on_refresh_button_clicked(self, button):
105        self.reload()
106
107    def on_back_button_clicked(self, button):
108        self.go_back()
109
110    def on_forward_button_clicked(self, button):
111        self.go_forward()
112
113    @common.threaded
114    def load_wikipedia_page(self, track):
115        if track != self.hometrack:
116            return
117
118        artist = track.get_tag_display('artist')
119        language = settings.get_option('plugin/wikipedia/language', 'en')
120        if language not in LANGUAGES:
121            log.error('Provided language "%s" not found.' % language)
122            language = 'en'
123
124        artist = urllib.parse.quote(artist.encode('utf-8'), '')
125        url = "https://%s.m.wikipedia.org/wiki/Special:Search/%s" % (language, artist)
126
127        try:
128            html = common.get_url_contents(url, self.__user_agent)
129        except urllib.error.URLError as e:
130            log.error(e)
131            log.error(
132                "Error occurred when trying to retrieve Wikipedia page "
133                "for %s." % artist
134            )
135            html = (
136                """
137                <p style="color: red">No Wikipedia page found for <strong>%s</strong></p>
138                """
139                % artist
140            )
141
142        GLib.idle_add(self.load_html, html, url)
143
144
145class WikiPanel(panel.Panel):
146    # Specifies the path to the UI file and the name of the root element
147    ui_info = (os.path.dirname(__file__) + "/data/wikipanel.ui", 'WikiPanel')
148
149    def __init__(self, parent, user_agent):
150        panel.Panel.__init__(self, parent, 'wikipedia', _('Wikipedia'))
151        self.parent = parent
152        self._browser = BrowserPage(self.builder, user_agent)
153        self.setup_widgets()
154
155    def destroy(self):
156        self._browser.destroy()
157
158    def setup_widgets(self):
159        self._scrolled_window = Gtk.ScrolledWindow()
160        self._scrolled_window.add(self._browser)
161        frame = self.builder.get_object('rendering_frame')
162        self._scrolled_window.show_all()
163        frame.add(self._scrolled_window)
164