diff --git a/.dockerignore b/.dockerignore index a3b6b46..5210f77 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,3 +22,7 @@ feed\.rss .travis\.yml _config\.yml + +Dockerfile + +assets/ diff --git a/.github/workflows/dev-docker-build-push.yml b/.github/workflows/dev-docker-build-push.yml new file mode 100644 index 0000000..b4d0470 --- /dev/null +++ b/.github/workflows/dev-docker-build-push.yml @@ -0,0 +1,31 @@ +name: push gmemstr/pogo:dev + +on: + push: + paths: + - '**.go' + - 'go.mod' + - 'go.sum' + - '.github/workflows/dev-docker-build-push.yml' + branches-ignore: + - 'master' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - + name: Login to DockerHub + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: gmemstr + password: ${{ secrets.GITHUB_TOKEN }} + - + name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + tags: ghcr.io/gmemstr/pogo:dev diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml new file mode 100644 index 0000000..c47e63f --- /dev/null +++ b/.github/workflows/docker-build-push.yml @@ -0,0 +1,31 @@ +name: push gmemstr/pogo:stable + +on: + push: + paths: + - '**.go' + - 'go.mod' + - 'go.sum' + - '.github/workflows/docker-build-push.yml' + branches: + - 'master' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - + name: Login to DockerHub + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: gmemstr + password: ${{ secrets.GITHUB_TOKEN }} + - + name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + tags: ghcr.io/gmemstr/pogo:stable diff --git a/.gitignore b/.gitignore index 5e8318f..c14f009 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ assets/config/users\.db run\.lockfile \.lock + +assets/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 04de097..0000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: go -sudo: false -services: - - docker -matrix: - include: - - go: 1.8 - - go: 1.9 - - go: 1.x - - go: master - allow_failures: - - go: master - - before_install: - - go get github.com/tools/godep - - install: - - godep restore - - script: - - go vet . - - go test - - go build - - ls -al - -script: - - docker build -t gmemstr/pogo . - - docker run -d --rm --name pogo -p 3000:3000 gmemstr/pogo - - sleep 10 - - docker ps | grep gmemstr/pogo - -after_success: - - if [ "$TRAVIS_BRANCH" == "master" ]; then - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker push gmemstr/pogo; - fi \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8e93505..b159f90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,21 @@ -# Use latest golang image -FROM golang:latest - -RUN mkdir -p /go/src \ - && mkdir -p /go/bin \ - && mkdir -p /go/pkg -ENV GOPATH=/go -ENV PATH=$GOPATH/bin:$PATH - -# Set working directory -WORKDIR $GOPATH/src/github.com/gmemstr/pogo - -# Add source to container so we can build -ADD . $GOPATH/src/github.com/gmemstr/pogo - -# 1. Install make and dependencies -# 2. Install Go dependencies -# 3. Build named Linux binary and allow execution -# 4. List directory structure (for debugging really)\ -# 5. Make empty podcast direcory -# 6. Create empty feed files -RUN go get github.com/tools/godep && \ - godep restore && \ - go build -o pogoapp && chmod +x pogoapp +FROM golang:stretch as builder +WORKDIR /build/pogo +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN GOOS=linux go build -ldflags "-s -w" + + +FROM debian:stretch-slim + +RUN apt update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* + +WORKDIR /app EXPOSE 3000 -CMD ./pogoapp +COPY --from=builder /build/pogo/pogo pogo + +ENTRYPOINT ["/app/pogo"] diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json deleted file mode 100644 index 1428fae..0000000 --- a/Godeps/Godeps.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "ImportPath": "github.com/gmemstr/pogo", - "GoVersion": "go1.8", - "GodepVersion": "v79", - "Deps": [ - { - "ImportPath": "github.com/fsnotify/fsnotify", - "Comment": "v1.4.2-6-g4da3e2c", - "Rev": "4da3e2cfbabc9f751898f250b49f2439785783a1" - }, - { - "ImportPath": "github.com/google/go-github/github", - "Rev": "fbfee053c26dab3772adfc7799d995eed379133e" - }, - { - "ImportPath": "github.com/google/go-querystring/query", - "Rev": "53e6ce116135b80d037921a7fdd5138cf32d7a8a" - }, - { - "ImportPath": "github.com/gorilla/feeds", - "Comment": "v1.0.0", - "Rev": "4b936b5221c53c99fcd4b15ac0b8c38ff490ab89" - }, - { - "ImportPath": "github.com/gorilla/mux", - "Comment": "v1.4.0-10-g18fca31", - "Rev": "18fca31550181693b3a834a15b74b564b3605876" - }, - { - "ImportPath": "github.com/mattn/go-sqlite3", - "Comment": "v1.3.0", - "Rev": "5160b48509cf5c877bc22c11c373f8c7738cdb38" - }, - { - "ImportPath": "golang.org/x/crypto/bcrypt", - "Rev": "9419663f5a44be8b34ca85f08abc5fe1be11f8a3" - }, - { - "ImportPath": "golang.org/x/crypto/blowfish", - "Rev": "9419663f5a44be8b34ca85f08abc5fe1be11f8a3" - }, - { - "ImportPath": "golang.org/x/net/context", - "Rev": "3da985ce5951d99de868be4385f21ea6c2b22f24" - }, - { - "ImportPath": "golang.org/x/sys/unix", - "Rev": "0b25a408a50076fbbcae6b7ac0ea5fbb0b085e79" - } - ] -} diff --git a/Godeps/Readme b/Godeps/Readme deleted file mode 100644 index 4cdaa53..0000000 --- a/Godeps/Readme +++ /dev/null @@ -1,5 +0,0 @@ -This directory tree is generated automatically by godep. - -Please do not edit. - -See https://github.com/tools/godep for more information. diff --git a/assets/config/config.json b/assets/config/config.json deleted file mode 100644 index d367062..0000000 --- a/assets/config/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Name": "Pogo Test Feed", - "Host": "Gabriel Simmer", - "Email": "admin@localhost", - "Description": "Discussion about open source projects on the internet.", - "Image": "localhost:3000/assets/logo-xs.png", - "PodcastUrl": "http://localhost:3000" -} \ No newline at end of file diff --git a/assets/web/README.md b/assets/web/README.md deleted file mode 100644 index c93116f..0000000 --- a/assets/web/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# What is this?! - -This is the _development version_ (DeV) of the web interface for Pogo. - -It is not recommended you use this for your own deployment, and instead rely on the auto-setup feature of the binary. If you still insist manually deploying your own binary, please consider downloading the latest `webassets.zip` release from [gmemstr/pogo-vue](https://github.com/gmmestr/pogo-vue/releases/latest), which contains the production version of the Vue.js interface. The interface in this repository should be considered "canary" or "nightly", and for testing routes and features during development. Thanks! - -~ Gabe \ No newline at end of file diff --git a/assets/web/admin.html b/assets/web/admin.html deleted file mode 100644 index 932e768..0000000 --- a/assets/web/admin.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Pogo Publish - - - - -
-
- -

{{ header }}

- -
-
- - - - - - \ No newline at end of file diff --git a/assets/web/index.html b/assets/web/index.html deleted file mode 100644 index 8a913c1..0000000 --- a/assets/web/index.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Pogo Loading - - - - - - - - -
-
-

Loading

-

Admin

- -
- -
-
- -
- - - \ No newline at end of file diff --git a/assets/web/login.html b/assets/web/login.html deleted file mode 100644 index 14bbadf..0000000 --- a/assets/web/login.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Login to Pogo Admin Page - - - -

Login

- -
- - - - - - - - - - -
- - - \ No newline at end of file diff --git a/assets/web/static/app.js b/assets/web/static/app.js deleted file mode 100644 index 27b3bdf..0000000 --- a/assets/web/static/app.js +++ /dev/null @@ -1,384 +0,0 @@ -const episodepublishform = { - template: `
-

Publish Episode

-
- - - - - - - -

- -
-
` -} - -const message = { - template: `

{{ this.$route.params.message }}

` -} - -const userlist = { - template: `
- New - - - - - - - - - - - -
UsernameEmail
{{ item.username }}{{ item.email }} - Edit -
-
`, - data() { - return { - loading: false, - items: null, - error: null - } - }, - created() { - // fetch the data when the view is created and the data is - // already being observed - this.fetchData() - }, - watch: { - // call again the method if the route changes - '$route': 'fetchData' - }, - methods: { - fetchData() { - this.error = this.items = [] - this.loading = true - - get("/admin/listusers", (err, items) => { - this.loading = false - if (err) { - this.error = err.toString() - } else { - var t = JSON.parse(items).reverse(); - for (var i = t.length - 1; i >= 0; i--) { - this.items.push({ - id: t[i].id, - username: t[i].username, - email: t[i].email, - }) - } - } - }) - } - } -} - -const usernew = { - template: `
-
-

New User

-
- - - - - - - - - - - -

-
-
-
` -} - -const useredit = { - template: `
-
-

Edit User

-
- - - - - - - - - - - - - -

- - - -

-
- Delete User -
-
`, - data() { - return { - loading: false, - user: null, - error: null - } - }, - created() { - // fetch the data when the view is created and the data is - // already being observed - this.fetchData() - }, - watch: { - // call again the method if the route changes - '$route': 'fetchData' - }, - methods: { - fetchData() { - this.error = this.user = [] - this.loading = true - - get("/admin/listusers", (err, items) => { - this.loading = false - if (err) { - this.error = err.toString() - } else { - var t = JSON.parse(items) - for (var i = t.length - 1; i >= 0; i--) { - if (t[i].id == this.$route.params.id) { - this.user = { - id: t[i].id, - username: t[i].username, - email: t[i].email, - realname: t[i].realname - } - } - } - } - }) - } - } -} - -const episodemanagement = { - template: `
- - - - - - - - - -
TitleURL
{{ item.id }}: {{ item.title }}{{ item.url }}Edit
-
`, - data() { - return { - loading: false, - items: null, - error: null - } - }, - created() { - // fetch the data when the view is created and the data is - // already being observed - this.fetchData() - }, - watch: { - // call again the method if the route changes - '$route': 'fetchData' - }, - methods: { - fetchData() { - this.error = this.items = [] - this.loading = true - - get("/json", (err, items) => { - this.loading = false - if (err) { - this.error = err.toString() - } else { - var t = JSON.parse(items).items - for (var i = t.length - 1; i >= 0; i--) { - console.log(i) - this.items.push({ - title: t[i].title, - url: t[i].url, - id: t[i].id - }) - } - } - }) - } - } -} - -const episodeedit = { - template: `
-
-

Edit Episode

-
- - - - - - - -
-
-
`, - data() { - return { - loading: false, - episode: null, - error: null - } - }, - created() { - // fetch the data when the view is created and the data is - // already being observed - this.fetchData() - }, - watch: { - // call again the method if the route changes - '$route': 'fetchData' - }, - methods: { - fetchData() { - this.error = this.episode = {} - this.loading = true - - get("/json", (err, items) => { - this.loading = false - if (err) { - this.error = err.toString() - } else { - var t = JSON.parse(items).items - for (var i = t.length - 1; i >= 0; i--) { - if (t[i].id == this.$route.params.id) { - time = t[i].date_published.split("T") - var prev = time[0] + "_" + t[i].title - this.episode = { - title: t[i].title, - description: t[i].summary, - url: t[i].url, - id: t[i].id, - time: time[0], - previousfilename: prev - } - } - } - } - console.log(this.episode) - }) - } - } -} - -const customcss = { - template: `
-

Theme

-
- -

- -
-
`, - data() { - return { - loading: false, - css: null, - error: null - } - }, - created() { - // fetch the data when the view is created and the data is - // already being observed - this.fetchData() - }, - watch: { - // call again the method if the route changes - '$route': 'fetchData' - }, - methods: { - fetchData() { - this.error = this.css = null - this.loading = true - - get("/admin/css", (err, css) => { - this.loading = false - if (css == "{}") { - this.css = "You aren't allowed to edit this CSS!" - } else { - if (err) { - this.error = err.toString() - } else { - this.css = css - } - } - }) - } - } -} - -const routes = [ - {path: '/', redirect: '/publish'}, - { path: '/publish', component: episodepublishform }, - { path: '/manage', component: episodemanagement }, - { path: '/theme', component: customcss }, - { path: '/edit/:id', component: episodeedit }, - { path: '/users/', component: userlist }, - { path: '/msg/:message', component: message }, - { path: '/user/:id', component: useredit }, - { path: '/users/new', component: usernew } -] - -const router = new VueRouter({ - routes -}) - -const app = new Vue({ - router, - data: { - header: 'Pogo Admin', - } -}).$mount('#app') - -function get(url,callback) { - var xmlHttp = new XMLHttpRequest(); - xmlHttp.onreadystatechange = function() { - if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { - if (xmlHttp.responseText == "Unauthorized") { - callback(null, "{}") - } else { - callback(null, xmlHttp.responseText) - } - } - } - xmlHttp.open("GET", url, true); - xmlHttp.send(null); -} - -function logout() { - document.cookie = "POGO_SESSION=;expires=Thu, 01 Jan 1970 00:00:01 GMT"; - window.location = "/"; -} \ No newline at end of file diff --git a/assets/web/static/custom.css b/assets/web/static/custom.css deleted file mode 100644 index 6202346..0000000 --- a/assets/web/static/custom.css +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This is the file of custom CSS styling that - * can be set by the publisher. - * - * If you're writing the custom CSS, please see the reference: - * https://github.com/gmemstr/Pogo/wiki/Custom-CSS/ - */ - -.container {} /* Basic container from styles.css */ -.title {} /* Page title */ -.adminlink { /* Link to admin interface */ - margin-left:100%; - display:inline-block; - margin-bottom: 10px; - background-color: #397AD6; - border: none; - color: white; - padding: 5px 32px; - text-align: center; - text-decoration: none; - display: inline-block; - font-size: 16px; - -webkit-transition:.52s; - -moz-transition: .5s; - -o-transition: .5s; - -ms-transition: .5s; - transition:.5s; -} -.adminlink:hover { - background-color: #50B7D5; -} - -.podcastlist {} /* Chronological podcast list */ - -.podcastitem {} /* Single podcast item (group of elements) */ -.podcasttitle {} /* Title of podcast item */ -.podcastdate {} /* Date podcast item was published */ -.podcastdesc {} /* Podcast item description */ -.podcastaudio {} /* Podcast