1
/* -*- coding: utf-8; indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- */
2
/* vim:set fileencodings=utf-8 tabstop=4 expandtab shiftwidth=4 softtabstop=4: */
4
* Copyright (C) 2010 Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23
class BetaRadio : GLib.Object {
24
private Gtk.StatusIcon icon = null;
25
private Gtk.Menu menu = null;
26
private GstPlayer player = null;
28
public static void main (string[] args) {
29
Intl.bindtextdomain( Config.PACKAGE_NAME, Config.LOCALEDIR );
30
Intl.bind_textdomain_codeset( Config.PACKAGE_NAME, "UTF-8" );
31
Intl.textdomain( Config.PACKAGE_NAME );
34
var app = new BetaRadio();
39
if (FileUtils.test(Config.DATADIR + "/pixmaps/betaradio/betaradio.png", FileTest.IS_REGULAR) == true) {
40
icon = new Gtk.StatusIcon.from_file(Config.DATADIR + "/pixmaps/betaradio/betaradio.png");
41
} else if (FileUtils.test("data/betaradio.png", FileTest.IS_REGULAR) == true) {
42
icon = new Gtk.StatusIcon.from_file("data/betaradio.png");
44
icon = new Gtk.StatusIcon.from_stock(Gtk.STOCK_MISSING_IMAGE);
46
icon.set_tooltip_text(_("BetaRadio Tuner"));
47
menu = new Gtk.Menu();
48
unowned SList<Gtk.RadioMenuItem> group = null;
50
var stop = new Gtk.RadioMenuItem.with_label(group, _("Stop"));
51
group = stop.get_group();
53
stop.activate.connect((e) => {
57
icon.set_tooltip_text(_("BetaRadio Tuner"));
61
menu.append(new Gtk.SeparatorMenuItem());
63
group = getMenu(menu, group);
65
menu.append(new Gtk.SeparatorMenuItem());
67
var quit = new Gtk.RadioMenuItem.with_label(group, _("Quit"));
68
group = stop.get_group();
70
quit.activate.connect((e) => {
74
icon.set_tooltip_text(_("BetaRadio Tuner"));
81
icon.button_release_event.connect((e) => {
82
menu.popup(null, null, null, e.button, e.time);
87
private unowned SList<Gtk.RadioMenuItem> getMenu(Gtk.Menu menu, SList<Gtk.RadioMenuItem> group) {
88
var list = new JsonSoup.http("http://betaradio.googlecode.com/svn/trunk/utils/list.json");
89
if (list.is_array() == false) {
92
int length = list.length();
93
for (int i = 0; i < length; i++) {
94
string feed = list.array(i).get_string();
95
var json = new JsonSoup.http(feed);
96
if (json.object("property").is_string() == false) {
99
string title = json.sibling("title").get_string();
100
var item = new Gtk.MenuItem.with_label(title);
102
var submenu = new Gtk.Menu();
103
item.set_submenu(submenu);
104
string property = json.sibling("property").get_string();
105
if (property == "category" && json.sibling("category").is_array() == true) {
106
group = getCategoryMenu(submenu, group, json);
107
} else if (property == "channel" && json.sibling("channel").is_array() == true) {
108
group = getChannelMenu(submenu, group, json);
115
private unowned SList<Gtk.RadioMenuItem> getCategoryMenu(Gtk.Menu menu, SList<Gtk.RadioMenuItem> group, JsonSoup json) {
116
int length = json.length();
117
for (int i = 0; i < length; i++) {
118
string category = json.array(i).object("title").get_string();
119
var item = new Gtk.MenuItem.with_label(category);
120
var submenu = new Gtk.Menu();
122
item.set_submenu(submenu);
123
int size = json.sibling("channel").length();
124
for (int j = 0; j < size; j++) {
125
string title = json.array(j).object("title").get_string();
126
string type = json.sibling("type").get_string();
127
string url = filter_url(json.sibling("url").get_string(), type);
128
var radio = new Gtk.RadioMenuItem.with_label(group, title);
129
group = radio.get_group();
130
radio.toggled.connect( (e) => {
131
if (player != null) {
134
player = new GstPlayer("BetaRadio", url);
136
icon.set_tooltip_text(title);
138
submenu.append(radio);
146
private unowned SList<Gtk.RadioMenuItem> getChannelMenu(Gtk.Menu menu, SList<Gtk.RadioMenuItem> group, JsonSoup json) {
147
int length = json.length();
148
for (int i = 0; i < length; i++) {
149
string title = json.array(i).object("title").get_string();
150
string type = json.sibling("type").get_string();
151
string url = filter_url(json.sibling("url").get_string(), type);
152
var radio = new Gtk.RadioMenuItem.with_label(group, title);
153
group = radio.get_group();
154
radio.toggled.connect( (e) => {
155
if (player != null) {
158
player = new GstPlayer("BetaRadio", url);
160
icon.set_tooltip_text(title);
168
private string filter_url(string url, string type) {
169
/* http://bcr.media.hinet.net/RA000042 */
170
/* mmsh://bcr.media.hinet.net/RA000042\?MSWMExt\=.asf */
171
if (type == "mms" && url.has_prefix("http://") == true) {
172
return url.replace("http", "mmsh").concat("\\?MSWMExt\\=.asf");