ifin24-client 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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