Merge orphan head
This commit is contained in:
commit
2e0f8fe90e
@ -4,12 +4,16 @@
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
|
||||
<classpathentry kind="src" output="target/classes" path="target/generated-sources/jaxb">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
|
||||
<attributes>
|
||||
<attribute name="owner.project.facets" value="java"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,5 +1,4 @@
|
||||
syntax:glob
|
||||
conf.properties
|
||||
users.xml
|
||||
target
|
||||
*.log
|
||||
syntax:regexp
|
||||
^users\.xml$
|
||||
^conf\.xml$
|
||||
^target$
|
||||
|
6
.project
6
.project
@ -5,6 +5,11 @@
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
@ -19,5 +24,6 @@
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
@ -1,6 +1,9 @@
|
||||
#Wed Sep 28 23:04:47 CEST 2011
|
||||
#Sat Dec 10 17:49:06 CET 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
|
4
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
4
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<installed facet="java" version="1.6"/>
|
||||
</faceted-project>
|
83
conf.sample.xml
Normal file
83
conf.sample.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
<context:component-scan base-package="fr.imirhil.april.hebdobot" />
|
||||
|
||||
<bean id="properties"
|
||||
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="file.suffix">revue.txt</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="userAliases" class="fr.imirhil.april.hebdobot.xml.UserAlias">
|
||||
<constructor-arg name="source" value="file:users.xml" />
|
||||
</bean>
|
||||
<bean id="bot" class="fr.imirhil.april.hebdobot.irc.Bot"
|
||||
init-method="init" destroy-method="close">
|
||||
<constructor-arg name="host" value="irc.freenode.org" />
|
||||
<constructor-arg name="port" value="6667" />
|
||||
<constructor-arg name="name" value="Hebdobot" />
|
||||
<constructor-arg name="channel" value="#april" />
|
||||
</bean>
|
||||
<bean id="pastebin" class="fr.imirhil.april.hebdobot.pastebin.PastebinClient">
|
||||
<constructor-arg name="apiKey"
|
||||
value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
|
||||
</bean>
|
||||
<bean id="identi.ca" class="fr.imirhil.april.hebdobot.statusnet.IdentiCaClient">
|
||||
<constructor-arg name="apiKey"
|
||||
value="ef8ad74a5ab4a92138ff397763776a14" />
|
||||
<constructor-arg name="apiSecret"
|
||||
value="70400fa3b7c1aebba6d72b46399f45c7" />
|
||||
<constructor-arg name="tokenKey"
|
||||
value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
|
||||
<constructor-arg name="tokenSecret"
|
||||
value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
|
||||
</bean>
|
||||
|
||||
<bean id="job" class="fr.imirhil.april.hebdobot.Job" />
|
||||
|
||||
<bean id="trigger30" class="org.springframework.scheduling.quartz.CronTriggerBean">
|
||||
<property name="jobDetail">
|
||||
<bean
|
||||
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||
<property name="targetObject" ref="job" />
|
||||
<property name="targetMethod" value="at30" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="cronExpression" value="* 30 11 ? * FRI" />
|
||||
</bean>
|
||||
<bean id="trigger45" class="org.springframework.scheduling.quartz.CronTriggerBean">
|
||||
<property name="jobDetail">
|
||||
<bean
|
||||
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||
<property name="targetObject" ref="job" />
|
||||
<property name="targetMethod" value="at45" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="cronExpression" value="0 45 11 ? * FRI" />
|
||||
</bean>
|
||||
<bean id="trigger55" class="org.springframework.scheduling.quartz.CronTriggerBean">
|
||||
<property name="jobDetail">
|
||||
<bean
|
||||
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||
<property name="targetObject" ref="job" />
|
||||
<property name="targetMethod" value="at55" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="cronExpression" value="0 55 11 ? * FRI" />
|
||||
</bean>
|
||||
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
|
||||
<property name="triggers">
|
||||
<list>
|
||||
<ref bean="trigger30" />
|
||||
<ref bean="trigger45" />
|
||||
<ref bean="trigger55" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
43
pom.xml
43
pom.xml
@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>fr.imirhil.april</groupId>
|
||||
<artifactId>hebdobot</artifactId>
|
||||
<version>1.1.1-SNAPSHOT</version>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<scm>
|
||||
<connection>scm:hg:file://${basedir}</connection>
|
||||
</scm>
|
||||
@ -72,14 +72,15 @@
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml</groupId>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<groupId>opensymphony</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.0.2</version>
|
||||
<version>1.6.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
@ -103,5 +104,39 @@
|
||||
<version>1.6.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scribe</groupId>
|
||||
<artifactId>scribe</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.0.6.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>3.0.6.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>3.0.6.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>3.0.6.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -1,8 +1,6 @@
|
||||
package fr.imirhil.april.hebdobot;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -10,63 +8,38 @@ import org.joda.time.DateTime;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.support.FileSystemXmlApplicationContext;
|
||||
|
||||
import fr.imirhil.april.hebdobot.irc.Bot;
|
||||
import fr.imirhil.april.hebdobot.irc.ReviewListener;
|
||||
import fr.imirhil.april.hebdobot.pastebin.PastebinClient;
|
||||
import fr.imirhil.april.hebdobot.review.Review;
|
||||
import fr.imirhil.april.hebdobot.xml.UserAlias;
|
||||
|
||||
public class Application implements ReviewListener {
|
||||
private static final String USERS_FILE = "users.xml";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory
|
||||
.getLogger(Application.class);
|
||||
|
||||
private static final String CONF_PROPERTIES = "conf.properties";
|
||||
private static final String IRC_HOST = "irc.host";
|
||||
private static final String IRC_PORT = "irc.port";
|
||||
private static final String IRC_NICK = "irc.nick";
|
||||
private static final String IRC_CHAN = "irc.chan";
|
||||
private static final String PASTEBIN_KEY = "pastebin.key";
|
||||
private static final String FILE_SUFFIX = "file.suffix";
|
||||
|
||||
private final Properties properties = new Properties();
|
||||
private final Bot bot;
|
||||
private final UserAlias userAlias;
|
||||
private final String channel;
|
||||
private final Properties properties = Context.getBean("properties");
|
||||
private final Bot bot = Context.getBean(Bot.class);
|
||||
private final PastebinClient pastebinClient = Context
|
||||
.getBean(PastebinClient.class);
|
||||
|
||||
private Application() throws Exception {
|
||||
this.userAlias = new UserAlias(new FileInputStream(USERS_FILE));
|
||||
|
||||
this.properties.load(new FileReader(CONF_PROPERTIES));
|
||||
final String name = this.properties.getProperty(IRC_NICK);
|
||||
this.channel = this.properties.getProperty(IRC_CHAN);
|
||||
|
||||
this.bot = new Bot(name, this.channel);
|
||||
this.bot.add(this);
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
this.bot.connect(this.properties.getProperty(IRC_HOST),
|
||||
Integer.valueOf(this.properties.getProperty(IRC_PORT)));
|
||||
this.bot.joinChannel(this.channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(final Review review) {
|
||||
final String date = ISODateTimeFormat.basicDate().print(new DateTime());
|
||||
final String text = review.toString(this.userAlias);
|
||||
if (this.properties.containsKey(PASTEBIN_KEY)) {
|
||||
final String text = review.toString();
|
||||
try {
|
||||
this.bot.sendMessage("Compte-rendu de la revue : "
|
||||
+ new PastebinClient(this.properties
|
||||
.getProperty(PASTEBIN_KEY)).paste(text,
|
||||
"Revue APRIL " + date));
|
||||
+ this.pastebinClient.paste(text, "Revue APRIL " + date));
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("Error during Pastebin submit", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.properties.containsKey(FILE_SUFFIX)) {
|
||||
try {
|
||||
@ -83,6 +56,7 @@ public class Application implements ReviewListener {
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
new Application().start();
|
||||
new FileSystemXmlApplicationContext("conf.xml");
|
||||
new Application();
|
||||
}
|
||||
}
|
||||
|
30
src/main/java/fr/imirhil/april/hebdobot/Context.java
Normal file
30
src/main/java/fr/imirhil/april/hebdobot/Context.java
Normal file
@ -0,0 +1,30 @@
|
||||
package fr.imirhil.april.hebdobot;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class Context implements ApplicationContextAware {
|
||||
private static ApplicationContext CONTEXT;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(
|
||||
final ApplicationContext applicationContext) throws BeansException {
|
||||
CONTEXT = applicationContext;
|
||||
}
|
||||
|
||||
public static <T> T getBean(final Class<T> clazz) {
|
||||
return CONTEXT.getBean(clazz);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(final String name) {
|
||||
return (T) CONTEXT.getBean(name);
|
||||
}
|
||||
|
||||
}
|
30
src/main/java/fr/imirhil/april/hebdobot/Job.java
Normal file
30
src/main/java/fr/imirhil/april/hebdobot/Job.java
Normal file
@ -0,0 +1,30 @@
|
||||
package fr.imirhil.april.hebdobot;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import fr.imirhil.april.hebdobot.irc.Bot;
|
||||
import fr.imirhil.april.hebdobot.statusnet.IdentiCaClient;
|
||||
|
||||
public class Job {
|
||||
@Resource
|
||||
private Bot bot;
|
||||
@Resource
|
||||
private IdentiCaClient identiCaClient;
|
||||
|
||||
private void notify(final String message) {
|
||||
this.bot.sendMessage(message);
|
||||
this.identiCaClient.post(message);
|
||||
}
|
||||
|
||||
public void at30() {
|
||||
this.notify("Revue hebdomadaire dans 30min !");
|
||||
}
|
||||
|
||||
public void at45() {
|
||||
this.notify("Revue hebdomadaire dans 15min !");
|
||||
}
|
||||
|
||||
public void at55() {
|
||||
this.notify("Revue hebdomadaire dans 5min !");
|
||||
}
|
||||
}
|
@ -12,14 +12,29 @@ import fr.imirhil.april.hebdobot.review.Review;
|
||||
import fr.imirhil.april.hebdobot.review.Topic;
|
||||
|
||||
public class Bot extends PircBot {
|
||||
private Review review = null;
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final String channel;
|
||||
private Review review = null;
|
||||
private final Collection<ReviewListener> listeners =
|
||||
new LinkedList<ReviewListener>();
|
||||
|
||||
public Bot(final String name, final String channel) {
|
||||
this.setName(name);
|
||||
public Bot(final String host, final int port, final String name,
|
||||
final String channel) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.channel = channel;
|
||||
this.setName(name);
|
||||
}
|
||||
|
||||
public void init() throws Exception {
|
||||
this.connect(this.host, this.port);
|
||||
this.joinChannel(this.channel);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.disconnect();
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
public void add(final ReviewListener listener) {
|
||||
@ -85,8 +100,7 @@ public class Bot extends PircBot {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.disconnect();
|
||||
this.dispose();
|
||||
this.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -42,18 +42,18 @@ public class PastebinClient {
|
||||
}
|
||||
}
|
||||
|
||||
private final String apiDevKey;
|
||||
private final String apiKey;
|
||||
private String apiUserKey = null;
|
||||
HttpClient httpClient = new DefaultHttpClient();
|
||||
|
||||
public PastebinClient(final String apiDevKey) {
|
||||
this.apiDevKey = apiDevKey;
|
||||
public PastebinClient(final String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
public void login(final String name, final String password)
|
||||
throws Exception {
|
||||
final List<NameValuePair> params = new LinkedList<NameValuePair>();
|
||||
setParameter(params, API_DEV_KEY, this.apiDevKey);
|
||||
setParameter(params, API_DEV_KEY, this.apiKey);
|
||||
setParameter(params, API_USER_NAME, name);
|
||||
setParameter(params, API_USER_PASSWORD, password);
|
||||
|
||||
@ -72,7 +72,7 @@ public class PastebinClient {
|
||||
final Format format, final boolean privat,
|
||||
final Expiration expiration) throws Exception {
|
||||
final List<NameValuePair> params = new LinkedList<NameValuePair>();
|
||||
setParameter(params, API_DEV_KEY, this.apiDevKey);
|
||||
setParameter(params, API_DEV_KEY, this.apiKey);
|
||||
setParameter(params, API_USER_KEY, this.apiUserKey);
|
||||
setParameter(params, API_OPTION, Option.PASTE.getValue());
|
||||
setParameter(params, API_PASTE_PRIVATE, privat ? "1" : "0");
|
||||
|
@ -9,11 +9,14 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
|
||||
import fr.imirhil.april.hebdobot.Context;
|
||||
import fr.imirhil.april.hebdobot.xml.UserAlias;
|
||||
|
||||
public class Review {
|
||||
private static final int LENGTH = 80;
|
||||
|
||||
private static final UserAlias USER_ALIAS = Context
|
||||
.getBean(UserAlias.class);
|
||||
private final Set<String> participants = new HashSet<String>();
|
||||
private final List<IndividualTopic> individualTopics =
|
||||
new LinkedList<IndividualTopic>();
|
||||
@ -60,7 +63,8 @@ public class Review {
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
public String toString(final UserAlias userService) {
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
addLine(buffer, '=');
|
||||
addCenter(buffer, "Revue de la semaine en cours");
|
||||
@ -74,7 +78,7 @@ public class Review {
|
||||
addEmpty(buffer);
|
||||
addCenter(buffer, "Participants", '-');
|
||||
for (final String participant : this.participants) {
|
||||
addChunk(buffer, "* " + userService.getRealName(participant) + "\n");
|
||||
addChunk(buffer, "* " + USER_ALIAS.getRealName(participant) + "\n");
|
||||
}
|
||||
|
||||
if (!this.individualTopics.isEmpty()) {
|
||||
@ -82,7 +86,7 @@ public class Review {
|
||||
addEmpty(buffer);
|
||||
addLine(buffer, '=');
|
||||
addEmpty(buffer);
|
||||
addCenter(buffer, userService.getRealName(participant), '-');
|
||||
addCenter(buffer, USER_ALIAS.getRealName(participant), '-');
|
||||
for (final IndividualTopic topic : this.individualTopics) {
|
||||
if (topic.hasParticipant(participant)) {
|
||||
addEmpty(buffer);
|
||||
|
@ -1,5 +0,0 @@
|
||||
package fr.imirhil.april.hebdobot.statusnet;
|
||||
|
||||
public class Client {
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package fr.imirhil.april.hebdobot.statusnet;
|
||||
|
||||
import org.scribe.builder.api.DefaultApi10a;
|
||||
import org.scribe.model.Token;
|
||||
|
||||
public class IdentiCaApi extends DefaultApi10a {
|
||||
private static final String IDENTI_CA_OAUTH_API_URL =
|
||||
"https://identi.ca/api/oauth";
|
||||
private static final String IDENTI_CA_OAUTH_API_REQUEST_TOKEN_URL =
|
||||
IDENTI_CA_OAUTH_API_URL + "/request_token";
|
||||
private static final String IDENTI_CA_OAUTH_API_ACCESS_TOKEN_URL =
|
||||
IDENTI_CA_OAUTH_API_URL + "/access_token";
|
||||
private static final String IDENTI_CA_OAUTH_API_AUTHORIZE_URL =
|
||||
IDENTI_CA_OAUTH_API_URL + "/authorize?oauth_token=%s";
|
||||
|
||||
@Override
|
||||
public String getRequestTokenEndpoint() {
|
||||
return IDENTI_CA_OAUTH_API_REQUEST_TOKEN_URL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return IDENTI_CA_OAUTH_API_ACCESS_TOKEN_URL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorizationUrl(final Token requestToken) {
|
||||
return String.format(IDENTI_CA_OAUTH_API_AUTHORIZE_URL,
|
||||
requestToken.getToken());
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package fr.imirhil.april.hebdobot.statusnet;
|
||||
|
||||
|
||||
public class IdentiCaClient extends StatusNetClient {
|
||||
private static final Class<IdentiCaApi> API_CLASS = IdentiCaApi.class;
|
||||
private static final String IDENTICA_API_URL = "https://identi.ca/api";
|
||||
|
||||
public IdentiCaClient(final String apiKey, final String apiSecret,
|
||||
final String tokenKey, final String tokenSecret) {
|
||||
super(API_CLASS, apiKey, apiSecret, tokenKey, tokenSecret);
|
||||
}
|
||||
|
||||
public static void register(final String apiKey, final String apiSecret) {
|
||||
StatusNetClient.register(API_CLASS, apiKey, apiSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiUrl() {
|
||||
return IDENTICA_API_URL;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package fr.imirhil.april.hebdobot.statusnet;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.scribe.builder.ServiceBuilder;
|
||||
import org.scribe.builder.api.Api;
|
||||
import org.scribe.model.OAuthRequest;
|
||||
import org.scribe.model.Token;
|
||||
import org.scribe.model.Verb;
|
||||
import org.scribe.model.Verifier;
|
||||
import org.scribe.oauth.OAuthService;
|
||||
|
||||
public abstract class StatusNetClient {
|
||||
private final OAuthService service;
|
||||
private final Token token;
|
||||
|
||||
public StatusNetClient(final Class<? extends Api> apiClass,
|
||||
final String apiKey, final String apiSecret, final String tokenKey,
|
||||
final String tokenSecret) {
|
||||
this.service = getService(apiClass, apiKey, apiSecret);
|
||||
this.token = new Token(tokenKey, tokenSecret);
|
||||
}
|
||||
|
||||
private static OAuthService getService(final Class<? extends Api> apiClass,
|
||||
final String apiKey, final String apiSecret) {
|
||||
return new ServiceBuilder().provider(apiClass).apiKey(apiKey)
|
||||
.apiSecret(apiSecret).build();
|
||||
}
|
||||
|
||||
public static void register(final Class<? extends Api> apiClass,
|
||||
final String apiKey, final String apiSecret) {
|
||||
final OAuthService service = getService(apiClass, apiKey, apiSecret);
|
||||
final Token requestToken = service.getRequestToken();
|
||||
System.out.println(service.getAuthorizationUrl(requestToken));
|
||||
System.out.print(">>");
|
||||
final Scanner scanner = new Scanner(System.in);
|
||||
Verifier verifier = new Verifier(scanner.nextLine());
|
||||
final Token token = service.getAccessToken(requestToken, verifier);
|
||||
System.out.println(token);
|
||||
}
|
||||
|
||||
public void post(final String message) {
|
||||
final OAuthRequest request =
|
||||
new OAuthRequest(Verb.POST, this.getApiUrl()
|
||||
+ "/statuses/update.json");
|
||||
request.addBodyParameter("status", message);
|
||||
this.service.signRequest(this.token, request);
|
||||
request.send();
|
||||
}
|
||||
|
||||
protected abstract String getApiUrl();
|
||||
}
|
86
src/test/java/fr/imirhil/april/hebdobot/irc/BotTest.java
Normal file
86
src/test/java/fr/imirhil/april/hebdobot/irc/BotTest.java
Normal file
@ -0,0 +1,86 @@
|
||||
package fr.imirhil.april.hebdobot.irc;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import fr.imirhil.april.hebdobot.review.Review;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "/fr/imirhil/april/hebdobot/conf.xml")
|
||||
public class BotTest implements ReviewListener {
|
||||
private static class BotMock extends Bot {
|
||||
public BotMock() throws Exception {
|
||||
super("", 0, "bot", "channel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void
|
||||
onMessage(final String channel, final String sender,
|
||||
final String login, final String hostname,
|
||||
final String message) {
|
||||
super.onMessage(channel, sender, login, hostname, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redo() throws Exception {
|
||||
final Bot bot = new BotMock();
|
||||
bot.add(this);
|
||||
|
||||
final InputStream is =
|
||||
BotTest.class
|
||||
.getResourceAsStream("/fr/imirhil/april/hebdobot/review.log");
|
||||
try {
|
||||
final Reader isr = new InputStreamReader(is);
|
||||
try {
|
||||
final BufferedReader isbr = new BufferedReader(isr);
|
||||
try {
|
||||
String line;
|
||||
final Pattern pattern =
|
||||
Pattern.compile(".*\\s+<([^>]+)>\\s+(.*)");
|
||||
while ((line = isbr.readLine()) != null) {
|
||||
final Matcher matcher = pattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
bot.onMessage("channel", matcher.group(1), "", "",
|
||||
matcher.group(2));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
isbr.close();
|
||||
}
|
||||
|
||||
} finally {
|
||||
isr.close();
|
||||
}
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(final Review review) {
|
||||
try {
|
||||
final String date =
|
||||
ISODateTimeFormat.basicDate().print(new DateTime());
|
||||
final String text = review.toString();
|
||||
final File file = new File("target/" + date + "_revue.txt");
|
||||
FileUtils.writeStringToFile(file, text);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package fr.imirhil.april.hebdobot.pastebin;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PastebinClientTest {
|
||||
private final PastebinClient client = new PastebinClient(
|
||||
"b95ea42d539ec9dca02a7da1f5b229c7");
|
||||
|
||||
@Test
|
||||
public void testPaste() throws Exception {
|
||||
System.out.println(this.client.paste("ééé", Expiration.MINUTE_10));
|
||||
}
|
||||
}
|
22
src/test/resources/fr/imirhil/april/hebdobot/conf.xml
Normal file
22
src/test/resources/fr/imirhil/april/hebdobot/conf.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
<context:component-scan base-package="fr.imirhil.april.hebdobot" />
|
||||
|
||||
<bean id="properties"
|
||||
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="file.suffix">revue.txt</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="userAliases" class="fr.imirhil.april.hebdobot.xml.UserAlias">
|
||||
<constructor-arg name="source" value="classpath:/fr/imirhil/april/hebdobot/users.xml" />
|
||||
</bean>
|
||||
|
||||
<bean id="bot" class="fr.imirhil.april.hebdobot.irc.BotTest.BotMock" />
|
||||
</beans>
|
166
src/test/resources/fr/imirhil/april/hebdobot/review.log
Normal file
166
src/test/resources/fr/imirhil/april/hebdobot/review.log
Normal file
@ -0,0 +1,166 @@
|
||||
2011-09-02 12:00:36 <janchou> !debut
|
||||
2011-09-02 12:00:36 <janchou> % rappel : toute ligne commençant par % ne sera considérée comme un commentaire et non prise en compte dans la synthèse
|
||||
2011-09-02 12:00:36 <janchou> # 1/ Actions passées ou en cours % quand vous avez fini vous le dites par
|
||||
2011-09-02 12:00:36 <janchou> % fini
|
||||
2011-09-02 12:00:55 * coinpan (500c6ecb@gateway/web/freenode/ip.80.12.110.203) a rejoint #april
|
||||
2011-09-02 12:00:59 <coinpan> coin
|
||||
2011-09-02 12:01:03 <_PoLuX_> Institutionnel : travail sur consultation cloud
|
||||
2011-09-02 12:01:10 <janchou> % coinpan : pile à temps, on démarre :)
|
||||
2011-09-02 12:01:10 <galilea> cloud : fin de la réponse à la consultation européenne
|
||||
2011-09-02 12:01:15 <_PoLuX_> Institutionnel : remarques sur tv connectée
|
||||
2011-09-02 12:01:19 <galilea> cloud note en cours
|
||||
2011-09-02 12:01:24 <aurelia> commande cartes de visites pour _PoLuX_
|
||||
2011-09-02 12:01:27 <benj> Initiatives Candidats.fr: amélioration de la plate-forme
|
||||
2011-09-02 12:01:34 <benj> Suivi achat portable Jeanne
|
||||
2011-09-02 12:01:34 <galilea> cloud : mise en ligne de la consultation
|
||||
2011-09-02 12:01:37 <aurelia> dépot chèque à la banque
|
||||
2011-09-02 12:01:41 <janchou> cloud : finalisation réponse consultation européenne, envoi, mise en ligne de la réponse sur le site de l'April
|
||||
2011-09-02 12:01:42 <benj> Création d'un compte SVN pour galilea
|
||||
2011-09-02 12:01:46 <benj> Divers relectures
|
||||
2011-09-02 12:01:48 <_PoLuX_> Suivi divers en trésorerie
|
||||
2011-09-02 12:01:54 <galilea> cloud : remerciement des participants
|
||||
2011-09-02 12:01:55 <coinpan> traductions : relayé l'appel à trad de Simon Descarpentries (livre Eloquent Javascript)
|
||||
2011-09-02 12:01:56 <janchou> TV connectée : suite préparation réponse de l'April
|
||||
2011-09-02 12:01:58 <benj> %fini
|
||||
2011-09-02 12:02:11 <coinpan> traductions : publié traduction relue (déclaration d'utilisation de LL)
|
||||
2011-09-02 12:02:16 <teymour> %oups je suis en retard
|
||||
2011-09-02 12:02:18 <galilea> agenda 2020 : bilan en cours 2012
|
||||
2011-09-02 12:02:25 <_PoLuX_> Entretient avec Antoine Chao + CR
|
||||
2011-09-02 12:02:26 <janchou> Formats ouverts : préparation de l'actu sur la généralisation des standards ouverts dans l'administration
|
||||
2011-09-02 12:02:32 <aurelia> prise de contact avec nouveau fournisseur poru les t-shirts
|
||||
2011-09-02 12:02:33 <teymour> réu dossier instit/réunion d'équipe
|
||||
2011-09-02 12:02:35 <janchou> % teymour : on en est encore aux activités semaine passée
|
||||
2011-09-02 12:02:38 <_PoLuX_> Relances diverses sur projet de guide libreasso
|
||||
2011-09-02 12:02:42 <teymour> format ouverts push des infos
|
||||
2011-09-02 12:02:42 <galilea> pt déj dossiers institutionnels
|
||||
2011-09-02 12:02:46 <coinpan> traductions : rédaction d'une niouze pour la publication de nouvelles trad + demande de publication
|
||||
2011-09-02 12:02:48 <benj> Réunion dossiers institutionnels / point d'équipe
|
||||
2011-09-02 12:02:49 <aurelia> appel à particpation pour la braderie de lille
|
||||
2011-09-02 12:02:53 <benj> %fini
|
||||
2011-09-02 12:02:57 <galilea> rapport d'étonnement 1 mois de stage
|
||||
2011-09-02 12:02:58 <teymour> RPVA rdv ministère de la justice + récupération d'infos
|
||||
2011-09-02 12:02:59 <aurelia> crétaion page wiki braderie de lille
|
||||
2011-09-02 12:03:06 <_PoLuX_> Préparation du stand pour la braprendre rdv avec le conseiller credit mut derie de lille
|
||||
2011-09-02 12:03:07 <coinpan> %fini
|
||||
2011-09-02 12:03:09 <janchou> entretien journaliste sur Hadopi
|
||||
2011-09-02 12:03:18 <_PoLuX_> Suivi divers pour le CA
|
||||
2011-09-02 12:03:19 <teymour> Loop suiv et correction du draft de _PoluX_
|
||||
2011-09-02 12:03:22 <aurelia> petit dèj institutionnel
|
||||
2011-09-02 12:03:26 <galilea> examen compétence hadopi sur accès aux info essentielles d'interop
|
||||
2011-09-02 12:03:31 <janchou> petit déjeuner point d'équipe
|
||||
2011-09-02 12:03:34 <teymour> envoi du courriel Loop au CA en cours
|
||||
2011-09-02 12:03:35 <_PoLuX_> Proposition de lettre de soutien au loop
|
||||
2011-09-02 12:03:39 <galilea> %fini
|
||||
2011-09-02 12:04:00 <janchou> discussions sur le bilan France Numérique 2012 et réponse à la consultation france numérique 2020
|
||||
2011-09-02 12:04:02 <aurelia> mise a jour bilan financier des rmll
|
||||
2011-09-02 12:04:14 <janchou> suivi reprise des travaux parlementaires (et réponses aux QE)
|
||||
2011-09-02 12:04:23 <teymour> routing d'un appel journaliste RFI sur HADOPI vers axx_ de LQDN
|
||||
2011-09-02 12:04:23 <_PoLuX_> Participation au petit dej institutionnel
|
||||
2011-09-02 12:04:27 <aurelia> commabde d'affiches et catalibre pour le stand de la braderie de lille
|
||||
2011-09-02 12:04:41 <janchou> % teymour : c'était Clare ?
|
||||
2011-09-02 12:04:49 <_PoLuX_> % fini
|
||||
2011-09-02 12:05:10 <teymour> %janchou oui elle m'a rappelé en fin de semaine derenière. Tu l'as rajoutée dans les contacts presse ou il faut que je le fasse ?
|
||||
2011-09-02 12:05:21 <teymour> relecture Cloud Computing
|
||||
2011-09-02 12:05:41 <janchou> % teymour : je m'en occupe (je l'ai vue mardi)
|
||||
2011-09-02 12:05:42 <aurelia> prise de rdv avec le conseiller bancaire
|
||||
2011-09-02 12:05:59 <teymour> % janchou galilea pour info, on m'a fait des compliments sur le draft de note sur le cloud ce matin
|
||||
2011-09-02 12:06:20 <galilea> %teymour :)
|
||||
2011-09-02 12:06:30 <teymour> %janchou cool pour Clare, je pensais qu'elle avait laché l'affaire avec nous pour son sujet
|
||||
2011-09-02 12:06:36 <aurelia> gestion relance 1er septembre
|
||||
2011-09-02 12:06:45 <PhilippeVay> commande d'un livre sur Drupal chez Eyrolles ^^
|
||||
2011-09-02 12:06:46 <teymour> %fini
|
||||
2011-09-02 12:06:48 <aurelia> gestion radiation 1er septembre
|
||||
2011-09-02 12:06:52 <PhilippeVay> % fini
|
||||
2011-09-02 12:07:10 <aurelia> mise a jour lettre interne
|
||||
2011-09-02 12:07:29 <janchou> % fini
|
||||
2011-09-02 12:07:39 <janchou> mise à jour lettre interme
|
||||
2011-09-02 12:07:42 <janchou> % fini pour de vrai
|
||||
2011-09-02 12:07:53 <aurelia> % fini
|
||||
2011-09-02 12:08:13 <janchou> % on va passer à la suite : Actions à venir
|
||||
2011-09-02 12:08:13 <janchou> # 2/ Actions à venir
|
||||
2011-09-02 12:08:13 <janchou> % quand vous avez fini vous le dites par % fini
|
||||
2011-09-02 12:08:23 <_PoLuX_> Participation Braderie de Lille
|
||||
2011-09-02 12:08:27 <echarp> revue de presse
|
||||
2011-09-02 12:08:29 <janchou> cloud : relecture de la note
|
||||
2011-09-02 12:08:30 <galilea> cloud : note en cours
|
||||
2011-09-02 12:08:31 <benj> Réception/configuration éventuelle portable Jeanne
|
||||
2011-09-02 12:08:33 <_PoLuX_> Rédaction du guide libreasso
|
||||
2011-09-02 12:08:38 <echarp> 4 questions à responsable de groupe
|
||||
2011-09-02 12:08:43 <_PoLuX_> Relance des contributeurs pour libreasso
|
||||
2011-09-02 12:08:46 <benj> Améliorations initiatives candidats.fr
|
||||
2011-09-02 12:08:48 <janchou> TV connectée : envoi de la réponse à l'appel à contribution
|
||||
2011-09-02 12:08:49 <galilea> mise à jour cahiers candidats. fr
|
||||
2011-09-02 12:09:00 <janchou> france numérique : suite discussion, préparation réponse
|
||||
2011-09-02 12:09:01 <galilea> agenda numérique 2020
|
||||
2011-09-02 12:09:11 <janchou> marchés publics : conférence à l'AMIF
|
||||
2011-09-02 12:09:11 <_PoLuX_> + Suivi divers et dépillage post-été
|
||||
2011-09-02 12:09:14 <coinpan> traductions : faire une trad
|
||||
2011-09-02 12:09:16 * xpo est parti (Quit: xpo)
|
||||
2011-09-02 12:09:17 <galilea> RPVA: voir pour les contacts
|
||||
2011-09-02 12:09:18 <aurelia> pointage compta aout
|
||||
2011-09-02 12:09:23 <coinpan> traductions : générer un nouveau listing de documents àtraduire
|
||||
2011-09-02 12:09:25 <benj> %fini
|
||||
2011-09-02 12:09:29 <janchou> RPVA : suivi contacts
|
||||
2011-09-02 12:09:33 <benj> Formation SVN Marie
|
||||
2011-09-02 12:09:33 <coinpan> %fini
|
||||
2011-09-02 12:09:34 <teymour> RPVA contacts
|
||||
2011-09-02 12:09:35 <janchou> vente liée : diverses relances
|
||||
2011-09-02 12:09:35 <galilea> comprendre SVN
|
||||
2011-09-02 12:09:35 <echarp> %fini
|
||||
2011-09-02 12:09:36 <benj> %fini pour de vrai
|
||||
2011-09-02 12:09:44 <teymour> Cloud relecture
|
||||
2011-09-02 12:09:47 <janchou> % galilea : impossible :)
|
||||
2011-09-02 12:09:52 <galilea> %fini
|
||||
2011-09-02 12:09:52 <aurelia> % galilea bonne chance :)
|
||||
2011-09-02 12:10:02 <benj> %/me aime les défis
|
||||
2011-09-02 12:10:03 <teymour> Marchés public, mettre en relation janchou avec Justice
|
||||
2011-09-02 12:10:05 <galilea> % l'espoir fait vivre
|
||||
2011-09-02 12:10:10 <aurelia> suivi bounce aout et septembre
|
||||
2011-09-02 12:10:18 <janchou> ACTA : mise à jour sur le site de l'April
|
||||
2011-09-02 12:10:23 <aurelia> suivi relance
|
||||
2011-09-02 12:10:30 <teymour> mettre nouveaux contacts dans dotproject
|
||||
2011-09-02 12:10:45 <teymour> Envoi lettre Loop
|
||||
2011-09-02 12:10:56 <aurelia> contacter ppsj pour arret
|
||||
2011-09-02 12:11:17 <janchou> france numérique : envoyer commentaire sur le projet de consultation
|
||||
2011-09-02 12:11:33 <janchou> vente liée : finalisation / validation de la synthèse ?
|
||||
2011-09-02 12:11:46 <janchou> %fini
|
||||
2011-09-02 12:11:48 <aurelia> % fini
|
||||
2011-09-02 12:12:12 <janchou> % teymour fini ?
|
||||
2011-09-02 12:12:16 <teymour> %fini
|
||||
2011-09-02 12:12:27 <janchou> % on va passer à la suite : Points de blocage
|
||||
2011-09-02 12:12:27 <janchou> ## 3/ Points de blocage existants ou levés cette semaine
|
||||
2011-09-02 12:12:27 <janchou> % si rien à dire vous dites %ras
|
||||
2011-09-02 12:12:38 <janchou> laptop : en cours de résolution
|
||||
2011-09-02 12:12:49 <coinpan> %ras
|
||||
2011-09-02 12:12:55 <galilea> %ras
|
||||
2011-09-02 12:12:56 <aurelia> prendre rdv avec le conseiller credit mut > réglé
|
||||
2011-09-02 12:12:56 <benj> Débloqué bug javascript/json bloquant pour les initiatives
|
||||
2011-09-02 12:13:08 <teymour> %ras
|
||||
2011-09-02 12:13:14 <benj> Recu confirmation livraison laptop
|
||||
2011-09-02 12:13:16 <benj> %fini
|
||||
2011-09-02 12:13:46 <aurelia> oubli de la braderie de lille, appel à participation tardif
|
||||
2011-09-02 12:14:11 <janchou> % on va passer à la suite : Points Forts et Points de Vigilance de la réunion
|
||||
2011-09-02 12:14:12 <janchou> ## 4/ Points forts de la réunion
|
||||
2011-09-02 12:14:12 <janchou> % 1 mn max
|
||||
2011-09-02 12:14:12 <janchou> % si rien à dire vous dites %ras
|
||||
2011-09-02 12:14:25 <coinpan> toujours aussi rapide et motivant
|
||||
2011-09-02 12:14:30 <janchou> beaucoup de présents, effet rentrée ?
|
||||
2011-09-02 12:14:41 <aurelia> beaucoup de boulot aussi
|
||||
2011-09-02 12:14:44 * _bibi (~obibi@office.bearstech.com) a rejoint #april
|
||||
2011-09-02 12:15:02 <galilea> du boulot on s'ennuie pas !
|
||||
2011-09-02 12:15:07 <galilea> %fini
|
||||
2011-09-02 12:15:16 <benj> Retour de plein de gens
|
||||
2011-09-02 12:15:22 * _bibi (~obibi@office.bearstech.com) a quitté #april
|
||||
2011-09-02 12:15:26 <galilea> %trop bien le stage :)
|
||||
2011-09-02 12:15:29 <janchou> % on va passer à la suite : Points de Vigilance de la réunion
|
||||
2011-09-02 12:15:29 <janchou> ## 5/ Points de vigilance de la réunion
|
||||
2011-09-02 12:15:29 <janchou> % si rien à dire vous dites
|
||||
2011-09-02 12:15:29 <janchou> %ras % 1 mn max
|
||||
2011-09-02 12:15:36 <coinpan> %ras
|
||||
2011-09-02 12:15:48 <galilea> %ras
|
||||
2011-09-02 12:16:02 <aurelia> % galilea tu dira plus ça quand tu aura ouvert svn :P
|
||||
2011-09-02 12:16:05 <janchou> % galilea : oui, tu apprends plein de trucs techniques... /o\
|
||||
2011-09-02 12:16:26 <benj> %ras
|
||||
2011-09-02 12:16:26 <janchou> % Fin de la revue hebdomadaire, merci à vous
|
||||
2011-09-02 12:16:26 <janchou> % Pensez à noter votre bénévalo : http://www.april.org/my?action=benevalo
|
||||
2011-09-02 12:16:26 <janchou> !fin
|
3
src/test/resources/fr/imirhil/april/hebdobot/users.xml
Normal file
3
src/test/resources/fr/imirhil/april/hebdobot/users.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<users xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="users.xsd" />
|
8
users.sample.xml
Normal file
8
users.sample.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<users xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="users.xsd">
|
||||
<user>
|
||||
<realName>Foo Bar</realName>
|
||||
<nick>foo</nick>
|
||||
<nick>foo_</nick>
|
||||
</user>
|
||||
</users>
|
Loading…
Reference in New Issue
Block a user