Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[XMLTV] Preparing for Crowdin and code refining #11594

Merged
merged 6 commits into from
Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.xmltv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The building of the XMLTV file itself is taken in charge by so called "grabbers"

Some websites provides updated XMLTV files than can be directly downloaded.

Here is a sample for France : https://www.xmltv.fr/
Here is a sample for France and Switzerland : https://xmltv.ch/

This binding takes an XMLTV file as input and creates a thing for each channel contained in it.
XmlTV channels are called Media Channels in this binding in order to avoid messing with openHAB Channels.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
*/
package org.openhab.binding.xmltv.internal;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
Expand All @@ -36,7 +33,6 @@ public class XmlTVBindingConstants {
public static final ThingTypeUID XMLTV_CHANNEL_THING_TYPE = new ThingTypeUID(BINDING_ID, "channel");

// Channel groups
public static final String GROUP_CURRENT_PROGRAMME = "currentprog";
public static final String GROUP_NEXT_PROGRAMME = "nextprog";
public static final String GROUP_CHANNEL_PROPERTIES = "channelprops";

Expand All @@ -56,6 +52,6 @@ public class XmlTVBindingConstants {
public static final String CHANNEL_PROGRAMME_TIMELEFT = "timeLeft";

// Supported Thing types
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
.unmodifiableSet(Stream.of(XMLTV_FILE_BRIDGE_TYPE, XMLTV_CHANNEL_THING_TYPE).collect(Collectors.toSet()));
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(XMLTV_FILE_BRIDGE_TYPE,
XMLTV_CHANNEL_THING_TYPE);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,28 @@

import static org.openhab.binding.xmltv.internal.XmlTVBindingConstants.*;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.xmltv.internal.discovery.XmlTVDiscoveryService;
import org.openhab.binding.xmltv.internal.handler.ChannelHandler;
import org.openhab.binding.xmltv.internal.handler.XmlTVHandler;
import org.openhab.binding.xmltv.internal.jaxb.Tv;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link XmlTVHandlerFactory} is responsible for creating things and thing
Expand All @@ -48,8 +46,16 @@
@NonNullByDefault
@Component(configurationPid = "binding.xmltv", service = ThingHandlerFactory.class)
public class XmlTVHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(XmlTVHandlerFactory.class);
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
private final XMLInputFactory xif = XMLInputFactory.newFactory();
private final TimeZoneProvider timeZoneProvider;
private final Unmarshaller unmarshaller;

@Activate
public XmlTVHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider) throws JAXBException {
this.timeZoneProvider = timeZoneProvider;
this.unmarshaller = JAXBContext.newInstance(Tv.class).createUnmarshaller();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
Expand Down Expand Up @@ -79,37 +85,11 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (XMLTV_FILE_BRIDGE_TYPE.equals(thingTypeUID)) {
try {
XmlTVHandler bridgeHandler = new XmlTVHandler((Bridge) thing);
registerDeviceDiscoveryService(bridgeHandler);
return bridgeHandler;
} catch (JAXBException e) {
logger.error("Unable to create XmlTVHandler : {}", e.getMessage());
}
return new XmlTVHandler((Bridge) thing, xif, unmarshaller);
} else if (XMLTV_CHANNEL_THING_TYPE.equals(thingTypeUID)) {
return new ChannelHandler(thing);
return new ChannelHandler(thing, timeZoneProvider.getTimeZone());
}

return null;
}

@Override
protected void removeHandler(ThingHandler thingHandler) {
if (thingHandler instanceof XmlTVHandler) {
Thing thing = thingHandler.getThing();
unregisterDeviceDiscoveryService(thing);
}
super.removeHandler(thingHandler);
}

private synchronized void registerDeviceDiscoveryService(XmlTVHandler bridgeHandler) {
XmlTVDiscoveryService discoveryService = new XmlTVDiscoveryService(bridgeHandler);
discoveryServiceRegs.put(bridgeHandler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
}

private synchronized void unregisterDeviceDiscoveryService(Thing thing) {
ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(thing.getUID());
serviceReg.unregister();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@
*/
package org.openhab.binding.xmltv.internal.configuration;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link XmlChannelConfiguration} class contains fields mapping
* Channel thing configuration parameters.
*
* @author Gaël L'hopital - Initial contribution
*/
@NonNullByDefault
public class XmlChannelConfiguration {
public static final String CHANNEL_ID = "channelId";

public String channelId;
public Integer offset;
public Integer refresh;
public String channelId = "";
public int offset = 0;
public int refresh = 60;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
*/
package org.openhab.binding.xmltv.internal.configuration;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link XmlTVConfiguration} class contains fields mapping TV bridge
* configuration parameters.
*
* @author Gaël L'hopital - Initial contribution
*/
@NonNullByDefault
public class XmlTVConfiguration {
public String filePath;
public Integer refresh;
public String encoding;
public String filePath = "";
public int refresh = 24;
public String encoding = "UTF8";
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@
*/
package org.openhab.binding.xmltv.internal.discovery;

import static org.openhab.binding.xmltv.internal.XmlTVBindingConstants.XMLTV_CHANNEL_THING_TYPE;
import static org.openhab.binding.xmltv.internal.XmlTVBindingConstants.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.xmltv.internal.XmlTVBindingConstants;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.xmltv.internal.configuration.XmlChannelConfiguration;
import org.openhab.binding.xmltv.internal.handler.XmlTVHandler;
import org.openhab.binding.xmltv.internal.jaxb.Tv;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -33,28 +36,33 @@
*
* @author Gaël L'hopital - Initial contribution
*/
@Component(service = ThingHandlerService.class)
@NonNullByDefault
public class XmlTVDiscoveryService extends AbstractDiscoveryService {
private final Logger logger = LoggerFactory.getLogger(XmlTVDiscoveryService.class);

private static final int SEARCH_TIME = 10;
public class XmlTVDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
private static final int SEARCH_TIME = 5;

private XmlTVHandler bridgeHandler;
private final Logger logger = LoggerFactory.getLogger(XmlTVDiscoveryService.class);
private @Nullable XmlTVHandler handler;

/**
* Creates a XmlTVDiscoveryService with background discovery disabled.
*/
public XmlTVDiscoveryService(XmlTVHandler bridgeHandler) {
super(XmlTVBindingConstants.SUPPORTED_THING_TYPES_UIDS, SEARCH_TIME);
this.bridgeHandler = bridgeHandler;
@Activate
public XmlTVDiscoveryService() {
super(SUPPORTED_THING_TYPES_UIDS, SEARCH_TIME);
}

@Override
public void deactivate() {
super.deactivate();
}

@Override
protected void startScan() {
logger.debug("Starting XmlTV discovery scan");
if (bridgeHandler.getThing().getStatus() == ThingStatus.ONLINE) {
Tv tv = bridgeHandler.getXmlFile();
if (tv != null) {
XmlTVHandler bridgeHandler = handler;
if (bridgeHandler != null && bridgeHandler.getThing().getStatus() == ThingStatus.ONLINE) {
bridgeHandler.getXmlFile().ifPresent(tv -> {
tv.getMediaChannels().stream().forEach(channel -> {
String channelId = channel.getId();
String uid = channelId.replaceAll("[^A-Za-z0-9_]", "_");
Expand All @@ -67,7 +75,19 @@ protected void startScan() {

thingDiscovered(discoveryResult);
});
}
});
}
}

@Override
public void setThingHandler(ThingHandler handler) {
if (handler instanceof XmlTVHandler) {
this.handler = (XmlTVHandler) handler;
}
}

@Override
public @Nullable ThingHandler getThingHandler() {
return handler;
}
}
Loading