This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository eradio.
View the commit online.
commit 0dabe08d4258c3fd963771a5f85c98af706570e3
Author: politebot <[email protected]>
AuthorDate: Fri Oct 10 13:33:40 2025 -0500
Update README
---
README.md | 27 +++++++++-----------
autogen.sh | 1 -
configure.ac | 2 +-
src/main.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
4 files changed, 82 insertions(+), 28 deletions(-)
diff --git a/README.md b/README.md
index 7352f18..8d9f738 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,28 @@
-# EFL Boilerplate Template
+# eradio
-A minimal, well-structured starter template for building desktop applications with Enlightenment Foundation Libraries (EFL). It provides a clean "Hello, World!" example, a consistent Makefile, and a conventional project layout that you can copy and adapt for new projects.
+A simple internet radio player built with the Enlightenment Foundation Libraries (EFL).
## Features
-- Simple EFL (Elementary) window with centered "Hello, World!" label
-- Consistent Makefile with build, run, install, and warning-level targets
-- Conventional layout (`src/`) for easy expansion
-- Minimal dependencies (only `elementary` via `pkg-config`)
+- Search for radio stations using the [radio-browser.info](http://radio-browser.info/) API
+- List stations with their favicons
+- Play, pause, and stop radio streams
+- Search by station name, country, language, or tag
## Prerequisites
- `EFL / Elementary`
- `gcc` with C99 support
- `pkg-config`
+- `libxml2`
## Project Structure
- `configure.ac` — Autoconf script for project configuration and dependency checks.
- `Makefile.am` — Top-level Automake file.
-- `src/main.c` — Entry point with a minimal EFL window.
+- `src/main.c` — Entry point and all application logic.
- `src/Makefile.am` — Automake file for the source directory.
+- `data/` — Contains data files, such as the `.desktop` file and icon.
- `README.md` — This guide.
## Build & Run
@@ -36,7 +38,7 @@ Then, configure, build, and run the application:
```bash
./configure
make
-./src/efl_hello
+./src/eradio
```
To clean the build artifacts:
@@ -45,13 +47,6 @@ To clean the build artifacts:
make clean
```
-## Customizing for New Projects
-
-- **Project Name:** Edit `AC_INIT` in `configure.ac` to set your project's name, version, and contact email.
-- **Program Name:** In `src/Makefile.am`, change `bin_PROGRAMS` and the associated `_SOURCES` variable if you rename the executable.
-- **Source Files:** Add new `.c` files to the `efl_hello_SOURCES` variable in `src/Makefile.am`.
-
## Code Overview
-The template initializes Elementary, creates a standard window, adds a background, and centers a label.
-It demonstrates core EFL concepts: window creation, object sizing, alignment, and the main event loop.
+The application initializes Elementary, creates a window with a search bar, a results list, and playback controls. It uses `Ecore_Con` to fetch station data from the `radio-browser.info` API, parses the XML response with `libxml2`, and populates a list. The `Emotion` library is used to handle media playback.
diff --git a/autogen.sh b/autogen.sh
deleted file mode 120000
index b209282..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/autogen.sh
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
index d1cbc52..c7a325c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([eradio], [1.0], [[email protected]])
+AC_INIT([eradio], [1.0], [])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
diff --git a/src/main.c b/src/main.c
index cf436e5..c7d829e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,6 +2,7 @@
#include <Ecore_Evas.h>
#include <Emotion.h>
#include <Ecore_Con.h>
+#include <Ethumb_Client.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
@@ -10,6 +11,7 @@ typedef struct _Station
const char *name;
const char *url;
const char *favicon;
+ const char *stationuuid;
} Station;
typedef struct _AppData
@@ -44,6 +46,22 @@ _hoversel_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
elm_object_text_set(obj, label);
}
+static void
+_station_click_counter_request(Station *st)
+{
+ char url_str[1024];
+ Ecore_Con_Url *url;
+
+ if (!st || !st->stationuuid) return;
+
+ snprintf(url_str, sizeof(url_str), "http://de2.api.radio-browser.info/xml/url/%s",
+ st->stationuuid);
+
+ url = ""
+ ecore_con_url_additional_header_add(url, "User-Agent", "eradio/1.0");
+ ecore_con_url_get(url);
+}
+
static void
_list_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
{
@@ -53,6 +71,8 @@ _list_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
if (!st) return;
+ _station_click_counter_request(st);
+
if (st->url && st->url[0])
{
emotion_object_file_set(ad->emotion, st->url);
@@ -104,6 +124,7 @@ _search_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
search_type, search_term);
url = ""
+ ecore_con_url_additional_header_add(url, "User-Agent", "eradio/1.0");
ecore_con_url_data_set(url, d_ctx);
ecore_con_url_get(url);
}
@@ -120,6 +141,8 @@ _url_data_cb(void *data, int type, void *event_info)
Ecore_Con_Event_Url_Data *url_data = event_info;
Download_Context *d_ctx = ecore_con_url_data_get(url_data->url_con);
+ if (!d_ctx) return ECORE_CALLBACK_PASS_ON;
+
if (!d_ctx->ctxt)
{
d_ctx->ctxt = xmlCreatePushParserCtxt(NULL, NULL,
@@ -132,6 +155,12 @@ _url_data_cb(void *data, int type, void *event_info)
return ECORE_CALLBACK_PASS_ON;
}
+static void
+_thumb_load_error_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ fprintf(stderr, "ERROR: could not load thumb\n");
+}
+
static Eina_Bool
_url_complete_cb(void *data, int type, void *event_info)
{
@@ -142,7 +171,11 @@ _url_complete_cb(void *data, int type, void *event_info)
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
- if (!d_ctx) return ECORE_CALLBACK_PASS_ON;
+ if (!d_ctx)
+ {
+ ecore_con_url_free(ev->url_con);
+ return ECORE_CALLBACK_PASS_ON;
+ }
ad = d_ctx->ad;
@@ -192,18 +225,42 @@ _url_complete_cb(void *data, int type, void *event_info)
{
xmlNodePtr cur = xpathObj->nodesetval->nodeTab[i];
Station *st = calloc(1, sizeof(Station));
- const char *name = (const char *)xmlGetProp(cur, (xmlChar *)"name");
- const char *url = "" char *)xmlGetProp(cur, (xmlChar *)"url_resolved");
- const char *favicon = (const char *)xmlGetProp(cur, (xmlChar *)"favicon");
+ xmlChar *prop;
- if (name) st->name = eina_stringshare_add(name);
- if (url) st->url = ""
- if (favicon) st->favicon = eina_stringshare_add(favicon);
+ prop = xmlGetProp(cur, (xmlChar *)"name");
+ if (prop)
+ {
+ st->name = eina_stringshare_add((const char *)prop);
+ xmlFree(prop);
+ }
+
+ prop = xmlGetProp(cur, (xmlChar *)"url_resolved");
+ if (prop)
+ {
+ st->url = "" char *)prop);
+ xmlFree(prop);
+ }
+
+ prop = xmlGetProp(cur, (xmlChar *)"favicon");
+ if (prop)
+ {
+ st->favicon = eina_stringshare_add((const char *)prop);
+ xmlFree(prop);
+ }
+
+ prop = xmlGetProp(cur, (xmlChar *)"stationuuid");
+ if (prop)
+ {
+ st->stationuuid = eina_stringshare_add((const char *)prop);
+ xmlFree(prop);
+ }
ad->stations = eina_list_append(ad->stations, st);
- Evas_Object *ic = elm_icon_add(ad->win);
- elm_icon_standard_set(ic, st->favicon);
- elm_list_item_append(ad->list, st->name, ic, NULL, NULL, st);
+ Evas_Object *thumb = elm_thumb_add(ad->win);
+ evas_object_smart_callback_add(thumb, "load,error", _thumb_load_error_cb, NULL);
+ if (st->favicon && st->favicon[0])
+ elm_thumb_file_set(thumb, st->favicon, NULL);
+ elm_list_item_append(ad->list, st->name, thumb, NULL, NULL, st);
}
elm_list_go(ad->list);
@@ -217,6 +274,7 @@ _url_complete_cb(void *data, int type, void *event_info)
static void
_stop_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+
{
AppData *ad = data;
emotion_object_play_set(ad->emotion, EINA_FALSE);
@@ -246,6 +304,7 @@ elm_main(int argc, char **argv)
}
ecore_con_init();
+ ethumb_client_init();
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
@@ -338,6 +397,7 @@ elm_main(int argc, char **argv)
evas_object_show(ad.win);
elm_run();
+ ethumb_client_shutdown();
ecore_con_shutdown();
return 0;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.