pokeplot 0.2.0beta

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/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # Pokeplot
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/pokeplot.svg)](https://badge.fury.io/rb/pokeplot) [![Test Coverage](https://codeclimate.com/github/xssc/pokeplot/badges/coverage.svg)](https://codeclimate.com/github/xssc/pokeplot/coverage) [![Dependency Status](https://gemnasium.com/badges/github.com/xssc/pokeplot.svg)](https://gemnasium.com/github.com/xssc/pokeplot) [![Gem](https://img.shields.io/gem/dt/pokeplot.svg?maxAge=2592000)](https://rubygems.org/gems/pokeplot)
4
+
5
+ Pokeplot is a gem to collect Pokemon Go spawning data and visualize it. It is currently a pre-release, expect frequent updates.
6
+
7
+ ![Graph Example](http://i.imgur.com/XRp14KV.png)
8
+
9
+ ### Contents
10
+
11
+ [**Getting Started**](https://github.com/xssc/pokeplot#getting-started)
12
+
13
+ [**Usage**](https://github.com/xssc/pokeplot#usage)
14
+
15
+ [**Features**](https://github.com/xssc/pokeplot#features)
16
+
17
+ [**Notifications**](https://github.com/xssc/pokeplot#notifications)
18
+
19
+ [**Updating**](https://github.com/xssc/pokeplot#updating)
20
+
21
+ [**Future and TODO**](https://github.com/xssc/pokeplot#future--todo)
22
+
23
+ [**Contanct, Requests, and Issues**](https://github.com/xssc/pokeplot#contact-requests-and-issues)
24
+
25
+ [**Contributing**](https://github.com/xssc/pokeplot#contributing)
26
+
27
+ ## Getting Started
28
+
29
+ Installing pokeplot is insanley easy. All you need is ruby 2.3.1. Don't have it? [Follow our easy Ruby install guide!](https://github.com/xssc/pokeplot/wiki/Install-Ruby-2.3.1)
30
+
31
+ We use MongoDB to quickly store large numbers of encounters. Download and install it from [HERE](https://www.mongodb.com/download-center?jmp=nav#community). Don't worry, it's easy!
32
+
33
+ Once done the only installation command is:
34
+
35
+ $ gem install pokeplot --pre
36
+
37
+ ## Usage
38
+
39
+ Open a terminal/cmd and make a folder for Pokeplot configuration to be stored
40
+
41
+ $ mkdir pokeplot
42
+ $ cd pokeplot
43
+
44
+ Then to generate the default config.json file, run
45
+
46
+ $ pokeplot config
47
+
48
+ Then go to the pokeplot folder you just made and open config.json in your favorite text editor. There are `_info` lines to help you along the way.
49
+
50
+ Then simply run
51
+
52
+ $ pokeplot
53
+
54
+ Real time graphs will be available at `http://localhost:5001` while pokeplot is running.
55
+
56
+ ## Features
57
+ * Single or Multithread
58
+ * Divides coordinates in a way that doesn't cause larger teleportations due to more accounts
59
+ * Multiple accounts (Combo lists also supported)
60
+ * Configurable config.json
61
+ * Real time website with graphs
62
+ * Ability to handle real time data yourslef with Ruby (Examples soon)
63
+ * Notifications
64
+ * A developer who has tons of freetime to work on this project!
65
+
66
+
67
+ ## Notifications
68
+
69
+ Currently Pokeplt only supports Pushbullet. [Follow the easy setup guide here](https://github.com/xssc/pokeplot/wiki/Pushbullet)
70
+
71
+
72
+ ## Updating
73
+
74
+ When a update is available for pokeplot, only one command is needed to install it
75
+
76
+ $ gem update pokeplot
77
+
78
+ Pokeplot will be updated frequently, I have lots of spare time.
79
+
80
+ ## Future & TODO
81
+ The following is planned (but not guarenteed)
82
+
83
+ * Maps
84
+ * More graphs
85
+ * Get Cell Ids in Ruby
86
+ * Add more notification services
87
+ * Fix any issues that arrise
88
+ * Lots more
89
+
90
+ ## Contact, Requests, and Issues
91
+ If you have any problems using this, I will do whatever I can to help you get up and running. Your options are
92
+
93
+ * Create an issue [HERE](https://github.com/xssc/pokeplot/issues)
94
+ * Email me @ xssc820@gmail.com
95
+ * Or PM me on reddit at [/u/xssc](https://www.reddit.com/message/compose?to=xssc)
96
+
97
+ ## Contributing
98
+
99
+ Bug reports and pull requests are welcome on GitHub at https://github.com/xssc/pokeplot
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
7
+ rescue LoadError
8
+ # no rspec available
9
+ end
data/bin/pokeplot ADDED
@@ -0,0 +1,223 @@
1
+ #!usr/bin/env ruby
2
+ require 'pokeplot'
3
+ require 'json'
4
+
5
+
6
+ default_config = %{ {
7
+ "_info": "Enter your accounts here, as many as you want",
8
+ "accounts": [
9
+ {
10
+ "username": "account1",
11
+ "password": "password1",
12
+ "provider": "ptc"
13
+ },
14
+ {
15
+ "username": "account2@gmail.com",
16
+ "password": "password2",
17
+ "provider": "google"
18
+ }
19
+ ],
20
+
21
+ "_info": "Enter the origin scan coordinates below [lat, lng]",
22
+ "location": [
23
+ 40.7829,
24
+ -73.9654
25
+ ],
26
+
27
+ "_info": "settings for API",
28
+ "api": {
29
+ "encryption_path": "/path/to/encryption/file",
30
+ "log": true
31
+ },
32
+
33
+ "_info": "settings for mongoDB (default host is already set)",
34
+ "mongo": {
35
+ "host": "127.0.0.1:27017"
36
+ },
37
+
38
+ "_info": "settings for the data miner",
39
+ "miner": {
40
+ "enabled": true,
41
+ "threaded": true,
42
+ "range": 40,
43
+ "interval": 900,
44
+ "pokemon": true,
45
+ "forts": true,
46
+ "log": true
47
+ },
48
+
49
+ "_info": "Pushbullet settings - see the wiki for easy set-up guide",
50
+ "pushbullet": {
51
+ "enabled": false,
52
+ "api_key": "apiKey",
53
+ "pokemon": [
54
+ "SNORLAX",
55
+ "DRATINI",
56
+ "DRAGONITE",
57
+ "MEWTWO"
58
+ ]
59
+ },
60
+
61
+ "_info": "settings for socket for real time webpage updates RECOMENDED YOU DONT CHANGE THIS",
62
+ "socket": {
63
+ "enabled": true,
64
+ "host": "0.0.0.0",
65
+ "port": "9090",
66
+ "log": true
67
+ },
68
+
69
+ "_info": "Web server settings",
70
+ "webserver": {
71
+ "enabled": true,
72
+ "host": "0.0.0.0",
73
+ "port": 5001
74
+ },
75
+
76
+ "_info": "optional ptc account combo list",
77
+ "combos": [
78
+ "SToCQSyJuVXj:BGyoYefXjQQZ",
79
+ "hdOMuITMabLF:kscSpsGGzBxu",
80
+ "vMpPCulIYkcT:GBbUdGlstxeW",
81
+ "FZmcNpLdbxha:CurAriesqPFZ",
82
+ "wVkKQBGmYJXK:XmZoKXLfvNvU",
83
+ "vgsqGbfVeawM:QhzXnffDjgAt",
84
+ "dJdUmaNsvuMC:HsHytSfNyvnS",
85
+ "UPmlEpbNFGYk:tZJMwBeDRAMs",
86
+ "xcxcPjUKRPal:iFCBrsSjHFRF",
87
+ "dldjzYhsQbLz:oaQaggnrVIjK",
88
+ "gZEekjgrBQCK:vUWhIaEHAclX",
89
+ "wLOToXHcLJBZ:RNIoYdwvDFTH",
90
+ "tBOjNYBHIJIo:CTqmQaCWaRRT",
91
+ "pbAGNZsvGnMC:TVWLsmdRRJjG",
92
+ "cneIEKBIGevh:CnFKUkBDJECj",
93
+ "WworruNrwycr:gYzkXQnHyPxy",
94
+ "YtbiVCtnYCIQ:jiBNmgTBWTBw",
95
+ "rwmUhrHCbWGW:gKdPdvUzbXEB",
96
+ "kdgqEBIsKMhO:rvESvQkNQtGs",
97
+ "PssVOTYjurWz:gSMXWHoFkvPq",
98
+ "kHlinSczQEim:rqFePFPryvUe",
99
+ "AIAVmolzTbQJ:mxvWoSJNrNRC",
100
+ "iBESkcpbrIdY:KQnQTqClDykQ",
101
+ "AXwyjTgvYIfn:vINTlbsjdtCx",
102
+ "yuHRAgIfVWTZ:VTTnyPBZSojM",
103
+ "nFrgKgQLzrRe:ooplsOvhQNFQ",
104
+ "iRFsCpCMUlte:koKrBewFLMxo",
105
+ "pOqWlFdPGYEl:gkhKikkcwpmh",
106
+ "NByvaUQkNchO:nPmVzbMPtXWY",
107
+ "RftfDbyWXmSe:wYLELjKLjkIJ",
108
+ "gLJMMYXGJibG:AnHNRvNmSkuA",
109
+ "zBCKrZlciUiV:SZJdvkMSkgRT",
110
+ "TyqcusJxatgm:EqKtdTEybJpz",
111
+ "fDDaoMvaOMOs:bmcEVoNcKyJC",
112
+ "dEgUOTTPOQpQ:elCgIExqkWOp",
113
+ "ZjZZftPIHKVj:gHzweZzDICAA",
114
+ "XuinqBhqynbE:PDfXbdSBkoJV",
115
+ "eYPkNTSSRngF:EShbqUEutCqQ",
116
+ "PvmFqqXdRnwG:IhDzJDSknest",
117
+ "CvbgGcNdKumE:gzmlCjYgybpZ",
118
+ "FiHNyzzpKmOs:tbIXrdCecmlB",
119
+ "dUsdcfxGJAlf:NTWKivTOeABd",
120
+ "BvVqSybVGuoD:xhCgeXTtsFST",
121
+ "GamYBkRElCCY:CFRHRROHlsrY",
122
+ "zeGrfdhyrtfY:AwSFrczizYsZ",
123
+ "bivTEnLISOyR:DQLoKikEWJON",
124
+ "FWMGCfVJcJjV:IJFxXGDqhDRK",
125
+ "yqDulLursWuk:CKieNAUmgcZM",
126
+ "TeXIZDsXBEJJ:gQSevIHOVxrd",
127
+ "iYgqvHkNlGjJ:WbSYJNhlJxbZ"
128
+ ]
129
+
130
+
131
+ }
132
+ }
133
+
134
+
135
+ if ARGV[0] == 'config'
136
+ File.open('config.json', 'w+') do |f|
137
+ f.puts default_config
138
+ puts "[+] config.json made, you can now edit it"
139
+ exit
140
+ end
141
+ end
142
+
143
+
144
+
145
+
146
+
147
+ begin
148
+ $conf = JSON.parse(File.read("config.json"))
149
+ rescue Exception
150
+ puts "[-] Something went wrong loading your config.json file"
151
+ exit
152
+ end
153
+
154
+ #Make ctrl+c exit whole script
155
+ trap "INT" do
156
+ Thread.list.each do |thread|
157
+ thread.exit unless thread == Thread.current
158
+ end
159
+ exit
160
+ end
161
+
162
+ #get rid of annoying messages
163
+ ouput_manager = StringIO.new
164
+ $stdout = ouput_manager
165
+ $stderr = ouput_manager
166
+
167
+ module Kernel
168
+ def puts(msg)
169
+ #if msg[0] == "["
170
+ ::STDOUT.printf(msg + "\n")
171
+ #end
172
+ end
173
+ end
174
+
175
+
176
+ module Pokeplot
177
+ include Database
178
+
179
+ Database.mongo_host = $conf["mongo"]["host"]
180
+
181
+ #Socket and notifications must come before miner to capture its database requests
182
+ if $conf["socket"]["enabled"]
183
+ s = Socket.new($conf["socket"]["host"], $conf["socket"]["port"], $conf["socket"]["log"])
184
+ Database.mongo_monitor(s)
185
+ end
186
+
187
+ if $conf["pushbullet"]["enabled"]
188
+ pb = Pushbullet.new($conf["pushbullet"]["api_key"], $conf["pushbullet"]["pokemon"])
189
+ Database.mongo_monitor(pb)
190
+ end
191
+
192
+ if $conf['combos'].is_a?(Array) && $conf['combos'].count > 0
193
+ $conf['combos'].each do |c|
194
+ c = c.split(':')
195
+ $conf['accounts'] << {'username' => c[0], 'password' => c[1], 'provider' => 'ptc'}
196
+ end
197
+ end
198
+
199
+
200
+ if $conf["miner"]["enabled"]
201
+ miner = Miner.new($conf['accounts'], $conf['location'][0], $conf['location'][1], $conf['miner']['range'], $conf['miner']['interval'], $conf['miner']['pokemon'], $conf['miner']['forts'], $conf['miner']['threaded'], $conf['api']['encryption_path'], $conf['miner']['log'], $conf['api']['log'])
202
+ miner.start
203
+ end
204
+
205
+ if $conf["webserver"]["enabled"]
206
+ web = Thread.new do
207
+ Web.config($conf["webserver"]["host"], $conf["webserver"]["port"])
208
+ Web.run!
209
+ end
210
+ end
211
+
212
+ # Join thread so it doesnt exit script
213
+ if miner.is_a?(Miner) && miner.miner.is_a?(Thread)
214
+ puts "[+] Joining thread"
215
+ miner.miner.join
216
+ end
217
+
218
+ if web && web.is_a?(Thread)
219
+ puts "[+] Joining thread"
220
+ web.join
221
+ end
222
+
223
+ end
@@ -0,0 +1,109 @@
1
+ require 'poke-api'
2
+ require 'pokeplot/helpers/cell_ids'
3
+
4
+ module Pokeplot
5
+ class API
6
+
7
+ def initialize(lat, lng, encryption, logging = true)
8
+ Poke::API::Logging.log_level = :FATAL
9
+ @api = Poke::API::Client.new
10
+ set_location(lat, lng)
11
+ @encryption = encryption
12
+ @logging = logging
13
+ end
14
+
15
+ def login(username, password, provider)
16
+ puts "[+] Logging in #{username} with #{provider}" if @logging
17
+ loop do
18
+ begin
19
+ @username = username
20
+ @password = password
21
+ @provider = provider
22
+ @api.login(username, password, provider)
23
+ @api.activate_signature(@encryption)
24
+ basic_request
25
+ break
26
+ rescue Poke::API::Errors::UnknownProtoFault
27
+
28
+ puts "[-] Login for #{username} failed, retrying in 5 seconds" if @logging
29
+ sleep(5)
30
+ end
31
+ end
32
+ end
33
+
34
+ def map_heartbeat
35
+
36
+ loop do
37
+ @api.get_player
38
+ @api.get_hatched_eggs
39
+ @api.get_inventory(last_timestamp_ms: (Time.now.to_f * 1000).to_i)
40
+ @api.check_awarded_badges
41
+ @api.download_settings(hash: "05daf51635c82611d1aac95c0b051d3ec088a930")
42
+
43
+ cell_ids = Helpers::CellIds.get(@api.lat, @api.lng)
44
+ @api.get_map_objects(
45
+ latitude: lat,
46
+ longitude: lng,
47
+ since_timestamp_ms: [0] * cell_ids.count,
48
+ cell_id: cell_ids
49
+ )
50
+
51
+ begin
52
+ response = @api.call.response
53
+ rescue StandardError
54
+ puts "[-] Error.. Re-logging in" if @logging
55
+ login(@username, @password, @provider)
56
+ next
57
+ end
58
+
59
+ case response[:status_code]
60
+ when 1
61
+ return response
62
+ when 2
63
+ puts "[-] Error... Retrying..." if @logging
64
+ basic_request
65
+ when 102
66
+ puts "[-] Error, re-logging in" if @logging
67
+ login(@username, @password, @provider)
68
+ else
69
+ puts "[-] Heartbeat error: status code #{response[:status_code]}" if @logging
70
+ puts "[+] Retrying in 2 seconds..." if @logging
71
+ sleep(2)
72
+ end
73
+ end
74
+ end
75
+
76
+ def set_location(latitude, longitude)
77
+ @api.lat = latitude
78
+ @api.lng = longitude
79
+ end
80
+
81
+ def lat
82
+ return @api.lat
83
+ end
84
+
85
+ def lng
86
+ return @api.lng
87
+ end
88
+
89
+ def lat=(lat)
90
+ @api.lat = lat
91
+ end
92
+
93
+ def lng=(lng)
94
+ @api.lng = lng
95
+ end
96
+
97
+
98
+ private
99
+
100
+ def basic_request
101
+ @api.get_player
102
+ @api.get_hatched_eggs
103
+ @api.get_inventory
104
+ @api.check_awarded_badges
105
+ @api.call
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,22 @@
1
+ require 'mongo'
2
+
3
+ module Pokeplot
4
+ module Database
5
+
6
+ @@mongo_host = '127.0.0.1:27017'
7
+
8
+ def self.mongo
9
+ Mongo::Logger.level = Logger::FATAL
10
+ return Mongo::Client.new([ @@mongo_host ], :database => 'pokeplot')
11
+ end
12
+
13
+ def self.mongo_host=(host)
14
+ @@mongo_host = host
15
+ end
16
+
17
+ def self.mongo_monitor(class_instance)
18
+ Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::COMMAND, class_instance)
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ class Array; def in_groups(num_groups)
2
+ return [] if num_groups == 0
3
+ slice_size = (self.size/Float(num_groups)).ceil
4
+ self.each_slice(slice_size).to_a
5
+ end; end
@@ -0,0 +1,14 @@
1
+ require 'poke-api/helpers'
2
+ module Pokeplot
3
+ module Helpers
4
+ class CellIds
5
+ class << self
6
+
7
+ def get(lat, long)
8
+ return ::Poke::API::Helpers.get_cells(lat, long)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module Pokeplot
2
+ module Helpers
3
+ class Math
4
+ class << self
5
+
6
+ def deg_to_rad(deg)
7
+ return deg * (::Math::PI / 180)
8
+ end
9
+
10
+ def get_earth_radius(lat)
11
+ earth_radius_max = 6378137.0
12
+ earth_radius_min = 6356752.3
13
+ latrad = deg_to_rad(lat)
14
+ return (1.0/(((::Math.cos(latrad))/earth_radius_max)**(2) + ((::Math.sin(latrad))/earth_radius_min)**(2)))**(1.0/2)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Pokeplot
2
+ module Helpers
3
+ class Time
4
+ class << self
5
+
6
+ def to_s(seconds)
7
+ m = (seconds / 60).floor
8
+ s = seconds % 60
9
+ return "#{m} minutes and #{s} seconds"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end