Commit 1d289acc authored by  Joel  Oksanen's avatar Joel Oksanen

Almost done with report

parent 11785997
......@@ -2,6 +2,7 @@
*.pt
__pycache__/
server/agent/amazon_data/
server/agent/SA/data/
server/agent/target_extraction/data/
server/agent/target_extraction/stanford-corenlp-full-2018-10-05
server/agent/target_extraction/BERT/data/
......
This diff is collapsed.
import pandas as pd
pd.set_option('display.max_colwidth', None)
# pd.set_option('display.max_colwidth', None)
def get_reviews(category, meta_file, review_file):
metadata_iter = pd.read_json(meta_file, lines=True, chunksize=1000)
......@@ -37,4 +36,4 @@ def save_top_reviewed_products(n, category, meta_file, review_file, output_file,
# 'amazon_data/Clothing_Shoes_and_Jewelry.json', 'amazon_data/reviews_for_watches.tsv',
# 'watch')
save_reviews('Necklaces', 'agent/amazon_data/meta_Clothing_Shoes_and_Jewelry.json', 'agent/amazon_data/Clothing_Shoes_and_Jewelry.json', 'agent/target_extraction/data/verified_necklace_reviews.tsv')
save_reviews('Stand Mixers', 'amazon_data/meta_Home_and_Kitchen.json', 'amazon_data/Home_and_Kitchen.json', 'target_extraction/data/verified_stand_mixer_reviews.tsv')
......@@ -6,7 +6,7 @@ import time
class ConceptNet:
url = 'http://api.conceptnet.io'
limit = 5
limit = 50
def find_related(self, feature, rel):
uri = '/query?node=/c/en/{feature}&other=/c/en&rel=/r/{rel}&limit={limit}'.format(feature=feature, rel=rel, limit=self.limit)
......@@ -64,7 +64,7 @@ class ConceptNet:
synonyms.add(node.name)
return synonyms
def sub_features_for_node(self, node):
def sub_features_for_argument(self, argument):
rels = ['UsedFor', 'HasA', 'CapableOf', 'Causes', 'HasSubevent', 'HasProperty', 'MadeOf']
features = set()
......@@ -72,10 +72,13 @@ class ConceptNet:
threads = []
for rel in rels:
t = threading.Thread(target=self.append_result, args=(node.name, rel, features, lock))
t = threading.Thread(target=self.append_result, args=(argument, rel, features, lock))
t.start()
threads.append(t)
for t in threads:
t.join()
return features
cnet = ConceptNet()
print(cnet.find_related('sweater', 'MadeOf'))
......@@ -30,6 +30,8 @@
9449FE4F240533FD00025F70 /* QueryOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9449FE4E240533FD00025F70 /* QueryOptionView.swift */; };
9449FE5124053DA500025F70 /* ChatManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9449FE5024053DA500025F70 /* ChatManager.swift */; };
945E6BBD2493931300C0DCAC /* ArgumentText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945E6BBC2493931300C0DCAC /* ArgumentText.swift */; };
945E6BC12494084C00C0DCAC /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945E6BC02494084C00C0DCAC /* SearchView.swift */; };
945E6BC32494097400C0DCAC /* ADAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945E6BC22494097400C0DCAC /* ADAView.swift */; };
94BE1EEB2407E26900741749 /* RatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94BE1EEA2407E26900741749 /* RatingView.swift */; };
94BE1EED240800D800741749 /* InitResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94BE1EEC240800D800741749 /* InitResponse.swift */; };
/* End PBXBuildFile section */
......@@ -60,6 +62,8 @@
9449FE4E240533FD00025F70 /* QueryOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryOptionView.swift; sourceTree = "<group>"; };
9449FE5024053DA500025F70 /* ChatManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatManager.swift; sourceTree = "<group>"; };
945E6BBC2493931300C0DCAC /* ArgumentText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArgumentText.swift; sourceTree = "<group>"; };
945E6BC02494084C00C0DCAC /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
945E6BC22494097400C0DCAC /* ADAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADAView.swift; sourceTree = "<group>"; };
94BE1EEA2407E26900741749 /* RatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingView.swift; sourceTree = "<group>"; };
94BE1EEC240800D800741749 /* InitResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitResponse.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -97,6 +101,8 @@
9449FE1A2402C84F00025F70 /* AppDelegate.swift */,
9449FE1C2402C84F00025F70 /* SceneDelegate.swift */,
9449FE1E2402C84F00025F70 /* ContentView.swift */,
945E6BC02494084C00C0DCAC /* SearchView.swift */,
945E6BC22494097400C0DCAC /* ADAView.swift */,
9449FE342402CCDA00025F70 /* ConnectionManager.swift */,
94BE1EEC240800D800741749 /* InitResponse.swift */,
9449FE3F2403EDD300025F70 /* Product */,
......@@ -233,8 +239,10 @@
9449FE452403F0A600025F70 /* Sender.swift in Sources */,
9449FE4D2404561400025F70 /* ArgumentQuery.swift in Sources */,
9449FE4924042D6500025F70 /* FeatureView.swift in Sources */,
945E6BC12494084C00C0DCAC /* SearchView.swift in Sources */,
9449FE312402C90800025F70 /* ChatView.swift in Sources */,
9449FE5124053DA500025F70 /* ChatManager.swift in Sources */,
945E6BC32494097400C0DCAC /* ADAView.swift in Sources */,
945E6BBD2493931300C0DCAC /* ArgumentText.swift in Sources */,
9449FE352402CCDA00025F70 /* ConnectionManager.swift in Sources */,
9449FE1D2402C84F00025F70 /* SceneDelegate.swift in Sources */,
......
......@@ -8,13 +8,19 @@
import SwiftUI
struct ProductView: View {
struct ADAView: View {
@ObservedObject var connectionManager: ConnectionManager
var drag: some Gesture {
DragGesture()
.onEnded { _ in self.connectionManager.quitMessaging() }
}
var body: some View {
VStack(spacing: 0) {
ProductView(connectionManager: connectionManager)
.zIndex(10)
.gesture(drag)
ChatView(connectionManager: connectionManager)
.zIndex(0)
}
......
......@@ -30,12 +30,16 @@ struct ADAMessage: Message, Decodable, Equatable {
textWithArguments += text.arguments[i]
}
}
let attributes = [NSAttributedString.Key.font: UIFont(name: "Helvetica Neue", size: 14)!,
let attributes = [NSAttributedString.Key.font: UIFont(name: text.style == .QUOT ? "HelveticaNeue-Italic" : "Helvetica Neue", size: 14)!,
NSAttributedString.Key.foregroundColor: UIColor.white]
let attributedString = NSMutableAttributedString(string: textWithArguments, attributes: attributes)
print(attributedString)
for (start, len) in argumentLocations {
attributedString.addAttribute(NSAttributedString.Key.font, value: text.style.getFont(), range: NSMakeRange(start, len))
attributedString.addAttribute(NSAttributedString.Key.font,
value: UIFont(name: text.style == .QUOT ? "HelveticaNeue-BoldItalic" : "HelveticaNeue-Bold", size: 14)!,
range: NSMakeRange(start, len))
// attributedString.addAttribute(NSAttributedString.Key.foregroundColor,
// value: UIColor(red: 140/255, green: 100/255, blue: 15/255, alpha:1.0).cgColor,
// range: NSMakeRange(start, len))
}
return attributedString
}
......
......@@ -21,11 +21,4 @@ enum TextStyle: String, Decodable {
case ARG
case QUOT
func getFont() -> UIFont {
switch self {
case .ARG: return UIFont(name: "HelveticaNeue-Bold", size: 14)!
case .QUOT: return UIFont(name: "HelveticaNeue-Italic", size: 14)!
}
}
}
......@@ -15,7 +15,7 @@ struct MessageView: View {
Sender.ADA: Color(red: 242/255, green: 159/255, blue: 31/255),
Sender.USER: Color(red: 35/255, green: 45/255, blue: 62/255)
]
let maxWidth: CGFloat = 300
let maxWidth: CGFloat = 260
let message: Message
let query: ArgumentQuery?
......@@ -45,11 +45,9 @@ struct MessageView: View {
Label(maxWidth: maxWidth, attributedText: self.message.getAttributedText())
.foregroundColor(Color.white)
// .font(Font.custom("Helvetica Neue", size: 14))
.fixedSize(horizontal: true, vertical: true)
.padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20))
.background(MessageBubble(sender: message.sender).foregroundColor(sent ? bubbleColors[message.sender] : FeatureView.bubbleColor))
// .frame(minWidth: 0, maxWidth: maxWidth, alignment: message.sender == .ADA ? .leading : .trailing)
.onTapGesture {
withAnimation(.easeInOut(duration: 0.3)) {
if self.message.sender == .ADA {
......@@ -77,14 +75,6 @@ struct MessageView: View {
}
struct Label: UIViewRepresentable {
// typealias TheUIView = UILabel
// fileprivate var configuration = { (view: TheUIView) in }
//
// func makeUIView(context: UIViewRepresentableContext<Self>) -> TheUIView { TheUIView() }
// func updateUIView(_ uiView: TheUIView, context: UIViewRepresentableContext<Self>) {
// configuration(uiView)
// }
var maxWidth: CGFloat
var attributedText: NSAttributedString
......
......@@ -9,15 +9,18 @@
import SwiftUI
class ConnectionManager: ObservableObject {
@Published var product = Product()
@Published var products = [Product]()
@Published var product: Product!
@Published var messaging: Bool = false
@Published var messages: [Message] = [Message]()
private let ip = "192.168.1.104"
private let port = "8000"
private var messageQueue: [Message]? = nil
private var productMap = [String: Product]()
init() {
requestProduct(id: "B00005UP2N")
requestProducts()
// B00RTGK0N0 - red Canon camera
// B004J3V90Y - Canon T3i
// B0012YA85A - Canon Rebel XSI
......@@ -25,22 +28,21 @@ class ConnectionManager: ObservableObject {
// B0075SUK14 - Backpack
// B000AYW0M2 - Watch
// B000ZKA0J6 - Starcraft game
// B00005UP2N - Mixer
// B00005UP2N - Silver Mixer
// B0001HLTTI - Another Mixer
}
private func requestProduct(id: String) {
let url = URL(string: "http://" + ip + ":" + port + "/ios_server/product/?id=" + id)!
private func requestProducts() {
let url = URL(string: "http://" + ip + ":" + port + "/ios_server/products")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
do {
print(data)
let resp = try JSONDecoder().decode(InitResponse.self, from: data)
let resp = try JSONDecoder().decode([ProductInfo].self, from: data)
DispatchQueue.main.async {
self.requestImage(at: resp.productInfo.imageURL)
self.product.name = resp.productInfo.name
self.product.starRating = resp.productInfo.starRating
self.addMessage(resp.message)
for productInfo in resp {
self.requestImage(for: productInfo)
}
}
} catch let parseError {
print(parseError)
......@@ -52,20 +54,44 @@ class ConnectionManager: ObservableObject {
task.resume()
}
private func requestImage(at urlString: String) {
let url = URL(string: urlString)!
private func requestImage(for productInfo: ProductInfo) {
let url = URL(string: productInfo.imageURL)!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self.product.image = image
let product = Product(id: productInfo.id, name: productInfo.name, starRating: productInfo.starRating, image: image)
self.productMap[productInfo.id] = product
self.products.append(product)
}
}
}
task.resume()
}
func requestProduct(id: String) {
let url = URL(string: "http://" + ip + ":" + port + "/ios_server/product?id=" + id)!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
do {
let resp = try JSONDecoder().decode(ADAMessage.self, from: data)
DispatchQueue.main.async {
self.addMessage(resp)
self.product = self.productMap[id]
self.messaging = true
}
} catch let parseError {
print(parseError)
DispatchQueue.main.async {
// Handle error in UI
}
}
}
task.resume()
}
func sendQuery(_ query: ArgumentQuery) {
let url = URL(string: "http://" + ip + ":" + port + "/ios_server/message/")!
var request = URLRequest(url: url)
......@@ -127,6 +153,14 @@ class ConnectionManager: ObservableObject {
}
}
func quitMessaging() {
self.messaging = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.messages = [Message]()
self.product = nil
}
}
private func handleClientError(error: Error) {
print("Client error occurred")
}
......
......@@ -10,15 +10,16 @@ import SwiftUI
struct ContentView: View {
@ObservedObject var connectionManager = ConnectionManager()
@State private var searching: Bool = true
var body: some View {
VStack(spacing: 0) {
ProductView(connectionManager: connectionManager)
.zIndex(10)
ChatView(connectionManager: connectionManager)
.zIndex(0)
if !connectionManager.messaging {
SearchView(connectionManager: connectionManager)
} else {
ADAView(connectionManager: connectionManager)
}
}
.edgesIgnoringSafeArea(.all)
.background(Color.black)
}
}
......
......@@ -8,16 +8,11 @@
import UIKit
struct Product {
struct Product: Identifiable {
var id: String
var name: String
var starRating: Double
var image: UIImage
init() {
self.name = ""
self.starRating = 0
self.image = UIImage()
}
}
......@@ -26,7 +26,7 @@ struct ProductView: View {
Text(connectionManager.product.name)
.font(Font.custom("Helvetica Neue", size: 14))
.foregroundColor(Color.gray)
RatingView(starRating: $connectionManager.product.starRating)
RatingView(starRating: connectionManager.product.starRating)
}
Spacer()
Image(uiImage: connectionManager.product.image)
......
......@@ -10,7 +10,7 @@ import SwiftUI
struct RatingView: View {
let dim: CGFloat = 16
@Binding var starRating: Double
var starRating: Double
var fullStars: Int {
get {
return Int(starRating.rounded(.down))
......
......@@ -6,4 +6,61 @@
// Copyright © 2020 Joel Oksanen. All rights reserved.
//
import Foundation
import SwiftUI
struct SearchView: View {
@ObservedObject var connectionManager: ConnectionManager
let height: CGFloat = 120
var body: some View {
VStack(spacing: 0) {
ZStack {
Rectangle()
.foregroundColor(Color.white)
.frame(height: height)
.shadow(color: Color(.sRGB, white: 0, opacity: 0.1), radius: 10, x: 0, y: 0)
VStack {
Spacer()
.frame(height: 30)
HStack {
Text("Products")
.font(Font.custom("HelveticaNeue-Bold", size: 28))
.foregroundColor(Color.gray)
.padding(EdgeInsets(top: 0, leading: 30, bottom: 0, trailing: 0))
Spacer()
}
}
}
.zIndex(10)
List(connectionManager.products) { product in
ProductRow(product: product)
.onTapGesture {
self.connectionManager.requestProduct(id: product.id)
}
}
}
.edgesIgnoringSafeArea(.all)
}
}
struct ProductRow: View {
var product: Product
var body: some View {
HStack(spacing: 0) {
Image(uiImage: product.image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100, height: 100)
.border(Color(white: 0.85), width: 1)
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 20))
VStack {
Text(product.name)
.font(Font.custom("Helvetica Neue", size: 14))
.foregroundColor(Color.gray)
RatingView(starRating: product.starRating)
}
}
}
}
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ADAgraph.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ADAgraph.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
//
// AppDelegate.swift
// ADAgraph
//
// Created by Joel Oksanen on 13.6.2020.
// Copyright © 2020 Joel Oksanen. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
//
// Argument.swift
// ADAgraph
//
// Created by Joel Oksanen on 13.6.2020.
// Copyright © 2020 Joel Oksanen. All rights reserved.
//
import Foundation
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],