Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
a9b7947
yml
Steppschuh Sep 4, 2016
c2aa7a6
yml
Steppschuh Sep 4, 2016
ec8ea69
yml
Steppschuh Sep 4, 2016
06276fe
yml
Steppschuh Sep 4, 2016
152b9c1
Fixed test
Steppschuh Sep 4, 2016
bbd15b5
Added backend test
Steppschuh Sep 4, 2016
074b6fd
yml
Steppschuh Sep 4, 2016
00bcb06
Added Slack integration
Steppschuh Sep 4, 2016
f92a82a
Fixed test
Steppschuh Sep 4, 2016
d180f0d
Merge pull request #1 from IntelliQ/tests
Steppschuh Sep 4, 2016
f60ae79
Added logging
Steppschuh Sep 4, 2016
e94ebe7
Merge branch 'dev' into logging
Steppschuh Sep 4, 2016
0c1c170
Code formatting
Steppschuh Sep 4, 2016
3214e5e
Merge pull request #2 from IntelliQ/logging
Steppschuh Sep 4, 2016
6323a4c
Created backup & restore tasks
Steppschuh Sep 4, 2016
1e89f81
Implemented local datastore backup & restore
Steppschuh Sep 5, 2016
33adbcc
Added local datastore backup
Steppschuh Sep 5, 2016
fa08ec8
Merge pull request #3 from IntelliQ/datastore
Steppschuh Sep 5, 2016
433fbcf
Mapped management buttons to API calls
Steppschuh Sep 5, 2016
f24f1bc
Merge pull request #4 from IntelliQ/queue_management
Steppschuh Sep 5, 2016
51c8d39
Implemented add customer modal
Steppschuh Sep 5, 2016
1343c42
Fixed issue with items created by queue management
Steppschuh Sep 5, 2016
27f7631
Fixed queue item ordereing
Steppschuh Sep 5, 2016
a0b5492
Added action tooltips, enhanced api & ui methods
Steppschuh Sep 6, 2016
70ef5bd
Added customer details modal, added reporting endpoint to api.js
Steppschuh Sep 6, 2016
b16640f
Merge branch 'dev' into queue_management
Steppschuh Sep 6, 2016
43ba1ad
Removed duplicate event handler from report button
Steppschuh Sep 6, 2016
394b5b0
Added web-app meta tags
Steppschuh Sep 6, 2016
b561afc
Implemented Google Analytics event tracking
Steppschuh Sep 6, 2016
eadf110
Added SSL enforcement
Steppschuh Sep 7, 2016
3d51c17
Authenticator refactoring
Steppschuh Sep 8, 2016
f2695ac
Authenticator refactoring
Steppschuh Sep 8, 2016
7d90cb2
Authentication refactoring
Steppschuh Sep 9, 2016
fe03328
Authenticator refactoring
Steppschuh Sep 9, 2016
3f74254
Authentication refactoring
Steppschuh Sep 10, 2016
b8e8ebd
Removed old files
Steppschuh Sep 10, 2016
dcd8587
Updated other management pages to new authenticator
Steppschuh Sep 10, 2016
3f287a1
Merge pull request #5 from IntelliQ/queue_management
Steppschuh Sep 12, 2016
73084d5
Fixed bug in authentication flow
Steppschuh Sep 12, 2016
19731b9
Merge branch 'dev' into queue_management
Steppschuh Sep 12, 2016
8289723
Started implementing distance calculation
Steppschuh Sep 13, 2016
988ac98
Added webapp
Steppschuh Sep 13, 2016
b423a72
Merge pull request #6 from IntelliQ/queue_management
Steppschuh Sep 13, 2016
f3b8726
Merge branch 'dev' into webapp
Steppschuh Sep 13, 2016
f5815ba
Added asset link json file for deep linking support
Steppschuh Sep 14, 2016
2a998db
Minor style & layout adjustments
Steppschuh Sep 14, 2016
156af2f
Implemented nearby queues rendering
Steppschuh Sep 14, 2016
6a8beb4
Implemented queue rendering
Steppschuh Sep 15, 2016
0d3e8ab
Improved queue rendering
Steppschuh Sep 15, 2016
446126d
Minor tracking changes
Steppschuh Sep 15, 2016
d5d5ecd
Queue rendering improvements
Steppschuh Sep 16, 2016
b5f8c54
fixed whitebar between header and main
StarkRobert Sep 16, 2016
c9ddfe8
Merge pull request #8 from IntelliQ/website_fixes
Steppschuh Sep 19, 2016
0ea83af
Merge branch 'dev' into webapp
Steppschuh Sep 19, 2016
7494868
Implemented queue item requesting
Steppschuh Sep 19, 2016
9cf0551
Added active tickets rendering to webapp pages
Steppschuh Sep 19, 2016
548f5ed
Improved string replacement
Steppschuh Sep 19, 2016
0b0fe7b
Improved ticket rendering
Steppschuh Sep 19, 2016
e43999f
Adjusted navigation bar
Steppschuh Sep 19, 2016
8633c4e
Added time utils
Steppschuh Sep 19, 2016
63d692e
Added datastore indexes, adjusted servlet mapping
Steppschuh Sep 19, 2016
f5097e1
Changed app engine host versioning
Steppschuh Sep 19, 2016
50dfdc1
Fixed navigation URL
Steppschuh Sep 19, 2016
aa825f2
UI adjustments
Steppschuh Sep 21, 2016
27ce4d8
Fixed bug with negative time since
Steppschuh Sep 21, 2016
cc91bc5
Implemented automatic ticket updating and queue status rendering
Steppschuh Sep 22, 2016
c4c351f
Minor layout adjustments
Steppschuh Sep 22, 2016
fcb7dcc
Implemented endpoint to get queue items by user
Steppschuh Sep 29, 2016
1d35c79
Adjusted queue item rendering in webapp
Steppschuh Sep 29, 2016
e8dd8b5
Updated gradle
Steppschuh Oct 8, 2016
76b2d23
Adjusted links in landing pages
Steppschuh Feb 25, 2017
d1bf5eb
Merge pull request #7 from IntelliQ/webapp
Steppschuh Feb 25, 2017
253977b
Merge branch 'master' into dev
Steppschuh Feb 25, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions IntelliQ/.gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
*.iml
**/*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/
.DS_Store
/build
/*/build
Expand Down
9 changes: 1 addition & 8 deletions IntelliQ/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion IntelliQ/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 34 additions & 2 deletions IntelliQ/backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7

dependencies {
//compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(dir: 'libs', include: ['*.jar'])
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.38'
compile group: 'com.google.apis', name: 'google-api-services-oauth2', version: 'v1-rev120-1.22.0'

Expand All @@ -42,8 +42,12 @@ dependencies {
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.2'

compile 'javax.servlet:servlet-api:2.5'
}

testCompile 'com.google.appengine:appengine-api-labs:1.9.8'
testCompile 'com.google.appengine:appengine-api-stubs:1.9.8'
testCompile 'com.google.appengine:appengine-testing:1.9.8'
testCompile 'junit:junit:4.12'
}

appengine {
downloadSdk = true
Expand All @@ -56,3 +60,31 @@ appengine {
enhanceOnBuild = true
}
}

task backupDataStore << {
copy {
from 'build/exploded-app/WEB-INF/appengine-generated'
into 'datastore/'
include '**/*.xml'
include '**/*.bin'
}
println "Backed up datastore"
}

task restoreDataStore << {
copy {
from 'datastore/'
into 'build/exploded-app/WEB-INF/appengine-generated'
include '**/*.xml'
include '**/*.bin'
}
println "Restored datastore"
}

appengineExplodeApp.doFirst {
backupDataStore.execute()
}

appengineExplodeApp.doLast {
restoreDataStore.execute()
}
4 changes: 4 additions & 0 deletions IntelliQ/backend/datastore/datastore-indexes-auto.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!-- Indices written at Thu, 29 Sep 2016 11:16:09 CEST -->

<datastore-indexes/>

Binary file added IntelliQ/backend/datastore/local_db.bin
Binary file not shown.
Binary file added IntelliQ/backend/libs/slackmessagebuilder.jar
Binary file not shown.
240 changes: 120 additions & 120 deletions IntelliQ/backend/src/main/java/com/intelliq/appengine/ImageServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,128 +28,128 @@
@SuppressWarnings("serial")
public class ImageServlet extends HttpServlet {

private static final Logger log = Logger.getLogger(ImageServlet.class.getName());

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

String requestUrl = req.getRequestURL().toString();

try {
// image request pattern: .../image/[imageKeyId]/[size].jpg

String imageSizeString = ParserHelper.getStringAfter("/", req.getPathInfo(), ParserHelper.MODE_LAST_LAST);
if (imageSizeString.contains(".png")) {
imageSizeString = ParserHelper.getStringBefore(".png", imageSizeString);
} else if (imageSizeString.contains(".jpg")) {
imageSizeString = ParserHelper.getStringBefore(".jpg", imageSizeString);
} else {
throw new Exception("Unknown file type requested");
}

String imageKeyIdParam = ParserHelper.getStringBefore("/" + imageSizeString, req.getPathInfo(), ParserHelper.MODE_LAST_LAST);
imageKeyIdParam = ParserHelper.getStringAfter("/", imageKeyIdParam, ParserHelper.MODE_LAST_LAST);
long imageKeyId = Long.parseLong(imageKeyIdParam);
if (imageKeyId < 0) {
throw new Exception("Image key ID is invalid");
}
ImageQuery imageQuery = new ImageQuery();
ImageEntry image = imageQuery.getImageByKeyId(imageKeyId);
if (image.getImageType() == null || image.getImage() == null) {
// image = EntryManager.fetchImageFromUrl(image.getUrl());
throw new Exception("Image data unavailable");
}
resp.setContentType(image.getImageType());
resp.getOutputStream().write(ImageHelper.resizeImage(image.getImage(), imageSizeString));
} catch (Exception e) {
resp.sendRedirect("/static/images/not_found.jpg");
}
}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
ApiResponse responseObject = new ApiResponse();
String response = "";
try {
ServletFileUpload upload = new ServletFileUpload();
res.setContentType("text/plain");

FileItemIterator iterator = upload.getItemIterator(req);

ImageEntry image = new ImageEntry();

while (iterator.hasNext()) {
FileItemStream item = iterator.next();
InputStream stream = item.openStream();

if (item.isFormField()) {
String key = item.getFieldName();
String value = Streams.asString(stream);
log.info("Form field: " + key + ", value = " + value);

if (key.equals("parentKeyId")) {
image.setParentKeyId(Long.parseLong(value));
} else if (key.equals("type")) {
image.setType(Byte.parseByte(value));
}
} else {
log.info("File: " + item.getFieldName() + ", key = " + item.getName());

String contentType = item.getContentType();

image.setImageType(contentType);
image.setImage(ByteStreams.toByteArray(stream));
}
}

if (image.getParentKeyId() > 0) {
Key imageKey = ImageHelper.saveEntry(image);
image.setKey(imageKey);

// add the new image key id to the parent business or queue
if (image.getType() == ImageEntry.TYPE_LOGO) {
BusinessEntry businessEntry = BusinessHelper.getEntryByKeyId(image.getParentKeyId());
if (businessEntry != null) {
businessEntry.setLogoImageKeyId(image.getKey().getId());
} else {
throw new Exception("Can't find parent business with Id: " + image.getParentKeyId());
}
BusinessHelper.saveEntry(businessEntry);
} else {
QueueEntry queueEntry = QueueHelper.getEntryByKeyId(image.getParentKeyId());
if (queueEntry != null) {
queueEntry.setPhotoImageKeyId(image.getKey().getId());
} else {
throw new Exception("Can't find parent queue with Id: " + image.getParentKeyId());
}
QueueHelper.saveEntry(queueEntry);
}
// remove the image data to use the same object as response
image.setImage(null);
responseObject.setContent(image);
response = responseObject.toJSON();
} else {
throw new Exception("Invalid parentKeyId specified");
}
} catch (Exception e) {
responseObject.setException(e);
response = responseObject.toJSON();
e.printStackTrace();
}
res.setContentType("application/json");
res.addHeader("Access-Control-Allow-Origin", "*");
private static final Logger log = Logger.getLogger(ImageServlet.class.getName());

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

String requestUrl = req.getRequestURL().toString();

try {
// image request pattern: .../image/[imageKeyId]/[size].jpg

String imageSizeString = ParserHelper.getStringAfter("/", req.getPathInfo(), ParserHelper.MODE_LAST_LAST);
if (imageSizeString.contains(".png")) {
imageSizeString = ParserHelper.getStringBefore(".png", imageSizeString);
} else if (imageSizeString.contains(".jpg")) {
imageSizeString = ParserHelper.getStringBefore(".jpg", imageSizeString);
} else {
throw new Exception("Unknown file type requested");
}

String imageKeyIdParam = ParserHelper.getStringBefore("/" + imageSizeString, req.getPathInfo(), ParserHelper.MODE_LAST_LAST);
imageKeyIdParam = ParserHelper.getStringAfter("/", imageKeyIdParam, ParserHelper.MODE_LAST_LAST);
long imageKeyId = Long.parseLong(imageKeyIdParam);

if (imageKeyId < 0) {
throw new Exception("Image key ID is invalid");
}

ImageQuery imageQuery = new ImageQuery();
ImageEntry image = imageQuery.getImageByKeyId(imageKeyId);

if (image.getImageType() == null || image.getImage() == null) {
// image = EntryManager.fetchImageFromUrl(image.getUrl());
throw new Exception("Image data unavailable");
}

resp.setContentType(image.getImageType());
resp.getOutputStream().write(ImageHelper.resizeImage(image.getImage(), imageSizeString));
} catch (Exception e) {
resp.sendRedirect("/static/images/not_found.jpg");
}
}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
ApiResponse responseObject = new ApiResponse();
String response = "";

try {
ServletFileUpload upload = new ServletFileUpload();
res.setContentType("text/plain");

FileItemIterator iterator = upload.getItemIterator(req);

ImageEntry image = new ImageEntry();

while (iterator.hasNext()) {
FileItemStream item = iterator.next();
InputStream stream = item.openStream();

if (item.isFormField()) {
String key = item.getFieldName();
String value = Streams.asString(stream);
log.info("Form field: " + key + ", value = " + value);

if (key.equals("parentKeyId")) {
image.setParentKeyId(Long.parseLong(value));
} else if (key.equals("type")) {
image.setType(Byte.parseByte(value));
}
} else {
log.info("File: " + item.getFieldName() + ", key = " + item.getName());

String contentType = item.getContentType();

image.setImageType(contentType);
image.setImage(ByteStreams.toByteArray(stream));
}
}

if (image.getParentKeyId() > 0) {

Key imageKey = ImageHelper.saveEntry(image);
image.setKey(imageKey);

// add the new image key id to the parent business or queue
if (image.getType() == ImageEntry.TYPE_LOGO) {
BusinessEntry businessEntry = BusinessHelper.getEntryByKeyId(image.getParentKeyId());
if (businessEntry != null) {
businessEntry.setLogoImageKeyId(image.getKey().getId());
} else {
throw new Exception("Can't find parent business with Id: " + image.getParentKeyId());
}
BusinessHelper.saveEntry(businessEntry);
} else {
QueueEntry queueEntry = QueueHelper.getEntryByKeyId(image.getParentKeyId());
if (queueEntry != null) {
queueEntry.setPhotoImageKeyId(image.getKey().getId());
} else {
throw new Exception("Can't find parent queue with Id: " + image.getParentKeyId());
}
QueueHelper.saveEntry(queueEntry);
}

// remove the image data to use the same object as response
image.setImage(null);

responseObject.setContent(image);
response = responseObject.toJSON();
} else {
throw new Exception("Invalid parentKeyId specified");
}
} catch (Exception e) {
responseObject.setException(e);
response = responseObject.toJSON();
e.printStackTrace();
}

res.setContentType("application/json");
res.addHeader("Access-Control-Allow-Origin", "*");
res.getWriter().write(response);
res.getWriter().flush();
res.getWriter().close();
}
}

}
Loading