Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nginx-redirector
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
eterfund
nginx-redirector
Commits
3444015e
Commit
3444015e
authored
May 30, 2019
by
Nick Yefremov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated redirector files, separated classes, updated setup
parent
2410da06
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
129 additions
and
116 deletions
+129
-116
__init__.py
core/__init__.py
+2
-0
const.py
core/const.py
+2
-0
generators.py
core/generators.py
+7
-6
logger.py
core/logger.py
+18
-0
parser.py
core/parser.py
+81
-85
redirector.py
core/redirector.py
+12
-19
setup.py
setup.py
+7
-6
No files found.
core/__init__.py
0 → 100644
View file @
3444015e
#!/usr/bin/env python
# -*- coding: utf-8 -*-
core/const.py
View file @
3444015e
NAME
=
"redirector"
REDIRECTOR_DIR
=
"/var/lib/redirector"
MAPS_DIR
=
REDIRECTOR_DIR
+
"/maps"
CONFIG_DIR
=
REDIRECTOR_DIR
+
"/location-includes"
\ No newline at end of file
core/generators.py
View file @
3444015e
...
...
@@ -2,9 +2,9 @@
class
MapGenerator
:
def
__init__
(
self
):
self
.
start_lines
=
[
"map $uri $
%
s-redirect {
\n
"
,
"
\n
map $uri $
%
s-option-redirect {
\n
"
,
"
\n
map $uri $
%
s-option {
\n
"
"map $uri $
%
s-redirect {
"
,
"
\n
map $uri $
%
s-option-redirect {"
,
"
\n
map $uri $
%
s-option {"
]
self
.
endline
=
"
\n
}"
...
...
@@ -13,17 +13,18 @@ class MapGenerator:
for
i
,
map_type
in
enumerate
(
self
.
start_lines
):
data
+=
map_type
%
project_name
for
arg1
,
arg2
in
redirects_sorted
[
i
]:
data
+=
"
\t
%
s
\t
%
s;"
%
(
arg1
,
arg2
)
data
+=
"
\
n\
t
%
s
\t
%
s;"
%
(
arg1
,
arg2
)
data
+=
self
.
endline
return
data
class
ConfigGenerator
:
def
__init__
(
self
):
self
.
start_line
=
"if($
%
s-redirect) {
\n
"
self
.
rewrite_line
=
"
\t
rewrite ^/
%
s/(.^)$
%
s redirect;
\n
}"
self
.
rewrite_line
=
"
\t
rewrite ^/
%
s/(.^)$
$
%
s redirect;
\n
}"
def
generate_conf
(
self
,
project_name
):
return
self
.
start_line
%
project_name
+
self
.
rewrite_line
%
project_name
return
(
self
.
start_line
%
project_name
)
+
(
self
.
rewrite_line
%
(
project_name
,
project_name
))
core/logger.py
0 → 100644
View file @
3444015e
import
logging
class
Logger
:
def
__init__
(
self
,
file_
=
None
):
if
file_
:
logging
.
basicConfig
(
filename
=
file_
)
def
log
(
self
,
message
,
level
=
"critical"
):
if
self
.
file_
:
if
level
==
"critical"
:
logging
.
critical
(
message
)
elif
level
==
"debug"
:
logging
.
debug
(
message
)
elif
level
==
"info"
:
logging
.
info
(
message
)
else
:
print
(
level
.
upper
()
+
":
\n
"
+
message
)
core/parser.py
View file @
3444015e
import
sys
import
yaml
from
pprint
import
pprint
as
pp
import
re
# Constants:
class
RedirectorParser
:
class
MapLineParser
:
def
__init__
(
self
,
logger
=
None
):
self
.
url_regexp
=
re
.
compile
(
r'(\/[(\w)-:]+)+\/?(\.\w+)?'
)
self
.
url_absolute
=
re
.
compile
(
r"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$"
)
self
.
url_absolute
=
re
.
compile
(
r"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$"
)
self
.
logger
=
logger
def
_parse_line
(
self
,
line
,
prefix
,
i
):
if
not
line
.
startswith
(
"#"
):
line
=
line
.
split
()
return_code
,
options
=
0
,
[]
if
len
(
line
)
==
0
:
return
-
1
,
None
,
None
elif
len
(
line
)
<
2
:
raise
self
.
ParseLineError
(
"Error on
%
s:{line};
\n
Not enough arguments to parse!"
.
format
(
line
=
i
),
None
)
elif
len
(
line
)
>
2
:
return_code
=
1
options
=
[
option
[
1
:
-
1
]
for
option
in
line
[
2
:]]
# not url - regexp
if
not
self
.
url_regexp
.
fullmatch
(
line
[
0
]):
try
:
re
.
compile
(
line
[
0
])
re
.
compile
(
line
[
1
])
except
re
.
error
:
raise
self
.
RegexpTestError
(
"Can
\'
t compile regular expressions {expression1} {expression2} in "
"
%
s:{line_num}"
.
format
(
expression1
=
line
[
0
],
expression2
=
line
[
1
],
line_num
=
i
),
re
.
error
)
# if new URI relative to the root
elif
line
[
0
]
.
startswith
(
"//"
):
line
[
0
]
=
line
[
0
][
1
:]
# cutting out extra '/' at the beginning
elif
line
[
1
]
.
startswith
(
"//"
):
line
[
1
]
=
line
[
1
][
1
:]
elif
self
.
url_absolute
.
fullmatch
(
line
[
1
]):
pass
# default url
else
:
line
[
0
]
=
prefix
+
line
[
0
]
line
[
1
]
=
prefix
+
line
[
1
]
return
return_code
,
line
[
0
],
line
[
1
],
options
else
:
def
parse_line
(
self
,
line
,
prefix
,
i
):
line
=
line
.
strip
()
return_code
,
options
=
0
,
[]
if
line
.
startswith
(
"#"
)
or
len
(
line
)
==
0
:
return
-
1
,
None
,
None
line
=
line
.
split
()
if
len
(
line
)
<
2
:
raise
self
.
ParseLineError
(
"Error on
%
s:{line};
\n
"
"Not enough arguments to parse!"
.
format
(
line
=
i
),
None
)
elif
len
(
line
)
>
2
:
return_code
=
1
options
=
[
option
[
1
:
-
1
]
for
option
in
line
[
2
:]]
if
not
self
.
url_regexp
.
fullmatch
(
line
[
0
]):
# not url - regexp
try
:
re
.
compile
(
line
[
0
])
re
.
compile
(
line
[
1
])
except
re
.
error
:
raise
self
.
RegexpTestError
(
"Can
\'
t compile regular expressions {expression1} {expression2} in "
"
%
s:{line_num}"
.
format
(
expression1
=
line
[
0
],
expression2
=
line
[
1
],
line_num
=
i
),
re
.
error
)
elif
line
[
0
]
.
startswith
(
"//"
):
# if new URI relative to the root
line
[
0
]
=
line
[
0
][
1
:]
# cutting out extra '/' at the beginning
elif
line
[
1
]
.
startswith
(
"//"
):
line
[
1
]
=
line
[
1
][
1
:]
elif
self
.
url_absolute
.
fullmatch
(
line
[
1
]):
pass
else
:
# default url
line
[
0
]
=
prefix
+
line
[
0
]
line
[
1
]
=
prefix
+
line
[
1
]
return
return_code
,
line
[
0
],
line
[
1
],
options
class
ParseLineError
(
Exception
):
"""Raised when line contains not enough arguments
Attributes:
message -- expanation where in .yaml config file aprser didn't find enough arguments
"""
def
__init__
(
self
,
message
,
errors
):
super
()
.
__init__
(
message
)
self
.
message
=
message
self
.
errors
=
errors
class
RegexpTestError
(
Exception
):
"""Raised when parser fails to compile url containing regular expression
Attributes:
message -- explanation what regexp failed to compile and where
"""
def
__init__
(
self
,
message
,
errors
):
super
()
.
__init__
(
message
)
self
.
message
=
message
self
.
errors
=
errors
class
ConfigReader
:
def
__init__
(
self
,
logger
=
None
):
self
.
line_parser
=
MapLineParser
(
logger
=
logger
)
if
logger
:
self
.
logger
=
logger
@staticmethod
def
_
parse_yaml
(
file_dir
):
def
parse_yaml
(
file_dir
):
return_list
=
[]
with
open
(
file_dir
,
'r'
)
as
stream
:
data
=
yaml
.
safe_load
(
stream
)
...
...
@@ -59,34 +90,23 @@ class RedirectorParser:
return_list
.
append
((
map_path
,
project_prefix
))
return
return_list
def
log
(
self
,
message
,
level
=
"critical"
):
if
self
.
logger
:
if
level
==
"critical"
:
self
.
logger
.
critical
(
message
)
elif
level
==
"debug"
:
self
.
logger
.
debug
(
message
)
elif
level
==
"info"
:
self
.
logger
.
info
(
message
)
else
:
print
(
level
.
upper
()
+
":
\n
"
+
message
)
def
parse_map
(
self
,
map_file
,
yaml_file
):
res
=
[[],
[],
[]]
res_prefix
=
None
try
:
for
map_path
,
prefix
in
self
.
_
parse_yaml
(
yaml_file
):
for
map_path
,
prefix
in
self
.
parse_yaml
(
yaml_file
):
if
map_path
==
map_file
:
# ???: Is the last directory of map_path a project's name?
res_prefix
=
prefix
.
split
(
"/"
)[
-
1
]
res_prefix
=
prefix
.
split
(
"/"
)[
-
1
]
# ???: Is the last directory of map_path a project's name?
with
open
(
map_file
,
"r"
)
as
file
:
for
i
,
line
in
enumerate
(
file
):
request_url
,
redirect_url
,
options
=
None
,
None
,
[]
try
:
return_code
,
request_url
,
redirect_url
,
*
options
=
self
.
_parse_line
(
line
,
prefix
,
i
)
except
self
.
RegexpTestError
as
e
:
self
.
log
(
e
.
message
%
map_file
)
except
self
.
ParseLineError
as
e
:
self
.
log
(
e
.
message
%
map_file
)
return_code
,
request_url
,
redirect_url
,
*
options
=
\
self
.
line_parser
.
parse_line
(
line
,
prefix
,
i
)
except
MapLineParser
.
RegexpTestError
as
e
:
self
.
logger
.
log
(
e
.
message
%
map_file
)
except
MapLineParser
.
ParseLineError
as
e
:
self
.
logger
.
log
(
e
.
message
%
map_file
)
if
not
request_url
or
not
redirect_url
or
return_code
==
-
1
:
continue
...
...
@@ -98,29 +118,5 @@ class RedirectorParser:
res
[
2
]
.
append
((
request_url
,
options
))
return
res
,
res_prefix
except
yaml
.
YAMLError
as
e
:
self
.
log
(
"Error occu
red while reading
%
s"
%
yaml_file
+
str
(
e
))
self
.
log
ger
.
log
(
"Error occur
red while reading
%
s"
%
yaml_file
+
str
(
e
))
class
ParseLineError
(
Exception
):
"""Raised when line contains not enough arguments
Attributes:
message -- expanation where in .yaml config file aprser didn't find enough arguments
"""
def
__init__
(
self
,
message
,
errors
):
super
()
.
__init__
(
message
)
self
.
message
=
message
self
.
errors
=
errors
class
RegexpTestError
(
Exception
):
"""Raised when parser fails to compile url containing regular expression
Attributes:
message -- explanation what regexp failed to compile and where
"""
def
__init__
(
self
,
message
,
errors
):
super
()
.
__init__
(
message
)
self
.
message
=
message
self
.
errors
=
errors
core/redirector.py
View file @
3444015e
import
sys
import
generators
import
parser
import
const
from
core
import
generators
from
core
import
logger
from
core
import
parser
from
core
import
const
class
Redirector
:
def
__init__
(
self
,
logger
=
None
):
self
.
parser
=
parser
.
RedirectorPars
er
(
logger
=
logger
)
self
.
parser
=
parser
.
ConfigRead
er
(
logger
=
logger
)
self
.
map_generator
=
generators
.
MapGenerator
()
self
.
config_generator
=
generators
.
ConfigGenerator
()
def
log
(
self
,
message
,
level
=
"critical"
):
if
self
.
logger
:
if
level
==
"critical"
:
self
.
logger
.
critical
(
message
)
elif
level
==
"debug"
:
self
.
logger
.
debug
(
message
)
elif
level
==
"info"
:
self
.
logger
.
info
(
message
)
else
:
print
(
level
.
upper
()
+
":
\n
"
+
message
)
def
generate
(
self
,
map_file
,
yaml_file
):
def
generate
(
self
,
yaml_file
,
map_file
):
import
pdb
pdb
.
set_trace
()
project_name
=
"Error"
try
:
data
,
project_name
=
self
.
parser
.
parse_map
(
map_file
,
yaml_file
)
# FIXME: what is the better way to do so?
except
Exception
as
e
:
raise
self
.
RedirectorParserError
(
"Can
\'
t parse .map file
%
s"
%
map_file
,
e
)
...
...
@@ -35,10 +28,10 @@ class Redirector:
with
open
(
const
.
CONFIG_DIR
+
"/
%
s.conf"
%
project_name
,
"w"
)
as
conf_file
:
conf_file
.
write
(
self
.
config_generator
.
generate_conf
(
project_name
))
except
Exception
as
e
:
print
(
e
)
raise
self
.
RedirectorGenerationError
(
"Can
\'
t generate new .conf or new .map file
\
from
%
s .map file for
%
s project"
%
(
map_file
,
project_name
)
.
e
)
from
%
s .map file for
%
s project"
%
(
map_file
,
project_name
)
,
e
)
class
RedirectorParserError
(
Exception
):
def
__init__
(
self
,
message
,
errors
):
super
()
.
__init__
(
message
)
...
...
setup.py
View file @
3444015e
...
...
@@ -5,10 +5,10 @@ setup(
name
=
const
.
NAME
,
version
=
"0.1"
,
packages
=
find_packages
(),
entry_points
=
"""
[redirector]
redirector = core.redirector:main
[redirector-watch]
redirector-watch = core.redirector:watch
"""
entry_points
=
{
'console_scripts'
:
[
'redirector = core.redirector:main'
,
'redirector-watch = core.redirector:watch'
]
}
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment