mirror of
https://github.com/httpjamesm/AnonymousOverflow.git
synced 2024-12-06 19:16:43 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 471e34b5e6 | |||
| 80b45bf034 | |||
| bcc932bd22 | |||
| e19717ff32 | |||
| 6ce4817489 | |||
| b2a675b94c | |||
| 7596516574 | |||
| 215f24cd53 | |||
| a4d9402a57 | |||
| c2a9b4368a | |||
| 67c09e5e89 | |||
| 8174f2ee44 |
@@ -2,34 +2,32 @@
|
|||||||
name: Bug report
|
name: Bug report
|
||||||
about: 'Create a report to help us improve'
|
about: 'Create a report to help us improve'
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: 'bug'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Please make sure you're on the latest version before submitting.
|
Please make sure you're on the latest version before submitting.
|
||||||
|
|
||||||
|
|
||||||
# What's Happening?
|
# What's Happening?
|
||||||
<!-- Describe here -->
|
|
||||||
|
|
||||||
|
<!-- Describe here -->
|
||||||
|
|
||||||
## How to reproduce:
|
## How to reproduce:
|
||||||
<!-- Describe here -->
|
|
||||||
|
|
||||||
|
<!-- Describe here -->
|
||||||
|
|
||||||
## Affected Platforms:
|
## Affected Platforms:
|
||||||
|
|
||||||
- [ ] macOS
|
- [ ] macOS
|
||||||
- [ ] Windows
|
- [ ] Windows
|
||||||
- [ ] Linux (Specify)
|
- [ ] Linux (Specify)
|
||||||
- [ ] iOS
|
- [ ] iOS
|
||||||
- [ ] Android
|
- [ ] Android
|
||||||
|
|
||||||
Version:
|
Version:
|
||||||
|
|
||||||
## Browser:
|
## Browser:
|
||||||
|
|
||||||
- [ ] Chromium-based (ex: Brave or Chrome)
|
- [ ] Chromium-based (ex: Brave or Chrome)
|
||||||
- [ ] Webkit-based (ex: Safari)
|
- [ ] Webkit-based (ex: Safari)
|
||||||
- [ ] Gecko-based (ex: Firefox)
|
- [ ] Gecko-based (ex: Firefox)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: 'Suggest a specific feature or enhancement'
|
||||||
|
title: ''
|
||||||
|
labels: 'enhancement'
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
# What does the feature entail?
|
||||||
|
|
||||||
|
<!-- Describe here -->
|
||||||
|
|
||||||
|
# Why is this feature important?
|
||||||
|
|
||||||
|
<!-- Describe here -->
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
name: New Instance
|
|
||||||
about: 'Add my public instance to the list'
|
|
||||||
title: "[INSTANCE] New public instance"
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Instance URL:
|
|
||||||
Region (Written Out - ex United States):
|
|
||||||
Operated by (Link to your site):
|
|
||||||
@@ -12,47 +12,9 @@ This project is super lightweight by design. The UI is simple and the frontend i
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Clearnet Instances
|
## Instances
|
||||||
|
|
||||||
| Instance URL | Region | Notes |
|
Visit the [AnonymousOverflow Hub](https://aohub.httpjames.space) for a list of instances.
|
||||||
| ----------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
||||||
| [code.whatever.social](https://code.whatever.social) | Germany | Operated by [Whatever Social](https://whatever.social) and [http.james](https://httpjames.space) |
|
|
||||||
| [ao.vern.cc](https://ao.vern.cc) | United States | Operated by [vern.cc](https://vern.cc) |
|
|
||||||
| [overflow.smnz.de](https://overflow.smnz.de) | Germany | Operated by [smnz.de](https://smnz.de) |
|
|
||||||
| [overflow.lunar.icu](https://overflow.lunar.icu) | Germany | Operated by [lunar.icu](https://lunar.icu/) |
|
|
||||||
| [overflow.adminforge.de](https://overflow.adminforge.de/) | Germany | Operated by [adminForge](https://adminforge.de/) |
|
|
||||||
| [overflow.hostux.net](https://overflow.hostux.net/) | France | Operated by [Hostux](https://hostux.net/) |
|
|
||||||
| [overflow.projectsegfau.lt](https://overflow.projectsegfau.lt/) | United States, Germany, India | Operated by [Project Segfault](https://projectsegfau.lt/) |
|
|
||||||
| [code.xbdm.fun](https://code.xbdm.fun) | Germany | Operated by [xbdm.fun](https://xbdm.fun) |
|
|
||||||
| [overflow.fascinated.cc](https://overflow.fascinated.cc/) | Germany | Operated by [fascinated.cc](https://fascinated.cc/) |
|
|
||||||
| [ao.bloat.cat](https://ao.bloat.cat) | Romania | Operated by [bloat.cat](https://bloat.cat) |
|
|
||||||
| [anonoverflow.frontendfriendly.xyz](https://anonoverflow.frontendfriendly.xyz/) | United States | Operated by [frontendfriendly.xyz](https://frontendfriendly.xyz/) |
|
|
||||||
| [ao.owo.si](https://ao.owo.si/) | Germany | Operated by [owo.si](https://owo.si/) |
|
|
||||||
| [overflow.datura.network](https://overflow.datura.network/) | Germany | Operated by [datura.network](https://datura.network) |
|
|
||||||
| [overflow.freedit.eu](overflow.freedit.eu) | United States | Operated by [freedit.eu](https://freedit.eu) |
|
|
||||||
| [ao.ftw.lol](https://ao.ftw.lol) | Germany | Operated by [ftw.lol](https://ftw.lol) |
|
|
||||||
| [anonoverflow.hyperreal.coffee](https://anonoverflow.hyperreal.coffee) | United States | Operated by [hyperreal.coffee](https://hyperreal.coffee) |
|
|
||||||
| [overflow.sudovanilla.com](https://overflow.sudovanilla.com) | United States | Operated by [SudoVanilla](https://sudovanilla.com) |
|
|
||||||
| [anonymousoverflow.privacyfucking.rocks](https://anonymousoverflow.privacyfucking.rocks/) | Germany | Operated by [privacyfucking.rocks](https://privacyfucking.rocks) |
|
|
||||||
| [exchange.seitan-ayoub.lol](https://exchange.seitan-ayoub.lol) | Germany | Operated by [Seitan Ayoub](https://seitan-ayoub.lol) |
|
|
||||||
| [overflow.r4fo.com](https://overflow.r4fo.com) | The Netherlands | Operated by [r4fo.com](https://r4fo.com) |
|
|
||||||
| [overflow.ducks.party](https://overflow.ducks.party) | The Netherlands | Operated by [ducks.party](https://ducks.party) |
|
|
||||||
| [ao.ngn.tf](https://ao.ngn.tf) | Turkey | Operated by [ngn](https://ngn.tf) |
|
|
||||||
| [overflow.snine.nl](https://overflow.snine.nl) | The Netherlands | Operated by [snine](https://snine.nl) |
|
|
||||||
| [anonymousoverflow.privacyredirect.com](https://anonymousoverflow.privacyredirect.com) | Finland | Operated by [privacyredirect.com](https://privacyredirect.com/) |
|
|
||||||
| [soflow.nerdvpn.de](https://soflow.nerdvpn.de) | Ukraine | Operated by [Sommerwiesel](https://github.com/Sommerwiesel) |
|
|
||||||
|
|
||||||
## Other Instances
|
|
||||||
|
|
||||||
| Instance URL | Region | Notes |
|
|
||||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | --------------------------------------------------------- |
|
|
||||||
| [ao.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion](http://ao.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion) | United States | Operated by [vern.cc](https://vern.cc) |
|
|
||||||
| [vernmzgraj6aaoafmehupvtkkynpaa67rxcdj2kinwiy6konn6rq.b32.i2p](http://vernmzgraj6aaoafmehupvtkkynpaa67rxcdj2kinwiy6konn6rq.b32.i2p) | United States | Operated by [vern.cc](https://vern.cc) |
|
|
||||||
| [overflow.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion](http://overflow.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion/) | Germany | Operated by [Project Segfault](https://projectsegfau.lt/) |
|
|
||||||
| [overflow.daturab6drmkhyeia4ch5gvfc2f3wgo6bhjrv3pz6n7kxmvoznlkq4yd.onion](http://overflow.daturab6drmkhyeia4ch5gvfc2f3wgo6bhjrv3pz6n7kxmvoznlkq4yd.onion/) | Germany | Operated by [datura.network](https://datura.network) |
|
|
||||||
| [ao.pk47sgwhncn5cgidm7bofngmh7lc7ukjdpk5bjwfemmyp27ovl25ikyd.onion](http://ao.pk47sgwhncn5cgidm7bofngmh7lc7ukjdpk5bjwfemmyp27ovl25ikyd.onion/) | Germany | Operated by [owo.si](https://owo.si/) |
|
|
||||||
| [ay7akchgdh76r4lc62hzd52z6xqoh67loototsetvqxo5o7ngo5q.b32.i2p](http://ay7akchgdh76r4lc62hzd52z6xqoh67loototsetvqxo5o7ngo5q.b32.i2p/) | Germany | Operated by [owo.si](https://owo.si/) |
|
|
||||||
| [overflow.r4focoma7gu2zdwwcjjad47ysxt634lg73sxmdbkdozanwqslho5ohyd.onion](http://overflow.r4focoma7gu2zdwwcjjad47ysxt634lg73sxmdbkdozanwqslho5ohyd.onion) | The Netherlands | Operated by [r4fo.com](https://r4fo.com) |
|
|
||||||
|
|
||||||
## Why use AnonymousOverflow over StackOverflow?
|
## Why use AnonymousOverflow over StackOverflow?
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
var Version = "1.12.1"
|
var Version = "1.13.0"
|
||||||
|
|||||||
+207
@@ -0,0 +1,207 @@
|
|||||||
|
{
|
||||||
|
"clearnet": [
|
||||||
|
{
|
||||||
|
"url": "https://code.whatever.social",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://whatever.social", "https://httpjames.space"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://ao.vern.cc",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://vern.cc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.smnz.de",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://smnz.de"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.lunar.icu",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://lunar.icu/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.adminforge.de/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://adminforge.de/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.hostux.net/",
|
||||||
|
"regions": ["France"],
|
||||||
|
"operators": ["https://hostux.net/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.projectsegfau.lt/",
|
||||||
|
"regions": ["United States", "Germany", "India"],
|
||||||
|
"operators": ["https://projectsegfau.lt/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://code.xbdm.fun",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://xbdm.fun"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.fascinated.cc/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://fascinated.cc/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://ao.bloat.cat",
|
||||||
|
"regions": ["Romania"],
|
||||||
|
"operators": ["https://bloat.cat"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://anonoverflow.frontendfriendly.xyz/",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://frontendfriendly.xyz/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://ao.owo.si/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://owo.si/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.datura.network/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://datura.network"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.freedit.eu",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://freedit.eu"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://ao.ftw.lol",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://ftw.lol"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://anonoverflow.nirn.quest",
|
||||||
|
"regions": ["Canada"],
|
||||||
|
"operators": ["https://nirn.quest", "https://hyperreal.coffee"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.sudovanilla.com",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://sudovanilla.com"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://anonymousoverflow.privacyfucking.rocks/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://privacyfucking.rocks"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://exchange.seitan-ayoub.lol",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://seitan-ayoub.lol"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.r4fo.com",
|
||||||
|
"regions": ["The Netherlands"],
|
||||||
|
"operators": ["https://r4fo.com"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.ducks.party",
|
||||||
|
"regions": ["The Netherlands"],
|
||||||
|
"operators": ["https://ducks.party"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://ao.ngn.tf",
|
||||||
|
"regions": ["Turkey"],
|
||||||
|
"operators": ["https://ngn.tf"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.snine.nl",
|
||||||
|
"regions": ["The Netherlands"],
|
||||||
|
"operators": ["https://snine.nl"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://anonymousoverflow.privacyredirect.com",
|
||||||
|
"regions": ["Finland"],
|
||||||
|
"operators": ["https://privacyredirect.com/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://soflow.nerdvpn.de",
|
||||||
|
"regions": ["Ukraine"],
|
||||||
|
"operators": ["https://github.com/Sommerwiesel"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.einfachzocken.eu/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://einfachzocken.eu"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.seasi.dev/",
|
||||||
|
"regions": ["Singapore"],
|
||||||
|
"operators": ["https://seasi.dev/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://anonymousoverflow.catsarch.com",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://catsarch.com"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://overflow.darkness.services/",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://zzz.darkness.services"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"onion": [
|
||||||
|
{
|
||||||
|
"url": "http://ao.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://vern.cc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://overflow.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://projectsegfau.lt/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://overflow.daturab6drmkhyeia4ch5gvfc2f3wgo6bhjrv3pz6n7kxmvoznlkq4yd.onion/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://datura.network"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://ao.pk47sgwhncn5cgidm7bofngmh7lc7ukjdpk5bjwfemmyp27ovl25ikyd.onion/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://owo.si/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://overflow.r4focoma7gu2zdwwcjjad47ysxt634lg73sxmdbkdozanwqslho5ohyd.onion",
|
||||||
|
"regions": ["The Netherlands"],
|
||||||
|
"operators": ["https://r4fo.com"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://anonymousoverflow.catsarchywsyuss6jdxlypsw5dc7owd5u5tr6bujxb7o6xw2hipqehyd.onion/",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://catsarch.com"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://overflow.darknessrdor43qkl2ngwitj72zdavfz2cead4t5ed72bybgauww5lyd.onion/",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": [
|
||||||
|
"http://darknessrdor43qkl2ngwitj72zdavfz2cead4t5ed72bybgauww5lyd.onion/"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"i2p": [
|
||||||
|
{
|
||||||
|
"url": "http://vernmzgraj6aaoafmehupvtkkynpaa67rxcdj2kinwiy6konn6rq.b32.i2p",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://vern.cc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://ay7akchgdh76r4lc62hzd52z6xqoh67loototsetvqxo5o7ngo5q.b32.i2p/",
|
||||||
|
"regions": ["Germany"],
|
||||||
|
"operators": ["https://owo.si/"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://ocp7zhdsbl2mjabv5ma5jvbzg2dqzglieayjvyj4j2r7qvsqlboa.b32.i2p/",
|
||||||
|
"regions": ["United States"],
|
||||||
|
"operators": ["https://catsarch.com"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -55,6 +55,23 @@ func main() {
|
|||||||
r.GET("/q/:id", routes.RedirectShortenedOverflowURL)
|
r.GET("/q/:id", routes.RedirectShortenedOverflowURL)
|
||||||
r.GET("/q/:id/:answerId", routes.RedirectShortenedOverflowURL)
|
r.GET("/q/:id/:answerId", routes.RedirectShortenedOverflowURL)
|
||||||
|
|
||||||
|
exchangeRouter := r.Group("/exchange/:sub")
|
||||||
|
{
|
||||||
|
exchangeRouter.GET("/questions/:id/:title", routes.ViewQuestion)
|
||||||
|
exchangeRouter.GET("/questions/:id", func(c *gin.Context) {
|
||||||
|
// redirect user to the question with the title
|
||||||
|
c.Redirect(302, fmt.Sprintf("/exchange/%s/questions/%s/placeholder", c.Param("sub"), c.Param("id")))
|
||||||
|
})
|
||||||
|
exchangeRouter.GET("/questions/:id/:title/:answerId", func(c *gin.Context) {
|
||||||
|
// redirect user to the answer with the title
|
||||||
|
c.Redirect(302, fmt.Sprintf("/exchange/%s/questions/%s/%s#%s", c.Param("sub"), c.Param("id"), c.Param("title"), c.Param("answerId")))
|
||||||
|
})
|
||||||
|
exchangeRouter.GET("/q/:id/:answerId", routes.RedirectShortenedOverflowURL)
|
||||||
|
exchangeRouter.GET("/q/:id", routes.RedirectShortenedOverflowURL)
|
||||||
|
exchangeRouter.GET("/a/:id/:answerId", routes.RedirectShortenedOverflowURL)
|
||||||
|
exchangeRouter.GET("/a/:id", routes.RedirectShortenedOverflowURL)
|
||||||
|
}
|
||||||
|
|
||||||
r.GET("/questions/:id", func(c *gin.Context) {
|
r.GET("/questions/:id", func(c *gin.Context) {
|
||||||
// redirect user to the question with the title
|
// redirect user to the question with the title
|
||||||
c.Redirect(302, fmt.Sprintf("/questions/%s/placeholder", c.Param("id")))
|
c.Redirect(302, fmt.Sprintf("/questions/%s/placeholder", c.Param("id")))
|
||||||
@@ -64,15 +81,6 @@ func main() {
|
|||||||
// redirect user to the answer with the title
|
// redirect user to the answer with the title
|
||||||
c.Redirect(302, fmt.Sprintf("/questions/%s/%s#%s", c.Param("id"), c.Param("title"), c.Param("answerId")))
|
c.Redirect(302, fmt.Sprintf("/questions/%s/%s#%s", c.Param("id"), c.Param("title"), c.Param("answerId")))
|
||||||
})
|
})
|
||||||
r.GET("/exchange/:sub/questions/:id/:title", routes.ViewQuestion)
|
|
||||||
r.GET("/exchange/:sub/questions/:id", func(c *gin.Context) {
|
|
||||||
// redirect user to the question with the title
|
|
||||||
c.Redirect(302, fmt.Sprintf("/exchange/%s/questions/%s/placeholder", c.Param("sub"), c.Param("id")))
|
|
||||||
})
|
|
||||||
r.GET("/exchange/:sub/questions/:id/:title/:answerId", func(c *gin.Context) {
|
|
||||||
// redirect user to the answer with the title
|
|
||||||
c.Redirect(302, fmt.Sprintf("/exchange/%s/questions/%s/%s#%s", c.Param("sub"), c.Param("id"), c.Param("title"), c.Param("answerId")))
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/proxy", routes.GetImage)
|
r.GET("/proxy", routes.GetImage)
|
||||||
|
|
||||||
|
|||||||
@@ -231,6 +231,8 @@ func extractAnswersData(doc *goquery.Document, domain string) ([]types.FilteredA
|
|||||||
doc.Find("div.answer").Each(func(i int, s *goquery.Selection) {
|
doc.Find("div.answer").Each(func(i int, s *goquery.Selection) {
|
||||||
var answer types.FilteredAnswer
|
var answer types.FilteredAnswer
|
||||||
|
|
||||||
|
answer.ID = s.AttrOr("data-answerid", "")
|
||||||
|
|
||||||
postLayout := s.Find("div.post-layout").First()
|
postLayout := s.Find("div.post-layout").First()
|
||||||
|
|
||||||
// Extract upvotes.
|
// Extract upvotes.
|
||||||
@@ -250,6 +252,8 @@ func extractAnswersData(doc *goquery.Document, domain string) ([]types.FilteredA
|
|||||||
processedAnswerBody := utils.ProcessHTMLBody(answerBodyHTML)
|
processedAnswerBody := utils.ProcessHTMLBody(answerBodyHTML)
|
||||||
answer.Body = template.HTML(processedAnswerBody)
|
answer.Body = template.HTML(processedAnswerBody)
|
||||||
|
|
||||||
|
answer.Comments = utils.FindAndReturnComments(answerBodyHTML, domain, postLayout)
|
||||||
|
|
||||||
// Extract author information and timestamp.
|
// Extract author information and timestamp.
|
||||||
extractAnswerAuthorInfo(s, &answer, domain)
|
extractAnswerAuthorInfo(s, &answer, domain)
|
||||||
|
|
||||||
|
|||||||
+15
-2
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
@@ -12,6 +13,7 @@ import (
|
|||||||
func RedirectShortenedOverflowURL(c *gin.Context) {
|
func RedirectShortenedOverflowURL(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
answerId := c.Param("answerId")
|
answerId := c.Param("answerId")
|
||||||
|
sub := c.Param("sub")
|
||||||
|
|
||||||
// fetch the stack overflow URL
|
// fetch the stack overflow URL
|
||||||
client := resty.New()
|
client := resty.New()
|
||||||
@@ -21,7 +23,13 @@ func RedirectShortenedOverflowURL(c *gin.Context) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
resp, err := client.R().Get(fmt.Sprintf("https://www.stackoverflow.com/a/%s/%s", id, answerId))
|
domain := "www.stackoverflow.com"
|
||||||
|
if strings.Contains(sub, ".") {
|
||||||
|
domain = sub
|
||||||
|
} else if sub != "" {
|
||||||
|
domain = fmt.Sprintf("%s.stackexchange.com", sub)
|
||||||
|
}
|
||||||
|
resp, err := client.R().Get(fmt.Sprintf("https://%s/a/%s/%s", domain, id, answerId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(400, "home.html", gin.H{
|
c.HTML(400, "home.html", gin.H{
|
||||||
"errorMessage": "Unable to fetch stack overflow URL",
|
"errorMessage": "Unable to fetch stack overflow URL",
|
||||||
@@ -41,5 +49,10 @@ func RedirectShortenedOverflowURL(c *gin.Context) {
|
|||||||
// get the redirect URL
|
// get the redirect URL
|
||||||
location := resp.Header().Get("Location")
|
location := resp.Header().Get("Location")
|
||||||
|
|
||||||
c.Redirect(302, fmt.Sprintf("%s%s", os.Getenv("APP_URL"), location))
|
redirectPrefix := os.Getenv("APP_URL")
|
||||||
|
if sub != "" {
|
||||||
|
redirectPrefix += fmt.Sprintf("/exchange/%s", sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Redirect(302, fmt.Sprintf("%s%s", redirectPrefix, location))
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-78
@@ -1,81 +1,62 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-theme="{{ .theme }}">
|
<html data-theme="{{ .theme }}">
|
||||||
<head>
|
|
||||||
<title>AnonymousOverflow - Private frontend for StackOverflow</title>
|
<head>
|
||||||
<link rel="stylesheet" href="/static/home.css" />
|
<title>AnonymousOverflow - Private frontend for StackOverflow</title>
|
||||||
<meta
|
<link rel="stylesheet" href="/static/home.css" />
|
||||||
http-equiv="Content-Security-Policy"
|
<meta http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'none'; style-src 'self'; script-src 'none'; img-src 'self';"
|
content="default-src 'none'; style-src 'self'; script-src 'none'; img-src 'self';" />
|
||||||
/>
|
<link rel="icon" href="/static/codecircles.webp" />
|
||||||
<link rel="icon" href="/static/codecircles.webp" />
|
<meta name="description" content="View StackOverflow threads in privacy and without the clutter." />
|
||||||
<meta
|
{{ template "sharedHead.html" }}
|
||||||
name="description"
|
</head>
|
||||||
content="View StackOverflow threads in privacy and without the clutter."
|
|
||||||
/>
|
<body>
|
||||||
{{ template "sharedHead.html" }}
|
<div class="container">
|
||||||
</head>
|
<div class="title">
|
||||||
<body>
|
<img class="logo" src="/static/codecircles.webp" alt="" />
|
||||||
<div class="container">
|
<h1>Anonymous­Overflow</h1>
|
||||||
<div class="title">
|
|
||||||
<img
|
|
||||||
class="logo"
|
|
||||||
src="/static/codecircles.webp"
|
|
||||||
alt="4 circles with alternating colors between green and white"
|
|
||||||
/>
|
|
||||||
<h1>Anonymous­Overflow</h1>
|
|
||||||
</div>
|
|
||||||
<h2>Get programming help without compromising your privacy.</h2>
|
|
||||||
<p>
|
|
||||||
AnonymousOverflow allows you to view StackOverflow threads
|
|
||||||
without the cluttered interface and exposing your IP address,
|
|
||||||
browsing habits and other browser fingerprint data to
|
|
||||||
StackOverflow.
|
|
||||||
</p>
|
|
||||||
{{ if .successMessage }}
|
|
||||||
<div class="success">
|
|
||||||
<p><b>Success</b>: {{ .successMessage }}</p>
|
|
||||||
</div>
|
|
||||||
{{ else}} {{ if .errorMessage }}
|
|
||||||
<div class="error">
|
|
||||||
<p><b>Error</b>: {{ .errorMessage }}</p>
|
|
||||||
</div>
|
|
||||||
{{end}} {{ end }}
|
|
||||||
<form method="POST" action="/">
|
|
||||||
<div class="view-form">
|
|
||||||
<input
|
|
||||||
class="view-input"
|
|
||||||
type="text"
|
|
||||||
name="url"
|
|
||||||
placeholder="https://stackoverflow.com/questions/123456/example-url"
|
|
||||||
/>
|
|
||||||
<button class="view-button" type="submit">View</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="options">
|
|
||||||
<div class="icon">
|
|
||||||
<a href="/options/images">
|
|
||||||
<img src="/static/icons/image.svg" alt="Toggle theme" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{ template "themeSwitcher.html" .}}
|
|
||||||
</div>
|
|
||||||
<p class="footer">
|
|
||||||
Brought to you by
|
|
||||||
<a
|
|
||||||
href="https://github.com/WhateverLabs"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>Whatever Labs</a
|
|
||||||
>
|
|
||||||
•
|
|
||||||
<a
|
|
||||||
href="https://github.com/httpjamesm/AnonymousOverflow"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>Source</a
|
|
||||||
>
|
|
||||||
• Version {{ .version }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
<h2>Get programming help without compromising your privacy.</h2>
|
||||||
</html>
|
<p>
|
||||||
|
AnonymousOverflow allows you to view StackOverflow threads
|
||||||
|
without the cluttered interface and exposing your IP address,
|
||||||
|
browsing habits and other browser fingerprint data to
|
||||||
|
StackOverflow.
|
||||||
|
</p>
|
||||||
|
{{ if .successMessage }}
|
||||||
|
<div class="success">
|
||||||
|
<p><b>Success</b>: {{ .successMessage }}</p>
|
||||||
|
</div>
|
||||||
|
{{ else}} {{ if .errorMessage }}
|
||||||
|
<div class="error">
|
||||||
|
<p><b>Error</b>: {{ .errorMessage }}</p>
|
||||||
|
</div>
|
||||||
|
{{end}} {{ end }}
|
||||||
|
<form method="POST" action="/">
|
||||||
|
<div class="view-form">
|
||||||
|
<input class="view-input" type="text" name="url"
|
||||||
|
placeholder="https://stackoverflow.com/questions/123456/example-url" />
|
||||||
|
<button class="view-button" type="submit">View</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="options">
|
||||||
|
<div class="icon">
|
||||||
|
<a href="/options/images">
|
||||||
|
<img src="/static/icons/image.svg" alt="Toggle theme" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ template "themeSwitcher.html" .}}
|
||||||
|
</div>
|
||||||
|
<p class="footer">
|
||||||
|
Brought to you by
|
||||||
|
<a href="https://github.com/WhateverLabs" target="_blank" rel="noopener noreferrer">Whatever Labs</a>
|
||||||
|
•
|
||||||
|
<a href="https://github.com/httpjamesm/AnonymousOverflow" target="_blank"
|
||||||
|
rel="noopener noreferrer">Source</a>
|
||||||
|
• Version {{ .version }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
+76
-89
@@ -1,84 +1,74 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-theme="{{ .theme }}">
|
<html data-theme="{{ .theme }}">
|
||||||
<head>
|
|
||||||
<title>{{ .question.Title }} | AnonymousOverflow</title>
|
|
||||||
<link rel="stylesheet" href="/static/question.css" />
|
|
||||||
<link rel="stylesheet" href="/static/syntax.css" />
|
|
||||||
<link rel="stylesheet" href="/static/comments.css" />
|
|
||||||
<meta
|
|
||||||
http-equiv="Content-Security-Policy"
|
|
||||||
content="default-src 'none'; style-src 'self'; script-src 'self'; img-src {{ .imagePolicy }}; font-src 'self';"
|
|
||||||
/>
|
|
||||||
<meta name="description" content="{{ .question.ShortenedBody }}..." />
|
|
||||||
{{ template "sharedHead.html" }}
|
|
||||||
<link rel="stylesheet" href="/static/katex/katex.min.css">
|
|
||||||
|
|
||||||
<!-- The loading of KaTeX is deferred to speed up page rendering -->
|
<head>
|
||||||
<script defer src="/static/katex/katex.min.js"></script>
|
<title>{{ .question.Title }} | AnonymousOverflow</title>
|
||||||
|
<link rel="stylesheet" href="/static/question.css" />
|
||||||
|
<link rel="stylesheet" href="/static/syntax.css" />
|
||||||
|
<link rel="stylesheet" href="/static/comments.css" />
|
||||||
|
<meta http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src 'none'; style-src 'self'; script-src 'self'; img-src {{ .imagePolicy }}; font-src 'self';" />
|
||||||
|
<meta name="description" content="{{ .question.ShortenedBody }}..." />
|
||||||
|
{{ template "sharedHead.html" }}
|
||||||
|
<link rel="stylesheet" href="/static/katex/katex.min.css">
|
||||||
|
|
||||||
<!-- To automatically render math in text elements, include the auto-render extension: -->
|
<!-- The loading of KaTeX is deferred to speed up page rendering -->
|
||||||
<script defer src="/static/katex/contrib/auto-render.min.js"></script>
|
<script defer src="/static/katex/katex.min.js"></script>
|
||||||
<script defer src="/static/question.js" type="text/javascript"></script>
|
|
||||||
|
<!-- To automatically render math in text elements, include the auto-render extension: -->
|
||||||
|
<script defer src="/static/katex/contrib/auto-render.min.js"></script>
|
||||||
|
<script defer src="/static/question.js" type="text/javascript"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<div class="header">
|
<body>
|
||||||
<a href="/" class="logo-link">
|
<div class="header">
|
||||||
<img
|
<a href="/" class="logo-link">
|
||||||
class="logo"
|
<img class="logo" src="/static/codecircles.webp" alt="AnonymousOverflow home" />
|
||||||
src="/static/codecircles.webp"
|
</a>
|
||||||
alt="4 circles with alternating colors between green and white"
|
{{ template "themeSwitcher.html" . }}
|
||||||
/>
|
</div>
|
||||||
</a>
|
<div class="card">
|
||||||
{{ template "themeSwitcher.html" . }}
|
<div class="card-header">
|
||||||
|
<h1>{{ .question.Title }}</h1>
|
||||||
|
<p class="timestamp">
|
||||||
|
Asked {{ .question.Timestamp }} by
|
||||||
|
<a href="{{ .question.AuthorURL }}" target="_blank" rel="noopener noreferrer">{{ .question.AuthorName
|
||||||
|
}}</a>.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card-body">{{ .question.Body }}</div>
|
||||||
<div class="card-header">
|
<div class="card-tags">
|
||||||
<h1>{{ .question.Title }}</h1>
|
{{ range .question.Tags }}
|
||||||
<p class="timestamp">
|
<div class="tag">{{ . }}</div>
|
||||||
Asked {{ .question.Timestamp }} by
|
{{ end }}
|
||||||
<a
|
|
||||||
href="{{ .question.AuthorURL }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>{{ .question.AuthorName }}</a
|
|
||||||
>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">{{ .question.Body }}</div>
|
|
||||||
<div class="card-tags">
|
|
||||||
{{ range .question.Tags }}
|
|
||||||
<div class="tag">{{ . }}</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ if .question.Comments }} {{ template "comments.html"
|
|
||||||
.question }} {{end}}
|
|
||||||
</div>
|
</div>
|
||||||
<hr class="post-divider" />
|
{{ if .question.Comments }} {{ template "comments.html"
|
||||||
<div class="answers-header">
|
.question }} {{end}}
|
||||||
<h2>Answers</h2>
|
</div>
|
||||||
<div class="sorting">
|
{{ if .answers }}
|
||||||
<form>
|
<hr class="post-divider" />
|
||||||
<select name="sort_by">
|
<div class="answers-header">
|
||||||
<option disabled value="">Sort answers by...</option>
|
<h2>Answers</h2>
|
||||||
<option value="votes"{{ if eq .sortValue "votes" }} selected{{ end }}>Votes</option>
|
<div class="sorting">
|
||||||
<option value="trending"{{ if eq .sortValue "trending" }} selected{{ end }}>Trending</option>
|
<form>
|
||||||
<option value="newest"{{ if eq .sortValue "newest" }} selected{{ end }}>Date modified (newest first)</option>
|
<select name="sort_by">
|
||||||
<option value="oldest"{{ if eq .sortValue "oldest" }} selected{{ end }}>Date created (oldest first)</option>
|
<option disabled value="">Sort answers by...</option>
|
||||||
</select>
|
<option value="votes" {{ if eq .sortValue "votes" }} selected{{ end }}>Votes</option>
|
||||||
<button type="submit">
|
<option value="trending" {{ if eq .sortValue "trending" }} selected{{ end }}>Trending</option>
|
||||||
<img
|
<option value="newest" {{ if eq .sortValue "newest" }} selected{{ end }}>Date modified (newest
|
||||||
src="/static/icons/sort.svg"
|
first)</option>
|
||||||
alt="Sieve icon"
|
<option value="oldest" {{ if eq .sortValue "oldest" }} selected{{ end }}>Date created (oldest first)
|
||||||
/>
|
</option>
|
||||||
</button>
|
</select>
|
||||||
</form>
|
<button type="submit">
|
||||||
</div>
|
<img src="/static/icons/sort.svg" alt="Sieve icon" />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{ range $answer := .answers }}
|
</div>
|
||||||
<div class="answer" id="{{ $answer.ID }}">
|
{{ range $answer := .answers }}
|
||||||
<div
|
<div class="answer" id="{{ $answer.ID }}">
|
||||||
class="answer-meta{{ if $answer.IsAccepted }} accepted{{end}}"
|
<div class="answer-meta{{ if $answer.IsAccepted }} accepted{{end}}">
|
||||||
>
|
|
||||||
<p>
|
<p>
|
||||||
{{ if $answer.IsAccepted }} Accepted - {{ end }}
|
{{ if $answer.IsAccepted }} Accepted - {{ end }}
|
||||||
{{$answer.Upvotes}} Votes
|
{{$answer.Upvotes}} Votes
|
||||||
@@ -89,21 +79,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{ $answer.Body }}
|
{{ $answer.Body }}
|
||||||
<div class="answer-author-parent">
|
<div class="answer-author-parent">
|
||||||
<div class="answer-author">
|
<div class="answer-author">
|
||||||
Answered {{ $answer.Timestamp }} by
|
Answered {{ $answer.Timestamp }} by
|
||||||
<a
|
<a href="{{ $answer.AuthorURL }}" target="_blank" rel="noopener noreferrer">{{ $answer.AuthorName }}</a>
|
||||||
href="{{ $answer.AuthorURL }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>{{ $answer.AuthorName }}</a
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{{ if $answer.Comments }} {{ template "comments.html" $answer }}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ if $answer.Comments }} {{ template "comments.html" $answer }}
|
||||||
</body>
|
{{end}}
|
||||||
</html>
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user