diff --git a/content/about.md b/content/custom/about.md similarity index 100% rename from content/about.md rename to content/custom/about.md diff --git a/content/posts/Raft-Consensus-Algorithm.md b/content/posts/Raft-Consensus-Algorithm.md index 821361a..b10df9a 100644 --- a/content/posts/Raft-Consensus-Algorithm.md +++ b/content/posts/Raft-Consensus-Algorithm.md @@ -5,9 +5,15 @@ draft = true [taxonomies] tags=["Raft","分布式"] +++ + ## Log compact机制 + snapshot中需要对log进行compact,防止log过多对服务造成大量压力。 + ### compact策略 -- 执行snapshot时,删除上次snapshot之前的数据 -- 执行snapshot时,固定保留最后n条entry -- leader计算近期(分钟级别)心跳中所有follower的next_index最小值,再保留前n条entry \ No newline at end of file + +* 执行snapshot时,删除上次snapshot之前的数据 +* 执行snapshot时,固定保留最后n条entry +* leader计算近期(分钟级别)心跳中所有follower的next_index最小值,再保留前n条entry + + diff --git a/content/posts/first.md b/content/posts/first.md index f3fbcfb..4f665c2 100644 --- a/content/posts/first.md +++ b/content/posts/first.md @@ -1,6 +1,7 @@ +++ title = "Hey, this is my blog" date = 2022-08-25 +draft = true +++ Congratulations! \ No newline at end of file diff --git a/content/posts/google.md b/content/posts/google.md new file mode 100644 index 0000000..fb2e584 --- /dev/null +++ b/content/posts/google.md @@ -0,0 +1,11 @@ ++++ +title = "Google" +date = 2022-12-08 +template = "redirect.html" +draft = true +[taxonomies] +tags=["links"] +[extra] +redirect = "https://www.google.co.jp/" ++++ +Google \ No newline at end of file diff --git a/content/posts/python-async-pipeline.md b/content/posts/python-async-pipeline.md new file mode 100644 index 0000000..e8ee1fe --- /dev/null +++ b/content/posts/python-async-pipeline.md @@ -0,0 +1,189 @@ ++++ +title = "Python异步管道" +date = 2022-12-09 +draft = false +[taxonomies] +tags=["python"] ++++ +最近flink使用比较多,使用python处理大规模数据的时,按照`Pythonic`风格编码很难受,在github上找了一下python流式管道的库,发现了[pypeln](https://github.com/cgarciae/pypeln),[aiostream](https://github.com/vxgmichel/aiostream)。 + +## pypeln使用 + +> Concurrent data pipelines in Python >>> + +pypeln是一个并发数据管道库,当你觉得使用Spark、Flink、Dask过重,直接处理太慢的时候,可以使用它。 + +### 安装 + +```bash +pip install pypeln -i https://pypi.douban.com/simple +``` + +### 基本用法 + +```python +## 使用多进程模式 +# import pypeln.process as operator + +## 使用多线程模式 +# import pypeln.thread as operator + +# 使用协程模式 +import pypeln.task as operator + +def before_start_hook(database_uri): + async def wrapper(): + return {'database':await MongoClient(database_uri)} + return wrapper + +async def on_done_hook(database): + await database.close() + +async def find_url(data_id,database): + return await database.get_url_by_id(data_id) + +async def mock_http(url): + # 模拟http请求 + return await asyncio.sleep(3,{'url':url}) + +async def mock_data_store(doc,database): + await database.insert_one(doc) + +async def mock_data_source(): + for i in range(100): + yield str(i) +pipes=(mock_data_source() +# on_start:依赖注入到运行函数中 on_done:在结束时回调 + |operator.map(find_url,on_start=before_start_hook('data_uri'),on_done=on_done_hook,workers=8,maxsize=8) + |operator.map(mock_http,maxsize=200,workers=200) + |operator.each(mock_data_store,on_start=before_start_hook('data_uri'),on_done=on_done_hook,workers=8,maxsize=8) + ) +# 运行 +for pipe in pipes: + pass +``` + +### pypeln的问题 + +pypeln对于普通的并发任务可以很好的处理,该库没有实现buffer运算符,无法将流转换成批进行批量操作,写数据库和写文件存在瓶颈。 + +## aiostream + +> Generator-based operators for asynchronous iteration + +aiostream是一个基于生成器的异步库,使用拉模型,天然背压。 + +### 安装 + +```bash +pip install aiostream -i https://pypi.douban.com/simple +``` + +### 基本使用 + +```python +import asyncio +from aiostream import stream, pipe + +async def mock_http(url): + # 模拟http请求 + return await asyncio.sleep(3,{'url':url}) + +async def mock_data_store(docs): + await database.insert_one(doc) + +async def mock_data_source(): + for i in range(100): + yield str(i) + +async def main(): + async with get_database() as database: + async def find_url(data_id): + return await database.get_url_by_id(data_id) + async def mock_data_store(docs): + await database.insert_many(docs) + await (stream.iterate(mock_data_source()) + |stream.map(find_url,task_limit=5) + |stream.map(mock_http,task_limit=5) + |stream.timeout_buffer(100,3) + |stream.map(mock_data_store,task_limit=2) + ) +asyncio.run(main()) +``` + + +上面示例代码中`timeout_buffer`操作符官方没有实现,根据github issue中作者给出了样例: + +```python +from contextlib import asynccontextmanager + +import asyncio +from aiostream import pipe, operator, streamcontext + + +@asynccontextmanager +async def buffer(streamer, size=1): + queue = asyncio.Queue(maxsize=size) + sentinel = object() + + async def consume(): + try: + async for item in streamer: + await queue.put(item) + finally: + await queue.put(sentinel) + + @operator + async def wrapper(): + while True: + item = await queue.get() + if item is sentinel: + await future + return + yield item + + + future = asyncio.ensure_future(consume()) + try: + yield wrapper() + finally: + future.cancel() + + +@operator(pipable=True) +async def catch(source, exc_cls): + async with streamcontext(source) as streamer: + try: + async for item in streamer: + yield item + except exc_cls: + return + + +@operator(pipable=True) +async def chunks(source, n, timeout): + async with streamcontext(source) as streamer: + async with buffer(streamer) as buffered: + async with streamcontext(buffered) as first_streamer: + async for first in first_streamer: + tail = await ( + buffered + | pipe.timeout(timeout) + | catch.pipe(asyncio.TimeoutError) + | pipe.take(n - 1) + | pipe.list() + ) + yield [first, *tail] +pipe.timeout_buffer = chunks.pipe +``` + +### aiostream的问题 +拉模型分组分流实现比较麻烦,所有的流使用`merge`操作符汇聚调用`await`方法执行,[RxPY](https://github.com/ReactiveX/RxPY)是一个很好的替代品,采取推模式,但是3.x之后官方不在维护背压(back-pressure),`reactivex`概念难以理解,只能放弃使用。 + +## 应用 + +aiostream除了适合流式处理数据,也特别适合处理爬虫业务,使用aiostream重构后的爬虫,整体结构更加清晰,适合长期维护的爬虫。依靠python异步的性能,资源利用率,数据爬取效率均有一定提升。 + +之前公司内部部分项目使用`scrapy`,但是99%的`scrapy`特性没有使用,只是将`scrapy`作为爬取器与调度器,然后通过pipeline落库。今年爬虫项目大部分都上了k8s集群维护,不依赖scrapy的进程守护、web查看等功能,因此写了一个简化版本的`scrapy`,兼容部分scrapy api,公司内部所有使用scrapy的爬虫均可以替换依赖的方式兼容,无需修改代码。 + +后续考虑使用aiostream重构一版异步scrapy兼容框架减少项目内存与CPU资源的占用。 \ No newline at end of file diff --git a/content/posts/resteay-client.md b/content/posts/resteay-client.md new file mode 100644 index 0000000..883f4aa --- /dev/null +++ b/content/posts/resteay-client.md @@ -0,0 +1,98 @@ ++++ +title = "使用ResteasyClient请求接口" +date = 2020-04-08 +draft = false +[taxonomies] +tags=["Java"] ++++ +从OkHttp转到ResteasyClient + +## Okhttp + +以前一直用OkHttpclient访问api服务,参数复杂需要手工编码。 + +- query参数需要手工编码或者使用uribuilder构建完整url +- request body需要指定类型,不能使用类直接传参 + +## Retrofit + +接手外包公司安卓项目时接触到Retrofit框架,一种使用动态代理机制将java接口转换成网络请求。主要好处就是解耦,分离api定义和使用。作为程序员,偷懒就是第一生产力,这么方便的使用api肯定要集成到项目中。跑到google搜了搜,看到ResteasyCient也支持proxy模式请求api,选择无情抛弃Retrofit,毕竟项目中引入了keycloak做认证和授权,自带了ResteasyClient + +## ResteasyClient + +Resteasy是一个实现了JAX-RS规范的轻量实现,该规范是针对基于http协议的RESTful Web Service而提供标准的JAVA API定义。 + +ResteasyClient是Resteasy提供的一个HttpClient,用来消费Resteasy api,项目使用maven作为包管理。 + +### 1. pom.xml + +```xml + + 3.9.1.Final + + + + org.jboss.resteasy + resteasy-client + ${resteasy.version} + + ... + +``` + +这个是keycloak内置的resteasy-client版本,也可以用最新的,不过最新版构建Client的方式略有不同 + +### 2. 代码 + +客户端代码主要设计三大类: + +- **Client** +- **WebTarget** +- **Response** + +WebTarget实例由Client生成。 + +每个WebTarget对应一个BaseUrl,项目中是可以有很多WebTarget。 + +生成Client实例的方式有两种: + +- *org.jboss.resteasy.client.ClientRequest* 生成 +- *ResteasyClientBuilder* 类生成 + +这里使用第二种方式构建client,用ResteasyClient就是为了偷懒。 + +### 3. api接口定义 + +定义好请求的端点: + +```java +public interface AddressInterface { + @GET + @Path("/spider/geo") + List getLocation(@QueryParam("addresses") String addresses); +} + +``` + +LocaltionResult类: + +```java +@Data +public class LocationResult { + private String location; +} +``` + +这里使用了lombok简化代码 + +### 4. 请求接口 + +```java + +ResteasyClient client = new ResteasyClientBuilder().build(); +ResteasyWebTarget target = client.target(UriBuilder.fromPath("https://127.0.0.1:8080")); +ServicesInterface proxy = target.proxy(AddressInterface.class); +List results=proxy.getLocation("厦门市思明区塔埔东路169号2层201单元L室") +``` + +很简单 \ No newline at end of file diff --git a/content/posts/traefik-ingress-grpc.md b/content/posts/traefik-ingress-grpc.md index 071ca85..65d6460 100644 --- a/content/posts/traefik-ingress-grpc.md +++ b/content/posts/traefik-ingress-grpc.md @@ -9,7 +9,7 @@ jina框架使用gPRC协议通讯,部署到k8s中对外暴露服务需要配置 k3s中默认使用Traefik Ingress,参考yaml配置如下: -```YAML +```yaml --- # Service diff --git a/public/no-style-please.css b/public/no-style-please.css index adfdff6..8967933 100644 --- a/public/no-style-please.css +++ b/public/no-style-please.css @@ -1 +1 @@ -html[data-theme="dark"]{--page-back-color: rgb(27, 27, 27);--main-text-color: rgb(240, 240, 240);--main-back-color: rgb(17, 17, 17);--link-text-color: rgb(120, 217, 113);--target-highlight-color: rgb(255, 255, 0);--code-back-color:rgba(99,110,123,0.4);--github-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/github.png);--twitter-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/twitter-squared.png);--email-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/email.png);--coffee-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/kawaii-coffee.png);--webring-icon-url: url(https://webring.xxiivv.com/icon.white.svg);--rss-icon-url: url(https://img.icons8.com/material/64/f0f0f0/rss.png);--search-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/search.png);--cc-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons.png);--attribution-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-by.png);--non_com-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-nc.png);--share_alike-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-sa.png);--copyright-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/copyright.png)}html[data-theme="light"]{--page-back-color: rgb(240, 240, 240);--main-text-color: rgb(0, 0, 0);--main-back-color: rgb(255, 255, 255);--link-text-color: rgb(255, 76, 31);--code-back-color:rgba(175,184,193,0.2);--target-highlight-color: rgb(125, 0, 255);--github-icon-url: url(https://img.icons8.com/material-sharp/64/000000/github.png);--twitter-icon-url: url(https://img.icons8.com/material-sharp/64/000000/twitter-squared.png);--email-icon-url: url(https://img.icons8.com/material-sharp/64/000000/email.png);--coffee-icon-url: url(https://img.icons8.com/material-sharp/64/000000/kawaii-coffee.png);--webring-icon-url: url(https://webring.xxiivv.com/icon.black.svg);--rss-icon-url: url(https://img.icons8.com/material/64/000000/rss.png);--search-icon-url: url(https://img.icons8.com/material-sharp/64/000000/search.png);--cc-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons.png);--attribution-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-by.png);--non_com-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-nc.png);--share_alike-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-sa.png);--copyright-icon-url: url(https://img.icons8.com/material-outlined/64/000000/copyright.png)}:root{--text-0: rgba(0, 0, 0, 87%);--text-1: rgba(0, 0, 0, 66%);--bordercl: rebeccapurple;--bg-0: #fff;--bg-1: #f2f2f2;--primary-color: #ef5350;--hover-color: white}body[a="dark"]{filter:invert(1)}body[a="dark"] img{filter:invert(1)}body[a="dark"] img.ioda{filter:invert(0)}@media (prefers-color-scheme: dark){body[a="auto"]{filter:invert(1)}body[a="auto"] img{filter:invert(1)}body[a="auto"] img.ioda{filter:invert(0)}}html,input,select,textarea,label,button{color:var(--main-text-color);background-color:var(--page-back-color);font-family:'MapleMono';font-size:1rem;line-height:1.5;-webkit-font-smoothing:antialiased}.post-meta{text-align:right}h2,h3,h4,h5,h6{margin-top:3rem}hr{margin:2rem 0}p{margin:1rem 0}li{margin:0.4rem 0}*:target{background-color:var(--target-highlight-color);color:var(--main-back-color)}.wrapper{position:relative;background-color:var(--main-back-color);min-height:calc(100vh - 8rem);max-width:70ch;margin:2rem auto;padding:2rem 2rem}hr{margin:2rem 0;text-align:center;border:0;color:var(--main-text-color)}hr:before{content:"| | |"}hr:after{content:attr(data-content) "| | |"}table{width:100%}table,th,td{border:thin solid var(--main-text-color);border-collapse:collapse;padding:0.4rem}p code{background-color:var(--code-back-color);padding:.2em .4em;margin:0;font-size:85%;border-radius:6px}div.highlighter-rouge code{display:block;overflow-x:auto;white-space:pre-wrap;padding:1rem}blockquote{font-style:italic;border:thin solid black;padding:1rem}blockquote p{margin:0}img{max-width:100%;display:block;margin:0 auto}a{color:var(--link-text-color);cursor:pointer}.post_date{font-size:1rem;font-style:italic;font-weight:bold;margin-bottom:2rem;margin-right:1rem}.github_icon{content:var(--github-icon-url)}.twitter_icon{content:var(--twitter-icon-url)}.email_icon{content:var(--email-icon-url)}.coffee_icon{content:var(--coffee-icon-url)}.search_icon{content:var(--search-icon-url)}.webring_icon{content:var(--webring-icon-url)}.rss_icon{content:var(--rss-icon-url)}a.cc_list{text-decoration:none}.copyright_icon{content:var(--copyright-icon-url);height:16px;margin:-3px}.cc_icon{content:var(--cc-icon-url);height:16px;margin:-3px}.attribution_icon{content:var(--attribution-icon-url);height:16px;margin:-3px}.non_com_icon{content:var(--non_com-icon-url);height:16px;margin:-3px}.share_alike_icon{content:var(--share_alike-icon-url);height:16px;margin:-3px}.octicon:hover{visibility:hidden}h1 .octicon{margin-left:-2.4em;margin-right:calc(2.4em - 1.8em)}h2 .octicon{margin-left:-2.9em;margin-right:calc(2.9em - 1.8em)}h3 .octicon{margin-left:-3.4em;margin-right:calc(3.4em - 1.8em)}h4 .octicon{margin-left:-3.9em;margin-right:calc(3.9em - 1.8em)}h5 .octicon{margin-left:-4.4em;margin-right:calc(4.4em - 1.8em)}h6 .octicon{margin-left:-4.9em;margin-right:calc(4.9em - 1.8em)}.octicon{fill:currentColor;visibility:visible;pointer-events:all;vertical-align:middle;width:1.2em;height:1.2em}input,select,textarea,label,button{border-radius:0.3em;margin-left:0}fieldset{border:none;padding:0}.textfield{max-width:100%;padding-bottom:1rem}.narrowfield{width:420px}.hp{display:none}textarea{vertical-align:top}.textfield__input{border:1px solid rgba(0,0,0,0.12);border-radius:0.3em;padding:0.4em;width:100%;max-width:-webkit-fill-available}.notify-me,.g-recaptcha{padding-bottom:1rem;max-width:min-content}.button{border:1px solid rgba(0,0,0,0.12);background:var(--page-back-color);border-radius:0.3em;padding:0.4em;overflow:hidden;cursor:pointer}button:hover{background-color:var(--main-text-color);color:var(--main-back-color)}footer{bottom:0;position:absolute;left:0;right:0;display:flex;align-items:center;flex-direction:column;padding-bottom:0.5rem}.soc{display:flex;align-items:center;justify-content:center;border-radius:4px;margin-right:1rem}.soc:hover{color:var(--main-back-color);background:var(--link-text-color)}.footer-info{padding:var(--footer-padding)}.list{margin-bottom:2rem}.horizon{display:flex;justify-content:end}.horizon .start{width:100%}article{margin-bottom:2rem}article .body{word-wrap:break-word}.pagination{margin-bottom:2rem}pre{padding:1rem;overflow:auto}pre[data-linenos]{padding:1rem 0}pre table td{padding:0}pre table td:nth-of-type(1){text-align:center;user-select:none}pre mark{display:block;background-color:rgba(254,252,232,0.9)}pre table{width:100%;border-collapse:collapse} +html[data-theme="dark"]{--page-back-color: rgb(27, 27, 27);--main-text-color: rgb(240, 240, 240);--main-back-color: rgb(17, 17, 17);--link-text-color: rgb(120, 217, 113);--target-highlight-color: rgb(255, 255, 0);--code-back-color:rgba(99,110,123,0.4);--github-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/github.png);--twitter-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/twitter-squared.png);--email-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/email.png);--coffee-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/kawaii-coffee.png);--webring-icon-url: url(https://webring.xxiivv.com/icon.white.svg);--rss-icon-url: url(https://img.icons8.com/material/64/f0f0f0/rss.png);--search-icon-url: url(https://img.icons8.com/material-sharp/64/f0f0f0/search.png);--cc-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons.png);--attribution-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-by.png);--non_com-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-nc.png);--share_alike-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/creative-commons-sa.png);--copyright-icon-url: url(https://img.icons8.com/material-outlined/64/f0f0f0/copyright.png)}html[data-theme="light"]{--page-back-color: rgb(240, 240, 240);--main-text-color: rgb(0, 0, 0);--main-back-color: rgb(255, 255, 255);--link-text-color: rgb(255, 76, 31);--code-back-color:rgba(175,184,193,0.2);--target-highlight-color: rgb(125, 0, 255);--github-icon-url: url(https://img.icons8.com/material-sharp/64/000000/github.png);--twitter-icon-url: url(https://img.icons8.com/material-sharp/64/000000/twitter-squared.png);--email-icon-url: url(https://img.icons8.com/material-sharp/64/000000/email.png);--coffee-icon-url: url(https://img.icons8.com/material-sharp/64/000000/kawaii-coffee.png);--webring-icon-url: url(https://webring.xxiivv.com/icon.black.svg);--rss-icon-url: url(https://img.icons8.com/material/64/000000/rss.png);--search-icon-url: url(https://img.icons8.com/material-sharp/64/000000/search.png);--cc-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons.png);--attribution-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-by.png);--non_com-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-nc.png);--share_alike-icon-url: url(https://img.icons8.com/material-outlined/64/000000/creative-commons-sa.png);--copyright-icon-url: url(https://img.icons8.com/material-outlined/64/000000/copyright.png)}:root{--text-0: rgba(0, 0, 0, 87%);--text-1: rgba(0, 0, 0, 66%);--bordercl: rebeccapurple;--bg-0: #fff;--bg-1: #f2f2f2;--primary-color: #ef5350;--hover-color: white;--footer-padding: 1rem}body[a="dark"]{filter:invert(1)}body[a="dark"] img{filter:invert(1)}body[a="dark"] img.ioda{filter:invert(0)}@media (prefers-color-scheme: dark){body[a="auto"]{filter:invert(1)}body[a="auto"] img{filter:invert(1)}body[a="auto"] img.ioda{filter:invert(0)}}html,input,select,textarea,label,button{color:var(--main-text-color);background-color:var(--page-back-color);font-family:'MapleMono';font-size:1rem;line-height:1.5;-webkit-font-smoothing:antialiased}.post-meta{text-align:right}h2,h3,h4,h5,h6{margin-top:3rem}hr{margin:2rem 0}p{margin:1rem 0}li{margin:0.4rem 0}*:target{background-color:var(--target-highlight-color);color:var(--main-back-color)}.wrapper{position:relative;background-color:var(--main-back-color);min-height:calc(100vh - 8rem);max-width:70ch;margin:2rem auto;padding:2rem 2rem 0 2rem}.wrapper .list{min-height:72vh}.discus{width:100%}hr{margin:2rem 0;text-align:center;border:0;color:var(--main-text-color)}hr:before{content:"| | |"}hr:after{content:attr(data-content) "| | |"}table{width:100%}table,th,td{border:thin solid var(--main-text-color);border-collapse:collapse;padding:0.4rem}p code{background-color:var(--code-back-color);padding:.2em .4em;margin:0;font-size:85%;border-radius:6px}div.highlighter-rouge code{display:block;overflow-x:auto;white-space:pre-wrap;padding:1rem}blockquote{font-style:italic;border:thin solid black;padding:1rem}blockquote p{margin:0}img{max-width:100%;display:block;margin:0 auto}a{color:var(--link-text-color);cursor:pointer}.post_date{font-size:1rem;font-style:italic;font-weight:bold;margin-bottom:2rem;margin-right:1rem}.github_icon{content:var(--github-icon-url)}.twitter_icon{content:var(--twitter-icon-url)}.email_icon{content:var(--email-icon-url)}.coffee_icon{content:var(--coffee-icon-url)}.search_icon{content:var(--search-icon-url)}.webring_icon{content:var(--webring-icon-url)}.rss_icon{content:var(--rss-icon-url)}a.cc_list{text-decoration:none}.copyright_icon{content:var(--copyright-icon-url);height:16px;margin:-3px}.cc_icon{content:var(--cc-icon-url);height:16px;margin:-3px}.attribution_icon{content:var(--attribution-icon-url);height:16px;margin:-3px}.non_com_icon{content:var(--non_com-icon-url);height:16px;margin:-3px}.share_alike_icon{content:var(--share_alike-icon-url);height:16px;margin:-3px}.octicon:hover{visibility:hidden}h1 .octicon{margin-left:-2.4em;margin-right:calc(2.4em - 1.8em)}h2 .octicon{margin-left:-2.9em;margin-right:calc(2.9em - 1.8em)}h3 .octicon{margin-left:-3.4em;margin-right:calc(3.4em - 1.8em)}h4 .octicon{margin-left:-3.9em;margin-right:calc(3.9em - 1.8em)}h5 .octicon{margin-left:-4.4em;margin-right:calc(4.4em - 1.8em)}h6 .octicon{margin-left:-4.9em;margin-right:calc(4.9em - 1.8em)}.octicon{fill:currentColor;visibility:visible;pointer-events:all;vertical-align:middle;width:1.2em;height:1.2em}input,select,textarea,label,button{border-radius:0.3em;margin-left:0}fieldset{border:none;padding:0}.textfield{max-width:100%;padding-bottom:1rem}.narrowfield{width:420px}.hp{display:none}textarea{vertical-align:top}.textfield__input{border:1px solid rgba(0,0,0,0.12);border-radius:0.3em;padding:0.4em;width:100%;max-width:-webkit-fill-available}.notify-me,.g-recaptcha{padding-bottom:1rem;max-width:min-content}.button{border:1px solid rgba(0,0,0,0.12);background:var(--page-back-color);border-radius:0.3em;padding:0.4em;overflow:hidden;cursor:pointer}button:hover{background-color:var(--main-text-color);color:var(--main-back-color)}footer{display:flex;align-items:center;flex-direction:column;padding-bottom:0.5rem}.soc{display:flex;align-items:center;justify-content:center;border-radius:4px;margin-right:1rem}.soc:hover{color:var(--main-back-color);background:var(--link-text-color)}.footer-info{padding:var(--footer-padding)}.list{margin-bottom:2rem}.horizon{display:flex;justify-content:end}.horizon .start{width:100%}.nav{width:20%;height:1.5em;min-width:max-content;margin-left:auto;margin-right:auto;text-align:justify;-ms-text-justify:distribute-all-lines;text-justify:distribute-all-lines}.nav a,.nav div{vertical-align:middle;display:inline-block;*display:inline}.nav img{height:1.5em}.stretch{width:100%;display:inline-block;font-size:0;line-height:0}article{margin-bottom:2rem}article .body{word-wrap:break-word;min-height:70vh}.pagination{margin-bottom:2rem}pre{padding:1rem;overflow:auto}pre[data-linenos]{padding:1rem 0}pre table td{padding:0}pre table td:nth-of-type(1){text-align:center;user-select:none}pre mark{display:block;background-color:rgba(254,252,232,0.9)}pre table{width:100%;border-collapse:collapse} diff --git a/sass/no-style-please.scss b/sass/no-style-please.scss index 4b06c30..3d8c734 100644 --- a/sass/no-style-please.scss +++ b/sass/no-style-please.scss @@ -9,6 +9,7 @@ --primary-color: #ef5350; --hover-color: white; + --footer-padding: 1rem; } // -------------- THEME SWITCHER -------------- // @mixin dark-appearance { @@ -85,9 +86,14 @@ li { min-height: calc(100vh - 8rem); max-width: 70ch; margin: 2rem auto; - padding: 2rem 2rem; + padding: 2rem 2rem 0 2rem; + .list { + min-height: 72vh; + } +} +.discus { + width: 100%; } - hr { margin: 2rem 0; text-align: center; @@ -323,10 +329,10 @@ button:hover { } footer { - bottom: 0; - position: absolute; - left: 0; - right: 0; + // bottom: 0; + // position: absolute; + // left: 0; + // right: 0; display: flex; align-items: center; flex-direction: column; @@ -360,11 +366,41 @@ footer { } } +.nav { + width: 20%; + height: 1.5em; + min-width: max-content; + margin-left: auto; + margin-right: auto; + text-align: justify; + -ms-text-justify: distribute-all-lines; + text-justify: distribute-all-lines; + + a, div { + vertical-align: middle; + display: inline-block; + *display: inline; + + } + + img { + height: 1.5em; + } +} + +.stretch { + width: 100%; + display: inline-block; + font-size: 0; + line-height: 0; +} + article { margin-bottom: 2rem; .body { word-wrap: break-word; + min-height: 70vh; } } .pagination { diff --git a/templates/base.html b/templates/base.html index 13f5587..fad04a2 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% import "macros/macros.html" as post_macros %} - + {% include "partials/header.html" %} diff --git a/templates/macros/macros.html b/templates/macros/macros.html index 1e6c5c9..fabbd1b 100644 --- a/templates/macros/macros.html +++ b/templates/macros/macros.html @@ -1,6 +1,6 @@ {% macro list_posts(pages, tag_name=false) %} @@ -61,7 +61,9 @@

{{ title }}

-{% endmacro content %} +{% endmacro page_header %} + + {% macro content(page) %}
@@ -70,6 +72,12 @@ {% if time < 1 %} {% set time = 1 %} {% endif %} + {% if page.lower %} + {% set_global previous = page.lower %} + {% endif %} + {% if page.higher %} + {% set_global next = page.higher %} + {% endif %}
diff --git a/templates/page.html b/templates/page.html index 0ed1a9f..390a382 100644 --- a/templates/page.html +++ b/templates/page.html @@ -1,4 +1,24 @@ {% extends "base.html" %} {% block main_content %} {{ post_macros::content(page=page)}} + + + {# +
{% endblock main_content %} \ No newline at end of file diff --git a/templates/partials/header.html b/templates/partials/header.html index 0491abe..bfcd176 100644 --- a/templates/partials/header.html +++ b/templates/partials/header.html @@ -14,7 +14,7 @@ {% else %} - {{ page.title | default(value=config.title) | default(value="Post") }} + {{ page.title | default(value=config.title) | default(value="Posts") |safe}} {% endif %} diff --git a/templates/posts.html b/templates/posts.html index 622f4f7..452c15e 100644 --- a/templates/posts.html +++ b/templates/posts.html @@ -5,8 +5,10 @@

{{ config.title }}

{%- if paginator %} + {%- set show_pages = paginator.pages -%} {% else %} + {% set section = get_section(path="posts/_index.md") %} {%- set show_pages = section.pages -%} {% endif -%} diff --git a/templates/redirect.html b/templates/redirect.html new file mode 100644 index 0000000..16569c3 --- /dev/null +++ b/templates/redirect.html @@ -0,0 +1,22 @@ + + + + + + + + Page Redirection + + {# Favicon #} + {% if config.extra.favicon %} + +{% endif %} + + + + + If you are not redirected automatically, follow this link. + + \ No newline at end of file