Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
ant.sr
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Anton Sarukhanov
ant.sr
Commits
ad2e77eb
Commit
ad2e77eb
authored
4 years ago
by
Anton Sarukhanov
Browse files
Options
Downloads
Patches
Plain Diff
WIP: Photo Gallery
parent
cf048d51
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
content/Photos/ukraine-2019.md
+5
-0
5 additions, 0 deletions
content/Photos/ukraine-2019.md
my_plugins/photos/photos.py
+585
-0
585 additions, 0 deletions
my_plugins/photos/photos.py
with
590 additions
and
0 deletions
content/Photos/ukraine-2019.md
0 → 100644
+
5
−
0
View file @
ad2e77eb
Title: Ukraine
Description: Kyiv, Turbiv, Vinnitsa
gallery: {photo}/ukraine-2019
test
This diff is collapsed.
Click to expand it.
my_plugins/photos/photos.py
0 → 100644
+
585
−
0
View file @
ad2e77eb
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
import
itertools
import
logging
import
multiprocessing
import
os
import
pprint
import
re
import
shutil
from
pelican.generators
import
ArticlesGenerator
from
pelican.generators
import
PagesGenerator
from
pelican.settings
import
DEFAULT_CONFIG
from
pelican
import
signals
from
pelican.utils
import
pelican_open
logger
=
logging
.
getLogger
(
__name__
)
try
:
from
PIL
import
Image
from
PIL
import
ImageOps
except
ImportError
:
logger
.
error
(
'
PIL/Pillow not found
'
)
try
:
import
piexif
except
ImportError
:
ispiexif
=
False
logger
.
warning
(
'
piexif not found! Cannot use exif manipulation features
'
)
else
:
ispiexif
=
True
logger
.
debug
(
'
piexif found.
'
)
def
initialized
(
pelican
):
"""
Initialize the plugin.
This should be triggered on Pelican
'
s `initialized` signal.
"""
p
=
os
.
path
.
expanduser
(
'
~/Pictures
'
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_LIBRARY
'
,
p
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_GALLERY
'
,
(
1024
,
768
,
80
))
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_ARTICLE
'
,
(
760
,
506
,
80
))
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_THUMB
'
,
(
192
,
144
,
60
))
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_SQUARE_THUMB
'
,
False
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_GALLERY_TITLE
'
,
''
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_RESIZE_JOBS
'
,
1
)
DEFAULT_CONFIG
.
setdefault
(
'
VIDEO_COPY_JOBS
'
,
1
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_EXIF_KEEP
'
,
False
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_EXIF_REMOVE_GPS
'
,
False
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_EXIF_AUTOROTATE
'
,
True
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_EXIF_COPYRIGHT
'
,
False
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_EXIF_COPYRIGHT_AUTHOR
'
,
DEFAULT_CONFIG
[
'
SITENAME
'
])
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_LIGHTBOX_GALLERY_ATTR
'
,
'
data-lightbox
'
)
DEFAULT_CONFIG
.
setdefault
(
'
PHOTO_LIGHTBOX_CAPTION_ATTR
'
,
'
data-title
'
)
DEFAULT_CONFIG
[
'
queue_resize
'
]
=
{}
DEFAULT_CONFIG
[
'
queue_copy
'
]
=
{}
DEFAULT_CONFIG
[
'
created_galleries
'
]
=
{}
DEFAULT_CONFIG
[
'
plugin_dir
'
]
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
))
if
pelican
:
pelican
.
settings
.
setdefault
(
'
PHOTO_LIBRARY
'
,
p
)
pelican
.
settings
.
setdefault
(
'
PHOTO_GALLERY
'
,
(
1024
,
768
,
80
))
pelican
.
settings
.
setdefault
(
'
PHOTO_ARTICLE
'
,
(
760
,
506
,
80
))
pelican
.
settings
.
setdefault
(
'
PHOTO_THUMB
'
,
(
192
,
144
,
60
))
pelican
.
settings
.
setdefault
(
'
PHOTO_SQUARE_THUMB
'
,
False
)
pelican
.
settings
.
setdefault
(
'
PHOTO_GALLERY_TITLE
'
,
''
)
pelican
.
settings
.
setdefault
(
'
PHOTO_RESIZE_JOBS
'
,
1
)
pelican
.
settings
.
setdefault
(
'
VIDEO_COPY_JOBS
'
,
1
)
pelican
.
settings
.
setdefault
(
'
PHOTO_EXIF_KEEP
'
,
False
)
pelican
.
settings
.
setdefault
(
'
PHOTO_EXIF_REMOVE_GPS
'
,
False
)
pelican
.
settings
.
setdefault
(
'
PHOTO_EXIF_AUTOROTATE
'
,
True
)
pelican
.
settings
.
setdefault
(
'
PHOTO_EXIF_COPYRIGHT
'
,
False
)
pelican
.
settings
.
setdefault
(
'
PHOTO_EXIF_COPYRIGHT_AUTHOR
'
,
pelican
.
settings
[
'
AUTHOR
'
])
pelican
.
settings
.
setdefault
(
'
PHOTO_LIGHTBOX_GALLERY_ATTR
'
,
'
data-lightbox
'
)
pelican
.
settings
.
setdefault
(
'
PHOTO_LIGHTBOX_CAPTION_ATTR
'
,
'
data-title
'
)
def
read_notes
(
filename
,
msg
=
None
):
notes
=
{}
try
:
with
pelican_open
(
filename
)
as
text
:
for
line
in
text
.
splitlines
():
if
line
.
startswith
(
'
#
'
):
continue
m
=
line
.
split
(
'
:
'
,
1
)
if
len
(
m
)
>
1
:
item
=
m
[
0
].
strip
()
note
=
m
[
1
].
strip
()
if
item
and
note
:
notes
[
item
]
=
note
else
:
notes
[
line
]
=
''
except
Exception
as
e
:
if
msg
:
logger
.
info
(
'
{} at file {}
'
.
format
(
msg
,
filename
))
logger
.
debug
(
'
read_notes issue: {} at file {}. Debug message:{}
'
.
format
(
msg
,
filename
,
e
))
return
notes
def
enqueue_resize
(
orig
,
resized
,
spec
=
(
640
,
480
,
80
)):
logger
.
debug
(
'
photos: enqueue_resize({}, {}, {}
'
.
format
(
orig
,
resized
,
spec
))
if
resized
not
in
DEFAULT_CONFIG
[
'
queue_resize
'
]:
DEFAULT_CONFIG
[
'
queue_resize
'
][
resized
]
=
(
orig
,
spec
)
elif
DEFAULT_CONFIG
[
'
queue_resize
'
][
resized
]
!=
(
orig
,
spec
):
logger
.
error
(
'
photos: resize conflict for {}, {}-{} is not {}-{}
'
.
format
(
resized
,
DEFAULT_CONFIG
[
'
queue_resize
'
][
resized
][
0
],
DEFAULT_CONFIG
[
'
queue_resize
'
][
resized
][
1
],
orig
,
spec
))
def
enqueue_copy
(
orig
,
copied
):
logger
.
debug
(
'
photos: enqueue_copy({}, {}
'
.
format
(
orig
,
copied
))
if
copied
not
in
DEFAULT_CONFIG
[
'
queue_copy
'
]:
DEFAULT_CONFIG
[
'
queue_copy
'
][
copied
]
=
orig
elif
DEFAULT_CONFIG
[
'
queue_copy
'
][
copied
]
!=
orig
:
logger
.
error
(
'
photos: copy conflict for {}, {} is not {}
'
.
format
(
copied
,
DEFAULT_CONFIG
[
'
queue_copy
'
][
copied
],
orig
))
def
rotate_image
(
img
,
exif_dict
):
if
"
exif
"
in
img
.
info
and
piexif
.
ImageIFD
.
Orientation
in
exif_dict
[
"
0th
"
]:
orientation
=
exif_dict
[
"
0th
"
].
pop
(
piexif
.
ImageIFD
.
Orientation
)
if
orientation
==
2
:
img
=
img
.
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
elif
orientation
==
3
:
img
=
img
.
rotate
(
180
)
elif
orientation
==
4
:
img
=
img
.
rotate
(
180
).
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
elif
orientation
==
5
:
img
=
img
.
rotate
(
-
90
).
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
elif
orientation
==
6
:
img
=
img
.
rotate
(
-
90
,
expand
=
True
)
elif
orientation
==
7
:
img
=
img
.
rotate
(
90
).
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
elif
orientation
==
8
:
img
=
img
.
rotate
(
90
)
return
(
img
,
exif_dict
)
def
manipulate_exif
(
img
,
settings
):
try
:
exif
=
piexif
.
load
(
img
.
info
[
'
exif
'
])
except
Exception
:
logger
.
debug
(
'
EXIF information not found
'
)
exif
=
{}
if
settings
[
'
PHOTO_EXIF_AUTOROTATE
'
]:
img
,
exif
=
rotate_image
(
img
,
exif
)
if
settings
[
'
PHOTO_EXIF_REMOVE_GPS
'
]:
exif
.
pop
(
'
GPS
'
)
return
(
img
,
piexif
.
dump
(
exif
))
def
resize_worker
(
orig
,
resized
,
spec
,
settings
):
logger
.
info
(
'
photos: make photo {} -> {}
'
.
format
(
orig
,
resized
))
im
=
Image
.
open
(
orig
)
if
ispiexif
and
settings
[
'
PHOTO_EXIF_KEEP
'
]
and
im
.
format
==
'
JPEG
'
:
# Only works with JPEG exif for sure.
try
:
im
,
exif_copy
=
manipulate_exif
(
im
,
settings
)
except
Exception
:
logger
.
info
(
'
photos: no EXIF or EXIF error in {}
'
.
format
(
orig
))
exif_copy
=
b
''
else
:
exif_copy
=
b
''
icc_profile
=
im
.
info
.
get
(
"
icc_profile
"
,
None
)
if
settings
[
'
PHOTO_SQUARE_THUMB
'
]
and
spec
==
settings
[
'
PHOTO_THUMB
'
]:
im
=
ImageOps
.
fit
(
im
,
(
spec
[
0
],
spec
[
1
]),
Image
.
ANTIALIAS
)
im
.
thumbnail
((
spec
[
0
],
spec
[
1
]),
Image
.
ANTIALIAS
)
directory
=
os
.
path
.
split
(
resized
)[
0
]
if
not
os
.
path
.
exists
(
directory
):
try
:
os
.
makedirs
(
directory
)
except
Exception
:
logger
.
exception
(
'
Could not create {}
'
.
format
(
directory
))
else
:
logger
.
debug
(
'
Directory already exists at {}
'
.
format
(
os
.
path
.
split
(
resized
)[
0
]))
im
.
save
(
resized
,
'
JPEG
'
,
quality
=
spec
[
2
],
icc_profile
=
icc_profile
,
exif
=
exif_copy
)
def
copy_worker
(
orig
,
resized
,
settings
):
logger
.
info
(
'
photos: copy video {} -> {}
'
.
format
(
orig
,
resized
))
directory
=
os
.
path
.
split
(
resized
)[
0
]
if
not
os
.
path
.
exists
(
directory
):
try
:
os
.
makedirs
(
directory
)
except
Exception
:
logger
.
exception
(
'
Could not create {}
'
.
format
(
directory
))
else
:
logger
.
debug
(
'
Directory already exists at {}
'
.
format
(
os
.
path
.
split
(
resized
)[
0
]))
shutil
.
copyfile
(
orig
,
resized
)
def
resize_photos
(
generator
,
writer
):
if
generator
.
settings
[
'
PHOTO_RESIZE_JOBS
'
]
==
-
1
:
debug
=
True
generator
.
settings
[
'
PHOTO_RESIZE_JOBS
'
]
=
1
else
:
debug
=
False
pool
=
multiprocessing
.
Pool
(
generator
.
settings
[
'
PHOTO_RESIZE_JOBS
'
])
logger
.
debug
(
'
Debug Status: {}
'
.
format
(
debug
))
for
resized
,
what
in
DEFAULT_CONFIG
[
'
queue_resize
'
].
items
():
resized
=
os
.
path
.
join
(
generator
.
output_path
,
resized
)
orig
,
spec
=
what
if
(
not
os
.
path
.
isfile
(
resized
)
or
os
.
path
.
getmtime
(
orig
)
>
os
.
path
.
getmtime
(
resized
)):
if
debug
:
resize_worker
(
orig
,
resized
,
spec
,
generator
.
settings
)
else
:
pool
.
apply_async
(
resize_worker
,
(
orig
,
resized
,
spec
,
generator
.
settings
))
pool
.
close
()
pool
.
join
()
def
copy_videos
(
generator
,
writer
):
if
generator
.
settings
[
'
VIDEO_COPY_JOBS
'
]
==
-
1
:
debug
=
True
generator
.
settings
[
'
VIDEO_COPY_JOBS
'
]
=
1
else
:
debug
=
False
pool
=
multiprocessing
.
Pool
(
generator
.
settings
[
'
VIDEO_COPY_JOBS
'
])
logger
.
debug
(
'
Debug Status: {}
'
.
format
(
debug
))
for
copied
,
orig
in
DEFAULT_CONFIG
[
'
queue_copy
'
].
items
():
copied
=
os
.
path
.
join
(
generator
.
output_path
,
copied
)
if
(
not
os
.
path
.
isfile
(
copied
)
or
os
.
path
.
getmtime
(
orig
)
>
os
.
path
.
getmtime
(
copied
)):
if
debug
:
copy_worker
(
orig
,
copied
,
generator
.
settings
)
else
:
pool
.
apply_async
(
resize_worker
,
(
orig
,
copied
,
generator
.
settings
))
pool
.
close
()
pool
.
join
()
def
detect_content
(
content
):
"""
Triggered by Pelican
'
s `content_object_init` signal.
"""
hrefs
=
None
def
replacer
(
m
):
what
=
m
.
group
(
'
what
'
)
value
=
m
.
group
(
'
value
'
)
tag
=
m
.
group
(
'
tag
'
)
output
=
m
.
group
(
0
)
if
what
in
(
'
photo
'
,
'
lightbox
'
):
if
value
.
startswith
(
'
/
'
):
value
=
value
[
1
:]
path
=
os
.
path
.
join
(
os
.
path
.
expanduser
(
settings
[
'
PHOTO_LIBRARY
'
]),
value
)
if
os
.
path
.
isfile
(
path
):
photo_prefix
=
os
.
path
.
splitext
(
value
)[
0
].
lower
()
if
what
==
'
photo
'
:
photo_article
=
photo_prefix
+
'
a.jpg
'
enqueue_resize
(
path
,
os
.
path
.
join
(
'
photos
'
,
photo_article
),
settings
[
'
PHOTO_ARTICLE
'
]
)
output
=
''
.
join
((
'
<
'
,
m
.
group
(
'
tag
'
),
m
.
group
(
'
attrs_before
'
),
m
.
group
(
'
src
'
),
'
=
'
,
m
.
group
(
'
quote
'
),
os
.
path
.
join
(
settings
[
'
SITEURL
'
],
'
photos
'
,
photo_article
),
m
.
group
(
'
quote
'
),
m
.
group
(
'
attrs_after
'
),
))
elif
what
==
'
lightbox
'
and
tag
==
'
img
'
:
photo_gallery
=
photo_prefix
+
'
.jpg
'
enqueue_resize
(
path
,
os
.
path
.
join
(
'
photos
'
,
photo_gallery
),
settings
[
'
PHOTO_GALLERY
'
]
)
photo_thumb
=
photo_prefix
+
'
t.jpg
'
enqueue_resize
(
path
,
os
.
path
.
join
(
'
photos
'
,
photo_thumb
),
settings
[
'
PHOTO_THUMB
'
]
)
lightbox_attr_list
=
[
''
]
gallery_name
=
value
.
split
(
'
/
'
)[
0
]
lightbox_attr_list
.
append
(
'
{}=
"
{}
"'
.
format
(
settings
[
'
PHOTO_LIGHTBOX_GALLERY_ATTR
'
],
gallery_name
))
captions
=
read_notes
(
os
.
path
.
join
(
os
.
path
.
dirname
(
path
),
'
captions.txt
'
),
msg
=
'
photos: No captions for gallery
'
)
caption
=
captions
.
get
(
os
.
path
.
basename
(
path
))
if
captions
else
None
if
caption
:
lightbox_attr_list
.
append
(
'
{}=
"
{}
"'
.
format
(
settings
[
'
PHOTO_LIGHTBOX_CAPTION_ATTR
'
],
caption
))
lightbox_attrs
=
'
'
.
join
(
lightbox_attr_list
)
output
=
''
.
join
((
'
<a href=
'
,
m
.
group
(
'
quote
'
),
os
.
path
.
join
(
settings
[
'
SITEURL
'
],
'
photos
'
,
photo_gallery
),
m
.
group
(
'
quote
'
),
lightbox_attrs
,
'
><img
'
,
m
.
group
(
'
attrs_before
'
),
'
src=
'
,
m
.
group
(
'
quote
'
),
os
.
path
.
join
(
settings
[
'
SITEURL
'
],
'
photos
'
,
photo_thumb
),
m
.
group
(
'
quote
'
),
m
.
group
(
'
attrs_after
'
),
'
</a>
'
))
else
:
logger
.
error
(
'
photos: No photo %s
'
,
path
)
return
output
if
hrefs
is
None
:
regex
=
r
"""
<\s*
(?P<tag>[^\s\>]+) # detect the tag
(?P<attrs_before>[^\>]*)
(?P<src>href|src) # match tag with src and href attr
\s*=
(?P<quote>[
"
\']) # require value to be quoted
(?P<path>{0}(?P<value>.*?)) # the url value
(?P=quote)
(?P<attrs_after>[^\>]*>)
"""
.
format
(
content
.
settings
[
'
INTRASITE_LINK_REGEX
'
]
)
hrefs
=
re
.
compile
(
regex
,
re
.
X
)
if
content
.
_content
and
(
'
{photo}
'
in
content
.
_content
or
'
{lightbox}
'
in
content
.
_content
):
settings
=
content
.
settings
content
.
_content
=
hrefs
.
sub
(
replacer
,
content
.
_content
)
def
galleries_string_decompose
(
gallery_string
):
splitter_regex
=
re
.
compile
(
r
'
[\s,]*?({photo}|{filename})
'
)
title_regex
=
re
.
compile
(
r
'
{(.+)}
'
)
galleries
=
map
(
str
.
strip
,
filter
(
None
,
splitter_regex
.
split
(
gallery_string
)))
galleries
=
[
gallery
[
1
:]
if
gallery
.
startswith
(
'
/
'
)
else
gallery
for
gallery
in
galleries
]
if
len
(
galleries
)
%
2
==
0
and
'
'
not
in
galleries
:
galleries
=
zip
(
zip
([
'
type
'
]
*
len
(
galleries
[
0
::
2
]),
galleries
[
0
::
2
]),
zip
([
'
location
'
]
*
len
(
galleries
[
0
::
2
]),
galleries
[
1
::
2
]))
galleries
=
[
dict
(
gallery
)
for
gallery
in
galleries
]
for
gallery
in
galleries
:
title
=
re
.
search
(
title_regex
,
gallery
[
'
location
'
])
if
title
:
gallery
[
'
title
'
]
=
title
.
group
(
1
)
gallery
[
'
location
'
]
=
re
.
sub
(
title_regex
,
''
,
gallery
[
'
location
'
]).
strip
()
else
:
gallery
[
'
title
'
]
=
DEFAULT_CONFIG
[
'
PHOTO_GALLERY_TITLE
'
]
return
galleries
else
:
logger
.
error
(
'
Unexpected gallery location format!
\n
{}
'
.
format
(
pprint
.
pformat
(
galleries
)))
def
process_gallery
(
generator
,
content
,
location
):
content
.
photo_gallery
=
[]
galleries
=
galleries_string_decompose
(
location
)
for
gallery
in
galleries
:
if
gallery
[
'
location
'
]
in
DEFAULT_CONFIG
[
'
created_galleries
'
]:
content
.
photo_gallery
.
append
(
(
gallery
[
'
location
'
],
DEFAULT_CONFIG
[
'
created_galleries
'
][
gallery
]))
continue
if
gallery
[
'
type
'
]
==
'
{photo}
'
:
dir_gallery
=
os
.
path
.
join
(
os
.
path
.
expanduser
(
generator
.
settings
[
'
PHOTO_LIBRARY
'
]),
gallery
[
'
location
'
])
rel_gallery
=
gallery
[
'
location
'
]
elif
gallery
[
'
type
'
]
==
'
{filename}
'
:
base_path
=
os
.
path
.
join
(
generator
.
path
,
content
.
relative_dir
)
dir_gallery
=
os
.
path
.
join
(
base_path
,
gallery
[
'
location
'
])
rel_gallery
=
os
.
path
.
join
(
content
.
relative_dir
,
gallery
[
'
location
'
])
if
os
.
path
.
isdir
(
dir_gallery
):
logger
.
info
(
'
photos: Gallery detected: {}
'
.
format
(
rel_gallery
))
dir_photo
=
os
.
path
.
join
(
'
photos
'
,
rel_gallery
.
lower
())
dir_thumb
=
os
.
path
.
join
(
'
photos
'
,
rel_gallery
.
lower
())
exifs
=
read_notes
(
os
.
path
.
join
(
dir_gallery
,
'
exif.txt
'
),
msg
=
'
photos: No EXIF for gallery
'
)
captions
=
read_notes
(
os
.
path
.
join
(
dir_gallery
,
'
captions.txt
'
),
msg
=
'
photos: No captions for gallery
'
)
blacklist
=
read_notes
(
os
.
path
.
join
(
dir_gallery
,
'
blacklist.txt
'
),
msg
=
'
photos: No blacklist for gallery
'
)
content_gallery
=
[]
title
=
gallery
[
'
title
'
]
for
item
in
sorted
(
os
.
listdir
(
dir_gallery
)):
if
item
.
startswith
(
'
.
'
):
continue
if
item
.
endswith
(
'
.txt
'
):
continue
if
item
in
blacklist
:
continue
if
item
.
endswith
(
'
.mp4.jpg
'
):
if
os
.
path
.
isfile
(
os
.
path
.
join
(
dir_gallery
,
os
.
path
.
splitext
(
item
)[
0
])):
continue
thumb
=
os
.
path
.
splitext
(
item
)[
0
]
+
'
t.jpg
'
if
item
.
endswith
(
'
.jpg
'
):
enqueue_resize
(
os
.
path
.
join
(
dir_gallery
,
item
),
os
.
path
.
join
(
dir_photo
,
item
),
generator
.
settings
[
'
PHOTO_GALLERY
'
])
enqueue_resize
(
os
.
path
.
join
(
dir_gallery
,
item
),
os
.
path
.
join
(
dir_thumb
,
thumb
),
generator
.
settings
[
'
PHOTO_THUMB
'
])
elif
item
.
endswith
(
'
.mp4
'
):
enqueue_copy
(
os
.
path
.
join
(
dir_gallery
,
item
),
os
.
path
.
join
(
generator
.
output_path
,
dir_photo
,
item
),
)
still
=
item
+
'
.jpg
'
if
os
.
path
.
isfile
(
os
.
path
.
join
(
dir_gallery
,
still
)):
still
=
os
.
path
.
join
(
dir_gallery
,
still
)
else
:
here
=
os
.
path
.
dirname
(
__file__
)
still
=
os
.
path
.
join
(
here
,
'
images/video-icon.png
'
)
enqueue_resize
(
still
,
os
.
path
.
join
(
dir_thumb
,
thumb
),
generator
.
settings
[
'
PHOTO_THUMB
'
])
content_gallery
.
append
((
item
,
os
.
path
.
join
(
dir_photo
,
item
),
os
.
path
.
join
(
dir_thumb
,
thumb
),
exifs
.
get
(
item
,
''
),
captions
.
get
(
item
,
''
)))
# DEBUG TODO
# for c in content_gallery:
# raise(Exception(c))
content
.
photo_gallery
.
append
((
title
,
content_gallery
))
logger
.
debug
(
'
Gallery Data:
'
.
format
(
pprint
.
pformat
(
content
.
photo_gallery
)))
DEFAULT_CONFIG
[
'
created_galleries
'
][
'
gallery
'
]
=
content_gallery
else
:
logger
.
error
(
'
photos: Gallery does not exist: {} at {}
'
.
format
(
gallery
[
'
location
'
],
dir_gallery
))
def
detect_gallery
(
generator
,
content
):
if
'
gallery
'
in
content
.
metadata
:
gallery
=
content
.
metadata
.
get
(
'
gallery
'
)
if
gallery
.
startswith
(
'
{photo}
'
)
or
gallery
.
startswith
(
'
{filename}
'
):
process_gallery
(
generator
,
content
,
gallery
)
elif
gallery
:
logger
.
error
(
'
photos: Gallery tag not recognized: {}
'
.
format
(
gallery
))
def
image_clipper
(
x
):
return
x
[
8
:]
if
x
[
8
]
==
'
/
'
else
x
[
7
:]
def
file_clipper
(
x
):
return
x
[
11
:]
if
x
[
10
]
==
'
/
'
else
x
[
10
:]
def
process_image
(
generator
,
content
,
image
):
if
image
.
startswith
(
'
{photo}
'
):
path
=
os
.
path
.
join
(
os
.
path
.
expanduser
(
generator
.
settings
[
'
PHOTO_LIBRARY
'
]),
image_clipper
(
image
))
image
=
image_clipper
(
image
)
elif
image
.
startswith
(
'
{filename}
'
):
path
=
os
.
path
.
join
(
content
.
relative_dir
,
file_clipper
(
image
))
image
=
file_clipper
(
image
)
if
os
.
path
.
isfile
(
path
):
photo
=
os
.
path
.
splitext
(
image
)[
0
].
lower
()
+
'
a.jpg
'
thumb
=
os
.
path
.
splitext
(
image
)[
0
].
lower
()
+
'
t.jpg
'
content
.
photo_image
=
(
os
.
path
.
basename
(
image
).
lower
(),
os
.
path
.
join
(
'
photos
'
,
photo
),
os
.
path
.
join
(
'
photos
'
,
thumb
))
enqueue_resize
(
path
,
os
.
path
.
join
(
'
photos
'
,
photo
),
generator
.
settings
[
'
PHOTO_ARTICLE
'
])
enqueue_resize
(
path
,
os
.
path
.
join
(
'
photos
'
,
thumb
),
generator
.
settings
[
'
PHOTO_THUMB
'
])
else
:
logger
.
error
(
'
photo: No photo for {} at {}
'
.
format
(
content
.
source_path
,
path
))
def
detect_image
(
generator
,
content
):
image
=
content
.
metadata
.
get
(
'
image
'
,
None
)
if
image
:
if
image
.
startswith
(
'
{photo}
'
)
or
image
.
startswith
(
'
{filename}
'
):
process_image
(
generator
,
content
,
image
)
else
:
logger
.
error
(
'
photos: Image tag not recognized: {}
'
.
format
(
image
))
def
detect_images_and_galleries
(
generators
):
"""
Runs generator on both pages and articles.
"""
for
generator
in
generators
:
if
isinstance
(
generator
,
ArticlesGenerator
):
for
article
in
itertools
.
chain
(
generator
.
articles
,
generator
.
translations
,
generator
.
drafts
):
detect_image
(
generator
,
article
)
detect_gallery
(
generator
,
article
)
elif
isinstance
(
generator
,
PagesGenerator
):
for
page
in
itertools
.
chain
(
generator
.
pages
,
generator
.
translations
,
generator
.
hidden_pages
):
detect_image
(
generator
,
page
)
detect_gallery
(
generator
,
page
)
def
register
():
"""
Map signals to plugin logic.
Required by Pelican.
Uses the new style of registration based on GitHub Pelican issue #314.
"""
signals
.
initialized
.
connect
(
initialized
)
try
:
signals
.
content_object_init
.
connect
(
detect_content
)
signals
.
all_generators_finalized
.
connect
(
detect_images_and_galleries
)
signals
.
article_writer_finalized
.
connect
(
resize_photos
)
signals
.
article_writer_finalized
.
connect
(
copy_videos
)
except
Exception
as
e
:
logger
.
exception
(
'
Plugin failed to execute: {}
'
.
format
(
pprint
.
pformat
(
e
)))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment