Skip to content

Commit 820e724

Browse files
committed
updates
1 parent 22839f9 commit 820e724

7 files changed

+383
-64
lines changed

Diff for: burgerbot.rb

+62-55
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,63 @@
22

33
# modified from https://gist.github.com/pbock/3ab260f3862c350e6b5f #
44

5+
6+
##################################################
7+
##################################################
8+
# NOTE: due to changes in Berlin's websites,
9+
# this script is currently borked
10+
##################################################
11+
##################################################
12+
13+
514
require 'selenium-webdriver'
615
require 'date'
7-
require 'pry'
16+
# require 'pry'
817

918
class BurgerBot
19+
CHARLOTTENBURG = [ 122210, 122217, 122219, 122227 ]
20+
KREUZBERG = [ 122231, 122238, 122243 ]
21+
LICTENBERG = [ 122252, 122254, 122260, 122262 ]
22+
MARZAHN = [ 122271, 122273, 122277 ]
23+
MITTE = [ 122280, 122282, 122284 ]
24+
NEUKOLLN = [ 122285, 122286, 122291, 122296 ]
25+
PANKOW = [ 122294, 122297, 122301, 150230 ]
26+
REINICKENDORF = [ 122304, 122309, 122311, 122312, 122314, 317869 ]
27+
SPANDAU = [ 122279, 122281, 122283, 324414 ]
28+
STEGLITZ = [ 122267, 122274, 122276 ]
29+
TEMPELHOF_SCHOENEBERG = [ 122246, 122251, 122257 ]
30+
TREPTOW_KOEPENICK = [ 122208, 122226 ]
31+
1032
def initialize(termin_type)
1133
today = Date.today
1234

1335
@attempt_count = 0
1436
@date = Date.new(today.year, today.month, 1)
15-
@url = determine_url(termin_type)
37+
@selected_locations = [KREUZBERG, NEUKOLLN, PANKOW].flatten.join(',')
38+
@termin_type = termin_type
39+
@url = determine_url
1640
end
1741

1842
def run
19-
until appointment_available?
20-
puts 'Sleeping.'
21-
sleep 35
43+
if visa_seeker?
44+
puts 'Entering kafkaesque nightmare. Hold on to your butts'
45+
puts '-'*80
46+
puts "Beginning attempt ##{@attempt_count += 1}"
47+
browser.get @url
48+
puts 'Page loaded'
49+
browser.find_elements(css: 'a').detect { |el| el.text == 'Termin buchen' }.click
50+
puts 'We\'re in'
51+
wait = Selenium::WebDriver::Wait.new
52+
wait.until { browser.find_elements(css: 'input').any?(&:displayed?) }
53+
checkbox = browser.find_element(css: 'input[name=gelesen]')
54+
p checkbox
55+
checkbox.click
56+
# browser.find_element(css: 'button#applicationForm:managedForm:proceed').click
57+
else
58+
until appointment_available?
59+
puts 'Sleeping.'
60+
sleep 35
61+
end
2262
end
2363
end
2464

@@ -43,13 +83,18 @@ def appointment_available?
4383
return false
4484
end
4585

46-
def determine_url(termin_type)
47-
case termin_type
86+
def visa_seeker?
87+
@termin_type == 'employee_visa'
88+
end
89+
90+
def determine_url
91+
case @termin_type
4892
when 'anmeldung' then anmeldung_url
4993
when 'background_check' then background_check_url
5094
when 'gewerbe' then gewerbe_registration_url
95+
when 'employee_visa' then employee_visa_url
5196
else
52-
raise ArgumentError, "Unknown termin type: #{termin_type}"
97+
raise ArgumentError, "Unknown termin type: #{@termin_type}"
5398
end
5499
end
55100

@@ -68,15 +113,15 @@ def background_check_url
68113
'https://service.berlin.de/terminvereinbarung/termin/tag.php?'\
69114
'termin=1&'\
70115
'anliegen[]=120926&'\
71-
'dienstleisterlist=122210,122217,122219,122227,122231,122238,122243,122254,331011,349977,122252,122260,122262,122271,122273,122277,122280,122282,122284,122291,122285,122286,122296,150230,122297,122294,122312,122314,122304,122311,122309,317869,122281,122279,122283,122276,122274,122267,122246,122251,122257,122208,122226&'\
116+
"dienstleisterlist=#{@selected_locations}&"\
72117
'herkunft=http%3A%2F%2Fservice.berlin.de%2Fdienstleistung%2F120926%2F'
73118
end
74119

75120
def gewerbe_registration_url
76121
'https://service.berlin.de/terminvereinbarung/termin/tag.php?'\
77122
'termin=1&'\
78123
'anliegen[]=327835&'\
79-
'dienstleisterlist=122210,122217,122219,122227,122231,122238,122243,122254,331011,349977,122252,122260,122262,122271,122273,122277,122280,122282,122284,122291,122285,122286,122296,324759,150230,122297,122294,122312,122314,122304,122311,122309,317869,122281,122279,122283,122276,122274,122267,122246,122251,122257,122208,122226&'\
124+
"dienstleisterlist=#{@selected_locations}&"\
80125
'herkunft=http%3A%2F%2Fservice.berlin.de%2Fdienstleistung%2F327835%2F'
81126
end
82127

@@ -85,60 +130,22 @@ def anmeldung_url
85130
'?id=&buergerID=&buergername=&absagecode='\
86131
"&Datum=#{@date}"\
87132
'&anliegen%5B%5D=120686'\
88-
'&dienstleister%5B%5D=122210'\
89-
'&dienstleister%5B%5D=122217'\
90-
'&dienstleister%5B%5D=122219'\
91-
'&dienstleister%5B%5D=122227'\
92-
'&dienstleister%5B%5D=122231'\
93-
'&dienstleister%5B%5D=122243'\
94-
'&dienstleister%5B%5D=122252'\
95-
'&dienstleister%5B%5D=122260'\
96-
'&dienstleister%5B%5D=122262'\
97-
'&dienstleister%5B%5D=122254'\
98-
'&dienstleister%5B%5D=122271'\
99-
'&dienstleister%5B%5D=122273'\
100-
'&dienstleister%5B%5D=122277'\
101-
'&dienstleister%5B%5D=122280'\
102-
'&dienstleister%5B%5D=122282'\
103-
'&dienstleister%5B%5D=122284'\
104-
'&dienstleister%5B%5D=122285'\
105-
'&dienstleister%5B%5D=122286'\
106-
'&dienstleister%5B%5D=122296'\
107-
'&dienstleister%5B%5D=150230'\
108-
'&dienstleister%5B%5D=122301'\
109-
'&dienstleister%5B%5D=122297'\
110-
'&dienstleister%5B%5D=122294'\
111-
'&dienstleister%5B%5D=122312'\
112-
'&dienstleister%5B%5D=122314'\
113-
'&dienstleister%5B%5D=122304'\
114-
'&dienstleister%5B%5D=122311'\
115-
'&dienstleister%5B%5D=122309'\
116-
'&dienstleister%5B%5D=317869'\
117-
'&dienstleister%5B%5D=324433'\
118-
'&dienstleister%5B%5D=325341'\
119-
'&dienstleister%5B%5D=324434'\
120-
'&dienstleister%5B%5D=122281'\
121-
'&dienstleister%5B%5D=324414'\
122-
'&dienstleister%5B%5D=122283'\
123-
'&dienstleister%5B%5D=122279'\
124-
'&dienstleister%5B%5D=122276'\
125-
'&dienstleister%5B%5D=122274'\
126-
'&dienstleister%5B%5D=122267'\
127-
'&dienstleister%5B%5D=122246'\
128-
'&dienstleister%5B%5D=122251'\
129-
'&dienstleister%5B%5D=122257'\
130-
'&dienstleister%5B%5D=122208'\
131-
'&dienstleister%5B%5D=122226'
133+
"&dienstleisterlist=#{@selected_locations}"
134+
end
135+
136+
def employee_visa_url
137+
'https://otv.verwalt-berlin.de/ams/TerminBuchen'
132138
end
133139
end
134140

135-
print "Which kind of appointment do you need?\n\n1. Anmeldung\n2. Background Check\n3. Gerwerbe Registration\n"
141+
print "Which kind of appointment do you need?\n\n1. Anmeldung\n2. Background Check\n3. Gerwerbe Registration\n4. Employee Visa\n"
136142
input = gets.chomp.to_i
137143

138144
termin_type = case input
139145
when 1 then 'anmeldung'
140146
when 2 then 'background_check'
141147
when 3 then 'gewerbe'
148+
when 4 then 'employee_visa'
142149
end
143150

144151
`clear`

Diff for: bus_stop_info.rb

+9-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def self.options_at_location(location, line = nil)
88
result = `curl -s 'https://v6.bvg.transport.rest/locations?query=#{location}&results=1'`
99
data = JSON.parse(result)[0]
1010

11+
return [] if data.nil?
1112
new(data['id'], data['name'], line).call
1213
end
1314

@@ -42,15 +43,18 @@ def call
4243
next if line && trip['line']['name'].downcase != line.downcase
4344
next if trip['direction'] == 'Fahrt endet hier'
4445

45-
arrivingAt = trip['when'] || trip['plannedWhen']
46-
next unless arrivingAt
46+
arrival = trip['when'] || trip['plannedWhen']
47+
next unless arrival
4748

48-
arrival = (DateTime.parse(arrivingAt).to_time - Time.now) / 60
49-
next if arrival.negative?
49+
arrives_at = DateTime.parse(arrival).to_time
50+
arrival_min = (arrives_at - Time.now) / 60
51+
next if arrival_min.negative?
5052

5153

5254
{
53-
arrives_in: arrival.round,
55+
arrives_in: arrival_min.round,
56+
arrives_at: arrives_at.to_s,
57+
arrives_at_int: arrives_at.to_i,
5458
mode: trip['line']['mode'],
5559
name: trip['line']['name'],
5660
direction: trip['direction'],

Diff for: forecaster.rb

+30-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
require 'date'
66

77
class Forecaster
8-
URL = 'https://api.openweathermap.org/data/3.0/onecall'
8+
BASE_URL = 'https://api.openweathermap.org/data'
9+
ONECALL_URL = "#{BASE_URL}/3.0/onecall"
10+
AIR_QUALITY_URL = "#{BASE_URL}/2.5/air_pollution"
911
API_KEY = ENV['OPENWEATHER_API_KEY']
1012

1113
def self.call(latitude, longitude)
@@ -15,17 +17,20 @@ def self.call(latitude, longitude)
1517
def initialize(latitude, longitude)
1618
@latitude = latitude
1719
@longitude = longitude
20+
@forecast = fetch_forecast
21+
@air_quality = fetch_air_quality
1822
end
1923

2024
def call
21-
build_structure(fetch_forecast)
25+
build_structure(@forecast, @air_quality)
2226
end
2327

2428
private
2529
attr_reader :latitude, :longitude
2630

27-
def build_structure(forecast)
31+
def build_structure(forecast, air_quality)
2832
current = {
33+
air_quality: quantify_air_quality(air_quality['list'][0]['main']['aqi']),
2934
temp: forecast['current']['temp'],
3035
desc: forecast['current']['weather'][0]['description'],
3136
icon_url: icon_url(forecast['current']['weather'][0]['icon'])
@@ -49,6 +54,18 @@ def build_structure(forecast)
4954
OpenStruct.new(current: current, daily: daily)
5055
end
5156

57+
def quantify_air_quality(aqi)
58+
case aqi
59+
when 1 then 'good'
60+
when 2 then 'fair'
61+
when 3 then 'moderate'
62+
when 4 then 'poor'
63+
when 5 then 'bad'
64+
else
65+
'extreme'
66+
end
67+
end
68+
5269
def risk_from_uv(uvi)
5370
case uvi
5471
when 0..2 then 'low'
@@ -60,8 +77,17 @@ def risk_from_uv(uvi)
6077
end
6178
end
6279

80+
def fetch_air_quality
81+
url = AIR_QUALITY_URL
82+
url += "?lat=#{latitude}"
83+
url += "&lon=#{longitude}"
84+
url += "&appid=#{API_KEY}"
85+
86+
JSON.parse(`curl -s '#{url}'`)
87+
end
88+
6389
def fetch_forecast
64-
url = URL
90+
url = ONECALL_URL
6591
url += "?lat=#{latitude}"
6692
url += "&lon=#{longitude}"
6793
url += "&appid=#{API_KEY}"

Diff for: moon_sign.rb

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Translated into ruby from www.astrocal.co.uk/apps/moonsign/moon.js
2+
3+
class MoonSign
4+
attr_reader :sign
5+
6+
OBLIQUITY_BASE = 23.452294
7+
8+
def initialize(time)
9+
@sign = calculate_sign(time)
10+
end
11+
12+
def symbol
13+
symbol_map[sign]
14+
end
15+
16+
def degree
17+
@degree # set in #calculate_sign
18+
end
19+
20+
private
21+
22+
def calculate_sign(time)
23+
julian_day = time.to_date.jd
24+
25+
zone = time.gmt_offset
26+
f = time.hour + (time.min / 60.to_f) + (zone / 3600.to_f)
27+
t = ((julian_day - 2415020)+ f/24-0.5) / 36525.to_f
28+
ll = 973563+ 1732564379*t- 4*t*t
29+
g = 1012395+ 6189*t
30+
n = 933060- 6962911*t+ 7.5*t*t
31+
g1 = 1203586+ 14648523*t- 37*t*t
32+
d = 1262655+ 1602961611*t- 5*t*t
33+
l = (ll- g1) / 3600.to_f
34+
l1 = ((ll- d)- g) / 3600.to_f
35+
f = (ll- n) / 3600
36+
d = d / 3600
37+
y = 2*d
38+
ml = 22639.6*FNs(l)- 4586.4*FNs(l- y)
39+
ml = ml + 2369.9*FNs(y)+ 769*FNs(2*l)- 669*FNs(l1)
40+
ml = ml - 411.6*FNs(2*f)- 212*FNs(2*l- y)
41+
ml = ml - 206*FNs(l+ l1- y)+ 192*FNs(l+ y)
42+
ml = ml - 165*FNs(l1- y)+ 148*FNs(l- l1)- 125*FNs(d)
43+
ml = ml - 110*FNs(l+ l1)- 55*FNs(2*f- y)
44+
ml = ml - 45*FNs(l+ 2*f)+ 40*FNs(l- 2*f)
45+
tn = n + 5392*FNs(2*f- y)- 541*FNs(l1)- 442*FNs(y)
46+
tn = tn + 423*FNs(2*f)- 291*FNs(2*l- 2*f)
47+
g = FNu(FNp(ll+ ml))
48+
sign = (g/30).floor
49+
@degree = (g-(sign*30))
50+
sign = sign+1
51+
52+
case sign
53+
when 1 then 'Aries'
54+
when 2 then 'Taurus'
55+
when 3 then 'Gemini'
56+
when 4 then 'Cancer'
57+
when 5 then 'Leo'
58+
when 6 then 'Virgo'
59+
when 7 then 'Libra'
60+
when 8 then 'Scorpio'
61+
when 9 then 'Sagittarius'
62+
when 10 then 'Capricorn'
63+
when 11 then 'Aquarius'
64+
when 12 then 'Pisces'
65+
end
66+
end
67+
68+
def symbol_map
69+
{
70+
'Aries' => '♈',
71+
'Taurus' => '♉',
72+
'Gemini' => '♊',
73+
'Cancer' => '♋',
74+
'Leo' => '♌',
75+
'Virgo' => '♍',
76+
'Libra' => '♎',
77+
'Scorpio' => '♏',
78+
'Sagittarius' => '♐',
79+
'Capricorn' => '♑',
80+
'Aquarius' => '♒',
81+
'Pisces' => '♓'
82+
}
83+
end
84+
85+
# unused?
86+
def obliquity(time)
87+
radians(OBLIQUITY_BASE - 0.0130125*time.to_i)
88+
end
89+
90+
def FNp(x)
91+
if(x<0)
92+
sgn=-1
93+
else
94+
sgn=1
95+
end
96+
97+
sgn*((x.abs/ 3600) / 360 - ((x.abs / 3600) / 360).floor) * 360
98+
end
99+
100+
def FNu(x)
101+
x-((x/360).floor*360)
102+
end
103+
104+
def radians(x)
105+
Math::PI / 180*x
106+
end
107+
108+
def FNs(x)
109+
Math.sin(radians(x))
110+
end
111+
end

0 commit comments

Comments
 (0)