ifin24-client 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -13,7 +13,8 @@ begin
13
13
  gem.homepage = "http://github.com/lucassus/ifin24-client"
14
14
  gem.authors = ["Łukasz Bandzarewicz"]
15
15
 
16
- gem.add_development_dependency "rspec", ">= 1.2.9"
16
+ gem.add_development_dependency "rspec"
17
+ gem.add_development_dependency "mocha"
17
18
 
18
19
  gem.add_dependency "mechanize"
19
20
  gem.add_dependency "highline"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 1.0.0
data/bin/ifin24 CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # encoding: utf-8
2
3
 
3
4
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
5
 
@@ -11,6 +12,9 @@ require 'ostruct'
11
12
 
12
13
  require 'ifin24'
13
14
 
15
+ class LoginError < StandardError
16
+ end
17
+
14
18
  class App
15
19
 
16
20
  def initialize(arguments)
@@ -23,44 +27,49 @@ class App
23
27
  end
24
28
 
25
29
  def run
26
- parse_options
30
+ parse_options!
27
31
 
28
32
  config = Ifin24::Configuration.instance
29
33
  login = @options.login || config[:login]
30
34
  password = @options.password || config[:password]
31
- client = Ifin24::Client.new(login, password)
32
35
 
33
- if client.logged?
36
+ begin
37
+ client = Ifin24::Client.new(login, password)
38
+ client.login or raise LoginError
39
+
34
40
  console = Ifin24::Console.new(client)
35
41
  console.main_menu
36
- else
37
- puts "Bad login or password."
42
+ rescue LoginError
43
+ puts "Zły login lub hasło."
44
+
45
+ login = ask('Login: ')
46
+ password = ask('Password: ') do |q|
47
+ q.echo = '*'
48
+ end
49
+
50
+ retry
38
51
  end
39
52
  end
40
53
 
41
54
  protected
42
55
 
43
- def parse_options
44
- # Specify options
56
+ def parse_options!
45
57
  opts = OptionParser.new
58
+
46
59
  opts.set_summary_indent(' ')
47
60
  script_name = File.basename($0)
48
- opts.banner = "Usage: #{script_name} [OPTIONS]"
49
- opts.define_head "Abstract description of script"
50
-
51
- opts.separator ""
52
- opts.separator "Mandatory arguments to long options are mandatory for short options too."
53
- opts.separator ""
61
+ opts.banner = "Użycie #{script_name} [OPCJE]"
62
+ opts.define_head "Konsola do iFIN24"
54
63
 
55
- opts.on("-l", "--login", "User login") do |login|
64
+ opts.on("-l", "--login", "Login użytkownika") do |login|
56
65
  @options.login = login
57
66
  end
58
67
 
59
- opts.on("-p", "--password", "User password") do |password|
68
+ opts.on("-p", "--password", "Hasło użytkownika") do |password|
60
69
  @options.password = password
61
70
  end
62
71
 
63
- opts.on_tail("-h", "--help", "Show this help message.") do
72
+ opts.on_tail("-h", "--help", "Wyświetla pomoc") do
64
73
  puts opts
65
74
  exit
66
75
  end
@@ -1,3 +1,2 @@
1
1
  :login: ifin24_console
2
2
  :password: ifin24_console
3
-
@@ -1,13 +1,23 @@
1
+ require 'mechanize'
2
+
1
3
  class Ifin24::Client
2
4
 
3
5
  LOGIN_FORM_URL = 'https://www.ifin24.pl/logowanie'
4
6
  ENTRY_FORM_URL = 'https://www.ifin24.pl/zarzadzanie-finansami/transakcje/dodaj-wydatek'
7
+
5
8
  LIST_URL = 'https://www.ifin24.pl/zarzadzanie-finansami/transakcje/lista'
6
- LIST_PAGE_PARAM = '?pageNumber='
9
+ LIMITS_URL = 'https://www.ifin24.pl/zarzadzanie-finansami/kontrola-wydatkow'
7
10
 
8
11
  def initialize(login, password)
9
- @agent = Mechanize.new
10
- login(login, password)
12
+ @login, @password = login, password
13
+ end
14
+
15
+ def agent
16
+ @agent ||= Mechanize.new
17
+ end
18
+
19
+ def agent=(agent)
20
+ @agent = agent
11
21
  end
12
22
 
13
23
  def categories
@@ -19,7 +29,7 @@ class Ifin24::Client
19
29
  end
20
30
 
21
31
  def send_entry(entry)
22
- page = @agent.get(ENTRY_FORM_URL)
32
+ page = agent.get(ENTRY_FORM_URL)
23
33
  form = page.forms.first
24
34
 
25
35
  form['entry.title'] = entry.title.to_s
@@ -34,7 +44,7 @@ class Ifin24::Client
34
44
  end
35
45
 
36
46
  def fetch_entries(curr_page = 1)
37
- page = @agent.get(LIST_URL + LIST_PAGE_PARAM + curr_page.to_s)
47
+ page = agent.get("#{LIST_URL}?pageNumber=#{curr_page}")
38
48
  total_pages = extract_entries_total_pages(page)
39
49
  entry_row_elements = page.search('table tbody tr')
40
50
 
@@ -67,25 +77,53 @@ class Ifin24::Client
67
77
  return entries, total_pages
68
78
  end
69
79
 
70
- def logged?
71
- @logged
72
- end
80
+ def fetch_limits
81
+ page = agent.get(LIMITS_URL)
73
82
 
74
- private
83
+ limits = []
84
+
85
+ table = page.search('table#expenses-tracking-limits tbody')
86
+ table.search('tr').each do |tr|
87
+ limit = Ifin24::Models::Limit.new
88
+ columns = tr.search('td')
89
+
90
+ name_column = columns[0]
91
+ limit.name = name_column.text.strip
92
+
93
+ amounts_column = columns[2]
94
+ match = amounts_column.text.strip.match(/^(?<amount>\d+,\d+) PLN z (?<max>\d+,\d+) PLN$/)
95
+ if match
96
+ limit.amount = sanitize_price(match['amount'])
97
+ limit.max = sanitize_price(match['max'])
98
+ end
75
99
 
76
- def login(login, password)
77
- page = @agent.get(LOGIN_FORM_URL)
100
+ limits << limit
101
+ end
102
+
103
+ return limits
104
+ end
105
+
106
+ def login
107
+ page = agent.get(LOGIN_FORM_URL)
78
108
  form = page.forms.first
79
109
 
80
- form['login'] = login
81
- form['password'] = password
110
+ form['login'] = @login
111
+ form['password'] = @password
82
112
 
83
113
  page = form.submit
84
114
  @logged = page.forms.first.nil?
115
+
116
+ return logged?
85
117
  end
86
118
 
119
+ def logged?
120
+ @logged
121
+ end
122
+
123
+ private
124
+
87
125
  def fetch_categories
88
- page = @agent.get(ENTRY_FORM_URL)
126
+ page = agent.get(ENTRY_FORM_URL)
89
127
  categories_element = page.search('ul.expenseCombo>li')
90
128
 
91
129
  categories = []
@@ -112,7 +150,7 @@ class Ifin24::Client
112
150
  end
113
151
 
114
152
  def fetch_accounts
115
- page = @agent.get(ENTRY_FORM_URL)
153
+ page = agent.get(ENTRY_FORM_URL)
116
154
  accounts_element = page.search('ul#bankAccountCombo>li')
117
155
 
118
156
  accounts = []
@@ -127,10 +165,14 @@ class Ifin24::Client
127
165
  return accounts
128
166
  end
129
167
 
130
- # TODO implement
131
168
  def extract_entries_total_pages(page)
132
- # page.search('div.pager a')
133
- 3
169
+ links = page.search('div.pager a')
170
+ return links[-2].text.to_i
171
+ end
172
+
173
+ def sanitize_price(price)
174
+ return 0.0 if price.nil?
175
+ return price.strip.gsub(',', '.').to_f
134
176
  end
135
177
 
136
178
  end
@@ -4,5 +4,6 @@ module Ifin24::Commands
4
4
  autoload :AddExpense, 'ifin24/commands/add_expense'
5
5
  autoload :ListAccounts, 'ifin24/commands/list_accounts'
6
6
  autoload :ListEntries, 'ifin24/commands/list_entries'
7
+ autoload :ListLimits, 'ifin24/commands/list_limits'
7
8
 
8
9
  end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ class Ifin24::Commands::ListLimits < Ifin24::Commands::Base
4
+ BAR_SIZE = 50
5
+
6
+ def execute
7
+ limits = @client.fetch_limits
8
+ limits.each do |limit|
9
+ widest_name_size = limits.map { |l| l.name }.inject(0) { |max, name| name.size >= max ? name.size : max }
10
+ name = limit.name.ljust(widest_name_size)
11
+ limit_bar = make_limit_bar(limit.amount, limit.max)
12
+ amount = "#{limit.amount}zł z #{limit.max}zł"
13
+
14
+ puts "#{name} #{limit_bar} #{amount}"
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def make_limit_bar(amount, max)
21
+ amount = [amount, max].min
22
+ taken = ((amount / max) * BAR_SIZE).to_i
23
+
24
+ bar = "["
25
+ taken.times do
26
+ bar << "#"
27
+ end
28
+
29
+ (BAR_SIZE - taken).times do
30
+ bar << "."
31
+ end
32
+ bar << "]"
33
+
34
+ return bar
35
+ end
36
+
37
+ end
@@ -4,14 +4,15 @@ require 'yaml'
4
4
  class Ifin24::Configuration
5
5
  include Singleton
6
6
 
7
+ CONFIG_FILE_NAME = File.join(ENV['HOME'], '.ifin24-client', 'config.yml')
8
+
7
9
  attr_reader :config
8
10
 
9
11
  def initialize
10
12
  @config = {}
11
13
 
12
- config_file_name = File.join(ENV['HOME'], '.ifin24-client', 'config.yml')
13
- if File.exist?(config_file_name)
14
- @config = YAML.load_file(config_file_name) rescue {}
14
+ if File.exist?(CONFIG_FILE_NAME)
15
+ @config = YAML.load_file(CONFIG_FILE_NAME) rescue {}
15
16
  end
16
17
  end
17
18
 
@@ -17,6 +17,7 @@ class Ifin24::Console
17
17
  menu.choice("Dodaj wydatek") { add_expense }
18
18
  menu.choice("Lista kont") { list_accounts }
19
19
  menu.choice("Lista ostatnich transakcji") { list_entries }
20
+ menu.choice("Kontrola wydatków") { list_limits }
20
21
 
21
22
  menu.choice("Koniec") { throw :exit }
22
23
  end
@@ -36,6 +37,10 @@ class Ifin24::Console
36
37
  execute_command(Ifin24::Commands::ListEntries)
37
38
  end
38
39
 
40
+ def list_limits
41
+ execute_command(Ifin24::Commands::ListLimits)
42
+ end
43
+
39
44
  private
40
45
 
41
46
  def execute_command(command)
@@ -4,5 +4,6 @@ module Ifin24::Models
4
4
  autoload :Account, 'ifin24/models/account'
5
5
  autoload :Category, 'ifin24/models/category'
6
6
  autoload :Entry, 'ifin24/models/entry'
7
+ autoload :Limit, 'ifin24/models/limit'
7
8
 
8
9
  end
@@ -0,0 +1,13 @@
1
+ class Ifin24::Models::Limit < Ifin24::Models::Base
2
+
3
+ attr_accessor :name
4
+ attr_accessor :amount
5
+ attr_accessor :max
6
+
7
+ def initialize(attributes = {})
8
+ super(attributes)
9
+ @amount ||= 0
10
+ @max ||= 0
11
+ end
12
+
13
+ end
@@ -0,0 +1,278 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <title>iFIN24 - Zarządzanie finansami osobistymi</title>
5
+
6
+ <style type="text/css" media="all">@import "/c/s.css?200912211724";</style>
7
+ <style type="text/css" media="all">@import "/c/jquery.datepick.css?200912211724";</style>
8
+
9
+ <script type="text/javascript" src="/js/jquery-1.3.2.min.js?200912211724"></script>
10
+ <script type="text/javascript" src="/js/jquery.form.js?200912211724"></script>
11
+ <script type="text/javascript" src="/js/jqModal.js?200912211724"></script>
12
+
13
+ <script type="text/javascript" src="/js/jquery.datepick.pack.js?200912211724"></script>
14
+ <script type="text/javascript" src="/js/jquery.datepick-pl.js?200912211724"></script>
15
+ <script type="text/javascript" src="/js/ifin.common.js?200912211724"></script>
16
+ <script type="text/javascript" src="/js/ifin.modal.js?200912211724"></script>
17
+ <script type="text/javascript" src="/js/ifin.combo.js?200912211724"></script>
18
+ <script type="text/javascript" src="/js/ifin.entlist.js?200912211724"></script>
19
+
20
+ <script type="text/javascript" src="/js/swfobject.js?200912211724"></script>
21
+
22
+ <meta name="description" content="iFIN24 - wygodny i bezpieczny serwis do zarządzania finansami osobistymi. Kontroluj wydatki, oszczędzaj i inwestuj!" />
23
+ <meta name="keywords" content="budżet domowy, domowe finanse, jak inwestować, finanse osobiste, oszczędzanie, jak oszczędzać, kontrola wydatków, planowanie wydatków, porady finansowe" />
24
+ <meta name="language" content="pl" />
25
+ <meta name="robots" content="all" />
26
+ <meta name="siteinfo" content="/c/robots.txt" />
27
+ <meta name="page-topic" content="budżet domowy, domowe finanse, jak inwestować, finanse osobiste" />
28
+ <meta name="author" content="iFIN24 S.A." />
29
+ <meta name="publisher" content="iFIN24 S.A." />
30
+ <meta name="reply-to" content="helpdesk@ifin24.pl" />
31
+ <meta name="copyright" content="Copyright (c) iFIN24 S.A. - www.ifin24.pl" />
32
+ <meta name="revisit-after" content="5 days" />
33
+ <meta name="audience" content="all" />
34
+ <meta name="rating" content="general" />
35
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
36
+ <meta http-equiv="content-style-type" content="text/css" />
37
+ <meta http-equiv="content-script-type" content="text/javascript" />
38
+ <meta http-equiv="pragma" content="private" />
39
+ <meta http-equiv="imagetoolbar" content="no" />
40
+
41
+
42
+ <meta http-equiv="Cache-Control" content="no-cache, no-store, max-age=0, must-revalidate" />
43
+
44
+ <meta name="MSSmartTagsPreventParsing" content="true" />
45
+ <meta name='DC.title' content="iFIN24 S.A." />
46
+
47
+ <link rel="Shortcut Icon" href="/c/favicon.ico" type="image/x-icon" />
48
+ <!--[if IE 7]>
49
+ <style type="text/css">
50
+ select {margin-top:2px}
51
+ .ddcb, .datepick-trigger, .c form.filter button {margin-top:1px}
52
+ </style>
53
+ <![endif]-->
54
+ </head>
55
+
56
+
57
+ <body>
58
+ <div id="w"> <div id="mh">
59
+ <h1><a id="h-logo" href="/" title="Strona główna">iFIN24</a></h1>
60
+ <div id="h-spacer"></div>
61
+ <ul id="h-options"> <li><a href="/wyloguj" title="Wyloguj" class="logout">Wyloguj: lucassus</a></li>
62
+
63
+ <li><a href="/zarzadzanie-finansami/ustawienia/profil-uzytkownika" title="Przejdź do ustawień iFIN24" class="settings">Ustawienia</a></li>
64
+ <li><a href="/faq" title="Pomoc użytkownika" class="help">FAQ</a></li>
65
+ <li><a href="/zarzadzanie-finansami/zglos-problem" title="Pomoc użytkownika" class="report showModal">Zgłoś problem</a></li>
66
+ </ul>
67
+ <ul id="h-navigation">
68
+ <li id="hn-finance"><a href="/" title="Zarządzanie finansami osobistymi" class="active">Zarządzanie Finasami</a></li>
69
+ <li id="hn-guides"><a href="http://porady.ifin24.pl" title="Porady finansowe">Porady</a></li>
70
+ <li id="hn-blogs"><a href="http://blogi.ifin24.pl" title="Blogi iFIN24">Blogi</a></li>
71
+
72
+ </ul>
73
+ </div> <div id="mn" class="finance">
74
+ <a href="/zarzadzanie-finansami" title="Przejdź do strony głównej" class="icon main-page">Strona główna</a>
75
+ <a href="/zarzadzanie-finansami/rachunki/gotowka/lista" title="Rachunki" class="icon accounts">Rachunki</a>
76
+ <a href="/zarzadzanie-finansami/kontrola-wydatkow" title="Kontrola wydatków" class="icon expense-tracking">Kontrola wydatków</a>
77
+ <a href="/zarzadzanie-finansami/transakcje/import/wczytaj-plik" title="Importuj transakcje" class="icon import-entries">Importuj transakcje</a>
78
+ <a href="/zarzadzanie-finansami/transakcje/dodaj-przychod" title="Dodaj przychód" class="icon add-income showModal">Dodaj przychód</a>
79
+
80
+ <a href="/zarzadzanie-finansami/transakcje/dodaj-wydatek" title="Dodaj wydatek" class="icon add-expense showModal">Dodaj wydatek</a>
81
+ <a href="/zarzadzanie-finansami/transakcje/lista" title="Lista transakcji" class="icon transactions">Lista transakcji</a>
82
+ <a href="/zarzadzanie-finansami/planer/zaplanuj-przychod" title="Zaplanuj przychód" class="icon plan-income showModal">Zaplanuj przychód</a>
83
+ <a href="/zarzadzanie-finansami/planer/zaplanuj-wydatek" title="Zaplanuj wydatek" class="icon plan-expense showModal">Zaplanuj wydatek</a>
84
+ <a href="/zarzadzanie-finansami/planer/lista-planow" title="Lista planów" class="icon plan-list">Lista planów</a>
85
+ <a href="/zarzadzanie-finansami/raporty/struktura-wydatkow-wykres" title="Pokaż raporty" class="icon reports">Raporty</a>
86
+
87
+ </div>
88
+
89
+ <div id="mc" class="c expenses-tracking">
90
+ <h1>Kontrola wydatków</h1>
91
+ <div id="mcm">
92
+ <div class="date-scroll"><a class="left" title="Poprzedni miesiąc" href="/zarzadzanie-finansami/kontrola-wydatkow?data=2010-07">
93
+ </a><span>sierpień 2010</span>
94
+ <a class="right" title="Następny miesiąc" href="/zarzadzanie-finansami/kontrola-wydatkow?data=2010-09"></a></div>
95
+ <ul>
96
+
97
+ <li>
98
+ <h2>W tym miesiącu możesz zaoszczędzić: <em class="red">-2 545,12 PLN</em></h2><br />
99
+ <div id="ch-expenses-tracking-summary"></div>
100
+ <div class="summary-label">
101
+ <p>przychód:<br />
102
+ <span class="amount green">236,27 <em>PLN</em></span>
103
+
104
+ </p>
105
+ </div>
106
+ <ul>
107
+ <li>
108
+ <div class="accomplished"></div>
109
+ <span>Wydatki zrealizowane</span>
110
+ <span class="amount float-right red">2 316,39 <em>PLN</em></span>
111
+
112
+ </li>
113
+ <li>
114
+ <div class="planned"></div>
115
+ <span>Wydatki zaplanowane niezrealizowane</span>
116
+ <span class="amount float-right red">465,00 <em>PLN</em></span>
117
+ </li>
118
+ </ul>
119
+
120
+ </li>
121
+ <br />
122
+ <li>
123
+ <h2 style="border-bottom:0">Limity na twoich wydatkach</h2>
124
+ <table id="expenses-tracking-limits">
125
+ <colgroup>
126
+ <col class="name" />
127
+ <col class="chart" />
128
+
129
+ <col class="amount" />
130
+ <col class="action" />
131
+ <col class="action" />
132
+ </colgroup>
133
+ <tbody>
134
+ <tr>
135
+ <td>Kursy i szkolenia</td>
136
+ <td><div id="ch-expenses-tracking-limits0"></div></td>
137
+
138
+ <td class="amount">0,00 <em>PLN</em> z 200,00 <em>PLN</em></td>
139
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3009">Edytuj</a></div></td>
140
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3009">Usuń</a></div></td>
141
+ </tr>
142
+ <tr>
143
+
144
+ <td>Zajęcia sportowe</td>
145
+ <td><div id="ch-expenses-tracking-limits1"></div></td>
146
+ <td class="amount">0,00 <em>PLN</em> z 100,00 <em>PLN</em></td>
147
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3120">Edytuj</a></div></td>
148
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3120">Usuń</a></div></td>
149
+
150
+ </tr>
151
+ <tr>
152
+ <td>Wynajem</td>
153
+ <td><div id="ch-expenses-tracking-limits2"></div></td>
154
+ <td class="amount">670,00 <em>PLN</em> z 800,00 <em>PLN</em></td>
155
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3294">Edytuj</a></div></td>
156
+
157
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3294">Usuń</a></div></td>
158
+ </tr>
159
+ <tr>
160
+ <td>Spłata kredytu</td>
161
+ <td><div id="ch-expenses-tracking-limits3"></div></td>
162
+ <td class="amount">342,27 <em>PLN</em> z 700,00 <em>PLN</em></td>
163
+
164
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3020">Edytuj</a></div></td>
165
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3020">Usuń</a></div></td>
166
+ </tr>
167
+ <tr>
168
+ <td>Wyjście do klubu/Impreza</td>
169
+ <td><div id="ch-expenses-tracking-limits4"></div></td>
170
+ <td class="amount"><span class="red">291,00 <em>PLN</em></span> z 200,00 <em>PLN</em></td>
171
+
172
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3047">Edytuj</a></div></td>
173
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3047">Usuń</a></div></td>
174
+ </tr>
175
+ <tr>
176
+ <td>Stołówka/ posiłki poza domem</td>
177
+ <td><div id="ch-expenses-tracking-limits5"></div></td>
178
+ <td class="amount"><span class="red">278,49 <em>PLN</em></span> z 200,00 <em>PLN</em></td>
179
+
180
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=2959">Edytuj</a></div></td>
181
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="2959">Usuń</a></div></td>
182
+ </tr>
183
+ <tr>
184
+ <td>Żywność</td>
185
+ <td><div id="ch-expenses-tracking-limits6"></div></td>
186
+ <td class="amount">166,15 <em>PLN</em> z 500,00 <em>PLN</em></td>
187
+
188
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3107">Edytuj</a></div></td>
189
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3107">Usuń</a></div></td>
190
+ </tr>
191
+ <tr>
192
+ <td>Opłaty bankowe</td>
193
+ <td><div id="ch-expenses-tracking-limits7"></div></td>
194
+ <td class="amount">6,50 <em>PLN</em> z 20,00 <em>PLN</em></td>
195
+
196
+ <td><div><a class="link-edit showModal" title="Edytuj" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/edytuj?id=3317">Edytuj</a></div></td>
197
+ <td class="last"><div><a class="link-remove" title="Usuń" href="#" rel="3317">Usuń</a></div></td>
198
+ </tr>
199
+ </tbody>
200
+ </table>
201
+ <form id="removeLimit" method="POST" action="/zarzadzanie-finansami/kontrola-wydatkow/limit/usun">
202
+ <input type="hidden" name="id" />
203
+ <input type="hidden" name="action" value="deleteLimitAction" />
204
+
205
+ <input type="hidden" name="data" value="2010-08" />
206
+ <div class="c modal confirmModal ask">
207
+ <a href="#" class="closeModal">&nbsp;</a>
208
+ <h1>Usuwanie limitu</h1>
209
+ <div class="confirm">
210
+ <h2>Czy chcesz usunąć wybrany limit?</h2>
211
+ <p>&nbsp;</p>
212
+ <div class="buttons">
213
+
214
+ <input type="submit" value="Usuń" class="confirmOk" />
215
+ <input type="button" value="Anuluj" class="bleft" />
216
+ </div>
217
+ </div>
218
+ </div>
219
+ </form>
220
+ <hr />
221
+ <a class="link-add showModal" href="/zarzadzanie-finansami/kontrola-wydatkow/limit/dodaj" title="Dodaj limit">Dodaj limit</a>
222
+
223
+ </li>
224
+ </ul>
225
+ </div>
226
+ <hr class="bottom" />
227
+ </div>
228
+
229
+ <script type="text/javascript">
230
+ $().ready(function() {
231
+ $('#removeLimit').bindSingleSubmit('.link-remove');
232
+ $('#ch-expenses-tracking-summary').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><background><color>EBF4F9</color><alpha>100</alpha></background><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><grid><category><alpha>0</alpha></category><value><alpha>0</alpha></value></grid><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width><balloon_text>{title}: {value} PLN</balloon_text></column><angle>0</angle><graphs><graph gid="0"><title>Wydatki zrealizowane</title><color>50859B</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Wydatki zaplanowane</title><color>95C7DC</color><visible_in_legend>0</visible_in_legend></graph><graph gid="2"><title>Oszczędności</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">2316.39</value></graph><graph gid="1"><value xid="0">465.00</value></graph><graph gid="2"><value xid="0">0.00</value></graph></graphs></chart>', '700', '44');
233
+ $('#ch-expenses-tracking-limits0').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">0.0</value></graph><graph gid="1"><value xid="0">200.0</value></graph></graphs></chart>', '350', '21');
234
+ $('#ch-expenses-tracking-limits1').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">0.0</value></graph><graph gid="1"><value xid="0">100.0</value></graph></graphs></chart>', '350', '21');
235
+ $('#ch-expenses-tracking-limits2').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">670.0</value></graph><graph gid="1"><value xid="0">130.0</value></graph></graphs></chart>', '350', '21');
236
+ $('#ch-expenses-tracking-limits3').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">342.27</value></graph><graph gid="1"><value xid="0">357.73</value></graph></graphs></chart>', '350', '21');
237
+ $('#ch-expenses-tracking-limits4').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value color="B61616" xid="0">291.0</value></graph><graph gid="1"><value color="B61616" xid="0">0.0</value></graph></graphs></chart>', '350', '21');
238
+ $('#ch-expenses-tracking-limits5').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value color="B61616" xid="0">278.49</value></graph><graph gid="1"><value color="B61616" xid="0">0.0</value></graph></graphs></chart>', '350', '21');
239
+ $('#ch-expenses-tracking-limits6').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">166.15</value></graph><graph gid="1"><value xid="0">333.85</value></graph></graphs></chart>', '350', '21');
240
+ $('#ch-expenses-tracking-limits7').ifnShowColumnChart('<settings><digits_after_decimal>2</digits_after_decimal><type>bar</type><font>segoe ui,tahoma,arial,helvetica,sans-serif</font><plot_area><margins><left>0</left><right>0</right><top>0</top><bottom>0</bottom></margins></plot_area><axes><category><alpha>0</alpha></category><value><alpha>0</alpha></value></axes><values><category><enabled>0</enabled></category><value><enabled>0</enabled><min>0</min></value></values><balloon><enabled>0</enabled></balloon><legend><enabled>0</enabled></legend><column><type>100% stacked</type><width>100</width></column><angle>0</angle><graphs><graph gid="0"><title>Zrealizowane</title><color>75AC03</color><visible_in_legend>0</visible_in_legend></graph><graph gid="1"><title>Pozostało</title><color>EBF4F9</color><visible_in_legend>0</visible_in_legend></graph></graphs></settings>', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chart><series><value xid="0"/></series><graphs><graph gid="0"><value xid="0">6.5</value></graph><graph gid="1"><value xid="0">13.5</value></graph></graphs></chart>', '350', '21');
241
+ });
242
+ </script>
243
+
244
+
245
+ <div id="mf">
246
+ <ul id="f-links">
247
+ <li><a href="/regulamin" title="Regulamin korzystania z serwisu iFIN24">Regulamin</a></li>
248
+
249
+ <li><a href="/o-serwisie" title="Informacje o serwisie">O serwisie</a></li>
250
+ <li><a href="/funkcjonalnosci" title="Dowiedz się więcej o funkcjonalnościach iFIN24">Co oferuje iFIN24?</a></li>
251
+ <li><a href="/bezpieczenstwo" title="Dowiedz się więcej o bezpieczeństwie serwisu iFIN24">Bezpieczeństwo</a></li>
252
+ <li><a href="/polityka-prywatnosci" title="Polityka prywatności iFIN24">Polityka prywatności</a></li>
253
+ <li><a href="http://centrumprasowe.ifin24.pl" title="Informacje dla mediów">Centrum prasowe</a></li>
254
+ <li><a href="/kontakt" title="Masz uwagi? Napisz do nas">Kontakt</a></li>
255
+
256
+ </ul>
257
+
258
+ <div id="f-logo"></div>
259
+ <ul id="f-legal">
260
+ <li>Copyright &copy; 2009 iFIN24 <span><a href="http://modulus.eu/" rel="external">interface design: MODULUS</a></span></li>
261
+ </ul>
262
+ </div>
263
+ <!-- GA -->
264
+
265
+ <script type="text/javascript">
266
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." :
267
+ "http://www.");
268
+ document.write(unescape("%3Cscript src='" + gaJsHost +
269
+ "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
270
+ </script>
271
+ <script type="text/javascript">
272
+ try {
273
+ var pageTracker = _gat._getTracker("UA-8470249-1");
274
+ pageTracker._trackPageview();
275
+ } catch(err) {}</script>
276
+ </div>
277
+ </body>
278
+ </html>
@@ -1,7 +1,68 @@
1
+ # encoding: utf-8
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
 
3
- describe "Ifin24Client" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
5
+ describe "Ifin24::Client" do
6
+ include MechanizeTestHelper
7
+
8
+ it "should fetch account limits" do
9
+ client = Ifin24::Client.new('login', 'password')
10
+ agent = client.agent
11
+
12
+ page = fake_page(load_html_fixture('list_limits.html'), agent)
13
+ agent.expects(:get).with(Ifin24::Client::LIMITS_URL).returns(page)
14
+ limits = client.fetch_limits
15
+
16
+ limits.class.should == Array
17
+ limits.size.should == 8
18
+
19
+ limit = limits.shift
20
+ limit.should_not == nil
21
+ limit.name.should == 'Kursy i szkolenia'
22
+ limit.amount.should == 0
23
+ limit.max.should == 200
24
+
25
+ limit = limits.shift
26
+ limit.should_not == nil
27
+ limit.name.should == 'Zajęcia sportowe'
28
+ limit.amount.should == 0
29
+ limit.max.should == 100
30
+
31
+ limit = limits.shift
32
+ limit.should_not == nil
33
+ limit.name.should == 'Wynajem'
34
+ limit.amount.should == 670
35
+ limit.max.should == 800
36
+
37
+ limit = limits.shift
38
+ limit.should_not == nil
39
+ limit.name.should == 'Spłata kredytu'
40
+ limit.amount.should == 342.27
41
+ limit.max.should == 700
42
+
43
+ limit = limits.shift
44
+ limit.should_not == nil
45
+ limit.name.should == 'Wyjście do klubu/Impreza'
46
+ limit.amount.should == 291
47
+ limit.max.should == 200
48
+
49
+ limit = limits.shift
50
+ limit.should_not == nil
51
+ limit.name.should == 'Stołówka/ posiłki poza domem'
52
+ limit.amount.should == 278.49
53
+ limit.max.should == 200
54
+
55
+ limit = limits.shift
56
+ limit.should_not == nil
57
+ limit.name.should == 'Żywność'
58
+ limit.amount.should == 166.15
59
+ limit.max.should == 500
60
+
61
+ limit = limits.shift
62
+ limit.should_not == nil
63
+ limit.name.should == 'Opłaty bankowe'
64
+ limit.amount.should == 6.50
65
+ limit.max.should == 20
6
66
  end
67
+
7
68
  end
@@ -3,7 +3,26 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'ifin24'
4
4
  require 'spec'
5
5
  require 'spec/autorun'
6
+ require 'mocha'
7
+
8
+ require 'mechanize'
6
9
 
7
10
  Spec::Runner.configure do |config|
8
11
 
9
12
  end
13
+
14
+ module MechanizeTestHelper
15
+
16
+ def fake_page(html, agent)
17
+ html_response = { 'content-type' => 'text/html' }
18
+ page = Mechanize::Page.new(nil, html_response, html, 200, agent)
19
+
20
+ return page
21
+ end
22
+
23
+ def load_html_fixture(file_name)
24
+ html = File.read(File.join(File.dirname(__FILE__), 'fixtures', file_name))
25
+ return html
26
+ end
27
+
28
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ifin24-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
- - 0
8
7
  - 1
9
- - 2
10
- version: 0.1.2
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "\xC5\x81ukasz Bandzarewicz"
@@ -26,16 +26,14 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 13
29
+ hash: 3
30
30
  segments:
31
- - 1
32
- - 2
33
- - 9
34
- version: 1.2.9
31
+ - 0
32
+ version: "0"
35
33
  type: :development
36
34
  version_requirements: *id001
37
35
  - !ruby/object:Gem::Dependency
38
- name: mechanize
36
+ name: mocha
39
37
  prerelease: false
40
38
  requirement: &id002 !ruby/object:Gem::Requirement
41
39
  none: false
@@ -46,10 +44,10 @@ dependencies:
46
44
  segments:
47
45
  - 0
48
46
  version: "0"
49
- type: :runtime
47
+ type: :development
50
48
  version_requirements: *id002
51
49
  - !ruby/object:Gem::Dependency
52
- name: highline
50
+ name: mechanize
53
51
  prerelease: false
54
52
  requirement: &id003 !ruby/object:Gem::Requirement
55
53
  none: false
@@ -62,6 +60,20 @@ dependencies:
62
60
  version: "0"
63
61
  type: :runtime
64
62
  version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: highline
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
65
77
  description: Console for iFIN24
66
78
  email: lucassus@gmail.com
67
79
  executables:
@@ -89,6 +101,7 @@ files:
89
101
  - lib/ifin24/commands/base.rb
90
102
  - lib/ifin24/commands/list_accounts.rb
91
103
  - lib/ifin24/commands/list_entries.rb
104
+ - lib/ifin24/commands/list_limits.rb
92
105
  - lib/ifin24/configuration.rb
93
106
  - lib/ifin24/console.rb
94
107
  - lib/ifin24/helpers.rb
@@ -98,6 +111,8 @@ files:
98
111
  - lib/ifin24/models/base.rb
99
112
  - lib/ifin24/models/category.rb
100
113
  - lib/ifin24/models/entry.rb
114
+ - lib/ifin24/models/limit.rb
115
+ - spec/fixtures/list_limits.html
101
116
  - spec/ifin24-client_spec.rb
102
117
  - spec/spec.opts
103
118
  - spec/spec_helper.rb