commit ff749d68b6868fbf0af3b4a2bc1aa1e991e1465d Author: Marcel Kapfer (mmk2410) Date: Thu Jun 2 12:01:32 2016 +0200 Initial commmit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0dc6abf --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +node_modules +# See https://www.dartlang.org/tools/private-files.html + +# Files and directories created by pub +.buildlog +.packages +.project +.pub/ +build/ +**/packages/ + +# Files created by dart2js +# (Most Dart developers will use pub build to compile Dart, use/modify these +# rules if you intend to use dart2js directly +# Convention is to use extension '.dart.js' for Dart compiled to Javascript to +# differentiate from explicit Javascript files) +*.dart.js +*.part.js +*.js.deps +*.js.map +*.info.json + +# Directory created by dartdoc +doc/api/ + +# Don't commit pubspec lock file +# (Library packages only! Remove pattern if developing an application package) +pubspec.lock +web/packages + +# IDE files +.idea/ +*.iml +.atom/ +completer.hist diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..2b6f469 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "esversion": 6 +} diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ed2d3d9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +# Here is a list of people that have contributed to this project +# Please keep this form: +# +# Name / Organization + +Marcel Kapfer diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4ab4c17 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,17 @@ +# Contributing + +If you want to contribute have a look at the project board at [phab.mmk2410.org](https://phab.mmk2410.org/project/view/19/) to see what you should do. + +## Workflow + +While there is no stable release this project will follow the feature workflow. As soon as there is a stable release I will switch to the Gitflow workflow. + +If your unfamiliar with these workflows I recommend reading [this article](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow/). + +## Contact + +If you want to ask me some questions, feel free to contact me at (marcelmichaelkapfer@yahoo.co.nz)[mailto:marcelmichaelkapfer@yahoo.co.nz]. + +## Honor + +Please add yourself to the AUTHORS file. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d51ed64 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +COPYRIGHT (c) 2016 Marcel Kapfer (mmk2410) + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..719006f --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Rangitaki Desktop Client + +This is the Rangitaki desktop client made with Dart, Polymer and Electron. + +***It is not fully developed and misses many features. The content of this repository is right now only for development purposes, but not for any productive usage.*** + +For contributing see the CONTRIBUTING.md. diff --git a/bcli.sh b/bcli.sh new file mode 100755 index 0000000..826b60b --- /dev/null +++ b/bcli.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +rlwrap /bin/bash ./run.sh diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..d6099a0 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,20 @@ +name: rangitakidesktop +version: 0.0.1 +description: > + Desktop app for Rangitaki +author: Marcel Kapfer (mmk2410) +homepage: https://mmk2410.org/rangitaki/rangitaki-desktop/ +documentation: https://mmk2410.org/rangitaki/rangitaki-lib/docs/ + +dependencies: + browser: '>=0.10.0 <0.11.0' + http: '^0.11.3+7' + polymer_elements: ^1.0.0-rc.8 + polymer: ^1.0.0-rc.2 + web_components: ^0.12.0 + test: "^0.12.13+4" + +transformers: +- polymer: + entry_points: + - web/index.html diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..bcdec14 --- /dev/null +++ b/run.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +while true; do + echo -n " (BCLI) > " + read -r command + + case $command in + build | b ) pub build & ;; + run | r ) + killall -q electron + electron build/web/ & + ;; + bar | br ) + killall -q electron + pub build + electron build/web/ & + ;; + get | g) pub get ;; + close | c) killall -q electron ;; + test | t) pub run test;; + lint | l) + jshint web/main.js + jshint web/renderer.js + dartanalyzer web/ + ;; + exit | quit | q | x | e) + exit ;; + about ) echo "mmk2410 - Build CLI script - MIT License" ;; + help | h | ? ) + echo """ +run, r Close running instances and run Electron in background +build, b Build app in background +bar, br Short for build and run +test, t Run tests. +close, c Exit running Electron instances +exit, quit, q, x, e Exit the script +about About text +get, g Get updates. +help, h, ? Prints this help + """ + ;; + * ) echo "Command $command not found." ;; + esac +done diff --git a/web/api.dart b/web/api.dart new file mode 100644 index 0000000..3842551 --- /dev/null +++ b/web/api.dart @@ -0,0 +1,119 @@ +import 'dart:async'; +import 'dart:html'; +import 'dart:convert'; + +import 'package:polymer_elements/paper_item.dart'; + +import 'article-view.dart'; + +/** + * Easily connects with the Rangitaki API and does also a part of the frontend. + */ +class RangitakiConnect { + + String baseurl; + String _username; + String _password; + String _auth; + + /** + * Initializer for RangitaiConnect. + * @value baseurl Root URL of your Rangitaki installation. + * @value username Username for authentication. + * @value password Password for authentication. + */ + RangitakiConnect(this.baseurl, this._username, this._password) { + _auth = BASE64.encode(UTF8.encode("$_username:$_password")); + } + + /** + * Fetch all blogs from the server and list them in the #list element. + */ + Future addBlogs() async { + var data = await _getBlogs(); + data = JSON.decode(data); + for (String blog in data) { + blog = blog.substring(0, blog.length - 3); + PaperItem item = new PaperItem(); + item.text = blog; + item.id = blog; + querySelector("#main-list").children.add(item); + } + } + + /** + * Fetch all articles of a blog from the server and list the in the #list + * element. + * @value blog Blog for which the articles shoul be fetched. + */ + Future addArticles(String blog) async { + var data = await _getArticles(blog); + + data = JSON.decode(data); + for (String article in data) { + article = article.substring(0, article.length - 3); + PaperItem item = new PaperItem(); + item.text = article; + item.id = article; + querySelector("#main-list").children.add(item); + } + } + + Future showArticle(String blog, String post, ArticleView articleView) async { + var data = await _getArticle(blog, post); + + print(data); + + data = JSON.decode(data); + List tags = data['tags']; + String tag = tags.join(", "); + + print("Tags: $tag"); + + print("ArticleView: $articleView"); + + articleView + ..title = data['title'] + ..author = data['author'] + ..date = data['date'] + ..tags = tag + ..text = data['text']; + } + + /** + * Internal method for fetching blogs from the server. + */ + Future _getBlogs() async { + String _url = "$baseurl/rcc/api/list/"; + return (await + HttpRequest.request( + _url, withCredentials: true, + requestHeaders: {'authorization' : 'Basic $_auth'} + )).responseText; + } + + /** + * Internal method for fetching articles of blog from the server. + */ + Future _getArticles(String blog) async { + String _url = "$baseurl/rcc/api/list/?blog=$blog"; + + return (await + HttpRequest.request( + _url, withCredentials: true, + requestHeaders: {'authorization' : 'Basic $_auth'} + )).responseText; + } + + Future _getArticle(blog, post) async { + print("Blog: $blog"); + print("Post: $post"); + String _url = "$baseurl/rcc/api/post/?blog=$blog&post=$post.md"; + print("URL: $_url"); + return (await + HttpRequest.request(_url, withCredentials: true, + requestHeaders: {'authorization' : 'Basic $_auth'} + )).responseText; + } + +} diff --git a/web/article-view.dart b/web/article-view.dart new file mode 100644 index 0000000..ae632c5 --- /dev/null +++ b/web/article-view.dart @@ -0,0 +1,18 @@ +@HtmlImport('article_view.html') +library mmk2410_rangitaki_app.article_view; + +import 'package:polymer/polymer.dart'; +import 'package:web_components/web_components.dart' show HtmlImport; + +@PolymerRegister('article-view') +class ArticleView extends PolymerElement { + + ArticleView.created() : super.created(); + + @property + String title; + String author; + String date; + String text; + String tags; +} diff --git a/web/article_view.html b/web/article_view.html new file mode 100644 index 0000000..09df542 --- /dev/null +++ b/web/article_view.html @@ -0,0 +1,16 @@ + + + + diff --git a/web/index.dart b/web/index.dart new file mode 100644 index 0000000..48c08f2 --- /dev/null +++ b/web/index.dart @@ -0,0 +1,61 @@ +/** + * @author Marcel Kapfer (mmk2410) + * Library for easily working with the Rangitaki API in your browswer. + */ +library mmk2410_rangitaki_app.index; + +import 'dart:html'; +import 'dart:async'; + +import 'package:polymer/polymer.dart'; + +import 'api.dart'; +import 'article-view.dart'; + +export 'article-view.dart'; +export 'package:polymer/init.dart'; + +final String username = ""; +final String pwd = ""; +final String baseurl = ""; + +RangitakiConnect rcc; +Element itemList; +ArticleView articleView; +String currentBlog; + +main() async { + await initPolymer(); + + print("Starting..."); + + rcc = new RangitakiConnect(baseurl, username, pwd); + + await rcc.addBlogs(); + + itemList = querySelector("#main-list"); + + for (Element item in itemList.children) { + item.onClick.listen(blogSelected); + } + + articleView = querySelector("articlev-iew"); +} + +Future blogSelected(Event e) async { + Element element = e.target; + itemList.children.clear(); + currentBlog = element.id; + await rcc.addArticles(element.id); + + for (Element item in itemList.children) { + item.onClick.listen(articleSelected); + } +} + +Future articleSelected(Event e) async { + Element element = e.target; + await rcc.showArticle(currentBlog, element.id, articleView); + itemList.hidden = true; + articleView.hidden = false; +} diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..d78dcc2 --- /dev/null +++ b/web/index.html @@ -0,0 +1,57 @@ + + + + + Rangitaki + + + + + + + + + + + + + + + + + Menu + + + + Blogs + Articles + Media + Settings + + + + + + +
Rangitaki
+
+ + +
+
+ + + +
+
+ + + + + + + + diff --git a/web/main.js b/web/main.js new file mode 100644 index 0000000..02b49d7 --- /dev/null +++ b/web/main.js @@ -0,0 +1,53 @@ +const electron = require('electron'); +// Module to control application life. +const app = electron.app; +// Module to create native browser window. +const BrowserWindow = electron.BrowserWindow; + +// Keep a global reference of the window object, if you don't, the window will +// be closed automatically when the JavaScript object is garbage collected. +let mainWindow; + +function createWindow () { + // Create the browser window. + mainWindow = new BrowserWindow({width: 1000, height: 800}); + + // and load the index.html of the app. + mainWindow.loadURL(`file://${__dirname}/index.html`); + + // Open the DevTools. + mainWindow.webContents.openDevTools(); + + // Emitted when the window is closed. + mainWindow.on('closed', function () { + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + mainWindow = null; + }); +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on('ready', createWindow); + +// Quit when all windows are closed. +app.on('window-all-closed', function () { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', function () { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (mainWindow === null) { + createWindow(); + } +}); + +// In this file you can include the rest of your app's specific main process +// code. You can also put them in separate files and require them here. diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..9695fbc --- /dev/null +++ b/web/package.json @@ -0,0 +1,23 @@ +{ + "name": "rangitaki-desktop", + "version": "0.0.1", + "description": "Rangtaki desktop app made with Dart, Polymer and Electron", + "main": "main.js", + "scripts": { + "start": "electron main.js" + }, + "repository": { + "type": "git", + "url": "git+https://gitlab.com/mmk2410/rangitaki-desktop.git" + }, + "keywords": [ + "Rangitaki", + "desktop" + ], + "author": "Marcel Kapfer (mmk2410)", + "license": "MIT", + "homepage": "https://gitlab.com/mmk2410/rangitaki-desktop", + "devDependencies": { + "electron-prebuilt": "^1.0.1" + } +} diff --git a/web/renderer.js b/web/renderer.js new file mode 100644 index 0000000..901d75e --- /dev/null +++ b/web/renderer.js @@ -0,0 +1,3 @@ +// This file is required by the index.html file and will +// be executed in the renderer process for that window. +// All of the Node.js APIs are available in this process. diff --git a/web/style.html b/web/style.html new file mode 100644 index 0000000..dec4d0c --- /dev/null +++ b/web/style.html @@ -0,0 +1,27 @@ + \ No newline at end of file