From bb78890c4d0e098e5d133d8251a0271220ee9102 Mon Sep 17 00:00:00 2001 From: Dariusz Walczak Date: Fri, 11 Oct 2013 23:49:20 +0200 Subject: [PATCH] LocalBitcoin places added --- coinmap-icons.js | 1 + icons/local_bitcoins.n.24.png | Bin 0 -> 1609 bytes lb/__init__.py | 0 lb/__init__.pyc | Bin 0 -> 101 bytes lb/public.py | 118 ++++++++++++++++++++++++++++ lb/public.pyc | Bin 0 -> 4141 bytes refresh.py | 142 ++++++++++++++++++++++------------ 7 files changed, 210 insertions(+), 51 deletions(-) create mode 100644 icons/local_bitcoins.n.24.png create mode 100644 lb/__init__.py create mode 100644 lb/__init__.pyc create mode 100644 lb/public.py create mode 100644 lb/public.pyc diff --git a/coinmap-icons.js b/coinmap-icons.js index 0af133a..6279cf7 100644 --- a/coinmap-icons.js +++ b/coinmap-icons.js @@ -139,3 +139,4 @@ var icon_transport_tram_stop = L.icon({iconUrl: 'icons/transport_tram_stop.n.24. var icon_transport_turning_circle = L.icon({iconUrl: 'icons/transport_turning_circle.n.24.png', iconSize: [24, 24] }); var icon_transport_weir = L.icon({iconUrl: 'icons/transport_weir.n.24.png', iconSize: [24, 24] }); var icon_transport_zebracrossing = L.icon({iconUrl: 'icons/transport_zebracrossing.n.24.png', iconSize: [24, 24] }); +var icon_local_bitcoins = L.icon({iconUrl:'icons/local_bitcoins.n.24.png', iconSize:[24,24]}); \ No newline at end of file diff --git a/icons/local_bitcoins.n.24.png b/icons/local_bitcoins.n.24.png new file mode 100644 index 0000000000000000000000000000000000000000..368416e162904d3b02018ba1ed9676da35f10383 GIT binary patch literal 1609 zcmV-P2DbT$P)z6z=uj%Y8fdoZtRHT85YI zn>@+$$M5-m&U1d}c@BIoWo8Tv49pLQ!|P+Q*b&1pI;4~yDdkNm|O-ci}s_Xi` z{{H^I6c-my0`iuHd7J4inDBT!Wr>N2FPf9%n{WJeYs&b(H3%Vyp8tU8;SVMO=1T&`dD^z@`nd(72=>UO&eGBY#(7`}Gtd!AP}3qk?Zv>Y-~(KU=6)vbG=R%~QkF9qqs$HnD07xv6#rCPGAGCgp`GJY8MJ z9sbjJ4?cq9-Wuj_*uAs;;>DLsmn?DLb_WRw3EvK$+@DQ2guP@1E!`75`Bpno1FV{Y zst9&Jun0{NIIJq|Lw+7T*i0<10@ayJq~$1qzB8+H^YWa;`*QSXq+CgJVZHO~M8Eb! zHXmq1Q&m!(8t0x}N#j#h+*6dw{)d-PknRBB>UfAf@AQ&hU5Bk~4Mc;*R;x8VF2M9( zFE#^i>?66*v;fW zccWiwR8=FK6BhsyR1KloZW&5u%c4$AQdvPV;?_(FAfy`z%{KKw(zMO2(LT>?<62&6 zj%Cp|Sfo2KOi+bH2!Ye4A|*Wik8aWuZIlmU0DJItZlVmbUone-g4l@ZUl>^}F2Z2nJ^9KO;m^?^^N`%mlTwc15; zFa5gBfnod6??uV z{k^SnWal#JexX_hz1IU?ulLyl2M(l9d(5@29n;C>j*hS7+>!riD@mhgEJUX}gkehl{#fZNM_xbtJa?A^OJbFP}Wa{yRo0R@1? zVu|MG=MSzfThLiql-#~BT|3;=)b#$QO`9g-ouB@_Oeg;Z7pj&sLh7_K00000NkvXX Hu0mjf`oRJL literal 0 HcmV?d00001 diff --git a/lb/__init__.py b/lb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lb/__init__.pyc b/lb/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..817d36d4c6518a26d53c9ae5552884d061cb0db0 GIT binary patch literal 101 zcmZSn%*&;w8WEJt00oRd+5w1*S%5?e14FO|NW@PANHCxg#e6`qoFx7D_{_Y_lK6PN Yg31yOppZ>&eoARhsvSsUF%UBV0ClSlp#T5? literal 0 HcmV?d00001 diff --git a/lb/public.py b/lb/public.py new file mode 100644 index 0000000..3f6be2c --- /dev/null +++ b/lb/public.py @@ -0,0 +1,118 @@ +''' +Created on 1 Aug 2013 + +@author: Jamie +''' + +import requests +import json + +import logging +logging.basicConfig(format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%H:%M:%S', + level=logging.DEBUG) + +root = 'https://localbitcoins.com/' + +def countrycodes(): + r = requests.get(root+'api/countrycodes/').json() + return r['data']['cc_list'] + +def payment_methods(countrycode=''): + r = requests.get(root+'api/payment_methods/%s' % countrycode).json() + return r['data']['methods'] + +def currencies(): + r = requests.get(root+'api/currencies').json() + return r['data']['currencies'] + +def get_buy_ads(currency=None, countrycode=None, payment_method=None): + return _get_ads('buy-bitcoins-online/', currency, countrycode, payment_method) + +def get_sell_ads(currency=None, countrycode=None, payment_method=None): + return _get_ads('sell-bitcoins-online/', currency, countrycode, payment_method) + +def get_local_buy_ads(location): + geocode = _geocode(location) + places = _get_places(geocode['lat'], geocode['lng']) + url = places[0]['buy_local_url'] + ads = _get_local_ads(url) + return ads + +def get_local_sell_ads(location): + geocode = _geocode(location) + places = _get_places(geocode['lat'], geocode['lng']) + url = places[0]['sell_local_url'] + ads = _get_local_ads(url) + return ads + +def _get_local_ads(url): + r = requests.get(url) + ads = json.loads(r.text) + return ads['data']['ad_list'] + +def _get_places(lat, lng, countrycode=None, location_string=None): + r = requests.get(root+'/api/places?', + params={'lat': lat, 'lon': lng, + 'countrycode': countrycode, + 'location_string': location_string}).json() + places = r['data']['places'] + return places + + +def _get_ads(trade_type, currency=None, countrycode=None, payment_method=None): + url = root + trade_type + country_ads = [] + currency_ads = [] + + if not countrycode == None: + url1 = url + countrycode + '/name/' + if not payment_method == None: + url1 += payment_method + '/' + url1 += '.json' + r = requests.get(url1).json() + country_ads = r['data']['ad_list'] + + if not currency == None: + url2 = url + currency + '/' + if not payment_method == None: + url2 += payment_method + '/' + url2 += '.json' + r = requests.get(url2).json() + currency_ads = r['data']['ad_list'] + + if countrycode == None and currency == None: + if not payment_method == None: + url += payment_method + '/' + url += '.json' + r = requests.get(url).json + ad_list = r['data']['ad_list'] + + elif not countrycode == None and not currency == None: + ad_list = [item for item in currency_ads if item in country_ads] + + else: + ad_list = country_ads + currency_ads + + return {'success': 1, 'ad_list': ad_list} + +def _geocode(location): + gmaps_url = 'https://maps.google.com/maps/api/geocode/json?' + r = requests.get(gmaps_url, + params={'address': location, + 'sensor': 'false'}).json() + if r['status'] == 'OK': + geocoded = r['results'][0]['geometry']['location'] + return {'success': 1, 'lat': geocoded['lat'], 'lng': geocoded['lng']} + else: + return {'success': 0} + + +def test(): + pass + +def main(): + test() + +if __name__ == '__main__': + main() diff --git a/lb/public.pyc b/lb/public.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cef768cfdf21cc3dbb64cea5706c65785defebb1 GIT binary patch literal 4141 zcmcIn?QR>#6}`hRi8LiyAGXZ2X_Y2w=r$JP1aJyBsFNy9f~01E6#@hT8e+A(X4YBm zGCRYd0?1!-fj&qdp^wxz=>N9o+#y9;u^bddDeZ9P&d$vJICJi0^`9H9+TmA0B=gT2 zzCXZYD@G(1IYnzEu1IF&6dm8M$Z2KKugYmvlBztdNnDi}ZC&Dq#A_<7%Y{@;ye_8@ zHRTz0T$8vZ@eO%~9oHpptFXy4=KmY=44d9q3?biCNn7GAeR)ITo7&lwcw0MLiY^ge?NL;WdKy@SQmS~4@z_H&PUNW(r!m~WF!HoY zqh}&hHM>ZjxAM z9Zwx5PG2vJ!grq9BJWZs$ENI}5p8T6z3i+vo}6WAbTmG96s#UhWh~DY(=o6Dv)rSC zhf+20E;_3Q!lv6RMjDwah@Ug^HrCL{adl~Zp)G&k~96LIbT6u?bvpaGneWs*l}GPkJ(d2}he z-Yg#eV`c<2ql4!%I1&BEhn_m-%q|+l1r&maAO_QlT-0#I=(fJyLwhzkzqdf|y&})j zJn4C$(7yu!X%NP?%Uu;_bM4QA4N7R|^PYT}-x()vh%>qAs~B2pBIduT zWLBZOd9CA`bY@lF{V6Uz7Sv?QC~(WZ-q$R2{yQJ05Q?LB=_X~D!KBQV5kO1|GJ?Wh z12oRU2v?uM(6L{{u<-;98$~WHa=lfH4S1L4YZ+ghqDpWfhSxcYE~TUVDf3vq4xuHw z#k9@7*+i=>@&EE#Km-J&5brPAu917*VF7bVz)KR4v(+ELPdNN38zM0H8JnM@d705f z&(i1xMt%k9i>#(M3G8Fe-$UcMaS4|S=^s!*0w*3kQh*-hKO_Mz?=ML(j6K!Umn$T= z&V4D%3Peol-X(u_9`|Y#dGN<9Q@`BDiLs$qrI-E&p75-&k1IYzcCTyOP$CdkJ9fsa4^QobllNz9WQ5qyJeH{+V)8xAJ_6x4`-dKbBM_+lS##x>zsuAQ^_ZqELnX*# znu}wa*B;Z*_Yr74ru^7k9?AZtEgeHEG1Nn9x=3r)_u!bhEed_ua>bCAa-yr{ppU(Zpak>b@{d-<nT+W5WR8zB2TW|$u2SB$c3&9<7D8@ z$H|pEq@1%_wlLxN!pj#2njiH5kn(*6>SFXxK)rO7x@7bc($X~e2rpaWS4_(^Orz3P za^A-1mf5~Cx&zwg%noK=G2Lpbq9nec1Eqq$U@KskNlzELHc2fs_09#g;tKQ}f!gKR>+>APF#ZXs-l1(xuI6Tt7J z%PilwM`#zd_$VCPqhV1DvqUR#j+I{K8L!9SJ_>$`B^uK(j!VQ;S@cPm*+lurCb=z2 z-$k`Ou>h>d7oY1Ayg$jD^;w5F!q%u#%X3XD3YUOsVM#cikd?fZiMYs<6%&yo5e}&+ zv%HV=d|M{@_+{~Ba*Oa-dO{H0He$C6in?uHt8hX;M6gDVVN}Oa(qC@8?EUb^0M|Iw z76rZ+)eyS+x!jm_9l(HKo0a`J9sCx}a)0f;_>fVU<|SU9AEHIeU_j|$&}E)i?+*rX z5e)|Z#;q@;Suq?U7wCmL3vC)57x|NPsA2u+55NEN6aRyOS2AFspp|p*YxYcXy%HMHlP>;E9U*sGOGCgsE8+7@;f5HzJ-Q&u#IO65o=W% em1eD7Yu0wEJJseI{_0!Joj028X0=&uoBsffS;U0^ literal 0 HcmV?d00001 diff --git a/refresh.py b/refresh.py index 4dfbc26..41732d7 100755 --- a/refresh.py +++ b/refresh.py @@ -4,6 +4,7 @@ import urllib2 import simplejson import os +from lb import public as locals icon_mapping = { 'aeroway:aerodrome': 'transport_airport', @@ -153,6 +154,7 @@ 'tourism:viewpoint': 'tourist_view_point', 'tourism:zoo': 'tourist_zoo', 'traffic_calming:yes': 'transport_speedbump', +'local_bitcoins:local_bitcoins': 'local_bitcoins', } def determine_icon(tags): @@ -161,7 +163,7 @@ def determine_icon(tags): k,v = kv.split(':') t = tags.get(k) if not t: - continue + continue t = t.split(';')[0] if t == v: icon = icon_mapping[kv] @@ -169,6 +171,63 @@ def determine_icon(tags): icon = icon.replace('-', '_') return icon + +def write_elements(f, e): + lat = e.get('lat', None) + lon = e.get('lon', None) + typ = e['type'] + tags = e.get('tags', {}) + for k in tags.keys(): + if tags[k]: + tags[k] = cgi.escape(tags[k]).replace('"', '\\"') + ide = e['id'] + + if typ == 'node': + nodes[ide] = (lat, lon) + if tags.get('payment:bitcoin') != 'yes': # nodes that are part of way (i.e. not accepting bitcoin) + return None + + if typ == 'way': + lat, lon = nodes[e['nodes'][0]] # extract coordinate of first node + + if not lat or not lon: + return None + + if 'name' in tags: + name = tags['name'] + else: + name = '%s %s' % (typ, ide) + + icon = determine_icon(tags) + popup = '%s *
' % (name, typ, ide) + if 'addr:street' in tags: + popup += '%s %s
' % (tags.get('addr:street', ''), tags.get('addr:housenumber', '')) + if 'addr:city' in tags: + popup += '%s %s
' % (tags.get('addr:postcode', ''), tags.get('addr:city', '')) + if 'addr:country' in tags: + popup += '%s
' % (tags.get('addr:country', '')) + popup += '
' + if 'contact:website' in tags: + w = tags['contact:website'] + if not w.startswith('http'): + w = 'http://' + w + popup += 'website: %s
' % (w, w) + elif 'website' in tags: + w = tags['website'] + if not w.startswith('http'): + w = 'http://' + w + popup += 'website: %s
' % (w, w) + if 'contact:email' in tags: + popup += 'email: %s
' % (tags['contact:email'], tags['contact:email']) + elif 'email' in tags: + popup += 'email: %s
' % (tags['email'], tags['email']) + if 'contact:phone' in tags: + popup += 'phone: %s
' % (tags['contact:phone']) + elif 'phone' in tags: + popup += 'phone: %s
' % (tags['phone']) + f.write(' L.marker([%s, %s], {"title": "%s", icon: icon_%s}).bindPopup("%s").addTo(markers);\n' % (lat, lon, name.encode('utf-8'), icon, popup.encode('utf-8'))) + + scriptdir = os.path.dirname(os.path.abspath(__file__)) f = urllib2.urlopen('http://overpass.osm.rambler.ru/cgi/interpreter?data=[out:json];(node["payment:bitcoin"=yes];way["payment:bitcoin"=yes];>;);out;') @@ -180,60 +239,41 @@ def determine_icon(tags): with open(scriptdir + '/coinmap-data.js', 'w') as f: f.write('function coinmap_populate(markers) {\n') + # overpass for e in json['elements']: - lat = e.get('lat', None) - lon = e.get('lon', None) - typ = e['type'] - tags = e.get('tags', {}) - for k in tags.keys(): - tags[k] = cgi.escape(tags[k]).replace('"', '\\"') - ide = e['id'] + place = write_elements(f, e) + if place: + cnt += 1 - if typ == 'node': - nodes[ide] = (lat,lon) - if tags.get('payment:bitcoin') != 'yes': # nodes that are part of way (i.e. not accepting bitcoin) - continue + # Bitcoin Locals + elements = [] - if typ == 'way': - lat, lon = nodes[e['nodes'][0]] # extract coordinate of first node + country_codes = locals.countrycodes() + for country in country_codes: + bl_data = locals.get_local_sell_ads(country) + for entry in bl_data[:2]: + e = entry['data'] + j = { + 'id': e.get('profile', {}).get('id', '-1'), + 'lat': e.get('lat', None), + 'lon': e.get('lon', None), + 'type': 'node', + 'tags': { + 'payment:bitcoin': 'yes', + 'local_bitcoins': 'local_bitcoins', + 'addr:city': e.get('city', ''), + 'add:country': e.get('countrycode', ''), + 'contact:website': 'https://localbitcoins.com/accounts/profile/' + + e.get('profile', {}).get('username', '') + }, + 'website': 'http://localbitcoins.com' + } + elements.append(j) - if not lat or not lon: - continue + for e in elements: + place = write_elements(f, e) + if place: + cnt += 1 - cnt += 1 - - if 'name' in tags: - name = tags['name'] - else: - name = '%s %s' % (typ, ide) - - icon = determine_icon(tags) - popup = '%s *
' % (name, typ, ide) - if 'addr:street' in tags: - popup += '%s %s
' % (tags.get('addr:street', ''), tags.get('addr:housenumber', '')) - if 'addr:city' in tags: - popup += '%s %s
' % (tags.get('addr:postcode', ''), tags.get('addr:city', '')) - if 'addr:country' in tags: - popup += '%s
' % (tags.get('addr:country', '')) - popup += '
' - if 'contact:website' in tags: - w = tags['contact:website'] - if not w.startswith('http'): - w = 'http://' + w - popup += 'website: %s
' % (w, w) - elif 'website' in tags: - w = tags['website'] - if not w.startswith('http'): - w = 'http://' + w - popup += 'website: %s
' % (w, w) - if 'contact:email' in tags: - popup += 'email: %s
' % (tags['contact:email'], tags['contact:email']) - elif 'email' in tags: - popup += 'email: %s
' % (tags['email'], tags['email']) - if 'contact:phone' in tags: - popup += 'phone: %s
' % (tags['contact:phone']) - elif 'phone' in tags: - popup += 'phone: %s
' % (tags['phone']) - f.write(' L.marker([%s, %s], {"title": "%s", icon: icon_%s}).bindPopup("%s").addTo(markers);\n' % (lat, lon, name.encode('utf-8'), icon, popup.encode('utf-8'))) f.write(' document.getElementById("count").innerHTML = "%d";\n' % cnt); f.write('}\n')