Pork Center
Voir le texte source
Page
Discussion
Voir le texte source
Historique
Rechercher
Navigation
Accueil
Communauté
Modifications récentes
Page au hasard
Chat
Aide
sitesupport
Outils personnels
3.141.200.180
Discussion avec cette adresse IP
Connexion
Boîte à outils
Pages liées
Suivi des pages liées
Pages spéciales
Voir le texte source
De Hack-it.org.
pour
Shalmaneser
== Genèse == L'idée est simple: utiliser l'irc comme un bloc-notes collectif, sans avoir à loguer, puis filtrer et publier. Il fallait donc une interface entre le chat et le web, un bot qui permettrait de bloguer depuis la fenêtre sur laquelle les maniaques passent une grande partie de leur temps libre. Vérification faite, il n'y avait pas grand chose d'existant qui remplissait le cahier des charges. Il a donc fallu réfléchir à une manière simple de créer ce "bloggerbot". Dans sa toute première version (''proof of concept'', plutôt), qui exista un après-midi de 2006 le code fait exactement... une ligne (<code>exec -o echo $PRIVMSG >> $TIME</code>). En effet, si l'on utilise un système de blog basé sur des fichiers, tel que [http://blosxom.sourceforge.net/ blosxom] il suffit d'écrire un .txt à partir d'un message privé. On obtient ainsi un mini-billet (460 signes) daté, et signé (nick de l'expéditeur). C'est d'ailleurs toujours sur ce principe que fonctionne Shalmaneser. Commencé dans le langage python ([[shal1]] bot minimal), on a trouvé plus pratique d'utiliser une api existante dont le code source puisse être rapidement assimilé (eggbot fait un peu mal à la tête). Le choix s'est porté sur [http://www.jibble.org/pircbot.php PircBot]. == Utilisation == * Rejoignez le [http://chat.inframonde.org/chat.php?c=inframonde canal #inframonde] sur [http://inframonde.org inframonde.org], dites bonjour, une fois opé, envoyez votre mini-billet en message privé à Shalmaneser. == Installation == Récapitulons: pour avoir un bot blogueur, il faut: * télécharger Shalmaneser: http://shalmaneser.com/downloads * installer le moteur de blog [http://blosxom.sourceforge.net/documentation/users/install/dynamic/ Blosxom] sur un hébergement (il existe d'autres blogs, utilisant un système ''flat files'', qui devraient fonctionner sans problèmes, mais bon, blosxom rules) * Editer le fichier config * lancer run.bat pour windows, run.sh pour linux ou se déplacer dans le répertoire Shalmaneser et taper: <code>java ShalmaneserMain</code> * '''Tout ceci est un gros hack de porkz en phase alpha, il va sans dire qu'il n'y a aucune garantie quant au code''' == Shalmaneser.java == <java> /* Shalmaneser est expérimenté par la porkz team sur le channel #arf irc.undernet.org Usage: /server irc.undernet.org /join #arf /msg Shalmaneser hello world copyleft Porkz sauf ce qui est pas à nous: - http://www.jibble.org/javadocs/pircbot/index.html ) - Après quelques déboires pour uploader un fichier en ftp (!) une solution simple a été trouvée à cet endroit: http://www.programmers-corner.com/sourcecode/142 */ import org.jibble.pircbot.*; import java.io.*; import java.util.*; import java.net.URL; import java.text.SimpleDateFormat; /** * Implémentation rapide de PircBot en tant que robot-blogueur sur irc * publie les messages privés qu'il reà§oit sur un blog * limitation: un billet ne peut faire que 460 signes */ public class Shalmaneser extends PircBot{ static Properties p = new Properties(); static String nick; static String owner; static String channel; static String host; static String login; static String pass; static String dir; static String firstnick; static String confirmationMessage; /** * Constructeur, le nick est Shalmaneser0, le temps de se loguer * pour éviter d'envoyer l'ip réelle, en cas de notify sur shalmaneser * (...) */ public Shalmaneser() { try{ p.load(new FileInputStream(new File("config"))); nick = p.getProperty("nick"); owner = p.getProperty("owner"); channel = p.getProperty("channel"); host = p.getProperty("FTPhost"); login = p.getProperty("FTPlogin"); pass = p.getProperty("FTPpassword"); dir = p.getProperty("directory"); firstnick = p.getProperty("firstnick"); confirmationMessage = p.getProperty("confirmationMessage"); }catch(FileNotFoundException nf){ }catch(IOException io){} this.setName(firstnick); try{ setEncoding("8859_1"); } catch( UnsupportedEncodingException e) {} } /** * Reconnection */ protected void onDisconnect(){ while (!isConnected()) { try { reconnect(); joinChannel(channel); } catch (Exception e) { // Couldn't reconnect! // Pause for a short while...? } } } /** * Envoie les messages de connexion au serveur tels que login, modes... * (ces messages sont envoyés sous forme de raw) * Ceci fait, Shalmaneser prend son nick de croisière */ public void onConnect(){ sendRawLine("PRIVMSG x@channels.undernet.org :login Shalmaneser ******"); sendRawLine("MODE "+firstnick+ " +x"); sendRawLine("PRIVMSG x :set invisible on"); sendRawLine("NICK "+ nick); } /** * auto-rejoin en cas de kick */ protected void onKick(String chan, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason){ if (recipientNick.equalsIgnoreCase(getNick())) { joinChannel(chan); } } /** * vérifie si un nick est autorisé à poster, * renvoie true si la personne est opée sur #arf, false sinon * On pourrait aussi utiliser la méthode getChannels() * mais... Shalmaneser ne va pas ailleurs */ public boolean isAllowed(String nick){ User [] userArray = this.getUsers(channel); for(int i=0; i<userArray.length; i++){ if(nick.equalsIgnoreCase(userArray[i].getNick()) && userArray[i].isOp()){ return true; } } return false; } /** * Crée un fichier txt (soit un billet pour blosxom) et l'envoie par ftp */ public static void uploadQuote(String sender, String message){ String time = new java.util.Date().toString(); String nomFichier= new String(time+"_"+sender+".txt"); String target = dir + nomFichier; nomFichier = "tmp" + System.getProperty("file.separator") + nomFichier; try { Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(nomFichier), "8859_1")); out.write(sender +"\n"); out.write("meta-markup: textile"+"\n"); out.write(message); out.close(); FTPupload ftp = new FTPupload(host, login, pass, nomFichier, target); File tmp = new File(nomFichier); tmp.delete(); } catch (UnsupportedEncodingException e) { } catch (IOException e) {} } /** * empàªche le html dans les messages */ public static String noHTML(String s){ return s.replaceAll("<", "<").replaceAll(">", ">"); } /** * Traite les messages privés. * Le propriétaire du bot, identifié par son username * dispose de commandes basiques (join, part, quit, nick) * On pourrait en rajouter (op, protection...) * mais d'autres bots font à§a très bien. * Les autres personnes peuvent publier un billet par pm, * s'ils font parties des personnes autorisées (voir isAllowed(String nick) ) */ public void onPrivateMessage (String sender, String login, String hostname, String message) { boolean me = (hostname.equalsIgnoreCase(owner)); if(me && message.substring(0,5).equalsIgnoreCase("!join")){ joinChannel(message.substring(6)); } else if(me && message.substring(0,5).equalsIgnoreCase("!part")){ partChannel(message.substring(6), "Lost little Robot"); } else if(me && message.substring(0,5).equalsIgnoreCase("!quit")){ quitServer("I knew I was a Robot"); } else if(me && message.substring(0,5).equalsIgnoreCase("!exit")){ quitServer("I knew I was a Robot"); System.exit(0); } else if(me && message.substring(0,5).equalsIgnoreCase("!nick")){ changeNick(message.substring(6)); } else if(me && message.substring(0,6).equalsIgnoreCase("!bored")){ bored(message.substring(7)); } else if (isAllowed(sender)){ uploadQuote(sender, noHTML(message)); sendMessage(sender, confirmationMessage); } } /** * Publie le topic comme un billet sur le blog * sauf si le topic est de sayber */ protected void onTopic(String channel, String topic, String setBy, long date, boolean changed){ if(changed && !setBy.equalsIgnoreCase("sayber") && !setBy.equalsIgnoreCase("X")){ topic = noHTML(topic); topic = "<u>topic</u>: " + topic; uploadQuote(setBy, topic); } } /** * Reconnait les commandes !addurl et !cowsay dans le canal * !addurl http://un_site.com publie http://un_site.com * !cowsay un_message, fait apparaitre ce message dans le canal * prononcé par la fameuse vache ascii */ public void onMessage(String channel, String sender, String login, String hostname, String message) { if (message.length()>=8 && message.substring(0,7).equalsIgnoreCase("!addurl")) { message = noHTML(message); uploadQuote(sender, "<a href=\""+message.substring(8)+"\">"+ message.substring(8)+"</a>"); sendMessage(sender, "Shalmaneser vient de publier votre url merci de votre contribution. Visitez shalmaneser.com"); } if (message.length()>=8 && message.substring(0,7).equalsIgnoreCase("!cowsay")) { String up = " _"; String down = " -"; for(int i=1; i<message.substring(8).length(); i++){ up = up+"_"; down = down +"-"; } sendMessage(channel,up); sendMessage(channel, " < "+ message.substring(8)+" >" ); sendMessage(channel, down); sendMessage(channel, " \\ ^__^"); sendMessage(channel, " \\ (oo)\\_______"); sendMessage(channel, " (__)\\ )\\/\\ "); sendMessage(channel, " ||----w |"); sendMessage(channel, " || ||"); } if (message.length()>=7 && message.substring(0,7).equalsIgnoreCase("!cuivre")) { try{ String s = getDoc("http://bourse.lesechos.fr/bourse/matieres/details_matieres.jsp?Code=GIRM&Place=RMSE-TR&Codif=TSB&Secteur=METAL"); String t = getDoc("http://www.fedem.fr/cours_metaux/cours.php?page=CU&repere=CU_CU&ts=JOURNALIERE&source=TMX&unite=EUR/100kg&titre=Les%20cours%20du%20cuivre&nom_repere=Base+m%E9tal+demi-produits+-+Cuivre&popup="); int i = s.indexOf("<td class=\"TABLEAU-DATA-16\" align=\"center\">"); int j = t.indexOf("€/100kg"); sendMessage(channel, s.substring(i+43,s.indexOf(" €")) + " euros/100kg (CUIVRE (GIRM) - Paris) (les echos)"); sendMessage(channel, t.substring(j+53,j+59)+" euros/100kg (FEDEM)"); }catch(IOException ioe){} } if (message.length()>=6 && message.substring(0,6).equalsIgnoreCase("!ascii")) { try{ this.printDoc("http://www.asciiartfarts.com/today.txt"); }catch(IOException ioe){} } } /** * récupère une page web * retourne une chaine de caractères */ public static String getDoc(String url) throws IOException{ URL u = new URL(url); InputStream in = u.openStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String leDoc = "";String ligne; while (null != (ligne = br.readLine())) leDoc += ligne; return leDoc; } /** * imprime une page web sur le canal * utilisé pour l'ascii art fart du jour */ public void printDoc(String url) throws IOException{ URL u = new URL(url); InputStream in = u.openStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String ligne; while (null != (ligne = br.readLine())){ sendMessage(channel, ligne); } } } </java> == ShalmaneserMain.java == <java>import java.util.*; import java.io.*; public class ShalmaneserMain { public static void main(String[] args) throws Exception { Properties p = new Properties(); p.load(new FileInputStream(new File("config"))); String channel = p.getProperty("channel"); String server = p.getProperty("server"); // Now start our bot up. Shalmaneser bot = new Shalmaneser(); // Enable debugging output. bot.setVerbose(true); // Connect to the IRC server. bot.connect(server); // Join the #arf channel. bot.joinChannel(channel); } }</java> == Changements == * 24/07/07 permalink, switch entre template nerdcore et kikoulol * 25/07/2007 le topic est publié quand il est changé (sauf si c'est sayber), on peut mettre des wikiwords et la syntaxe textile dans les billets (liens). Rejoin et reconnect * 27/07/2007 utilisation d'un fichier de config, création d'un exécutable pour windows et linux * 04/08/2007 ajout des commandes !cuivre et !ascii (cours du cuivre et ascii art fart) ainsi que de !bored (connerie) * 29/10/2007 On passe à autre chose, la source est dispo, il n'y aura pas de nouveaux développements.
Revenir à la page
Shalmaneser
.