So I am trying to test this code:
#Test
public void faarFalse() throws IOException {
String filStiTilArrangementer = "src/main/java/gruppeeksamen/arrangementer.csv";
String filStiTilLoggetInn = "../../View/loggetInn.fxml";
ObservableList listeFor = FXCollections.observableArrayList();
dataHandler.hentDataHele(filStiTilArrangementer, listeFor);
navnPaaArrangement = "Test arrangement";
datoPaaArrangement = "2020-10-10";
typeIdrettPaaArrangement = "Ski";
leggTilArrangementController.leggeTilArrangementet(navnPaaArrangement, datoPaaArrangement, typeIdrettPaaArrangement, filStiTilArrangementer, filStiTilLoggetInn); //Line 148 ref. error message
ObservableList listeEtter = FXCollections.observableArrayList();
dataHandler.hentDataHele(filStiTilArrangementer, listeEtter);
assertTrue(listeFor.size() < listeEtter.size());
//fjernet linjen som er lagt til
RandomAccessFile f = new RandomAccessFile(filStiTilArrangementer, "rw");
long length = f.length() - 1;
byte b;
do {
length -= 1;
f.seek(length);
b = f.readByte();
} while(b != 10);
f.setLength(length+1);
f.close();
}
which is testing this code:
public class LeggTilArrangementController {
#FXML
private Button btnGaaTilbake;
public void leggeTilArrangementet(String arrangement, String dato, String idrett, String filstienTilArrangementene, String filstienTilLoggetInn) {
//sjekker om alle "forhåndsregler" er gjort for å kunne legge til et arrangement
if (sjekkOmAlleInputErFyltUt(arrangement, dato, idrett) && sjekkOmdagensDatoErMindreEnnDatePicker(dato) && arrangementPaaSammeDatoIkkeFinnes(arrangement, dato.replace("-","."), idrett)){
//lager en ny linje med navnet på arrangementet, antall utøvere (som fra start skal være 0), utøvere (som fra start skal være tom), datoen (åååå.mm.dd), type idrett
String nyttArrangement = arrangement + ";0"/*antall utøvere*/ + ";" /*utøvere*/ + ";" + dato.replace("-",".") + ";" + idrett + "\n";
//prøver å legge til arrangementet på sisten av arrangementer.csv
try {
FileWriter filenSomSkalSkrivesTil = new FileWriter(filstienTilArrangementene, true);
filenSomSkalSkrivesTil.append(nyttArrangement);
filenSomSkalSkrivesTil.flush();
filenSomSkalSkrivesTil.close();
} catch (IOException e) {
e.printStackTrace();
}
//lukker nåværende vindu
goBack(filstienTilLoggetInn); //Line 76 ref. error message
} else {
MainJavaFX.visAlertFeilmelding("Mangler arrangement, dato eller idrett","Må fylle inn en av delene");
}
}
private void goBack(String filstienTilLoggetInn) {
Stage stage = (Stage) btnGaaTilbake.getScene().getWindow(); //Line 50 ref. error message
stage.close();
DataHandler.sendTilNyScene(filstienTilLoggetInn, "Arrengementer", 500, 500);
}
}
The test is supposed to test if a new line has been wrote to a CSV-file, but when i try to run the test, all I get is this message:
java.lang.NullPointerException
at gruppeeksamen.Controller.LeggTilArrangementController.goBack(LeggTilArrangementController.java:50)
at gruppeeksamen.Controller.LeggTilArrangementController.leggeTilArrangementet(LeggTilArrangementController.java:76)
at gruppeeksamen.Controller.LeggTilArrangementControllerTest.faarFalse(LeggTilArrangementControllerTest.java:148)
Anyone know why I get this error message?
PS: When i delete/comment out line 76 ref. error message, the test works all fine, but then the program won't work.
Looking at the code and line that you have highlighted it could be due to one of two reasons:
btnGaaTilbake.getScene()
Either btnGaaTilbake is null or method getScene() is retuning null. Kindly check both the variables are returning correct values.
Related
I have an inherited project, a BMC Remedy application and never worked with this Remedy stuff. This project modifies Incidents and Work Orders from remedy through the Remedy API. I have literally no idea on this.
There's a process that closes incidents that are in resolved state and have not been modified in the last 36 hours. Sometimes, those incidents have the 'categorization' field empty, and the client wants to fill this categorization before closing it.
This is part of the code:
Connection to Remedy:
public static void main(String args[]) {
// Inicializamos el logger
java.util.logging.LogManager.getLogManager().reset();
try {
// Nos conectamos a Remedy y a MySQL
LOGGER.info("Conectando a bases de datos");
if (!connect()) {
throw new Exception("Fallo al conectar a Remedy o a MySQL");
}
// Metodo para cerrar incidecias resueltas
remedy.cerrarIncidencias(sql.queryResueltas36h());
// Desconectamos de Remedy y MySQL
disconnect();
} catch (Exception e) {
LOGGER.error("Error critico: ", e);
try {
remedy.desconectar();
} catch (Exception e1) {
}
try {
sql.desconectar();
} catch (Exception e1) {
}
}
}
Function to closing incidents:
public void cerrarIncidencias(List<String> incs) throws Exception {
int contador = 1;
for (String inc : incs) {
try {
// Obtenemos la incidencia
QualifierInfo qual = server.parseQualification("HPD:Help Desk", "'Incident Number' = \"" + inc + "\"");
List<Entry> entries = server.getListEntryObjects("HPD:Help Desk", qual, 0, 0, null,
Constantes.CAMPOS_HPD_HELP_DESK_CERRAR_INCIDENCIA, false, null);
// Rellenamos un comentario generico
Entry comment = new Entry();
comment.put(Constantes.HPD_WORKLOG_DETAILED_DESCRIPTION, new Value("Cierre automatico tras 36 horas en resuelto."));
comment.put(Constantes.HPD_WORKLOG_INCIDENT_NUMBER, new Value(inc));
comment.put(Constantes.HPD_WORKLOG_DESCRIPTION, new Value("----"));
comment.put(Constantes.HPD_WORKLOG_WORKLOG_TYPE, new Value(8000));
for (Entry entry : entries) {
entry.put(Constantes.HPD_HELP_DESK_STATUS, new Value(5)); // Estado a cerrado
if (entry.get(Constantes.HPD_HELP_DESK_ASSIGNEE_LOGIN_ID).getValue() == null) {
entry.put(Constantes.HPD_HELP_DESK_ASSIGNEE_LOGIN_ID, new Value("lmoren70"));
entry.put(Constantes.HPD_HELP_DESK_ASSIGNEE, new Value("Luis Manuel Moreno Rodriguez")); // Usuario asignado
}
server.setEntry("HPD:Help Desk", entry.getEntryId(), entry, null, 0);
server.createEntry("HPD:WorkLog", comment);
LOGGER.info("Incidencia " + inc + " cerrada con exito - " + contador + " de " + incs.size());
}
} catch (Exception e) {
LOGGER.error("Incidencia " + inc + " NO se ha podido cerrar - " + contador + " de " + incs.size() + "\n"
+ e.getMessage());
}
contador++;
}
}
Query:
I thought to do an update directly to the database BUT this database reads from Remedy, so I have to update Remedy.
public List<String> queryResueltas36h() {
String query = "SELECT inc FROM vdf_tickets, vdf_groups WHERE status = 'Resuelto' AND LENGTH(inc) > 9 "
+ "AND vdf_groups.group = creator_group AND (vdf_groups.categorization = 'TES' OR vdf_groups.group IN ('TES', 'ARCA', 'NetOps TES Assurance')) "
+ "AND last_resolved_date < DATE_ADD(NOW(), INTERVAL -36 HOUR) ORDER BY inc DESC";
List<String> incs = new ArrayList<String>();
try {
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String inc = rs.getString("inc");
incs.add(inc);
}
stmt.close();
} catch (Exception e) {
LOGGER.error("Error al obtener lista de incidencias de la base de datos", e);
try {
stmt.close();
} catch (Exception e1) {
}
}
return incs;
}
What I want is to put the categorization to 'TES', in case there's no categorization.
One option I thought is to do an automation with Selenium and Python and not touching this code, but is far better to have all in the same project.
Any ideas? Thanks in advance!
You need to update your cerrarIncidencias function. But first you need to ask what categorisation you need to update.
There are three levels of categorisation.
Operational Categorisation
Product Categorisation
Resolution Categorisation
So decide which one you want to populate and get the field id for that field. For this example, I will say
Categorisation Tier 1 which is 1000000063
You'll need to add to CAMPOS_HPD_HELP_DESK_CATEGORISATION_TIER1=1000000063 to your Constantes file.
Then in your block
for (Entry entry : entries)
You need something like:
if (entry.get(Constantes.CAMPOS_HPD_HELP_DESK_CATEGORISATION_TIER1).getValue() == null) {
entry.put(Constantes.CAMPOS_HPD_HELP_DESK_CATEGORISATION_TIER1, new Value("Your Value for Categorisation Tier 1"));
}
I got an error in my quickfixj Application. First, I got an error like this:
Out of order repeating group members
After that, I added this text into my initiator.config:
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
But now I got another error in my application:
quickfix.FieldNotFound: Field was not found in message, field=55
at quickfix.FieldMap.getField(FieldMap.java:223)
at quickfix.FieldMap.getString(FieldMap.java:237)
at com.dxtr.fastmatch.marketdatarequestapps.TestMarketdataRequest.fromApp(TestMarketdataRequest.java:38)
at quickfix.Session.fromCallback(Session.java:1847)
at quickfix.Session.verify(Session.java:1791)
at quickfix.Session.verify(Session.java:1862)
at quickfix.Session.next(Session.java:1047)
at quickfix.Session.next(Session.java:1204)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:163)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:113)
at quickfix.mina.SingleThreadedEventHandlingStrategy.lambda$blockInThread$1(SingleThreadedEventHandlingStrategy.java:145)
at quickfix.mina.SingleThreadedEventHandlingStrategy$ThreadAdapter$RunnableWrapper.run(SingleThreadedEventHandlingStrategy.java:267)
at java.lang.Thread.run(Thread.java:748)
My code for get value of symbols is :
public void fromApp(quickfix.Message message, SessionID sessionID)
throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
try {
String symbol = message.getString(Symbol.FIELD);
System.out.println(" FromApp " + message);
message.getString(TransactTime.FIELD);
// String seqNo = message.getString(MsgSeqNum.FIELD);
double bid = message.getDouble(MDEntryPx.FIELD);
double ask = message.getDouble(MDEntryPx.FIELD);
// System.out.println(seqNo + " " + message);
} catch (FieldNotFound fieldNotFound) {
fieldNotFound.printStackTrace();
}
}
I have also using this code
public void onMessage (MarketDataIncrementalRefresh message, SessionID sessionID) throws FieldNotFound{
try
{
MDReqID mdreqid = new MDReqID();
SendingTime sendingtime = new SendingTime();
NoMDEntries nomdentries = new NoMDEntries();
quickfix.fix42.MarketDataIncrementalRefresh.NoMDEntries group
= new quickfix.fix42.MarketDataIncrementalRefresh.NoMDEntries();
MDUpdateAction mdupdateaction = new MDUpdateAction();
DeleteReason deletereason = new DeleteReason();
MDEntryType mdentrytype = new MDEntryType();
MDEntryID mdentryid = new MDEntryID();
Symbol symbol = new Symbol();
MDEntryOriginator mdentryoriginator = new MDEntryOriginator();
MDEntryPx mdentrypx = new MDEntryPx();
Currency currency = new Currency();
MDEntrySize mdentrysize = new MDEntrySize();
ExpireDate expiredate = new ExpireDate();
ExpireTime expiretime = new ExpireTime();
NumberOfOrders numberoforders = new NumberOfOrders();
MDEntryPositionNo mdentrypositionno = new MDEntryPositionNo();
message.getField(nomdentries);
message.getField(sendingtime);
message.getGroup(1, group);
int list = nomdentries.getValue();
for (int i = 0; i < list; i++)
{
message.getGroup(i + 1, group);
group.get(mdupdateaction);
if (mdupdateaction.getValue() == '2')
System.out.println("Enter");
group.get(deletereason);
group.get(mdentrytype);
group.get(mdentryid);
group.get(symbol);
group.get(mdentryoriginator);
if (mdupdateaction.getValue() == '0')
group.get(mdentrypx);
group.get(currency);
if (mdupdateaction.getValue() == '0')
group.get(mdentrysize);
}
System.out.printf("Got Symbol {0} Price {1}",
symbol.getValue(), mdentrypx.getValue());
}catch (Exception ex)
{
System.out.println("error" + ex);
}
but i also get error like this
quickfix.FieldNotFound: Field was not found in message, field=55
at quickfix.FieldMap.getField(FieldMap.java:223)
at quickfix.FieldMap.getString(FieldMap.java:237)
at com.dxtr.fastmatch.marketdatarequestapps.TestMarketdataRequest.fromApp(TestMarketdataRequest.java:39)
at quickfix.Session.fromCallback(Session.java:1847)
at quickfix.Session.verify(Session.java:1791)
at quickfix.Session.verify(Session.java:1862)
at quickfix.Session.next(Session.java:1047)
at quickfix.Session.next(Session.java:1204)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:163)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:113)
at quickfix.mina.SingleThreadedEventHandlingStrategy.lambda$blockInpacket_write_wait: Connection to 3.13.235.241 port 22: Broken pipe
and here the value i check in my message.log
8=FIX.4.2^A9=0217^A35=X^A34=7291^A49=Fastmatch1^A52=20200401-10:47:59.833^A56=MDValueTrade2UAT1^A262=VT_020^A268=02^A279=2^A55=GBP/CHF^A269=0^A278=1140851192^A270=1.19503^A271=02000000^A279=0^A55=GBP/CHF^A269=0^A278=1140851194^A270=1.19502^A271=06000000^A10=114^A
my broker have send to me the price and etc
My question is: how to fix my problem from this code ?
First, I got an error like this:
Out of order repeating group members
Your data dictionary doesn't match your counterparty's. Fix that and this will go away.
After that, I added this text into my initiator.config:
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
This did not fix anything -- it HIDES your actual problem and has you looking at a new fake problem.
What you need to do:
Your configuration has this, right?
UseDataDictionary=Y
DataDictionary=path/to/FIXnn.xml
# or if FIX5:
AppDataDictionary=path/to/FIX5n.xml
TransportDataDictionary=path/to/FIXT.xml
Find your counterparty's documentation, and make sure your xml file's messages and fields match what they say they're going to send you. Make sure all repeating groups have the same fields in the same order.
Here is some documentation about how the Data Dictionary xml file is structured. It's pretty easy.
I am facing a problem while trying to persist the existing stock in a preproduction environment.
What I am trying to do is actually to loop on a text file and insert substrings from that file into the database.
Here is the class that I execute :
public class RepriseStock {
private static Session session;
public RepriseStock() {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
}
public static int insererPartenaires(String sCurrentLine, int i) {
String sql = "INSERT INTO PARTENAIRE(ID,"
+ "MVTSOC,"
+ " MVTAGR, "
+ "MVTNOMSOC,"
+ "MVTCPTTMAG,"
+ "DATEAGREMENT,"
+ "MVTCHAINE,"
+ "MVTRGPT,"
+ "MVTUNION,"
+ "MVTNOMMAG,"
+ "MVTTELSOC,"
+ "MVTADRMAG,"
+ "MVTVILMAG,"
+ "MVTMAIL,"
+ "MVTSITU)"
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
Query query = session.createSQLQuery(sql);
query.setInteger(0, i);
query.setInteger(1, Integer.parseInt(sCurrentLine.substring(0, 3)));
query.setInteger(2, Integer.parseInt(sCurrentLine.substring(3, 10)));
query.setString(3, sCurrentLine.substring(10, 34));
query.setInteger(4, Integer.parseInt(sCurrentLine.substring(48, 53)));
query.setString(5, sCurrentLine.substring(77, 83));
query.setInteger(6, Integer.parseInt(sCurrentLine.substring(86, 90)));
query.setInteger(7, Integer.parseInt(sCurrentLine.substring(90, 94)));
// union
query.setInteger(8, Integer.parseInt(sCurrentLine.substring(94, 98)));
// enseigne 30
query.setString(9, sCurrentLine.substring(248, 278));
// tel
query.setString(10, sCurrentLine.substring(278, 293));
// adresse
query.setString(11, sCurrentLine.substring(293, 323));
// ville
query.setString(12, sCurrentLine.substring(323, 348));
// mail
query.setString(13, sCurrentLine.substring(398, 448));
// situ
query.setString(14, sCurrentLine.substring(449, 452));
return query.executeUpdate();
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Module de remplacement de méthode auto-généré
BufferedReader br = null;
RepriseStock rs = new RepriseStock();
try {
String sCurrentLine;
br = new BufferedReader(
new FileReader(
"C:\\Users\\test\\Desktop\\test\\reprise de stock\\nouveauFichierPREPROD.dat"));
int i = 0;
sCurrentLine = br.readLine();
while ((sCurrentLine = br.readLine()) != null) {
i++;
RepriseStock.insererPartenaires(sCurrentLine, i);
System.out.println("Nombre de fois : " + i);
}
System.out.println("total (" + i + " )");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
After the script is executed, i have the total of loops is 1022 times. But the data is not persisted into oracle table (Partenaire)
My log doesn't display any error.
Do you see the issue ?
It looks like you're not committing the transaction.
If you want each update to be a separate transaction, try moving session.beginTransaction(); to the beginning of the insererPartenaires method and capturing the Transaction object returned from that statement in a variable. Then, after each update, make sure to call commit() on the Transaction object.
If you want all of the updates to be the same transaction, move the beginTransaction() and commit() methods to surround the while loop in the main method.
Also just note that you're unnecessarily mixing static and non-static here. Try changing public static int insererPartenaires(String sCurrentLine, int i) to public int insererPartenaires(String sCurrentLine, int i). Then just use the instantiated RepriseStock object to call the method instead of invoking it statically.
You'll also need to change private static Session session to be private Session session
I'm trying to use and understand AntLR, this is new to me. My purpose is to read a source code file written in C and extract from it the identifiers (variables and function names).
In my C grammar (file C.g4) consider:
identifierList
: Identifier
| identifierList Comma Identifier
;
Identifier
: IdentifierNondigit
( IdentifierNondigit
| Digit
)*
;
After generation of parser and listener I create my own listener to the identifierList.
Note that MyCListener class extends CBaseListener:
public class MyCListener extends CBaseListener {
#Override
public void enterIdentifierList(CParser.IdentifierListContext ctx) {
List<ParseTree> children = ctx.children;
for (ParseTree parseTree : children) {
System.out.println(parseTree.getText());
}
}
Then I have this in main class:
String fileurl = "C:/example.c";
CLexer lexer;
try {
lexer = new CLexer(new ANTLRFileStream(fileurl));
CommonTokenStream tokens = new CommonTokenStream(lexer);
CParser parser = new CParser(tokens);
CParser.IdentifierListContext identifierContext = parser.identifierList();
ParseTreeWalker walker = new ParseTreeWalker();
MyCListener listener = new MyCListener();
walker.walk(listener, identifierContext);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
Where example.c is:
int main() {
// this is C
int i=0; // i is int
/* double j=0.0;
C
*/
}
What am I doing wrong?
Maybe I didn't write MyCListener properly, or identifierList is not what I need to listen... Really don't know. I'm sorry, but I didn't even understand my output, why is there a lexical error?:
line 3:4 mismatched input '(' expecting {<EOF>, ','}
main
(
)
{
int
i
=
0
;
}
As you see, I'm very confused about this. Can somebody help me ? Please...
With this line:
CParser.IdentifierListContext identifierContext = parser.identifierList();
you're trying to parse your entire input as an identifierList. But your input isn't just that.
Assuming you're using the C.g4 from the ANTLR4 Github repository, try to let the parser start at the entry point of the grammar (which is the rule compilationUnit):
MyCListener listener = new MyCListener();
ParseTreeWalker.DEFAULT.walk(listener, parser.compilationUnit());
EDIT
Here's a quick demo:
public class Main {
public static void main(String[] args) throws Exception {
final List<String> identifiers = new ArrayList<String>();
String source = "int main() {\n" +
"\n" +
"// this is C\n" +
"\n" +
" int i=0; // i is int\n" +
" /* double j=0.0;\n" +
" C\n" +
" */\n" +
"}";
CLexer lexer = new CLexer(new ANTLRInputStream(source));
CParser parser = new CParser(new CommonTokenStream(lexer));
ParseTreeWalker.DEFAULT.walk(new CBaseListener(){
#Override
public void enterDirectDeclarator(#NotNull CParser.DirectDeclaratorContext ctx) {
if (ctx.Identifier() != null) {
identifiers.add(ctx.Identifier().getText());
}
}
// Perhaps override other rules that use `Identifier`
}, parser.compilationUnit());
System.out.println("identifiers -> " + identifiers);
}
}
which would print:
identifiers -> [main, i]
I am trying to read IRC and pull data from individual IRC messages in Processing. You can see the code (also with twitter library, ignore that) and I need some pointers on how I can pull the data out in the format of Nick:Message so it can be displayed in a visualization.
//Twitter
import twitter4j.conf.*;
import twitter4j.*;
import twitter4j.auth.*;
import twitter4j.api.*;
import java.util.*;
// Import the net libraries
import processing.net.*;
// Declare a client
Client client;
Twitter twitter;
String searchString = "god";
List<Status> tweets;
String server = "irc.twitch.tv";
String nick = "NugShow";
//String user = "simple_bot";
int port = 6667;
String channel = "#nugshow";
String password = "xx";
String in = "butt";
String checkFor;
//bools
Boolean isLive = false;
int privMsgIndex;
int atIndex;
String playerSubstring;
// The channel which the bot will joString channel = "#irchacks";
int currentTweet;
void setup()
{
size(800,600);
frameRate(60);
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("xx");
cb.setOAuthConsumerSecret("xx");
cb.setOAuthAccessToken("xx");
cb.setOAuthAccessTokenSecret("xx");
TwitterFactory tf = new TwitterFactory(cb.build());
twitter = tf.getInstance();
getNewTweets();
currentTweet = 0;
thread("refreshTweets");
thread("loopChat");
connectToServer();
//IRC
}
void draw()
{
if (client.available() > 0) {
String in = client.readString();
println(in);
}
if (isLive == false){
if (client.available() > 0) {
}
} else {
}
/*
fill(0, 40);
rect(0, 0, width, height);
currentTweet = currentTweet + 1;
if (currentTweet >= tweets.size())
{
currentTweet = 0;
}
Status status = tweets.get(currentTweet);
fill(200);
text(status.getText(), random(width), random(height), 300, 200);
delay(100);
*/
}
void joinChannel() {
String in = client.readString();
client.write( "JOIN " + channel + "\n\r" );
client.clear();
in = client.readString();
println(in);
if (in != null){
//println("Recieved data");
println(in);
//String inString = myClient.readStringUntil("");
isLive = true;
println(isLive);
}
}
void connectToServer()
{
client = new Client(this, server , 6667);
client.write( "PASS " + password + "\n\r" );
println(password + " sent!");
client.write( "NICK " + nick + "\n\r" );
println(nick + " sent!");
joinChannel();
}
void getNewTweets()
{
try
{
Query query = new Query(searchString);
QueryResult result = twitter.search(query);
tweets = result.getTweets();
}
catch (TwitterException te)
{
System.out.println("Failed to search tweets: " + te.getMessage());
System.exit(-1);
}
}
void refreshTweets()
{
while (true)
{
getNewTweets();
println("Updated Tweets");
delay(30000);
}
}
void loopChat()
{
while (true)
{
if (privMsgIndex != 0){
println(privMsgIndex);
//privMsgIndex = privMsgIndex - 15;
atIndex = in.indexOf("#");
println(atIndex);
//atIndex = atIndex + 1;
playerSubstring = in.substring(atIndex, privMsgIndex);
println(playerSubstring);
} else {
println("looped");
}
delay(300);
client.clear();
in = null;
}
}
void keyPressed()
{
}
void tweet()
{
try
{
Status status = twitter.updateStatus("This is a tweet sent from Processing!");
System.out.println("Status updated to [" + status.getText() + "].");
}
catch (TwitterException te)
{
System.out.println("Error: "+ te.getMessage());
}
}
The chat commands look like this: :nugshow!nugshow#nugshow.testserver.local PRIVMSG #nugshow :dddd where nugshow is the username, #nugshow is the channel, and dddd is the message. I need to get it into the format of nugshow: dddd.
there is a lot of header information that I'm not sure how to strip out of client.recieved buffer as well, it looks like this:
:testserver.local 001 nugshow :Welcome, GLHF!
:testserver.local 002 nugshow :Your host is testserver.local
:testserver.local 003 nugshow :This server is rather new
:testserver.local 004 nugshow :-
:testserver.local 375 nugshow :-
:testserver.local 372 nugshow :You are in a maze of twisty passages, all alike.
:testserver.local 376 nugshow :>
:nugshow!nugshow#nugshow.testserver.local JOIN #nugshow
:nugshow.testserver.local 353 nugshow = #nugshow :nugshow
:nugshow.testserver.local 366 nugshow #nugshow :End of /NAMES list
:jtv!jtv#jtv.testserver.local PRIVMSG nugshow :HISTORYEND nugshow
I would not recommend regex here. At least not if you want to be able to catch all types of IRC messages. The key is to look at the message code to know what you can actually get out of the message. As I'm also writing an IRC-client (just for giggles) I have some notes for you.
Be sure to answer any PINGs that the server sends you so you don't get kicked off. As the PING is sent with an identifier, you need to catch that and send it back. A simple way to do this is to check the last line that was sent from the server and substring it.
String line = inputStream.readLine();
if(line.substring(0,4).equals("PING")){
send("PONG " + line.substring(5)); // Assume you have some send-function.
}
This will make sure you don't get kicked off and can proceed to actually stay on a server.
As I mentioned, I do not recommend using regex for this as it would become a RegEx-of-doom. So, what I have done is to just split the line you get and put all the results in a String array.
String[] arr = line.split(" ");
As you know by your own message line you have posted, the IRC protocol separates things with spaces. So splitting at spaces in not all that shabby (we'll get how to deal with actual text in a bit).
The basic structure that is always the same (as far as I can tell) in messages is PREFIX COMMAND PARAM PARAM/TRAILING. So what does this mean? The PREFIX is where the message was sent from. Example ":user!user#host.com". The COMMAND is what the line actually is. You are looking for PRIVMSG here, but there are many, many, others that you might want to take care of. Like JOIN, PART, QUIT, 332 (current topic), 353 (nicks in channel, 404 (unable to send to channel), etc. etc. The PARAM and PARAM/TRAILING will all depend on the COMMAND.
So, what do we gain from splitting at spaces? This:
arr[0] = :user!user#host.com
arr[1] = COMMAND
arr[2] = PARAM
arr[3 onwards] = rest
We can now easily manage every command in it's own needed way.
Without further delay, lets get to your actual question, the PRIVMSG.
I will use this string: ":Chewtoy!chewtoy#stackoverflow.com PRIVMSG #stackoverflow :Ty: I saw your question and thought I should give you an answer."
After doing a split at the spaces, we get the array
arr[0] = :Chewtoy!chewtoy#stackoverflow.com
arr[1] = PRIVMSG
arr[2] = #stackoverflow
arr[3] = :Ty:
arr[4] = I
arr[5] = saw
...
As you can see, everything from 3 and onwards is the message you want. 0-2 is stuff that you need to be able to know who sent what where. My code for getting all this looks like this:
String[] arr = receivedLine.split(" ");
if(arr[1].equals("PRIVMSG")){
String[] usr = arr[0].split(!"); // Get the user, which is in usr[0]. Host in usr[1]
StringBuilder msg = new StringBuilder();
for(int i=3; i<arr.length; i++){ // We know the message starts at arr[3], so start counting from that.
msg.append(arr[i] + " ");
}
String chan = "";
if(arr[2].substring(0,1).equals("#")){ // We need to differentiate between sending to channel and sending a PM. The only difference in this is where the text is sent.
chan = arr[2];
} else{
chan = usr[0].substring(1); // substring(1) because we want Chewtoy, not :Chewtoy
}
// The result here will be:
// <#stackoverflow> Chewtoy: Ty: I saw your question and thought I should give you an answer.
sendItAllToWhereYouWantIt("<" + chan +"> " + usr[0].substring(1) + ": " + msg.substring(1));
}
Hope that helps.