Compare commits

...

143 Commits

Author SHA1 Message Date
Tal Moran cf891549bb Fixed typo in mixer docs 2018-05-10 18:07:59 +03:00
Tal Moran 21ad93f4e1 Updated to gradle 4.2.1 2017-10-16 17:02:35 +03:00
Tal Moran 73619b0c9e Better win compatibility for bb-server frontent 2017-07-09 11:09:07 +03:00
Tal Moran 252a761005 Better cross-platform support for building bb-server frontend 2017-07-06 12:00:04 +03:00
Tal Moran 931bb56378 Fixed npm_install dependency that broke clean builds 2017-07-03 02:51:02 -04:00
Tal Moran fa4656f0a9 added dependency on npmInstall to ensure protobufjs is installed in bb server frontend 2017-07-03 03:37:32 +03:00
Tal Moran 08d9bd6217 Integrated bb-server angular frontend in gradle build 2017-07-03 03:24:00 +03:00
Tal Moran 173b952e09 Added proxy to bb frontend (no need for cross-origin headers); support periodic status calls 2017-07-02 17:54:36 +03:00
Tal Moran c0b21f82ee Added toy angular application (for bulletin-board frontend) 2017-07-02 16:42:45 +03:00
Tal Moran 05c7a25bb7 Renamed proto files to use standard (lowercase-underscore) naming convention); added a separate proto for bb webapp 2017-06-30 02:28:03 +03:00
Tal Moran 68e1737f22 Dependency cleaning; more spongification; use composite build to include qilin (need qilin 1.3+ now) 2017-06-26 01:59:32 +03:00
Tal Moran 3c52eb2e8d Done refactoring scannerAPI; fixed android scanner to use modern settings api and allow URL+nonce 2017-06-26 00:22:20 +03:00
Tal Moran 0dfd2480d2 Added connection to android scanner; problems with missing crypto providers 2017-06-25 19:27:38 +03:00
Tal Moran 291f7d93c0 Scanner serverdata now tries to get a non-localhost IPV4 address if possible 2017-06-25 18:54:34 +03:00
Tal Moran 6b47387920 Code now builds 2017-06-25 18:05:52 +03:00
Tal Moran 324a079a90 Refactored and fixed NetworkVirtualPrinter 2017-06-25 17:51:25 +03:00
Tal Moran 6f35f105c5 Mostly finished with scanAPI refactoring 2017-06-25 16:20:28 +03:00
Tal Moran cb1d2343c4 More refactoring for scannerAPI 2017-06-25 10:15:09 +03:00
Tal Moran 7e4260b8d5 Added signature key generation to crypto API 2017-06-24 03:15:59 +03:00
Tal Moran ceba09e65c working on scanner API refactoring (doesn't compile yet) 2017-06-22 17:56:59 +03:00
Tal Moran c7dd5bd663 Added settings activity to android scanner; started refactoring scanner api 2017-06-22 11:50:59 +03:00
Tal Moran 24e3556320 fixed build so android-scanner compiles; changed android-scanner to use meerkat scanner API rather than custom REST library 2017-06-22 02:58:01 +03:00
Tal Moran 62349f9fe7 removed apparently unecessary file 2017-06-22 01:45:48 +03:00
Tal Moran 3b3a6a09b2 Removed debug printout 2017-06-22 01:42:24 +03:00
Tal Moran 1387de97e2 Updated gradlew 2017-06-22 01:42:08 +03:00
Tal Moran ef2e09ba6b Added appcompat dependency to scanner to allow build 2017-06-22 01:41:50 +03:00
Tal Moran c921fef055 Added fixed version of osdetector that is compatible with android plugin 2017-06-22 01:41:08 +03:00
Tal Moran ea8813bade Updated voting-booth-gui build script to work without local nexus repository 2017-06-21 17:28:07 +03:00
Tal Moran 355ea1758b Imported scanner project; doesn't compile yet 2017-06-21 13:19:00 +03:00
Tal Moran 9ad0828eb2 Removed .orig files 2017-06-20 23:41:53 +03:00
Tal Moran 33a5c493f0 Upgraded to gradle 4.0 2017-06-20 23:17:21 +03:00
Laura Radaelli 24b111a20b voting questions flow fixed (removed button cancel) 2017-06-14 19:15:13 +03:00
Laura Radaelli f813cf49ee channel single question 2017-06-14 18:17:07 +03:00
Laura Radaelli 646824de44 parse ScannedData serial number 2017-04-27 16:32:12 +03:00
Laura Radaelli 4e1b66f890 ip address set to work on tethering 2017-04-27 14:43:23 +03:00
Laura Radaelli cc3e151a26 main that starts threads added 2017-04-16 17:09:35 +03:00
Laura Radaelli 29f6b244d7 polling station server and client communicate (reading scannedData works) 2017-04-16 14:59:44 +03:00
Laura Radaelli ed7b50de23 fixed ScanErrorCallback error in ReceiverWebAPI 2017-03-20 18:20:30 +02:00
Laura Radaelli 09ee63eca4 polling station server and scanner client communicate (but missing response) 2017-03-20 18:03:08 +02:00
Laura Radaelli 11b86dd2aa new files with new names (old test passed) 2017-03-20 10:37:02 +02:00
Laura Radaelli db4cf6a734 QR code for cast (missing QR code for audit) + test interaction polling station 2017-03-20 09:34:21 +02:00
Laura Radaelli 6350da1fc2 Merge branch 'master' of https://vcs.factcenter.org/meerkat/meerkat-java into voting-booth-gui 2017-03-19 10:33:24 +02:00
Tal Moran 181f49145f Allow specifying elliptic curve name when generating keys on mixer command-line 2017-02-01 21:34:18 +02:00
Laura Radaelli 97fbfcecaf remove unused import and fixed cast/audit buttons width 2017-01-25 22:10:09 +02:00
Laura Radaelli 17d7d5eca4 Merge branch 'master' of https://vcs.factcenter.org/meerkat/meerkat-java into voting-booth-gui 2017-01-25 21:45:50 +02:00
Laura Radaelli f393825b26 printer added clean() method 2017-01-25 19:12:30 +02:00
Tal Moran b360ae81bb Fix gradle build files to work without nexus repository credentials 2017-01-25 19:10:18 +02:00
Laura Radaelli 480f4e52bb moved code for fx to voting-booth-gui 2017-01-25 16:01:13 +02:00
Laura Radaelli 0cf9390fa5 prints test qr-code to virtual printer 2017-01-25 12:50:01 +02:00
Laura Radaelli e60e76f104 changed titles of FX windows 2017-01-25 10:46:13 +02:00
Tal Moran 06526a16db Clean up build files and remove dependency on local nexus repository 2017-01-24 17:17:09 +02:00
Tal Moran 53cc13b51b Cleaning up unchecked casts 2017-01-24 16:28:57 +02:00
Tal Moran ce0e0e0d62 Fix protobuf decoding bug 2017-01-23 15:41:27 +02:00
Tal Moran 5b7fbffb09 Update to gradle 3.3 2017-01-23 15:40:45 +02:00
Tal Moran c8f82223bc Merge branch 'master' of https://vcs.factcenter.org/meerkat/meerkat-java into mixer 2017-01-23 10:46:14 +02:00
Laura Radaelli 5386acfd1b added css 2017-01-12 18:24:38 +02:00
Laura Radaelli 72d96c4d78 virtual printer (javaFX window) added 2017-01-12 18:03:40 +02:00
Laura Radaelli b8418156b1 got to Cast or Audit screen 2017-01-12 12:32:59 +02:00
Laura Radaelli 29b8ef9734 javafx integration runs till channel choice 2017-01-06 17:24:38 +02:00
Laura Radaelli c8044fc93d fx gui with mainController and navigator (incomplete again) 2016-12-16 22:11:00 +02:00
Laura Radaelli 5113c2235b fx gui with MainController and Navigator (incomplete) 2016-12-16 22:10:23 +02:00
Laura Radaelli c97519c28e starting fx window and communicating with graphicalUI thread 2016-12-16 17:55:56 +02:00
Laura Radaelli 0b1d334d3c start javaFX window from voting booth ToyRun 2016-12-13 10:23:51 +02:00
Laura Radaelli 971db5d89c barcode window always on top 2016-12-08 13:13:07 +02:00
Laura Radaelli 71076f5c7e fix NullPointerException when calling votersBallot.toString and add showBallot (new window) 2016-12-08 12:11:04 +02:00
Tal Moran 9db8efd75b Updated to gradle 3.2.1 2016-11-28 13:51:24 +02:00
VladimirEliTokarev 0509bf6dda Resolved the umextendablity of the summary ballot panel 2016-11-12 17:49:48 +02:00
VladimirEliTokarev 08cc50c22a Resulted the bug with the not expendable panel 2016-11-12 17:37:42 +02:00
VladimirEliTokarev 6161898805 Changed the configuration parser
The usage of \\z delimeter is mustable
2016-11-12 17:17:17 +02:00
VladimirEliTokarev 7b937cc754 Added the creator of the jar to compile and create jar
The jar converts json configuration into normal
2016-11-12 17:05:53 +02:00
Tal Moran 97f52bfd82 Fixed fatmain bug in build.gradle-template 2016-11-09 15:21:16 +02:00
Tal Moran e611d0c721 Removed generated files from repository 2016-11-05 23:58:33 +02:00
Tal Moran f5e71dec2f Added JOpt.simple dependency for command-line parsing; fixed bug in build.gradle to support alternative fatmain 2016-11-05 23:56:19 +02:00
VladimirEliTokarev d6ea9412e3 Changed the usage of json configuration
For now we use an binary file which contains all the protobuf ballot
quesitons.
However there is a problem, the jar that suppose to convert json into
binary configuraiton file doesnt work.
2016-11-05 18:00:28 +02:00
Tal Moran c4e0e5f56d Allow using resource paths for images linked in the JSON configuration file 2016-10-30 15:34:58 +02:00
Tal Moran ac4d668984 Use configuration file from bundled resource in test 2016-10-30 13:32:39 +02:00
VladimirEliTokarev b601619d39 Changed the configuraitons tests 2016-10-29 23:10:18 +03:00
VladimirEliTokarev 555783d30c Removed unnsessery panels 2016-10-29 23:06:28 +03:00
VladimirEliTokarev c5dcb9f06e Added the description of the picture of the candidate 2016-10-29 09:48:29 +03:00
VladimirEliTokarev fbc1707b37 Added the validation that the answers given are valid strings and pictures 2016-10-28 20:02:27 +03:00
VladimirEliTokarev e440bb3e76 Added configuration validation 2016-10-28 19:55:51 +03:00
Tal Moran ca89514c97 Modified JSON and BARBECUE deps to use external maven sources 2016-10-26 00:50:23 +03:00
VladimirEliTokarev d575eaf1d2 Moved the main file into outer folder 2016-10-24 17:12:10 +03:00
VladimirEliTokarev 2bf78f7c73 Added the logging to the configuration parsing and the main 2016-10-24 16:47:38 +03:00
VladimirEliTokarev 0af9d94a73 Addded logging to all of the panels. 2016-10-24 16:31:48 +03:00
VladimirEliTokarev 37f8893224 Added the randomiztaion of the answesr 2016-10-18 11:55:31 +03:00
VladimirEliTokarev c474bc5ffb Added the creation of the barcode 2016-10-05 17:12:44 +03:00
VladimirEliTokarev 5a78f723e5 Added button which takes you back 2016-10-05 16:52:28 +03:00
VladimirEliTokarev 94adef22f3 Added the thank for auditing pannel 2016-10-05 16:48:30 +03:00
VladimirEliTokarev dcaf36f8fa Added local usage of json configuration ar 2016-10-05 15:54:06 +03:00
VladimirEliTokarev ef5cd70cc9 The summiting of the voters selections working 2016-10-05 15:37:53 +03:00
VladimirEliTokarev 8e2fdb7828 Every pannel that choses somthing now saves it into VotersBallot` 2016-10-05 13:11:18 +03:00
VladimirEliTokarev 6655f2dc8e Added the usage of VotersBallot 2016-10-05 13:00:57 +03:00
VladimirEliTokarev af2622b05c Changed the project structure 2016-10-05 12:28:19 +03:00
VladimirEliTokarev f535847ee5 Added tests to conbfiguration creator 2016-10-04 19:52:08 +03:00
VladimirEliTokarev 55279e2e3d The new object which creates protobuf from jason working 2016-10-04 15:50:00 +03:00
VladimirEliTokarev 80a0a2fc2c Added the Object which creates configurations based on json file 2016-10-04 15:09:58 +03:00
VladimirEliTokarev 80a032d373 Added the selection of the channel 2016-10-03 21:15:44 +03:00
VladimirEliTokarev 6e47a4df98 Added pictures showing
Now from given configuration the the pictures showed two,
2016-10-03 20:30:43 +03:00
VladimirEliTokarev 21867fb5da Added the ability to display pictures 2016-10-03 20:11:42 +03:00
VladimirEliTokarev 91b0d947f2 Started implementing the representation of the pictures for voter 2016-10-03 12:48:16 +03:00
VladimirEliTokarev 352fb7a548 Now the text question represented in the select name panel 2016-10-03 12:15:08 +03:00
VladimirEliTokarev 4e071c83ce Createing the object that will update the new strings answers 2016-10-02 23:02:42 +03:00
VladimirEliTokarev fe5a4d7be1 Created Succesefully whole config object 2016-10-02 22:26:38 +03:00
VladimirEliTokarev ef1ff8dea1 Creating configuration file 2016-10-02 21:35:59 +03:00
VladimirEliTokarev 272e40647e Resolved the issue with the encoding 2016-10-02 21:03:42 +03:00
VladimirEliTokarev c410fc6693 Added the changes of two way node to number of clases 2016-10-02 19:11:34 +03:00
VladimirEliTokarev 5267c7026f Implementing the usage of voting booth gui config 2016-10-02 18:52:20 +03:00
Vladimir Eliezer Tokarev 68291d34f3 Added the protobuf that describes the voting booth question
And changed the panels to work with voting booth configuration object
instead of the backend.
2016-10-01 18:50:33 +03:00
Vladimir Eliezer Tokarev 5c2de6d009 Inserted the VotingBoothConfiguration into every panel
For now every panel will have the configuration object when created and
will represent the questions/answers according to it.
2016-10-01 15:56:26 +03:00
Vladimir Eliezer Tokarev c0ed5ea3fc Added the configuration object that will contains all needed data for
voting booth initilization
2016-10-01 15:41:13 +03:00
Vladimir Eliezer Tokarev 51ea368c01 Removed the packages problem 2016-10-01 11:07:43 +03:00
Vladimir Eliezer Tokarev 7cda19247e Updated the slesect candidate by pictures 2016-10-01 11:00:25 +03:00
Vladimir Eliezer Tokarev 9211c70c2e Merge branch 'voting-booth-gui' of http://cs.idc.ac.il/rhodecode/meerkat/meerkat-java into voting-booth-gui 2016-09-24 19:17:40 +03:00
Vladimir Eliezer Tokarev 16e0633b75 Removed unnesesery fields 2016-09-24 19:09:13 +03:00
Vladimir Eliezer Tokarev 37be8f3a52 Added the ability to submit questions and answers 2016-09-24 19:08:24 +03:00
Vladimir Eliezer Tokarev f1704ce16e Implemented the start new session functionality
When new session needed to be started we call the doStartNewSesison method
which generates all of the gui panels and gives to them the primary
stage.
2016-09-24 13:26:15 +03:00
Tal Moran a9fbf555d6 Refactored voting-booth-gui to use gradle and match maven directory style 2016-09-21 17:21:34 +03:00
Tal Moran 1ff490a354 Merge branch 'master' of https://cs.idc.ac.il/rhodecode/meerkat/meerkat-java into voting-booth-gui 2016-09-21 16:23:45 +03:00
Vladimir Eliezer Tokarev 0007df38b8 updated documentation 2016-09-17 13:50:06 +03:00
Vladimir Eliezer Tokarev d7fca43817 Removed unnesesary test2 class 2016-09-17 13:40:22 +03:00
Vladimir Eliezer Tokarev 210994ca75 Added the main method into VotingBoothGUIManager 2016-09-17 13:36:37 +03:00
Vladimir Eliezer Tokarev d8adf7b49e Created the VotingBoothGUIManager
This object creates a map of visual panels and can convert the
VotingBoothUI methods into actions (can execute them on wanted panels)
2016-09-17 13:29:21 +03:00
Vladimir Eliezer Tokarev 9444072f40 Created the Graphical User Interface
This objhect is the connector between the backed and the voting booth gui
also moved  number of methods from SystemConsoleUI into Utils class for
all the UI's classes be able to use those methods.
2016-09-17 12:33:40 +03:00
Vladimir Eliezer Tokarev c6f2ffff9b Merge branch 'master' of http://cs.idc.ac.il/rhodecode/meerkat/meerkat-java into voting-booth-gui 2016-09-10 14:00:14 +03:00
Vladimir Eliezer Tokarev dda2d3e55b Added Vote have been cast into flow 2016-08-27 17:06:35 +03:00
Vladimir Eliezer Tokarev 38f1624071 Added the cast or audit into the flow 2016-08-27 16:56:53 +03:00
Vladimir Eliezer Tokarev b687782f5c Added the ballot summary to the flow 2016-08-27 16:48:50 +03:00
Vladimir Eliezer Tokarev 4591c4e2e8 Added Select candidate by picture to the flow 2016-08-27 16:24:25 +03:00
Vladimir Eliezer Tokarev 36d9276ad8 Added the Select Candidate name into the flaw 2016-08-27 16:05:18 +03:00
Vladimir Eliezer Tokarev 01cda996f9 Connected the Welcome splash to straight channel section
When start voting pressed in welcome splash panel strair channel loaded
2016-08-27 15:07:18 +03:00
Vladimir Eliezer Tokarev e200bc0f8b Converted TwoWayNode into abstract class
Becuase all the classes that will extend this class will implelmett thisa
same logic, so there is no reason to implement it as interface.
2016-08-27 14:24:00 +03:00
Vladimir Eliezer Tokarev 9b636f2d2e Converted WelcomeSplash into two way link
Welcome Splash should be the first object to displayed and when the next
button pressed it shoud jump to already created straight channel section.
2016-08-27 14:07:13 +03:00
Vladimir Eliezer Tokarev e605089666 Created the basic idea polling booth gui
The idea is simple all of the fxmls panels will be connected this how
every one willknow which is the next or the previous panel
2016-08-27 13:34:03 +03:00
Vladimir Eliezer Tokarev c39d0774f9 Changed the name of fxml 2016-08-27 12:38:38 +03:00
Vladimir Eliezer Tokarev 19b11736e0 Created the vote has been casted
This was the last fxml that i needed to create now i should connect by
simple flow all of the panels.
next is implement panels logic and then work with the backend.
2016-08-20 13:01:27 +03:00
Vladimir Eliezer Tokarev 3a86e6f01a Created the thank for auditing panel
this panel returns the voter into first stage of selection.
2016-08-20 12:27:27 +03:00
Vladimir Eliezer Tokarev c26acbc3cf Created cast of audit panel
This panel lets you choose whenerver you want to cast or audit your vote
voting will set your vote as countable, and acudit is the choise for
checking the encoding process works fine.
2016-08-20 12:15:58 +03:00
Vladimir Eliezer Tokarev 86de5b07a4 Created the printing commitment barcode panel
Printing Commitment Barcode panel represent the progress of the printing
of the voters choise.
2016-08-20 11:55:14 +03:00
Vladimir Eliezer Tokarev 8a73f21f48 Created the ballot summary panel
ballot summary panel summaries the status of current voter
2016-08-20 11:48:54 +03:00
Vladimir Eliezer Tokarev bc790c3eb4 Created select candidate by picture fxml 2016-08-06 16:19:34 +03:00
Vladimir Eliezer Tokarev 99edbcf1b1 Created the candidate write name and the candidate selections uml 2016-08-06 16:01:33 +03:00
Vladimir Eliezer Tokarev 4f3fc40dc6 Created the voting-booth-station
The created branch is for the voting booth gui, and created the enter
splash fxml file and the straight into channel fxml.
2016-07-30 16:57:17 +03:00
347 changed files with 12439 additions and 1238 deletions

20
.gitignore vendored
View File

@ -16,3 +16,23 @@ out
*.db
*.sql
.arcconfig
/meerkat_election_params_tempfile.dat
/meerkat_booth_system_messages.dat
local.properties
# Angular junk
*/tmp
*/dist
*/out-tsc
*/node_modules
*/e2e/*.js
*/e2e/*.map
*/.sass-cache
*/connect.lock
*/coverage
*/libpeerconnection.log
npm-debug.log
testem.log
*/typings
bundle.js
bundle.d.ts

View File

@ -0,0 +1,10 @@
This file describes Wombat Code & Documentation Conventions:
Code Conventions:
* Code- The good old classic java code conventions
camelCase convention, constants should be capital letters with underscore etc...
Documentation Conventions:
* Comments- The good old classic java code documentation, Block Comments (to describe
method/class/interface etc...) // comments too describe complex code
(only if the code block complicated)

View File

@ -0,0 +1,82 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.meerkat.laura.fakescannerapp"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// Enabling multidex support.
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
configurations.all {
resolutionStrategy.dependencySubstitution {
// Avoid Android compilation error caused by two different javax.inject dependencies.
substitute module('org.glassfish.hk2.external:javax.inject:2.4.0-b34') with module('javax.inject:javax.inject:1')
}
// Exclude non-android logback modules
exclude group:"ch.qos.logback", module:"logback-core"
exclude group:"ch.qos.logback", module:"logback-classic"
}
dependencies {
// compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':meerkat-common')
compile project(':scanner-api-common')
compile 'com.android.support:appcompat-v7:26.0.+'
compile 'com.google.protobuf:protobuf-java:3.+'
compile 'com.android.support:support-v4:26.0.+'
compile 'com.android.support:support-vector-drawable:26.0.+'
testCompile 'junit:junit:4.12'
// Android logging
compile 'com.github.tony19:logback-android-core:1.1.1-6'
compile('com.github.tony19:logback-android-classic:1.1.1-6') {
// workaround issue #73
exclude group: 'com.google.android', module: 'android'
}
}
repositories {
mavenLocal()
jcenter()
}

1
android-scanner/gradlew vendored Symbolic link
View File

@ -0,0 +1 @@
../gradlew

7
android-scanner/lint.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="InvalidPackage">
<!-- Ignore javax.mail from logback https://github.com/tony19/logback-android/issues/140-->
<ignore regexp="javax.mail"/>
</issue>
</lint>

View File

@ -0,0 +1,13 @@
package com.meerkat.laura.fakescannerapp;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.meerkat.laura.fakescannerapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings">
</activity>
</application>
</manifest>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
<tagEncoder>
<pattern>%logger{12}</pattern>
</tagEncoder>
<encoder>
<pattern>[%-20thread] %msg</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="logcat" />
</root>
</configuration>

View File

@ -0,0 +1,508 @@
package com.google.zxing.integration.android;
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
/**
* <p>A utility class which helps ease integration with Barcode Scanner via {@link Intent}s. This is a simple
* way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
* project's source code.</p>
*
* <h2>Initiating a barcode scan</h2>
*
* <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
* for the result in your app.</p>
*
* <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
* {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
*
* <p>There are a few steps to using this integration. First, your {@link Activity} must implement
* the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
*
* <pre>{@code
* public void onActivityResult(int requestCode, int resultCode, Intent intent) {
* IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
* if (scanResult != null) {
* // handle scan result
* }
* // else continue with any other code you need in the method
* ...
* }
* }</pre>
*
* <p>This is where you will handle a scan result.</p>
*
* <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
*
* <pre>{@code
* IntentIntegrator integrator = new IntentIntegrator(yourActivity);
* integrator.initiateScan();
* }</pre>
*
* <p>Note that {@link #initiateScan()} returns an {@link AlertDialog} which is non-null if the
* user was prompted to download the application. This lets the calling app potentially manage the dialog.
* In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
* method.</p>
*
* <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
* {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
* yes/no button labels can be changed.</p>
*
* <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
* to invoke the scanner. This can be used to set additional options not directly exposed by this
* simplified API.</p>
*
* <p>By default, this will only allow applications that are known to respond to this intent correctly
* do so. The apps that are allowed to response can be set with {@link #setTargetApplications(List)}.
* For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
*
* <h2>Sharing text via barcode</h2>
*
* <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
*
* <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
*
* <h2>Enabling experimental barcode formats</h2>
*
* <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
* PDF417. Use {@link #initiateScan(Collection)} with
* a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
* formats.</p>
*
* @author Sean Owen
* @author Fred Lin
* @author Isaac Potoczny-Jones
* @author Brad Drehmer
* @author gcstang
*/
public class IntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
private static final String TAG = IntentIntegrator.class.getSimpleName();
public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
public static final String DEFAULT_MESSAGE =
"This application requires Barcode Scanner. Would you like to install it?";
public static final String DEFAULT_YES = "Yes";
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
public static final Collection<String> ONE_D_CODE_TYPES =
list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
"ITF", "RSS_14", "RSS_EXPANDED");
public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
public static final Collection<String> ALL_CODE_TYPES = null;
public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
public static final List<String> TARGET_ALL_KNOWN = list(
BSPLUS_PACKAGE, // Barcode Scanner+
BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
BS_PACKAGE // Barcode Scanner
// What else supports this intent?
);
private final Activity activity;
private final Fragment fragment;
private String title;
private String message;
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
/**
* @param activity {@link Activity} invoking the integration
*/
public IntentIntegrator(Activity activity) {
this.activity = activity;
this.fragment = null;
initializeConfiguration();
}
/**
* @param fragment {@link Fragment} invoking the integration.
* {@link #startActivityForResult(Intent, int)} will be called on the {@link Fragment} instead
* of an {@link Activity}
*/
public IntentIntegrator(Fragment fragment) {
this.activity = fragment.getActivity();
this.fragment = fragment;
initializeConfiguration();
}
private void initializeConfiguration() {
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleByID(int titleID) {
title = activity.getString(titleID);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageByID(int messageID) {
message = activity.getString(messageID);
}
public String getButtonYes() {
return buttonYes;
}
public void setButtonYes(String buttonYes) {
this.buttonYes = buttonYes;
}
public void setButtonYesByID(int buttonYesID) {
buttonYes = activity.getString(buttonYesID);
}
public String getButtonNo() {
return buttonNo;
}
public void setButtonNo(String buttonNo) {
this.buttonNo = buttonNo;
}
public void setButtonNoByID(int buttonNoID) {
buttonNo = activity.getString(buttonNoID);
}
public Collection<String> getTargetApplications() {
return targetApplications;
}
public final void setTargetApplications(List<String> targetApplications) {
if (targetApplications.isEmpty()) {
throw new IllegalArgumentException("No target applications");
}
this.targetApplications = targetApplications;
}
public void setSingleTargetApplication(String targetApplication) {
this.targetApplications = Collections.singletonList(targetApplication);
}
public Map<String,?> getMoreExtras() {
return moreExtras;
}
public final void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
/**
* Initiates a scan for all known barcode types with the default camera.
*
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan() {
return initiateScan(ALL_CODE_TYPES, -1);
}
/**
* Initiates a scan for all known barcode types with the specified camera.
*
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(int cameraId) {
return initiateScan(ALL_CODE_TYPES, cameraId);
}
/**
* Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
return initiateScan(desiredBarcodeFormats, -1);
}
/**
* Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
// check requested camera ID
if (cameraId >= 0) {
intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
/**
* Start an activity. This method is defined to allow different methods of activity starting for
* newer versions of Android and for compatibility library.
*
* @param intent Intent to start.
* @param code Request code for the activity
* @see Activity#startActivityForResult(Intent, int)
* @see Fragment#startActivityForResult(Intent, int)
*/
protected void startActivityForResult(Intent intent, int code) {
if (fragment == null) {
activity.startActivityForResult(intent, code);
} else {
fragment.startActivityForResult(intent, code);
}
}
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (String targetApp : targetApplications) {
if (contains(availableApps, targetApp)) {
return targetApp;
}
}
}
return null;
}
private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApp.equals(packageName)) {
return true;
}
}
return false;
}
private AlertDialog showDownloadDialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String packageName;
if (targetApplications.contains(BS_PACKAGE)) {
// Prefer to suggest download of BS if it's anywhere in the list
packageName = BS_PACKAGE;
} else {
// Otherwise, first option:
packageName = targetApplications.get(0);
}
Uri uri = Uri.parse("market://details?id=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
}
}
});
downloadDialog.setNegativeButton(buttonNo, null);
downloadDialog.setCancelable(true);
return downloadDialog.show();
}
/**
* <p>Call this from your {@link Activity}'s
* {@link Activity#onActivityResult(int, int, Intent)} method.</p>
*
* @param requestCode request code from {@code onActivityResult()}
* @param resultCode result code from {@code onActivityResult()}
* @param intent {@link Intent} from {@code onActivityResult()}
* @return null if the event handled here was not related to this class, or
* else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
*/
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
return new IntentResult(contents,
formatName,
rawBytes,
orientation,
errorCorrectionLevel);
}
return new IntentResult();
}
return null;
}
/**
* Defaults to type "TEXT_TYPE".
*
* @param text the text string to encode as a barcode
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
* @see #shareText(CharSequence, CharSequence)
*/
public final AlertDialog shareText(CharSequence text) {
return shareText(text, "TEXT_TYPE");
}
/**
* Shares the given text by encoding it as a barcode, such that another user can
* scan the text off the screen of the device.
*
* @param text the text string to encode as a barcode
* @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
return null;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.integration.android;
/**
* <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
*
* @author Sean Owen
*/
public final class IntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
IntentResult() {
this(null, null, null, null, null);
}
IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
}
/**
* @return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
*/
public String getFormatName() {
return formatName;
}
/**
* @return raw bytes of the barcode content, if applicable, or null otherwise
*/
public byte[] getRawBytes() {
return rawBytes;
}
/**
* @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
*/
public Integer getOrientation() {
return orientation;
}
/**
* @return name of the error correction level used in the barcode, if applicable
*/
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
@Override
public String toString() {
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
return "Format: " + formatName + '\n' +
"Contents: " + contents + '\n' +
"Raw bytes: (" + rawBytesLength + " bytes)\n" +
"Orientation: " + orientation + '\n' +
"EC level: " + errorCorrectionLevel + '\n';
}
}

View File

@ -0,0 +1,109 @@
package com.meerkat.laura.fakescannerapp;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
*/
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
}

View File

@ -0,0 +1,252 @@
package com.meerkat.laura.fakescannerapp;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import ch.qos.logback.classic.android.BasicLogcatConfigurator;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import meerkat.crypto.DigitalSignatureGenerator;
import meerkat.crypto.concrete.ECDSADeterministicSignature;
import meerkat.pollingstation.PollingStationScanner;
import meerkat.pollingstation.ScannerClientAPI;
import meerkat.protobuf.PollingStation;
import java.math.BigInteger;
import java.util.Date;
import static com.meerkat.laura.fakescannerapp.R.xml.preferences;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
static {
BasicLogcatConfigurator.configureDefaultContext();
}
final public static String SCANNER_NAME = "AndroidScanner";
SharedPreferences sharedPref;
Button scanBtn;
TextView formatTxt, contentTxt, responseTxt, serverStatus;
PollingStationScanner.ScannerClient scannerClient;
DigitalSignatureGenerator signer;
class AsyncScanConnect extends AsyncTask<Void, Void, Boolean> {
PollingStation.ConnectionServerData serverData;
public AsyncScanConnect(PollingStation.ConnectionServerData connectionServerData) {
this.serverData = connectionServerData;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
serverStatus.setTextColor(Color.BLUE);
serverStatus.setText("Connecting to " + serverData.getServerUrl());
}
@Override
protected Boolean doInBackground(Void... foo) {
try {
return scannerClient.connect(serverData);
} catch (RuntimeException e) {
Log.e("MainActivity", "Exception during connect: " + e.toString());
return false;
}
}
@Override
protected void onPostExecute(Boolean res) {
super.onPostExecute(res);
if (res) {
serverStatus.setTextColor(Color.GREEN);
serverStatus.setText("Connected to " + serverData.getServerUrl());
} else {
serverStatus.setTextColor(Color.RED);
serverStatus.setText("Connection failed: " + serverData.getServerUrl());
}
}
}
class AsyncScanSend extends AsyncTask<Void, Void, Boolean> {
Message data;
public AsyncScanSend(Message data) {
this.data = data;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
serverStatus.setTextColor(Color.BLUE);
serverStatus.setText("Sending to server...");
}
@Override
protected Boolean doInBackground(Void... foo) {
try {
if (data instanceof PollingStation.ScannedBallot) {
return scannerClient.newScan((PollingStation.ScannedBallot) data);
} else if (data instanceof PollingStation.ScanError) {
return scannerClient.reportError((PollingStation.ScanError) data);
} else {
Log.e("MainActivity", "Trying to send invalid message to scanner");
return false;
}
} catch (RuntimeException e) {
Log.e("MainActivity", "Exception during send: " + e.toString());
return false;
}
}
@Override
protected void onPostExecute(Boolean res) {
super.onPostExecute(res);
if (res) {
serverStatus.setTextColor(Color.GREEN);
serverStatus.setText("Sent successfully");
Log.i("MainActivity", "post submitted to API.");
} else {
serverStatus.setTextColor(Color.RED);
serverStatus.setText("Send failed");
Log.e("MainActivity", "Unable to submit post to API.");
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_settings:
Intent i = new Intent(this, SettingsActivity.class);
startActivity(i);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
void setNewScannerClientAPI(SharedPreferences sharedPref) {
String pscUrlString = sharedPref.getString(SettingsFragment.PSC_URL, "");
long nonce = 0;
try {
nonce = Long.parseLong(sharedPref.getString(SettingsFragment.PSC_NONCE, "0"));
} catch (NumberFormatException e) {
// Ignore
}
if (pscUrlString.isEmpty())
return;
PollingStation.ConnectionServerData serverData = PollingStation.ConnectionServerData.newBuilder()
.setServerUrl(pscUrlString)
.setNonce(nonce)
.build();
new AsyncScanConnect(serverData).execute();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
signer = new ECDSADeterministicSignature();
signer.generateSigningCertificate(BigInteger.ONE, new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365), SCANNER_NAME);
scannerClient = new ScannerClientAPI(signer);
PreferenceManager.setDefaultValues(this, preferences, false);
sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.registerOnSharedPreferenceChangeListener(this);
scanBtn = (Button) findViewById(R.id.scan_button);
formatTxt = (TextView) findViewById(R.id.scan_format);
contentTxt = (TextView) findViewById(R.id.scan_content);
responseTxt = (TextView) findViewById(R.id.server_response);
serverStatus = (TextView) findViewById(R.id.serverStatus);
setNewScannerClientAPI(sharedPref);
scanBtn.setOnClickListener(this);
}
public void onClick(View v) {
if (v.getId() == R.id.scan_button) {
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
formatTxt.setText("Initiating scan...");
scanIntegrator.initiateScan();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanningResult != null) {
String scanContent = scanningResult.getContents();
byte[] rawBytes = scanningResult.getRawBytes();
String scanFormat = scanningResult.getFormatName();
formatTxt.setText("FORMAT: " + scanFormat);
contentTxt.setText("CONTENT: " + scanContent + "sending data to server...");
// sendPost(rawBytes);
sendPost(scanContent);
} else {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received!", Toast.LENGTH_SHORT);
toast.show();
}
}
// public void sendPost(byte[] body) {
public void sendPost(String scanContent) {
try {
PollingStation.ScannedBallot scannedBallot = PollingStation.ScannedBallot.parseFrom(Base64.decode(scanContent.getBytes(), Base64.DEFAULT));
//
// PollingStation.ScannedData scannedData = PollingStation.ScannedData.newBuilder()
// .setChannel(ByteString.copyFrom(body))
// .build();
new AsyncScanSend(scannedBallot).execute();
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
public void showResponse(String response) {
responseTxt.setText(response);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
setNewScannerClientAPI(sharedPreferences);
}
}

View File

@ -0,0 +1,26 @@
package com.meerkat.laura.fakescannerapp;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
/**
* Created by talm on 25/06/17.
*/
public class SettingsActivity extends Activity {
SettingsFragment settings;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settings = new SettingsFragment();
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(settings);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settings)
.commit();
}
}

View File

@ -0,0 +1,34 @@
package com.meerkat.laura.fakescannerapp;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
public final static String PSC_URL = "psc_url";
public final static String PSC_NONCE = "psc_nonce";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref == null)
return;
switch(key) {
case SettingsFragment.PSC_URL:
pref.setSummary(sharedPreferences.getString(key, ""));
break;
case SettingsFragment.PSC_NONCE:
pref.setSummary(sharedPreferences.getString(key, ""));
break;
}
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z"/>
</vector>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView android:text="@string/instructions" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_txt"
android:id="@+id/scan_button"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:id="@+id/scan_format"
android:layout_below="@+id/scan_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:id="@+id/scan_content"
android:layout_below="@+id/scan_format"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp" />
<TextView
android:id="@+id/server_response"
android:layout_below="@+id/scan_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp" />
<TextView
android:text="Not Connected"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/serverStatus"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true" android:layout_alignParentStart="true"/>
</RelativeLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Settings, should always be in the overflow -->
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="never"/>
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@ -0,0 +1,80 @@
<resources>
<string name="app_name">FakeScannerApp</string>
<string name="button_txt">SCAN</string>
<string name="instructions">Please, press the button below to scan the vote receipt.</string>
<string name="title_activity_settings">Settings</string>
<!-- Strings related to Settings -->
<string name="action_settings">Settings</string>
<!-- Example General settings -->
<string name="pref_header_general">General</string>
<string name="pref_title_social_recommendations">Enable social recommendations</string>
<string name="pref_description_social_recommendations">Recommendations for people to contact based on your message
history
</string>
<string name="pref_title_psc_url">Scanner Service URL</string>
<string name="pref_default_psc_url">http://192.168.70.10:8880/scan</string>
<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
<!-- Example settings for Data & Sync -->
<string name="pref_header_data_sync">Data &amp; sync</string>
<string name="pref_title_sync_frequency">Sync frequency</string>
<string-array name="pref_sync_frequency_titles">
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>3 hours</item>
<item>6 hours</item>
<item>Never</item>
</string-array>
<string-array name="pref_sync_frequency_values">
<item>15</item>
<item>30</item>
<item>60</item>
<item>180</item>
<item>360</item>
<item>-1</item>
</string-array>
<string-array name="list_preference_entries">
<item>Entry 1</item>
<item>Entry 2</item>
<item>Entry 3</item>
</string-array>
<string-array name="list_preference_entry_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="multi_select_list_preference_default_value"/>
<string name="pref_title_system_sync_settings">System sync settings</string>
<!-- Example settings for Notifications -->
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_new_message_notifications">New message notifications</string>
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>
</resources>

View File

@ -0,0 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

View File

@ -0,0 +1,28 @@
<PreferenceScreen xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<EditTextPreference
android:key="psc_url"
android:title="@string/pref_title_psc_url"
android:defaultValue="@string/pref_default_psc_url"
android:selectAllOnFocus="true"
android:singleLine="true"
android:maxLines="1"
android:inputType="textUri" />
<EditTextPreference
android:key="psc_nonce"
android:title="Nonce"
android:defaultValue="0"
android:selectAllOnFocus="true"
android:singleLine="true"
android:maxLines="1"
android:inputType="number"/>
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
dismiss it. -->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
</PreferenceScreen>

View File

@ -0,0 +1,15 @@
package com.meerkat.laura.fakescannerapp;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

View File

@ -1,15 +1,17 @@
plugins {
id "com.google.osdetector" version "1.4.0"
}
apply plugin: com.google.gradle.osdetector.OsDetectorPlugin
subprojects { proj ->
proj.afterEvaluate {
// Used to generate initial maven-dir layout
task "create-dirs" { description = "Create default maven directory structure" } << {
task "create-dirs" {
description = "Create default maven directory structure"
doLast {
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs() }
}
}
}
}
// Script to create a copy of the protobuf compiler jar in the top-level build directory

View File

@ -1,7 +1,7 @@
plugins {
id "us.kirchmeier.capsule" version "1.0.2"
id 'com.google.protobuf' version '0.8.0'
id 'com.google.protobuf' version '0.8.1'
}
apply plugin: 'java'
@ -25,8 +25,11 @@ ext {
// Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing)
// Should be set in ${HOME}/.gradle/gradle.properties
nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : ""
nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : ""
// Credentials for publishing repositories
publishRepository = "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
publishUser = project.hasProperty('publishUser') ? project.property('publishUser') : ""
publishPassword = project.hasProperty('publishPassword') ? project.property('publishPassword') : ""
}
description = "TODO: Add a description"
@ -131,17 +134,19 @@ if (project.hasProperty('mainClassName') && (mainClassName != null)) {
destinationDir = buildDir
def fatMain = hasProperty('fatmain') ? fatmain : mainClassName
def fatMain
if (this.hasProperty('fatmain')) {
fatMain = fatmain
appendix = "fat-${fatMain}"
} else {
fatMain = mainClassName
appendix = "fat"
}
applicationClass fatMain
def testJar = hasProperty('test')
if (hasProperty('fatmain')) {
appendix = "fat-${fatMain}"
} else {
appendix = "fat"
}
def testJar = this.hasProperty('test')
if (testJar) {
from sourceSets.test.output
@ -155,21 +160,6 @@ if (project.hasProperty('mainClassName') && (mainClassName != null)) {
*===================================*/
repositories {
// Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral)
maven {
url nexusRepository
if (isSnapshot) {
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
// Use local maven repository
mavenLocal()
@ -177,13 +167,15 @@ repositories {
mavenCentral()
}
task "info" << {
task "info" {
doLast {
println "Project: ${project.name}"
println "Description: ${project.description}"
println "Description: ${project.description}"
println "--------------------------"
println "GroupId: $groupId"
println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})"
println ""
}
}
info.description 'Print some information about project parameters'
@ -205,12 +197,12 @@ publishing {
}
repositories {
maven {
url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
url publishRepository
credentials { username
password
username nexusUser
password nexusPassword
username publishUser
password publishPassword
}
}
}

25
buildSrc/build.gradle Normal file
View File

@ -0,0 +1,25 @@
apply plugin: 'groovy'
description = 'A Gradle plugin that detects the OS name and architecture, providing a uniform\
classifier to be used in the names of native artifacts.'
group = 'com.google.gradle'
// The major and minor versions are aligned with the Maven plugin's.
version = '1.5.0-SNAPSHOT'
dependencies {
compile gradleApi(),
localGroovy(),
'kr.motd.maven:os-maven-plugin:1.5.0.Final'
// Newer versions of gradle conflict with the default guava 10. dependency of the maven
// plugin.
compile("com.google.guava:guava:19.0") {
force = true
}
testCompile 'junit:junit:4.12'
}
repositories {
mavenLocal()
mavenCentral()
}

1
buildSrc/gradlew vendored Symbolic link
View File

@ -0,0 +1 @@
../gradlew

View File

@ -0,0 +1,25 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gradle.osdetector
import org.gradle.api.Plugin
import org.gradle.api.Project
class OsDetectorPlugin implements Plugin<Project> {
void apply(final Project project) {
project.extensions.create('osdetector', OsDetector)
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gradle.osdetector;
import kr.motd.maven.os.Detector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class OsDetector {
private static final Logger logger = LoggerFactory.getLogger(OsDetector.class.getName());
private final List<String> classifierWithLikes = new ArrayList<String>();
private Impl impl;
public String getOs() {
return (String) getImpl().detectedProperties.get(Detector.DETECTED_NAME);
}
public String getArch() {
return (String) getImpl().detectedProperties.get(Detector.DETECTED_ARCH);
}
public String getClassifier() {
return (String) getImpl().detectedProperties.get(Detector.DETECTED_CLASSIFIER);
}
public Release getRelease() {
Impl impl = getImpl();
Object releaseId = impl.detectedProperties.get(Detector.DETECTED_RELEASE);
if (releaseId == null) {
return null;
}
return new Release(impl);
}
public synchronized void setClassifierWithLikes(List<String> classifierWithLikes) {
if (impl != null) {
throw new IllegalStateException("classifierWithLikes must be set before osdetector is read.");
}
this.classifierWithLikes.clear();
this.classifierWithLikes.addAll(classifierWithLikes);
}
private synchronized Impl getImpl() {
if (impl == null) {
impl = new Impl(classifierWithLikes);
}
return impl;
}
/**
* Accessor to information about the current OS release.
*/
public static class Release {
private final Impl impl;
private Release(Impl impl) {
this.impl = impl;
}
/**
* Returns the release ID.
*/
public String getId() {
return (String) impl.detectedProperties.get(Detector.DETECTED_RELEASE);
}
/**
* Returns the version ID.
*/
public String getVersion() {
return (String) impl.detectedProperties.get(Detector.DETECTED_RELEASE_VERSION);
}
/**
* Returns {@code true} if this release is a variant of the given base release (for example,
* ubuntu is "like" debian).
*/
public boolean isLike(String baseRelease) {
return impl.detectedProperties.containsKey(
Detector.DETECTED_RELEASE_LIKE_PREFIX + baseRelease);
}
}
private static class Impl extends Detector {
final Properties detectedProperties = System.getProperties();
@Override
protected void log(String message) {
logger.info(message);
}
@Override
protected void logProperty(String name, String value) {
logger.info(name + "=" + value);
}
Impl(List<String> classifierWithLikes) {
detect(detectedProperties, classifierWithLikes);
}
}
}

View File

@ -0,0 +1 @@
implementation-class=com.google.gradle.osdetector.OsDetectorPlugin

View File

@ -0,0 +1,62 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gradle.osdetector
import org.gradle.testfixtures.ProjectBuilder
import org.gradle.api.Project
import org.junit.Test
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.fail
class OsDetectorPluginTest {
@Test
public void pluginAddsExtensionToProject() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'com.google.osdetector'
assertNotNull(project.osdetector)
assertNotNull(project.osdetector.os)
assertNotNull(project.osdetector.arch)
assertEquals(project.osdetector.os + '-' + project.osdetector.arch,
project.osdetector.classifier)
System.err.println('classifier=' + project.osdetector.classifier)
if (project.osdetector.os == 'linux') {
assertNotNull(project.osdetector.release.id)
assertNotNull(project.osdetector.release.version)
System.err.println('release.id=' + project.osdetector.release.id)
System.err.println('release.version=' + project.osdetector.release.version)
System.err.println('release.isLike(debian)=' + project.osdetector.release.isLike('debian'))
System.err.println('release.isLike(redhat)=' + project.osdetector.release.isLike('redhat'))
} else if (project.osdetector.release) {
fail("Should be null")
}
}
@Test
public void setClassifierWithLikes() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'com.google.osdetector'
project.osdetector.classifierWithLikes = ['debian', 'fedora']
assertNotNull(project.osdetector.os)
assertNotNull(project.osdetector.arch)
System.err.println('classifier=' + project.osdetector.classifier)
try {
project.osdetector.classifierWithLikes = ['debian']
fail("Should throw IllegalStateException")
} catch (IllegalStateException expected) {
}
}
}

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: meerkat.voting.gui.configuration.Converter

View File

@ -1,7 +1,7 @@
plugins {
id "us.kirchmeier.capsule" version '1.0.2'
id 'com.google.protobuf' version '0.8.0'
id 'com.google.protobuf' version '0.8.1'
}
apply plugin: 'java'
@ -16,18 +16,17 @@ ext { isSnapshot = false }
ext {
groupId = 'org.factcenter.meerkat'
nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/"
// Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing)
// Should be set in ${HOME}/.gradle/gradle.properties
nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : ""
nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : ""
// Credentials for publishing repositories
publishRepository = "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
publishUser = project.hasProperty('publishUser') ? project.property('publishUser') : ""
publishPassword = project.hasProperty('publishPassword') ? project.property('publishPassword') : ""
}
description = "Meerkat Voting Common Library"
// Your project version
version = "0.0"
version = "0.1"
version += "${isSnapshot ? '-SNAPSHOT' : ''}"
@ -38,23 +37,10 @@ dependencies {
compile project(':meerkat-common')
compile project(':restful-api-common')
// Jersey for RESTful API
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+'
// Databases
compile 'org.xerial:sqlite-jdbc:3.7.+'
// Logging
compile 'org.slf4j:slf4j-api:1.7.7'
runtime 'ch.qos.logback:logback-classic:1.1.2'
runtime 'ch.qos.logback:logback-core:1.1.2'
// Google protobufs
compile 'com.google.protobuf:protobuf-java:3.+'
// Crypto
compile 'org.factcenter.qilin:qilin:1.1+'
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
// Depend on test resources from meerkat-common
testCompile project(path: ':meerkat-common', configuration: 'testOutput')
@ -63,8 +49,6 @@ dependencies {
testCompile 'junit:junit:4.+'
testCompile 'org.hamcrest:hamcrest-all:1.3'
runtime 'org.codehaus.groovy:groovy:2.4.+'
}
test {
@ -178,34 +162,22 @@ if (project.hasProperty('mainClassName') && (mainClassName != null)) {
*===================================*/
repositories {
// Use local repo if possible
mavenLocal();
// Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral)
maven {
url nexusRepository
if (isSnapshot) {
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
// Use 'maven central' for other dependencies.
mavenCentral()
}
task "info" << {
task "info" {
doLast {
println "Project: ${project.name}"
println "Description: ${project.description}"
println "--------------------------"
println "GroupId: $groupId"
println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})"
println ""
}
}
info.description 'Print some information about project parameters'
@ -227,12 +199,12 @@ publishing {
}
repositories {
maven {
url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
url publishRepository
credentials { username
password
username nexusUser
password nexusPassword
username publishUser
password publishPassword
}
}
}

1
bulletin-board-client/gradlew vendored Symbolic link
View File

@ -0,0 +1 @@
../gradlew

View File

@ -1,6 +1,6 @@
package meerkat.bulletinboard;
import meerkat.protobuf.BulletinBoardAPI.BatchChunk;
import meerkat.protobuf.BulletinBoardApi.BatchChunk;
import meerkat.bulletinboard.AsyncBulletinBoardClient.BatchIdentifier;
import java.util.List;

View File

@ -3,7 +3,7 @@ package meerkat.bulletinboard;
import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.Timestamp;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto.Signature;
import meerkat.protobuf.Voting.*;

View File

@ -8,7 +8,7 @@ import meerkat.comm.MessageInputStream;
import meerkat.comm.MessageInputStream.MessageInputStreamFactory;
import meerkat.comm.MessageOutputStream;
import meerkat.crypto.concrete.SHA256Digest;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto.Signature;
import meerkat.protobuf.Voting.*;
import meerkat.util.BulletinBoardUtils;

View File

@ -6,8 +6,8 @@ import com.google.protobuf.Int64Value;
import meerkat.bulletinboard.workers.singleserver.*;
import meerkat.comm.CommunicationException;
import meerkat.crypto.concrete.SHA256Digest;
import meerkat.protobuf.BulletinBoardAPI;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Voting.*;
import meerkat.rest.*;
import meerkat.util.BulletinBoardUtils;

View File

@ -3,7 +3,7 @@ package meerkat.bulletinboard;
import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.ByteString;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.util.BulletinBoardUtils;
import java.util.LinkedList;

View File

@ -9,7 +9,7 @@ import com.google.protobuf.Timestamp;
import meerkat.bulletinboard.workers.singleserver.*;
import meerkat.comm.CommunicationException;
import meerkat.crypto.concrete.SHA256Digest;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.Voting.BulletinBoardClientParams;
import meerkat.util.BulletinBoardUtils;

View File

@ -4,7 +4,7 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.Timestamp;
import meerkat.bulletinboard.workers.multiserver.*;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto.Signature;
import meerkat.protobuf.Voting.*;

View File

@ -3,10 +3,10 @@ package meerkat.bulletinboard;
import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.Timestamp;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.util.BulletinBoardUtils;
import static meerkat.protobuf.BulletinBoardAPI.FilterType.*;
import static meerkat.protobuf.BulletinBoardApi.FilterType.*;
import java.util.*;
import java.util.concurrent.Semaphore;

View File

@ -4,7 +4,7 @@ import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.MultiServerWorker;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import java.util.Iterator;
import java.util.List;

View File

@ -2,7 +2,7 @@ package meerkat.bulletinboard.workers.multiserver;
import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessage;
import java.util.List;

View File

@ -2,7 +2,7 @@ package meerkat.bulletinboard.workers.multiserver;
import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import java.util.List;

View File

@ -2,7 +2,7 @@ package meerkat.bulletinboard.workers.multiserver;
import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import java.util.List;

View File

@ -2,8 +2,8 @@ package meerkat.bulletinboard.workers.multiserver;
import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardAPI.MessageID;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardApi.MessageID;
import java.util.List;

View File

@ -2,7 +2,7 @@ package meerkat.bulletinboard.workers.multiserver;
import com.google.common.util.concurrent.FutureCallback;
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import java.util.List;

View File

@ -3,7 +3,7 @@ package meerkat.bulletinboard.workers.singleserver;
import com.google.protobuf.Int64Value;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage;
import meerkat.protobuf.BulletinBoardApi.BeginBatchMessage;
import meerkat.rest.Constants;
import javax.ws.rs.ProcessingException;

View File

@ -1,6 +1,6 @@
package meerkat.bulletinboard.workers.singleserver;
import meerkat.protobuf.BulletinBoardAPI.CloseBatchMessage;
import meerkat.protobuf.BulletinBoardApi.CloseBatchMessage;
import static meerkat.bulletinboard.BulletinBoardConstants.CLOSE_BATCH_PATH;

View File

@ -3,8 +3,8 @@ package meerkat.bulletinboard.workers.singleserver;
import com.google.protobuf.Int64Value;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.SyncQuery;
import meerkat.protobuf.BulletinBoardAPI.GenerateSyncQueryParams;
import meerkat.protobuf.BulletinBoardApi.SyncQuery;
import meerkat.protobuf.BulletinBoardApi.GenerateSyncQueryParams;
import meerkat.rest.Constants;
import javax.ws.rs.ProcessingException;

View File

@ -3,7 +3,7 @@ package meerkat.bulletinboard.workers.singleserver;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.comm.MessageInputStream;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.rest.Constants;
import javax.ws.rs.client.Client;

View File

@ -1,6 +1,6 @@
package meerkat.bulletinboard.workers.singleserver;
import meerkat.protobuf.BulletinBoardAPI.BatchMessage;
import meerkat.protobuf.BulletinBoardApi.BatchMessage;
import static meerkat.bulletinboard.BulletinBoardConstants.POST_BATCH_PATH;

View File

@ -1,6 +1,6 @@
package meerkat.bulletinboard.workers.singleserver;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessage;
import static meerkat.bulletinboard.BulletinBoardConstants.POST_MESSAGE_PATH;

View File

@ -2,8 +2,8 @@ package meerkat.bulletinboard.workers.singleserver;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.BulletinBoardAPI.SyncQuery;
import meerkat.protobuf.BulletinBoardAPI.SyncQueryResponse;
import meerkat.protobuf.BulletinBoardApi.SyncQuery;
import meerkat.protobuf.BulletinBoardApi.SyncQueryResponse;
import meerkat.rest.Constants;
import javax.ws.rs.ProcessingException;

View File

@ -3,7 +3,7 @@ package meerkat.bulletinboard.workers.singleserver;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.comm.MessageInputStream;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.rest.Constants;
import javax.ws.rs.client.Client;

View File

@ -3,10 +3,10 @@ package meerkat.bulletinboard.workers.singleserver;
import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.comm.MessageInputStream;
import meerkat.protobuf.BulletinBoardAPI;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList;
import meerkat.protobuf.BulletinBoardAPI.MessageFilterList;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.BulletinBoardApi;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessageList;
import meerkat.protobuf.BulletinBoardApi.MessageFilterList;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessage;
import meerkat.rest.Constants;
import javax.ws.rs.ProcessingException;

View File

@ -11,7 +11,7 @@ import meerkat.bulletinboard.sqlserver.H2QueryProvider;
import meerkat.comm.CommunicationException;
import meerkat.crypto.concrete.ECDSASignature;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.util.BulletinBoardMessageComparator;
import meerkat.util.BulletinBoardMessageGenerator;
import org.junit.*;

View File

@ -6,7 +6,7 @@ import com.google.protobuf.Timestamp;
import meerkat.comm.CommunicationException;
import meerkat.crypto.concrete.ECDSASignature;
import meerkat.crypto.concrete.SHA256Digest;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto;
import meerkat.util.BulletinBoardMessageComparator;
import meerkat.util.BulletinBoardMessageGenerator;

View File

@ -5,7 +5,7 @@ import com.google.protobuf.ByteString;
import com.google.protobuf.Timestamp;
import meerkat.comm.CommunicationException;
import meerkat.crypto.concrete.ECDSASignature;
import meerkat.protobuf.BulletinBoardAPI.*;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.util.BulletinBoardMessageComparator;
import meerkat.util.BulletinBoardMessageGenerator;

View File

@ -0,0 +1,57 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "bulletin-board-server-frontend"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}

View File

@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@ -0,0 +1,42 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# dependencies
/node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
testem.log
/typings
# e2e
/e2e/*.js
/e2e/*.map
# System Files
.DS_Store
Thumbs.db

View File

@ -0,0 +1,28 @@
# BulletinBoardServerFrontend
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.2.0.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
Before running the tests make sure you are serving the app via `ng serve`.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@ -0,0 +1,60 @@
plugins {
id "com.moowork.node" version "1.2.0"
}
node {
download = true;
}
ext {
bundlejs = "src/app/bundle.js"
bundlets = "src/app/bundle.d.ts"
}
//task installAngularCli(type: NpmTask) {
// args = ['install', '@angular/cli']
//}
//npm_install.dependsOn(installAngularCli);
task printProtos {
doLast {
println getProtoFiles().join(" ")
}
}
printProtos.description = "List all the .proto files we can find."
def getProtoFiles() {
def protoFiles = []
rootProject.subprojects { proj ->
if (proj.hasProperty('sourceSets') && proj.sourceSets.hasProperty('main') &&
proj.sourceSets.main.hasProperty('proto')) {
protoFiles = protoFiles + proj.sourceSets.main.proto.getFiles();
}
}
return protoFiles;
}
task generateProtobufBundle(type: NpmTask) {
doFirst {
// We need do this in doFirst since getProtoFiles won't find all subprojects
// until after configuration is complete
def protoFiles = getProtoFiles()
generateProtobufBundle.args = ['run', 'protoc', '--' ] + protoFiles;
}
dependsOn npm_install
}
generateProtobufBundle.description = "Generate the bundle.js/bundle.d.ts files containing compiled protobufs"
npm_run_build.dependsOn(npm_install)
npm_run_build.dependsOn(generateProtobufBundle)
npm_start.dependsOn(generateProtobufBundle)
// It would be nice if this worked, but it seems to get stuck:
//npm_start.dependsOn(project(':bulletin-board-server').jettyStart);

View File

@ -0,0 +1,14 @@
import { BulletinBoardServerFrontendPage } from './app.po';
describe('bulletin-board-server-frontend App', () => {
let page: BulletinBoardServerFrontendPage;
beforeEach(() => {
page = new BulletinBoardServerFrontendPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to app!!');
});
});

View File

@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class BulletinBoardServerFrontendPage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

View File

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}

View File

@ -0,0 +1,32 @@
#!/usr/bin/env node
const { execFileSync } = require('child_process');
const path = require('path');
const isWin = (process.platform === 'win32');
const bundlejs = 'src/app/bundle.js'
const bundlets = 'src/app/bundle.d.ts'
const npm = isWin ? 'npm.cmd' : 'npm';
var args = process.argv.slice(2).map(function(x) {
return path.normalize(x);
});
var pbjs_args = [
'-t', 'static-module', '-w', 'commonjs', '-o', bundlejs
].concat(args);
console.log("Running pbjs " + pbjs_args.join(" "));
var out = execFileSync(npm, ['run', 'pbjs', '--'].concat(pbjs_args));
console.log("" + out);
var pbts_args = [
'-o', bundlets, bundlejs
];
console.log("Running pbts " + pbts_args.join(" "));
out = execFileSync(npm, ['run', 'pbts', '--'].concat(pbts_args));
console.log("" + out);

1
bulletin-board-server-frontend/gradlew vendored Symbolic link
View File

@ -0,0 +1 @@
../gradlew

View File

@ -0,0 +1,33 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

View File

@ -0,0 +1,53 @@
{
"name": "bulletin-board-server-frontend",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build",
"test": "ng test",
"lint": "ng e2e",
"pbts": "pbts",
"pbjs": "pbjs",
"protoc" : "node ./generate-protobuf.js"
},
"private": true,
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"@types/long": "^3.0.31",
"core-js": "^2.4.1",
"protobufjs": "^6.8.0",
"rxjs": "^5.1.0",
"zone.js": "^0.8.4"
},
"devDependencies": {
"@angular/cli": "^1.2.0",
"@angular/compiler-cli": "^4.0.0",
"@angular/language-service": "^4.0.0",
"@types/jasmine": "~2.5.53",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "~3.0.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.0.4",
"tslint": "~5.3.2",
"typescript": "~2.3.3"
}
}

View File

@ -0,0 +1,28 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

View File

@ -0,0 +1,6 @@
{
"/bbserver" : {
"target" : "http://localhost:8081/",
"secure" : false
}
}

View File

@ -0,0 +1,12 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{title}}!!
</h1>
<h3>Current status: {{status}}</h3>
<img width="300" src="assets/meerkat-logo.svg">
<hr>
{{errorMessage}}
</div>

View File

@ -0,0 +1,32 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
}));
});

View File

@ -0,0 +1,55 @@
import {Component, OnInit} from '@angular/core';
import {IntervalObservable} from "rxjs/observable/IntervalObservable";
import {BBService} from "./bb.service";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [BBService]
})
export class AppComponent implements OnInit {
title = 'Bulletin-Board Server';
status = 'Not connected';
errorMessage = '';
private alive: boolean; // used to unsubscribe from the IntervalObservable
// when OnDestroy is called.
constructor(private bbservice : BBService) { }
ngOnInit(): void {
// Get initial status
this.bbservice.getStatus().subscribe(
status => { this.status = status.name; this.errorMessage = ""; },
error => { this.status = "Not connected"; this.errorMessage = <any>error; }
);
this.alive = true;
// Get new status every second
let o = IntervalObservable.create(1000)
//.takeWhile(() => this.alive) // only fires when component is alive
.subscribe(n => {
if (!this.alive) {
o.unsubscribe();
return;
}
this.bbservice.getStatus().subscribe(
status => { this.status = status.name + " " + n; this.errorMessage = ""; },
error => { this.errorMessage = <any>error; this.status = "Not connected"; }
);
});
}
ngOnDestroy(){
this.alive = false; // switches your IntervalObservable off
}
}

View File

@ -0,0 +1,20 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import {BBService} from "./bb.service";
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
HttpModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -0,0 +1,36 @@
/// <reference types="@types/long" />
import { Injectable } from '@angular/core';
import {Headers, Http, RequestOptions, ResponseContentType} from '@angular/http';
import { meerkat } from "./bundle.js";
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class BBService {
private headers = new Headers({'Content-Type': 'application/x-protobuf'});
private bbUrl = '/bbserver'; // URL to web api
private statusPath = '/status';
constructor(private http: Http) { }
getStatus(): Observable<meerkat.ServerStatus> {
let options = new RequestOptions({
responseType: ResponseContentType.ArrayBuffer
});
let res = this.http.get(this.bbUrl + this.statusPath, options);
return res
.catch(this.handleError)
.map(x => {
return meerkat.ServerStatus.decode(new Uint8Array(x.arrayBuffer()));
});
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -0,0 +1,3 @@
export const environment = {
production: true
};

View File

@ -0,0 +1,8 @@
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `.angular-cli.json`.
export const environment = {
production: false
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>BulletinBoardServerFrontend</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@ -0,0 +1,11 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -0,0 +1,72 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
// import 'core-js/es6/parse-int';
// import 'core-js/es6/parse-float';
// import 'core-js/es6/number';
// import 'core-js/es6/math';
// import 'core-js/es6/string';
// import 'core-js/es6/date';
// import 'core-js/es6/array';
// import 'core-js/es6/regexp';
// import 'core-js/es6/map';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/set';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/** Evergreen browsers require these. **/
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
/**
* Required to support Web Animations `@angular/animation`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/***************************************************************************************************
* Zone JS is required by Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
/**
* Date, currency, decimal and percent pipes.
* Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
*/
// import 'intl'; // Run `npm install --save intl`.
/**
* Need to import at least one locale-data with intl.
*/
// import 'intl/locale-data/jsonp/en';

View File

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

View File

@ -0,0 +1,32 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare const __karma__: any;
declare const require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();

View File

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}

View File

@ -0,0 +1,20 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"module": "commonjs",
"target": "es5",
"baseUrl": "",
"types": [
"jasmine",
"node"
]
},
"files": [
"test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

Some files were not shown because too many files have changed in this diff Show More