1
- # https://trac.openstreetmap.org/browser/subversion/applications/editors/josm/plugins/ tag2link/resources/tag2link_sources.xml?rev=30720&format=txt
1
+ # https://raw.githubusercontent.com/JOSM/ tag2link/master/index.json
2
2
3
- import re
4
- import xml .sax
5
- from typing import Any , Dict , List
6
- from xml .sax .xmlreader import AttributesImpl
7
-
8
-
9
- class Exact (xml .sax .handler .ContentHandler ):
10
- def __init__ (self ):
11
- self .rules : List [Dict [str , Any ]] = []
12
- self .val : Regex = re .compile ("(%[^%]+%|\{[^}]+})" ) # noqa
13
-
14
- def unposix (self , regex : str ) -> str :
15
- regex = regex .replace ("\p{Lower}" , "[a-z]" ) # noqa
16
- regex = regex .replace ("\p{Upper}" , "[A-Z]" ) # noqa
17
- regex = regex .replace ("\p{Digit}" , "[0-9]" ) # noqa
18
- return regex
19
-
20
- def startElement (self , name : str , attrs : AttributesImpl ) -> None :
21
- if name == "rule" :
22
- self .rules .append ({"conditions" : [], "link" : None })
23
- elif name == "condition" :
24
- self .rules [- 1 ]["conditions" ].append (
25
- {
26
- "kk" : attrs ["k" ],
27
- "k" : re .compile ("^" + self .unposix (attrs ["k" ]) + "$" ),
28
- "v" : (
29
- re .compile ("^" + self .unposix (attrs ["v" ]) + "$" )
30
- if "v" in attrs
31
- else None
32
- ),
33
- "id" : attrs ["id" ] if "id" in attrs else None ,
34
- }
35
- )
36
- elif name == "link" :
37
- link = attrs ["href" ]
38
- subs = []
39
- if "%" in link or "{" in link :
40
- for valmatch in self .val .finditer (link ):
41
- sub = []
42
- v = valmatch .group (1 )
43
- link = link .replace (v , "%s" , 1 )
44
- var = v [1 :- 1 ].split (":" )
45
- for ll in var :
46
- if "." not in ll and ll != "v" and ll != "k" :
47
- vv = ll
48
- else :
49
- vv = ll .split ("." )
50
- if vv [0 ] in ("k" , "v" ):
51
- vv = [None ] + vv
52
- if len (vv ) == 2 :
53
- vv .append (0 )
54
- else :
55
- vv [2 ] = int (vv [2 ])
56
- sub .append (vv )
57
- subs .append (sub )
58
- self .rules [- 1 ]["link" ] = {"url" : link , "subs" : subs }
3
+ import json
4
+ from typing import Dict , List
59
5
60
6
61
7
class tag2link :
62
8
def __init__ (self , rulesFiles : str ):
63
- parser = xml .sax .make_parser ()
64
- handler = Exact ()
65
- parser .setContentHandler (handler )
66
- parser .parse (open (rulesFiles , "r" , encoding = "utf-8" ))
67
- self .rules = handler .rules
68
- self .all = re .compile (".*" )
9
+ rules_json = json .load (open (rulesFiles , "r" , encoding = "utf-8" ))
10
+ self .rules : Dict [str , str ] = dict (
11
+ map (
12
+ lambda rule : [
13
+ rule ["key" ][4 :],
14
+ rule ["url" ],
15
+ ],
16
+ filter (lambda rule : rule ["key" ].startswith ("Key:" ), rules_json ),
17
+ )
18
+ )
19
+ print (self .rules )
69
20
70
- def checkTags (self , tags : Dict [str , str ]) -> Dict [str , str ]:
71
- try :
72
- urls : Dict [str , str ] = {}
73
- for rule in self .rules :
74
- valid = True
75
- id = {}
76
- for condition in rule ["conditions" ]:
77
- match = False
78
- for key in tags .keys ():
79
- kmatch = condition ["k" ].match (key )
80
- if kmatch :
81
- id [condition ["id" ]] = {"k" : kmatch }
82
- if condition ["v" ] is None :
83
- vmatch = self .all .match (tags [key ])
84
- id [condition ["id" ]]["v" ] = vmatch
85
- match = True
86
- break
87
- else :
88
- vmatch = condition ["v" ].match (tags [key ])
89
- if vmatch :
90
- id [condition ["id" ]]["v" ] = vmatch
91
- match = True
92
- break
93
- if not match :
94
- valid = False
95
- break
96
- if valid :
97
- replace = []
98
- for sub in rule ["link" ]["subs" ]:
99
- for v in sub :
100
- if isinstance (v , str ):
101
- replace .append (v )
102
- break
103
- else :
104
- val = id [v [0 ]][v [1 ]].group (v [2 ])
105
- if val :
106
- replace .append (val )
107
- break
108
- ret = rule ["link" ]["url" ] % tuple (replace )
109
- if "://" not in ret :
110
- ret = "http://" + ret
111
- urls [id [rule ["link" ]["subs" ][0 ][0 ][0 ]]["k" ].group (0 )] = ret
112
- return urls
113
- except Exception :
114
- return {}
21
+ def addLinks (self , tags : Dict [str , str ]) -> List [Dict [str , str ]]:
22
+ links = []
23
+ for key , value in tags .items ():
24
+ links .append ({"k" : key , "v" : value })
25
+ if key in self .rules :
26
+ links [- 1 ]["vlink" ] = self .rules [key ].replace ("$1" , tags [key ])
27
+ return links
115
28
116
29
117
30
if __name__ == "__main__" :
118
- t2l = tag2link ("tag2link_sources.xml " )
119
- print (t2l .checkTags ({"oneway" : "yes" }))
120
- print (t2l .checkTags ({"url" : "plop.com" }))
121
- print (t2l .checkTags ({"url" : "http://plop.com" }))
122
- print (t2l .checkTags ({"ref:UAI" : "123" }))
31
+ t2l = tag2link ("tag2link_sources.json " )
32
+ print (t2l .addLinks ({"oneway" : "yes" }))
33
+ print (t2l .addLinks ({"url" : "plop.com" }))
34
+ print (t2l .addLinks ({"url" : "http://plop.com" }))
35
+ print (t2l .addLinks ({"ref:UAI" : "123" }))
123
36
print (
124
- t2l .checkTags (
37
+ t2l .addLinks (
125
38
{"man_made" : "survey_point" , "source" : "©IGN 2012" , "ref" : "1234567 - A" }
126
39
)
127
40
)
128
41
print (
129
- t2l .checkTags (
42
+ t2l .addLinks (
130
43
{
131
44
"url" : "span://bad" ,
132
45
"man_made" : "survey_point" ,
@@ -135,7 +48,7 @@ def checkTags(self, tags: Dict[str, str]) -> Dict[str, str]:
135
48
}
136
49
)
137
50
)
138
- print (t2l .checkTags ({"wikipedia:fr" : "toto" }))
139
- print (t2l .checkTags ({"wikipedia" : "fr:toto" }))
140
- print (t2l .checkTags ({"wikipedia" : "toto" }))
141
- print (t2l .checkTags ({"source" : "source" , "source:url" : "http://example.com" }))
51
+ print (t2l .addLinks ({"wikipedia:fr" : "toto" }))
52
+ print (t2l .addLinks ({"wikipedia" : "fr:toto" }))
53
+ print (t2l .addLinks ({"wikipedia" : "toto" }))
54
+ print (t2l .addLinks ({"source" : "source" , "source:url" : "http://example.com" }))
0 commit comments