From e89c3c5d6290d62498d837633fab6e238f5c2e93 Mon Sep 17 00:00:00 2001 From: Arshi Annafi Date: Mon, 21 Aug 2017 16:19:51 -0700 Subject: [PATCH 1/8] Add Atom package Generated an Atom package for Orion using Atom's package generator. --- modules/orionode.collab.atom/.gitignore | 3 + modules/orionode.collab.atom/CHANGELOG.md | 10 +++ modules/orionode.collab.atom/LICENSE.md | 5 ++ .../orionode.collab.atom/keymaps/orion.json | 5 ++ .../orionode.collab.atom/lib/orion-view.js | 29 ++++++++ modules/orionode.collab.atom/lib/orion.js | 49 +++++++++++++ modules/orionode.collab.atom/menus/orion.json | 26 +++++++ modules/orionode.collab.atom/package.json | 16 ++++ .../orionode.collab.atom/spec/orion-spec.js | 73 +++++++++++++++++++ .../spec/orion-view-spec.js | 9 +++ .../orionode.collab.atom/styles/orion.less | 8 ++ 11 files changed, 233 insertions(+) create mode 100644 modules/orionode.collab.atom/.gitignore create mode 100644 modules/orionode.collab.atom/CHANGELOG.md create mode 100644 modules/orionode.collab.atom/LICENSE.md create mode 100644 modules/orionode.collab.atom/keymaps/orion.json create mode 100644 modules/orionode.collab.atom/lib/orion-view.js create mode 100644 modules/orionode.collab.atom/lib/orion.js create mode 100644 modules/orionode.collab.atom/menus/orion.json create mode 100644 modules/orionode.collab.atom/package.json create mode 100644 modules/orionode.collab.atom/spec/orion-spec.js create mode 100644 modules/orionode.collab.atom/spec/orion-view-spec.js create mode 100644 modules/orionode.collab.atom/styles/orion.less diff --git a/modules/orionode.collab.atom/.gitignore b/modules/orionode.collab.atom/.gitignore new file mode 100644 index 0000000000..ade14b9196 --- /dev/null +++ b/modules/orionode.collab.atom/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +npm-debug.log +node_modules diff --git a/modules/orionode.collab.atom/CHANGELOG.md b/modules/orionode.collab.atom/CHANGELOG.md new file mode 100644 index 0000000000..f54f04d268 --- /dev/null +++ b/modules/orionode.collab.atom/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + + + +## 0.0.1 - First Release +- Generated Atom package: Orion diff --git a/modules/orionode.collab.atom/LICENSE.md b/modules/orionode.collab.atom/LICENSE.md new file mode 100644 index 0000000000..a0a98092e4 --- /dev/null +++ b/modules/orionode.collab.atom/LICENSE.md @@ -0,0 +1,5 @@ +Copyright (c) 2012, 2013, 2017 IBM Corporation and others. +All rights reserved. This program and the accompanying materials are made +available under the terms of the Eclipse Public License v1.0 +(http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution +License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). diff --git a/modules/orionode.collab.atom/keymaps/orion.json b/modules/orionode.collab.atom/keymaps/orion.json new file mode 100644 index 0000000000..de015031fe --- /dev/null +++ b/modules/orionode.collab.atom/keymaps/orion.json @@ -0,0 +1,5 @@ +{ + "atom-workspace": { + "ctrl-alt-o": "orion:toggle" + } +} diff --git a/modules/orionode.collab.atom/lib/orion-view.js b/modules/orionode.collab.atom/lib/orion-view.js new file mode 100644 index 0000000000..c15284584f --- /dev/null +++ b/modules/orionode.collab.atom/lib/orion-view.js @@ -0,0 +1,29 @@ +'use babel'; + +export default class OrionView { + + constructor(serializedState) { + // Create root element + this.element = document.createElement('div'); + this.element.classList.add('orion'); + + // Create message element + const message = document.createElement('div'); + message.textContent = 'The Orion package is Alive! It\'s ALIVE!'; + message.classList.add('message'); + this.element.appendChild(message); + } + + // Returns an object that can be retrieved when package is activated + serialize() {} + + // Tear down any state and detach + destroy() { + this.element.remove(); + } + + getElement() { + return this.element; + } + +} diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js new file mode 100644 index 0000000000..ceff189252 --- /dev/null +++ b/modules/orionode.collab.atom/lib/orion.js @@ -0,0 +1,49 @@ +'use babel'; + +import OrionView from './orion-view'; +import { CompositeDisposable } from 'atom'; + +export default { + + orionView: null, + modalPanel: null, + subscriptions: null, + + activate(state) { + this.orionView = new OrionView(state.orionViewState); + this.modalPanel = atom.workspace.addModalPanel({ + item: this.orionView.getElement(), + visible: false + }); + + // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable + this.subscriptions = new CompositeDisposable(); + + // Register command that toggles this view + this.subscriptions.add(atom.commands.add('atom-workspace', { + 'orion:toggle': () => this.toggle() + })); + }, + + deactivate() { + this.modalPanel.destroy(); + this.subscriptions.dispose(); + this.orionView.destroy(); + }, + + serialize() { + return { + orionViewState: this.orionView.serialize() + }; + }, + + toggle() { + console.log('Orion was toggled!'); + return ( + this.modalPanel.isVisible() ? + this.modalPanel.hide() : + this.modalPanel.show() + ); + } + +}; diff --git a/modules/orionode.collab.atom/menus/orion.json b/modules/orionode.collab.atom/menus/orion.json new file mode 100644 index 0000000000..f0e28b8ee3 --- /dev/null +++ b/modules/orionode.collab.atom/menus/orion.json @@ -0,0 +1,26 @@ +{ + "context-menu": { + "atom-text-editor": [ + { + "label": "Toggle orion", + "command": "orion:toggle" + } + ] + }, + "menu": [ + { + "label": "Packages", + "submenu": [ + { + "label": "Orion", + "submenu": [ + { + "label": "Toggle", + "command": "orion:toggle" + } + ] + } + ] + } + ] +} diff --git a/modules/orionode.collab.atom/package.json b/modules/orionode.collab.atom/package.json new file mode 100644 index 0000000000..e6292c84f4 --- /dev/null +++ b/modules/orionode.collab.atom/package.json @@ -0,0 +1,16 @@ +{ + "name": "orion", + "main": "./lib/orion", + "version": "0.0.1", + "description": "An Atom plugin to connect to Eclipse Orion and collaborate", + "keywords": [ + "eclipse", "orion", "collaboration" + ], + "repository": "https://github.com/eclipse/orion.client", + "license": "EPL-1.0", + "engines": { + "atom": ">=1.0.0 <2.0.0" + }, + "dependencies": { + } +} diff --git a/modules/orionode.collab.atom/spec/orion-spec.js b/modules/orionode.collab.atom/spec/orion-spec.js new file mode 100644 index 0000000000..a1a85d17b7 --- /dev/null +++ b/modules/orionode.collab.atom/spec/orion-spec.js @@ -0,0 +1,73 @@ +'use babel'; + +import Orion from '../lib/orion'; + +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// +// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` +// or `fdescribe`). Remove the `f` to unfocus the block. + +describe('Orion', () => { + let workspaceElement, activationPromise; + + beforeEach(() => { + workspaceElement = atom.views.getView(atom.workspace); + activationPromise = atom.packages.activatePackage('orion'); + }); + + describe('when the orion:toggle event is triggered', () => { + it('hides and shows the modal panel', () => { + // Before the activation event the view is not on the DOM, and no panel + // has been created + expect(workspaceElement.querySelector('.orion')).not.toExist(); + + // This is an activation event, triggering it will cause the package to be + // activated. + atom.commands.dispatch(workspaceElement, 'orion:toggle'); + + waitsForPromise(() => { + return activationPromise; + }); + + runs(() => { + expect(workspaceElement.querySelector('.orion')).toExist(); + + let orionElement = workspaceElement.querySelector('.orion'); + expect(orionElement).toExist(); + + let orionPanel = atom.workspace.panelForItem(orionElement); + expect(orionPanel.isVisible()).toBe(true); + atom.commands.dispatch(workspaceElement, 'orion:toggle'); + expect(orionPanel.isVisible()).toBe(false); + }); + }); + + it('hides and shows the view', () => { + // This test shows you an integration test testing at the view level. + + // Attaching the workspaceElement to the DOM is required to allow the + // `toBeVisible()` matchers to work. Anything testing visibility or focus + // requires that the workspaceElement is on the DOM. Tests that attach the + // workspaceElement to the DOM are generally slower than those off DOM. + jasmine.attachToDOM(workspaceElement); + + expect(workspaceElement.querySelector('.orion')).not.toExist(); + + // This is an activation event, triggering it causes the package to be + // activated. + atom.commands.dispatch(workspaceElement, 'orion:toggle'); + + waitsForPromise(() => { + return activationPromise; + }); + + runs(() => { + // Now we can test for view visibility + let orionElement = workspaceElement.querySelector('.orion'); + expect(orionElement).toBeVisible(); + atom.commands.dispatch(workspaceElement, 'orion:toggle'); + expect(orionElement).not.toBeVisible(); + }); + }); + }); +}); diff --git a/modules/orionode.collab.atom/spec/orion-view-spec.js b/modules/orionode.collab.atom/spec/orion-view-spec.js new file mode 100644 index 0000000000..2245dccb4e --- /dev/null +++ b/modules/orionode.collab.atom/spec/orion-view-spec.js @@ -0,0 +1,9 @@ +'use babel'; + +import OrionView from '../lib/orion-view'; + +describe('OrionView', () => { + it('has one valid test', () => { + expect('life').toBe('easy'); + }); +}); diff --git a/modules/orionode.collab.atom/styles/orion.less b/modules/orionode.collab.atom/styles/orion.less new file mode 100644 index 0000000000..d8b2459d03 --- /dev/null +++ b/modules/orionode.collab.atom/styles/orion.less @@ -0,0 +1,8 @@ +// The ui-variables file is provided by base themes provided by Atom. +// +// See https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less +// for a full listing of what's available. +@import "ui-variables"; + +.orion { +} From bd6ffae79a9d94f29a172c140e93046ba14f5893 Mon Sep 17 00:00:00 2001 From: Rickus Date: Thu, 24 Aug 2017 09:17:11 -0700 Subject: [PATCH 2/8] Restructure README.md Added information about the Atom Package code base, as well as future work to be done. --- modules/orionode.collab.atom/CHANGELOG.md | 1 + modules/orionode.collab.atom/README.md | 164 +++++++++++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/modules/orionode.collab.atom/CHANGELOG.md b/modules/orionode.collab.atom/CHANGELOG.md index f54f04d268..76b1140445 100644 --- a/modules/orionode.collab.atom/CHANGELOG.md +++ b/modules/orionode.collab.atom/CHANGELOG.md @@ -8,3 +8,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## 0.0.1 - First Release - Generated Atom package: Orion + diff --git a/modules/orionode.collab.atom/README.md b/modules/orionode.collab.atom/README.md index ccef86da95..5351d2fdd3 100644 --- a/modules/orionode.collab.atom/README.md +++ b/modules/orionode.collab.atom/README.md @@ -1 +1,163 @@ -Placeholder for atom editor code +# Orion - Atom Package + +Orion - Atom is a package that enables connections to Eclipse Orion for collaboration. + +## Getting Started + +These instructions will get you an instance of the Atom package up and running on your local machine for development and testing purposes. + +### Prerequisites + +Please ensure that you have the latest version of Atom installed: + +``` +https://atom.io/ +``` + +Also ensure that your Eclipse Orion repository is up to date. The repository can be found at: + +``` +https://github.com/eclipse/orion.client +``` + +### Installing the package + +1. Within your terminal, navigate to: + ``` + orion.client/modules/orionode.collab.atom + ``` +2. Within this directory, link the package to Atom using: + ``` + apm link + ``` + +## Running the package + +(*Refer to each command's specific section for configuration details before running the package.*) + +Running the Atom - Orion package consists of three consecutive commands: + +1. Start_Collab +2. Join_Session +3. Join_Document + +These three commands can be executed in Atom using the Command Palette +```MAC: Command + Shift + P``` +```PC and Linux: Control + Shift + P``` + +### Orion: Start_Collab + +Upon execution, function start_collab within *orion.js* is called. Start_collab handles the connections through socket.io, as well as message transfers. + +At the moment **there are two attributes that must be entered manually** in respect to their Orion values: + +- Orion Collab Hub IP + Port +- SessionID + +Example: + +``` +mySocket = io.connect('http://localhost:8082/' + "?sessionId=" + 'jnpO0CBn8n', { + path: "/socket.io/" +}); +``` +The SessionID can be found in *orion.client/modules/orionode.collab.hub/server.js* by printing to terminal: + +``` +var sessionID = sock.conn.request._query.sessionID; (~ Line 30) +console.log("The SessionID is: " + sessionID); +``` + +#### Socket.IO Channels + +Transferring of text from Orion to Atom is done within the 'message' channel as described below. + +'connect' : Calls join_session() + +'disconnect' : Disconnects user from current socket.io session + +'error' : Displays all socket.io server errors + +'message' : Has types 'init-document' and 'operation' + +##### ***If the message object has type 'operation', text is transferred and inserted into Atom.*** + +``` +if (msgObj.type === 'operation') { + atom.workspace.getActiveTextEditor().insertText(msgObj.operation[1]); +} +``` + +### Orion: Join_Session + +Upon execution, function join_session within *orion.js* is called. Join_session handles the connection of users to a specific Orion session. + +At the moment there are two attributes that must be entered manually in respect to their Orion values: +- ClientID ```In the form of: username.12345``` +- Token ```In the form: username``` + + +**Temporary Alert: *Both Authentication and Token usage were removed (commented out) to enable Atom connections to Orion. This avoids the need for JWT_SECRET within each user object.*** + +### Orion: Join_Document + +Upon execution, function join_document within *orion.js* is called. Join_document handles the connection of users to a specific Orion document. + +At the moment there are two attributes that must be entered manually in respect to their Orion values: +- Document path +- The same ClientID from Orion: Join_Session + +``` +mySocket.emit('message', JSON.stringify({ + type: 'join-document', + doc: '/arshi-OrionContent/Test/test.txt', + clientId: 'arshi3.12345' +})); +``` + +## To Do + +List of things to do towards the completion of the Atom - Orion package. + +**Real-time Editing** + +- Sending messages/text from Orion to Atom + - *Text Insertion location needs to be same on both editors (In progress)* +- Sending messages/text from Atom to Orion + +**Authentication** + +- Restore the security layer for Atom users such that the Atom user needs to be authenticated to view/edit files and directories. + - *Authentication had been temporarily removed for development purposes.* + +**Invitation/Revoke Access Control** + +- Show Atom user a list of workspaces that he has access to. + +**Workspaces** + +- Let the user choose the workspace he wishes to work on. +- Get a representation of the tree (files and directories) once they are in a workspace. + - Render the tree + - Starter goal: List View + - End goal: GUI within Atom +- Synchronized file manipulation, such as Create, Rename, Delete. +- Let Atom user select a file (in the chosen workspace) so that they can view/edit the document. +- Get file content for the chosen file and render it on Atom when Atom user joins a document. + - *Content is currently fetched and inserted into the Atom editor* + +**Text, Audio, and Video Communication** + +- Implementation of a text chat with individual chatroom scopes for: Workspace, Project Folder, and File. + +## Contributing + +Please read [CONTRIBUTING.md](https://github.com/eclipse/orion.client/blob/master/CONTRIBUTING.md) for details on our code of conduct, and developer resources. + +## Versioning + +We use Github for versioning. For the versions available, see the commits on [this repository](https://github.com/eclipse/orion.client). + +## License + +Dual-licensed under the [Eclipse Public License v1.0](http://www.eclipse.org/legal/epl-v10.html) and the [Eclipse Distribution License v1.0](http://www.eclipse.org/org/documents/edl-v10.html). \ No newline at end of file From b9263d4c24cab3571e1c724bd9f55c4500d29d07 Mon Sep 17 00:00:00 2001 From: Rickus Senekal Date: Tue, 22 Aug 2017 10:31:19 -0700 Subject: [PATCH 3/8] Add prototype functions for Atom commands Functions: - start_collab - join_session - join_document --- modules/orionode.collab.atom/lib/orion.js | 30 +++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js index ceff189252..4a268fbcdf 100644 --- a/modules/orionode.collab.atom/lib/orion.js +++ b/modules/orionode.collab.atom/lib/orion.js @@ -1,7 +1,9 @@ 'use babel'; import OrionView from './orion-view'; -import { CompositeDisposable } from 'atom'; +import { + CompositeDisposable +} from 'atom'; export default { @@ -23,6 +25,18 @@ export default { this.subscriptions.add(atom.commands.add('atom-workspace', { 'orion:toggle': () => this.toggle() })); + + this.subscriptions.add(atom.commands.add('atom-workspace', { + 'orion:start_collab': () => this.start_collab() + })); + + this.subscriptions.add(atom.commands.add('atom-workspace', { + 'orion:join_session': () => this.join_session() + })); + + this.subscriptions.add(atom.commands.add('atom-workspace', { + 'orion:join_document': () => this.join_document() + })); }, deactivate() { @@ -44,6 +58,18 @@ export default { this.modalPanel.hide() : this.modalPanel.show() ); - } + }, + + start_collab() { + console.info('start_collab not implemented'); + }, + + join_session() { + console.info('join_session not implemented'); + }, + + join_document() { + console.info('join_document not implemented'); + }, }; From 7da633ebd6b68646f00b493c93cc8bd99458c2c7 Mon Sep 17 00:00:00 2001 From: Arshi Annafi Date: Tue, 22 Aug 2017 11:18:49 -0700 Subject: [PATCH 4/8] Add Socket.io connection to Collab Hub server Socket.io Events: - connect - disconnect - error - message --- modules/orionode.collab.atom/lib/orion.js | 34 ++++++++++++++++++++++- modules/orionode.collab.atom/package.json | 1 + 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js index 4a268fbcdf..f08ae498e0 100644 --- a/modules/orionode.collab.atom/lib/orion.js +++ b/modules/orionode.collab.atom/lib/orion.js @@ -61,7 +61,39 @@ export default { }, start_collab() { - console.info('start_collab not implemented'); + + const io = require('socket.io-client'); + + mySocket = io.connect('http://localhost:8082/' + "?sessionId=" + 'jnpO0CBn8n', { + path: "/socket.io/" + }); + + if (!mySocket.connected) { + console.error('Socket connection failed'); + /* + * Check: + * - Servers are running + * - `sessionId` above (attined from Collab Hub server) is correct + * - Port number for the Collab Hub server above is correct + */ + } + + mySocket.on('connect', function() { + console.info('Socket connection successful'); + }); + + mySocket.on('disconnect', function() { + console.info('Socket disconnected'); + }); + + mySocket.on('error', function(e) { + console.info('Server sent an error message'); + }); + + mySocket.on('message', function(data) { + console.info('Server sent a message'); + }); + }, join_session() { diff --git a/modules/orionode.collab.atom/package.json b/modules/orionode.collab.atom/package.json index e6292c84f4..3c91be4e9a 100644 --- a/modules/orionode.collab.atom/package.json +++ b/modules/orionode.collab.atom/package.json @@ -12,5 +12,6 @@ "atom": ">=1.0.0 <2.0.0" }, "dependencies": { + "socket.io": "^2.0.0" } } From 0ea1f828211db563f91aa5c8c5bc7512259e96ad Mon Sep 17 00:00:00 2001 From: Rickus Senekal Date: Tue, 22 Aug 2017 14:27:54 -0700 Subject: [PATCH 5/8] Add 'join_session' and 'join_document' Functions: - join_session - join_document These functions (with hardcoded values) establish a connection to Orion, receive newly typed text from Orion, and insert the text where the cursor is in Atom. IDs and paths are hardcoded and auth is bypassed for dev purposes. --- modules/orionode.collab.atom/lib/orion.js | 45 +++++++++++++++++------ modules/orionode.collab.hub/server.js | 43 +++++++++++++++++++--- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js index f08ae498e0..e4b3945e25 100644 --- a/modules/orionode.collab.atom/lib/orion.js +++ b/modules/orionode.collab.atom/lib/orion.js @@ -68,15 +68,16 @@ export default { path: "/socket.io/" }); - if (!mySocket.connected) { - console.error('Socket connection failed'); - /* - * Check: - * - Servers are running - * - `sessionId` above (attined from Collab Hub server) is correct - * - Port number for the Collab Hub server above is correct - */ - } + setTimeout(function() { + if (!mySocket.connected) { + console.error('Socket connection failed'); + /* Check: + * - if servers are running + * - `sessionId` above (attined from Collab Hub server) is correct + * - Port number for the Collab Hub server above is correct + */ + } + }, 2000); mySocket.on('connect', function() { console.info('Socket connection successful'); @@ -91,17 +92,37 @@ export default { }); mySocket.on('message', function(data) { - console.info('Server sent a message'); + + var msgObj = JSON.parse(data); + console.log(msgObj); + + if (msgObj.type === 'init-document') { + console.info('Successfully joined document') + } + + if (msgObj.type === 'operation') { + // Insert recieved text from Orion + // to where the cursor is in Atom + atom.workspace.getActiveTextEditor().insertText(msgObj.operation[1]); + } + }); }, join_session() { - console.info('join_session not implemented'); + mySocket.emit('message', JSON.stringify({ + 'clientId': 'arshi3.12345', + 'token_bypass': 'arshi3' + })); }, join_document() { - console.info('join_document not implemented'); + mySocket.emit('message', JSON.stringify({ + type: 'join-document', + doc: '/arshi-OrionContent/Test/demo.txt', + clientId: 'arshi3.12345' + })); }, }; diff --git a/modules/orionode.collab.hub/server.js b/modules/orionode.collab.hub/server.js index c6c4b234c9..7f1dbb3616 100644 --- a/modules/orionode.collab.hub/server.js +++ b/modules/orionode.collab.hub/server.js @@ -28,6 +28,7 @@ var sessions = new SessionManager(); io.on('connection', function(sock) { // Get session ID var sessionId = sock.conn.request._query.sessionId; + console.log('[Info] sessionId: ' + sessionId); /** * Handle the initial message (authentication) @@ -35,16 +36,42 @@ io.on('connection', function(sock) { */ sock.on('message', function initMsgHandler(msg) { try { + var msgObj = JSON.parse(msg); - if (msgObj.type !== 'authenticate') { - throw new Error('Not authenticated.'); - } - // Authenticate + // Commenting out the following code + // to skip authentication + // + // TODO: + // - Restore the following code + // when Atom is capable of authentication + // + // + // // Original Code: + // + // if (msgObj.type !== 'authenticate') { + // throw new Error('Not authenticated.'); + // } + // + // if (!msgObj.token) { + // throw new Error('No token is specified.'); + // } + // + // // End of Original Code + // + // + // // New code to skip auth //////////////////////////////////////// + console.log('[Info] Skipping authentication for atom plugin dev.') + if (!msgObj.token) { - throw new Error('No token is specified.'); + var user = { + 'username': msgObj.token_bypass + } + } else { + var user = jwt.verify(msgObj.token, JWT_SECRET); } - var user = jwt.verify(msgObj.token, JWT_SECRET); + // // End of new code ////////////////////////////////////////////// + // // Give the control to a session sessions.addConnection(sessionId, sock, msgObj.clientId, user.username).then(function() { @@ -53,7 +80,11 @@ io.on('connection', function(sock) { }).catch(function(err) { sock.send(JSON.stringify({ type: 'error', error: err })); }); + } catch (ex) { + + console.log(ex); + sock.send(JSON.stringify({ type: 'error', message: ex.message From e70dacf4bd070590333be7b448d69aae4edf9970 Mon Sep 17 00:00:00 2001 From: Arshi Annafi Date: Thu, 24 Aug 2017 10:37:36 -0700 Subject: [PATCH 6/8] Update README.md --- modules/orionode.collab.atom/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/orionode.collab.atom/README.md b/modules/orionode.collab.atom/README.md index 5351d2fdd3..14247f402d 100644 --- a/modules/orionode.collab.atom/README.md +++ b/modules/orionode.collab.atom/README.md @@ -42,8 +42,10 @@ Running the Atom - Orion package consists of three consecutive commands: 3. Join_Document These three commands can be executed in Atom using the Command Palette -```MAC: Command + Shift + P``` -```PC and Linux: Control + Shift + P``` + +`MAC: Command + Shift + P` + +`PC and Linux: Control + Shift + P` ### Orion: Start_Collab @@ -93,8 +95,8 @@ if (msgObj.type === 'operation') { Upon execution, function join_session within *orion.js* is called. Join_session handles the connection of users to a specific Orion session. At the moment there are two attributes that must be entered manually in respect to their Orion values: -- ClientID ```In the form of: username.12345``` -- Token ```In the form: username``` +- ClientID `In the form of: username.12345` +- Token `In the form: username` **Temporary Alert: *Both Authentication and Token usage were removed (commented out) to enable Atom connections to Orion. This avoids the need for JWT_SECRET within each user object.*** @@ -156,8 +158,8 @@ Please read [CONTRIBUTING.md](https://github.com/eclipse/orion.client/blob/maste ## Versioning -We use Github for versioning. For the versions available, see the commits on [this repository](https://github.com/eclipse/orion.client). +We use GitHub for versioning. For the versions available, see the commits on [this repository](https://github.com/eclipse/orion.client). ## License -Dual-licensed under the [Eclipse Public License v1.0](http://www.eclipse.org/legal/epl-v10.html) and the [Eclipse Distribution License v1.0](http://www.eclipse.org/org/documents/edl-v10.html). \ No newline at end of file +Dual-licensed under the [Eclipse Public License v1.0](http://www.eclipse.org/legal/epl-v10.html) and the [Eclipse Distribution License v1.0](http://www.eclipse.org/org/documents/edl-v10.html). From 67985616373969b9bf7c9d87f793b4de5bd1c015 Mon Sep 17 00:00:00 2001 From: Arshi Annafi Date: Thu, 24 Aug 2017 09:52:31 -0700 Subject: [PATCH 7/8] Add more text operations and demo - Fetch document content (bypassing authentication) - Handle more Orion operations on Atom: - Backspaces - Insertion: - First char in an empty document - First char in a non-empty document - Char that was inserted in the middle - Char that was inserted at the end - Demo (Working towards inserting text in the correct position in Atom) - Insert text in-place - Insert text at a certain position in the document --- modules/orionode.collab.atom/lib/orion.js | 90 ++++++++++++++++++++++- modules/orionode.collab.atom/package.json | 3 +- modules/orionode/index.js | 15 +++- 3 files changed, 103 insertions(+), 5 deletions(-) diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js index e4b3945e25..ed342358b4 100644 --- a/modules/orionode.collab.atom/lib/orion.js +++ b/modules/orionode.collab.atom/lib/orion.js @@ -101,9 +101,75 @@ export default { } if (msgObj.type === 'operation') { - // Insert recieved text from Orion - // to where the cursor is in Atom - atom.workspace.getActiveTextEditor().insertText(msgObj.operation[1]); + + let editor = atom.workspace.getActiveTextEditor(); + + let operation = msgObj.operation; + let startPosition = 0; + let text = ''; + + // First char in empty doc + if (operation.length === 1) { + startPosition = 0; + text = operation[0]; + } + + // First char in non-empty doc + if (operation.length === 2 && Number.isInteger(operation[1])) { + startPosition = 0; + text = operation[0]; + } + + // Char in the middle + if (operation.length === 3) { + startPosition = operation[0]; + text = operation[1]; + } + + // Char at the end + if (operation.length === 2 && Number.isInteger(operation[0])) { + startPosition = operation[0]; + text = operation[1]; + } + + // ############################################################### demo + + // editor.setTextInBufferRange() // TODO ideal function to use + + let _demo_basic = false; + let _demo_insert_at_position = true; + + // + + if (_demo_basic) { + if (Number.isInteger(text) && text < 0) { + let backspaceCount = -text; + for (let count = 0; count < backspaceCount; count++) { + editor.delete(); + } + } else { + // Insert received text from Orion + editor.insertText(text); + } + } // end of '_demo_basic' + + // + + if (_demo_insert_at_position) { + if (Number.isInteger(text) && text < 0) { + let backspaceCount = -text; + for (let count = 0; count < backspaceCount; count++) { + // Simulating backspace without moving the cursor + editor.setTextInBufferRange([[2,2],[2,3]], ''); + } + } else { + // Insert received text from Orion + editor.setTextInBufferRange([[2,2],[2,2]], text); + } + } // end of '_demo_insert_at_position' + + // ################################################### end of demo code + } }); @@ -123,6 +189,24 @@ export default { doc: '/arshi-OrionContent/Test/demo.txt', clientId: 'arshi3.12345' })); + + var request = require('request'); + // Requesting content of 'demo.txt' file + request('http://localhost:8081/file/arshi-OrionContent/Test/demo.txt', function(error, response, body) { + + if (error) { + console.log('error:', error); + console.log('statusCode:', response && response.statusCode); + } + + let editor = atom.workspace.getActiveTextEditor(); + // Clear all content of the open Atom file + editor.selectAll(); + editor.backspace(); + // Insert received content into the open Atom file + editor.insertText(body); + + }); }, }; diff --git a/modules/orionode.collab.atom/package.json b/modules/orionode.collab.atom/package.json index 3c91be4e9a..2e44a3d2eb 100644 --- a/modules/orionode.collab.atom/package.json +++ b/modules/orionode.collab.atom/package.json @@ -12,6 +12,7 @@ "atom": ">=1.0.0 <2.0.0" }, "dependencies": { - "socket.io": "^2.0.0" + "socket.io": "^2.0.0", + "request": "^2.81.0" } } diff --git a/modules/orionode/index.js b/modules/orionode/index.js index 4786aefd1d..c4190240a5 100755 --- a/modules/orionode/index.js +++ b/modules/orionode/index.js @@ -85,7 +85,20 @@ function startServer(options) { app.use('/site', checkAuthenticated, require('./lib/sites')(options)); app.use('/task', checkAuthenticated, require('./lib/tasks').router({ taskRoot: contextPath + '/task', options: options})); app.use('/filesearch', checkAuthenticated, require('./lib/search')(options)); - app.use('/file*', checkAuthenticated, require('./lib/file')({ workspaceRoot: contextPath + '/workspace', fileRoot: contextPath + '/file', options: options })); + + // + // Bypassing authentication for Atom plugin development + // + // TODO restore authentication when Atom plugin is capable of auth + // + // Old code: + // app.use('/file*', checkAuthenticated, require('./lib/file')({ workspaceRoot: contextPath + '/workspace', fileRoot: contextPath + '/file', options: options })); + // + // New Code: + app.use('/file*', require('./lib/file')({ workspaceRoot: contextPath + '/workspace', fileRoot: contextPath + '/file', options: options })); + // End of auth bypass + // + app.use('/workspace*', checkAuthenticated, require('./lib/workspace')({ workspaceRoot: contextPath + '/workspace', fileRoot: contextPath + '/file', gitRoot: contextPath + '/gitapi', options: options })); /* Note that the file and workspace root for the git middleware should not include the context path to match java implementation */ app.use('/gitapi', checkAuthenticated, require('./lib/git')({ gitRoot: contextPath + '/gitapi', fileRoot: /*contextPath + */'/file', workspaceRoot: /*contextPath + */'/workspace', options: options})); From fcb1bab4c209cb3d9ac81b47ba868e02b0a55bcb Mon Sep 17 00:00:00 2001 From: Rickus Senekal Date: Thu, 24 Aug 2017 13:36:56 -0700 Subject: [PATCH 8/8] Add comments, 'TODO', and 'HACK' tags - Comments and TODO tags to identify areas of work. - HACK tags mark hardcoded values. --- modules/orionode.collab.atom/lib/orion.js | 43 +++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/modules/orionode.collab.atom/lib/orion.js b/modules/orionode.collab.atom/lib/orion.js index ed342358b4..3dd7957273 100644 --- a/modules/orionode.collab.atom/lib/orion.js +++ b/modules/orionode.collab.atom/lib/orion.js @@ -64,6 +64,7 @@ export default { const io = require('socket.io-client'); + // HACK hardcoded value: sessionId mySocket = io.connect('http://localhost:8082/' + "?sessionId=" + 'jnpO0CBn8n', { path: "/socket.io/" }); @@ -134,18 +135,22 @@ export default { // ############################################################### demo - // editor.setTextInBufferRange() // TODO ideal function to use - - let _demo_basic = false; - let _demo_insert_at_position = true; + let _demo_basic = true; + let _demo_insert_at_position = false; // + /* + * This code will insert text where the cursor is on Atom + * regardless of where the Orion user is typing + */ if (_demo_basic) { if (Number.isInteger(text) && text < 0) { let backspaceCount = -text; for (let count = 0; count < backspaceCount; count++) { editor.delete(); + // TODO handle backspace separately + // editor.backspace(); } } else { // Insert received text from Orion @@ -155,16 +160,32 @@ export default { // + /* + * This code will insert text at a given position in Atom + * regardless of where the cursor is + * + * Currently inserting text on row: 2 and col: 2 for demo. + * TODO: Send row-col value from Orion and use that data here + */ if (_demo_insert_at_position) { if (Number.isInteger(text) && text < 0) { let backspaceCount = -text; for (let count = 0; count < backspaceCount; count++) { - // Simulating backspace without moving the cursor - editor.setTextInBufferRange([[2,2],[2,3]], ''); + // Simulating backspace: + // Replacing from [2,2] to [2,3] (one char) with empty string + // HACK hardcoded value: range array + editor.setTextInBufferRange([ + [2, 2], + [2, 3] + ], ''); } } else { // Insert received text from Orion - editor.setTextInBufferRange([[2,2],[2,2]], text); + // HACK hardcoded value: range array + editor.setTextInBufferRange([ + [2, 2], + [2, 2] + ], text); } } // end of '_demo_insert_at_position' @@ -180,6 +201,7 @@ export default { mySocket.emit('message', JSON.stringify({ 'clientId': 'arshi3.12345', 'token_bypass': 'arshi3' + // HACK hardcoded values: 'clientId' and 'token_bypass' })); }, @@ -188,11 +210,18 @@ export default { type: 'join-document', doc: '/arshi-OrionContent/Test/demo.txt', clientId: 'arshi3.12345' + // HACK hardcoded values: 'doc' and 'clientId' })); var request = require('request'); // Requesting content of 'demo.txt' file request('http://localhost:8081/file/arshi-OrionContent/Test/demo.txt', function(error, response, body) { + // TODO add authentication with this request + // HACK hardcoded value: URL + // + // The authentication to fetch content of the file + // on 'modules/orionode/index.js' ~ line 90 + // is disabled if (error) { console.log('error:', error);