summaryrefslogtreecommitdiff
path: root/src/main/groovy/org/xapek/yvesf/classifieds/Main.groovy
blob: 67b20676d08c10846bcd7f2ae4cf12a01d4e23e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package org.xapek.yvesf.classifieds

import groovy.json.JsonSlurper
import groovy.transform.CompileStatic
import groovyx.net.http.HTTPBuilder
import org.apache.http.HttpResponse
import org.xapek.yvesf.classifieds.util.Failable

import static org.xapek.yvesf.classifieds.util.ParserStaticMethods.*

@CompileStatic
final class Main {
  private final static JsonSlurper jsonParser = new JsonSlurper()

  private final static url = 'http://www.glocals.com/classifieds/housing-and-real-estate/&get_classified_flats'

  static void main(String[] args) {
    final data = handleData(
        args.length == 1 ?
            readInputStream(new FileInputStream(args[0])) : readNetwork());
    if (data.isSuccess()) {
      Dumper.dump(data.getValue(), new PrintWriter(System.out));
      System.exit(0);
    } else {
      System.out.println("Failed: " + data.errorTrace.join(' -> '))
      System.exit(1);
    }
  }

  static Object readInputStream(InputStream is) {
    return jsonParser.parse(is)
  }

  static Object readNetwork() {
    final http = new HTTPBuilder(url)
    http.post(
        body: ['start': '20', 'limit': '20', 'form[bl_city_network]': '-1'],
        headers: ['User-Agent': 'Mozilla/5.0 Firefox/3.0.4',
                  'Accept'    : 'application/json']) { HttpResponse resp ->
      assert resp.statusLine.statusCode < 300 && resp.statusLine.statusCode >= 200:
          "HTTP Request failed with status code ${resp.statusLine.statusCode}"
      return jsonParser.parse(resp.entity.content)
    } as Object
  }

  static Failable<Model.ClassifiedsList> handleData(Object object) {
    ifType(object, Map) then { Map m ->
      ifField(m, 'totalCount', Number) then { Number totalCount ->
        ifField(m, 'classifieds', List) then { List rawClassifieds ->
          all(rawClassifieds.collect { handleClassified(it) }) then { List<Model.Classified> classifieds ->
            final classifiedList = new Model.ClassifiedsList(totalCount: totalCount)
            classifiedList.addAll(classifieds)
            success(classifiedList)
          }
        }
      }
    }
  }

  private static Failable<Model.Classified> handleClassified(Object p) {
    ifType(p, Map) then { Map map ->
      try {
        return success(new Model.Classified(map))
      } catch (Exception e) {
        return fail("type=${e.class}: ${e.message}") as Failable<Model.Classified>
      }
    }
  }
}