Sterowanie genaratorem planów zajęć przy pomocy JSON_RPC v. 1.1 API

Zdalne sterowanie generatorem przy użyciu wywołań RPC (remote procedure call) jest teraz bardzo proste. Aby to zrobić musisz posiadać specjalne konto utworzone przez administratora serwisu. Wymiana danych pomiędzy generatorem a systemem zewnętrznym odbywa się w oparciu o format XSD zdefiniowany pod adresem http://www.school-timetable.eu/t4s_v10.xsd.

Poniżej przykładowy kod używający standardu JSON-RPC w językach Ruby & Java.

Kod w Ruby

require 'rubygems'
require 'cgi'
require 'json'
require 'zlib'
require 'stringio'
require 'json_rpc_client'

class RpcClient < JsonRpcClient
    json_rpc_service 'http://www.planzajec.pl/api'
end

def compress(term)
    zm=StringIO.new
    gz = Zlib::GzipWriter.new(zm)
    gz.write term
    gz.close
    zm.string
end

def decompress(term)
    zr=Zlib::GzipReader.new(StringIO.new(term))
    zr.read
end

def rpctest

# Zalogowanie się do serwisu. Argumenty: wersja, użytkownik, hasło
    ses=RpcClient.login 1,'user','password'
    puts "Session:"+ses


# Uruchomienie generatora
# Argumenty: sesja, plan_id, maxtime[min], base[0,1], find_close[0,1], teacher_gaps_mode, room_mode, room_count_only[0,1], optym_mode, optym_from
# a)teacher_gaps_mode:
# -2: Domyślnie
# -1: Bez znaczenia
# 0: Wybrani nauczyciele - Bez okienek
# 1: Wybrani nauczyciele - Jedno okienko w dniu (jedna godzina)
# 2: Wybrani nauczyciele - Jedna przerwa (np. kilkugodzinna) w dniu
# b) room_mode
# 0: Priorytet:min przejść i pref sala dla klasy,potem dla nauczyciela,pref sala dla przedmiotu">Minimalizuj przejścia klas
# 1: Priorytet:min przejść i pref sala dla nauczyciela,potem dla klasy,pref sala dla przedmiotu">Minimalizuj przejścia nauczycieli
# 2: Priorytet:pref sala dla przedmiotu, potem min przejść i pref sala dla klasy i nauczyciela">Pref sale dla przed,przejść klas
# 3: Priorytet:pref sala dla przedmiotu, potem min przejść i pref sala dla nauczyciela i klasy">Pref sale dla przed,przejść naucz
# 4: Priorytet:pref sala i min przejść dla klasy,potem dla nauczyciela,pref sala dla przedmiotu">Preferowane sale dla klas
# 5: Priorytet:pref sala i min przejść dla nauczyciela,potem dla klasy,pref sala dla przedmiotu">Preferowane sale dla nauczycieli
# 6: Priorytet:pref sala dla przedmiotu, potem pref sala i min przejść dla klasy i nauczyciela" selected>Pref sale dla przed i klas
# 7: Priorytet:pref sala dla przedmiotu, potem pref sala i min przejść dla nauczyciela i klasy">Pref sale dla przed i nauczycieli
# c) optym_mode
# Nie optymalizuj
# Szybka
# Normalna
# Iteracyjnie - duży krok
# Iteracyjnie - mały krok

    str=RpcClient.run ses,697,10,0,1,-2,2,1,1,3
    puts "Timetables:"+str

# Status rozwiązania
# Returns: zatrzymany=>0,zaplanowany=>1,uruchomiony=>2,rozwiazany=>3,sprzecznosc/blad=>4,oczekujący=>5
    str=RpcClient.status ses,697
    puts "Status:"+str

# Zatrzymanie generatora
    str=RpcClient.stop ses,697
    puts "Status:"+str

# Przesłanie danych o planie zajęć na serwer
    timXML=File.read("tim.xml")
    tim_id=RpcClient.putT4s ses,CGI.escape(compress(timXML))
    puts "ID of Timetable:"+tim_id

# Usunięcie planu zajęć
    str=RpcClient.remove ses,712
    puts "Status:"+str

# Lista zapisanych w systemie rozkładów. Przykład: 100, 101, 321,
    str=RpcClient.list ses
    puts "Timetables:"+str

# Odczytanie danych o planie zajęć z rozwiązaniem
    tim_xml=RpcClient.getT4s ses,711
    puts "Timetable XML:"+decompress(CGI.unescape(tim_xml))
end



Kod w Java


import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.io.FileOutputStream;
import java.io.*;
import java.util.zip.*;
import java.io.ByteArrayOutputStream;
import org.codebistro.jsonrpc.Client;
import org.codebistro.jsonrpc.TransportRegistry;

public class TestClient{

  public void test() throws Exception{
    Client client= new Client(TransportRegistry.i().createSession("http://www.planzajec.pl/api"));
    Test tester= client.openProxy("",Test.class);
    String session=tester.login(1,"user","password");
    String ls=tester.list(session);
    ls=tester.run(session,734,10,0,1,-2,2,1,1,3);
    ls=tester.status(session,734);
    ls=tester.stop(session,734);
    ls=tester.status(session,734);
    ls=tester.getT4s(session,734);
    byte[] bt=unescape(ls);
    ls=gzipDecompress(bt);

    BufferedReader fin = new BufferedReader(new FileReader("myTimetable.xml"));

    String tim="";
    String s = fin.readLine();
    while (s != null) {
      tim+=s;
      s = fin.readLine();
    }
    bt=gzipCompress(tim);
    tim=escape(bt);
    System.out.println(tim);
    tester.putT4s(session,tim);
  }

  public static void main(String args[]) throws Exception{
    (new TestClient()).test();
  }

  private byte[] gzipCompress(String from) throws Exception {

    InputStream in = new ByteArrayInputStream( from.getBytes() );

    ByteArrayOutputStream bt=new ByteArrayOutputStream();
    BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(bt));

    int c;
    while ((c = in.read()) != -1) out.write(c);
    in.close();
    out.close();

    return bt.toByteArray();
  }

  private String gzipDecompress(byte[] from) throws Exception {
    BufferedReader in = new BufferedReader(new InputStreamReader(
      new GZIPInputStream(new ByteArrayInputStream(from))));
    String tim="";
    String s = in.readLine();
    while (s != null) {
      tim+=s;
      s = in.readLine();
    }

    return tim;
  }

  private String escape(byte[] bt) throws UnsupportedEncodingException{
    String res="";
    /*def CGI::escape(string)
      string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
        '%' + $1.unpack('H2' * $1.size).join('%').upcase
      end.tr(' ', '+')
    end
    */
    int i=0;
    while (i<bt.length) {
      int code=bt[i];
      if ((code>=97 && code <=122) || (code>=65 && code <=90) || (code>=48 && code <=57) || (code==32) || (code==95) || (code==46) || (code==45)) {
        if (code==32) res+="+";
        else res+=(char)code;
      }
      else {
        res+="%"+String.format("%02X", (byte)code);
      }
      i++;
    }
    return res;
  }

  private byte[] unescape(String str) throws Exception{
    ArrayList al = new ArrayList();

    /*def CGI::unescape(string)
      string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
        [$1.delete('%')].pack('H*')
    end*/
    int i=0;
    while (i<str.length()) {
      if (str.charAt(i)=='%') {
        byte code= (byte)Integer.parseInt(str.substring(i+1,i+3),16);
        al.add(code);
        i+=3;
      }
      else {
        if ((byte)(str.charAt(i))==43) {al.add((byte)32);}
        else {al.add((byte)(str.charAt(i) & 0xFF));}
        i++;     }  
    }
    Byte[] b=new Byte[al.size()];
    b=al.toArray(b);
    byte[] c=new byte[b.length];
    for (int j=0; j<b.length; j++) {
      c[j]=b[j];
    }
    return c;
  }

}


public interface Test {
  String login(int version, String user, String password);
  String list(String session);
  String getT4s(String session, int timId);
  String remove(String session, int timId);
  String stop(String session, int timId);
  String status(String session, int timId);
  String run(String session, int timId, int maxTim, int base, int findClose, int teacherGapsMode, int roomMode, int roomCountOnly, int optymMode, int optymFrom);
  int putT4s(String session, String timXML);
}

Już 4184 użytkowników zarejestrowało się w naszym serwisie.