initBasti / Amazon2PlentySync (public) (License: GPLv3) (since 2019-01-27) (hash sha1)
Transfer your data from you Amazon Flatfile spreadsheet over to the Plentymarkets system. How to is included in the readme
List of commits:
Subject Hash Author Date (UTC)
new config handling d65bdfae89eceab6b1319d01373cf70ac7d8b63e Sebastian Fricke 2019-11-13 08:57:14
Fixed a problem, that caused Data to not pass sorting; Fixed error handling with the product type; Updated category ids 9a62d369fb24bc80765cd19e31fb255398fb8ed5 Sebastian Fricke 2019-09-12 09:27:54
fixed a merge conflict bug e6b4d9613237009d980cdbfc7ec65c3383a3495a Sebastian Fricke 2019-08-16 11:31:02
current status 15.8 94db3a5c98c596b24f00624fa4b772b9fd830b03 Sebastian Fricke 2019-08-15 14:26:42
Added manual file choosing in case of empty config 2df178528d70be15bfb2e1c9058f69e128236622 Sebastian Fricke 2019-08-15 10:11:41
Added Markdown choosing, fixed various bugs 991ed44df370cf80fc2e2c51d7427d63e221888f Sebastian Fricke 2019-08-15 09:30:55
Changed the item upload format to fix errors in the sync, moved active upload to properties because it has to be done seperatly to the creation process 3b466364e3dcdf14b4cef5b8649ec9573c992324 Sebastian Fricke 2019-06-17 14:09:23
Removed the image upload from item upload and added a exportfile together with functions to get the variation id for the image upload, the image upload is now a single process 6349c4a7177345c25aa6d8ecd03740a75fa2520f Sebastian Fricke 2019-06-13 12:58:36
Updated the feature list to the current active list b5d1675bcb56c38a97c928d7800b6a29c2dea116 LagerBadel PC:Magdalena 2019-06-11 12:11:06
fixed a bug with the encoding of very large datasets were the 10000 letters were not enough, increased waiting time but removed some mistakes that way 8f431d6a68fb21699950b1ca48a1592976789c74 LagerBadel PC:Magdalena 2019-06-06 13:41:52
small debugging improvements in writeCSV and missing colors 88db9e1362a4178805671f443554a7f0d3db9e69 LagerBadel PC:Magdalena 2019-06-06 11:52:31
Major Update added a gui category chooser, attribute id connection and updated the whole Script to work on Elastic Sync a8a6156e26e2783a695c87bda35aba725fd77023 Sebastian Fricke 2019-06-05 12:45:29
fixed a bug with the encoding function 0c5b9dd0414037743bf39fdc3420d55035bffa61 Sebastian Fricke 2019-05-14 15:10:17
Major Update added a config file for better useability and added a gui to enter the category and the name of the product further work towards the rework from dynamic import to elastic sync e4356af15a4b8f7393f85bd51c16b330bc3555af Sebastian Fricke 2019-05-14 14:43:03
Changed the price upload to identify items that are not in plentymarkets and added a webshop price 4ab9bcd988f9eb26647748a8f80f25c8c5b7f2e2 Sebastian Fricke 2019-05-03 09:18:35
added Webshop to marketconnections 84f93694fe0c67972ad951649d9f6f0d577d3e29 Sebastian Fricke 2019-05-01 14:12:00
Added the modelnumber feature and removed the creation of empty features ea98391f2dbdf8fb8e601153b4f6ebfca504929c Sebastian Fricke 2019-05-01 12:31:19
Changed the feature upload into a loop for more overview 0a1bee82659a576c6fb4f2641aa3990d8d686b3c Sebastian Fricke 2019-05-01 10:04:20
Added a few new instructions to the Instructions file b4878c59958f89a02937de1dfc7aabbd23e71061 LagerBadel PC:Magdalena 2019-04-18 09:41:10
Made some fields not required but added Warnings for the log file, additionally some new amazon features were added. 6392338b7e9968be3bc4da9031144c3cc2cfae48 Sebastian Fricke 2019-04-18 09:37:51
Commit d65bdfae89eceab6b1319d01373cf70ac7d8b63e - new config handling
Author: Sebastian Fricke
Author date (UTC): 2019-11-13 08:57
Committer name: Sebastian Fricke
Committer date (UTC): 2019-11-13 08:57
Parent(s): 9a62d369fb24bc80765cd19e31fb255398fb8ed5
Signing key:
Tree: f226eb4f6e63ae840fd4bf729d839e23da71d747
File Lines added Lines deleted
.gitignore 3 0
build_windows_version.sh 12 0
example_config.txt 4 0
packages/config.py 139 26
packages/item_upload.py 0 4
File .gitignore changed (mode: 100644) (index bd272f7..cf2db18)
... ... clean_upload.sh
10 10 build_new_version.sh build_new_version.sh
11 11 /__pycache__ /__pycache__
12 12 /packages/__pycache__/ /packages/__pycache__/
13 /packages/gui/__pycache__/
14 Windows_build.txt
15 debug-checklist.txt
File build_windows_version.sh added (mode: 100644) (index 0000000..7d1e4ee)
1 #!/bin/bash
2
3 cd Windows_version/
4 echo "Delete all existing content of 'Windows_version'"
5 rm -irf *
6
7 if [ ! -f $PWD/item_upload ]; then
8 echo "Build the script into a executable file using pyinstaller"
9 pyinstaller -y -F -i "C:/Users/bkkas/Downloads/LogoNameless.ico" -n item_upload "C:/Users/bkkas/Dropbox/Scripts/Item_Upload/product_import.py"
10 fi
11
12 cp ../example_config.txt Windows_version/dist/config.txt
File example_config.txt added (mode: 100644) (index 0000000..734fc24)
1 upload_folder=C:/Users/bkkas/Dropbox/Scripts/Item_Upload/Upload
2 data_folder=C:/Users/bkkas/Dropbox/Scripts/Item_Upload/Input_files
3 attribute_file=C:/Users/bkkas/Dropbox/Scripts/Item_Upload/Input_files/attribute-270619.csv
4 file_change_date=
File packages/config.py changed (mode: 100644) (index 9b97c8b..87eb981)
1 1 import tkinter import tkinter
2 2 import tkinter.filedialog import tkinter.filedialog
3 import csv
4 3 import os import os
4 import csv
5 import enum
6 import datetime
7
8
9 class State(enum.Enum):
10 CONFIG_UPLOAD_EXIST = 0
11 CONFIG_DATA_EXIST = 1
12 CONFIG_ATTR_EXIST = 2
13 CONFIG_NOT_FOUND = 3
14 CONFIG_BAD = 4
15
16
17 fields = ['upload_folder', 'data_folder', 'attribute_file', 'file_change_date']
18
19
20 def config_open(path, option):
21 if(option not in ['r', 'w', 'a']):
22 print("Bad file opening option: [{1}] used with path {0}"
23 .format(path, option))
24 return []
25
26 with open(path, mode=option) as item:
27 # remove spaces/newlines, create list of options between ;
28 rows = [row.strip(' ').strip('\n').split(';') for row in item]
29
30 return rows
31
5 32
6 33 def config_creation(): def config_creation():
7 # variable declaration
8 current_path = str('')
9 configpath = str('')
34 current_path = ''
35 configpath = ''
10 36
11 # path choosing dialog gui
12 37 root = tkinter.Tk() root = tkinter.Tk()
13 38 root.withdraw() root.withdraw()
14 39
15 40 current_path = os.getcwd() current_path = os.getcwd()
16 41 configpath = os.path.join(current_path, 'config.txt') configpath = os.path.join(current_path, 'config.txt')
17 if(not( os.path.isfile(configpath) )):
42 if(not( os.path.isfile(configpath))):
18 43 with open(configpath, mode='w') as item: with open(configpath, mode='w') as item:
19 44 item.write('upload_folder=\n') item.write('upload_folder=\n')
20 45 item.write('data_folder=\n') item.write('data_folder=\n')
 
... ... def config_creation():
25 50 else: else:
26 51 return None return None
27 52
53
28 54 def config_read(configpath): def config_read(configpath):
29 config = {'upload_folder':'', 'data_folder':'',
30 'attribute_file':'', 'file_change_date':''}
31 if(not(configpath)):
32 configpath = config_creation()
33 with open(configpath, mode='r') as item:
34 rows = [row.strip(' ').strip('\n').split(';') for row in item]
55 config = {'upload_folder': '', 'data_folder': '',
56 'attribute_file': '', 'file_change_date': ''}
57 rows = config_open(path=configpath, option='r')
35 58
36 for row in rows:
37 option = "".join(row[0]).split('=')
59 for row in rows:
60 option = "".join(row[0]).split('=')
38 61
39 if(option[0].strip(' ') == 'upload_folder'):
40 config[ 'upload_folder' ] = option[1].strip(' ')
41 if(option[0].strip(' ') == 'data_folder'):
42 config[ 'data_folder' ] = option[1].strip(' ')
43 if(option[0].strip(' ') == 'attribute_file'):
44 config[ 'attribute_file' ] = option[1].strip(' ')
45 if(option[0].strip(' ') == 'file_change_date'):
46 config[ 'file_change_date' ] = option[1].strip(' ')
62 for field in fields:
63 if(option[0].strip(' ') == field):
64 config[field] = option[1].strip(' ')
47 65
48 66 return config return config
49 67
68
50 69 def config_write(configpath, data): def config_write(configpath, data):
51 # read the current content of the config
52 70 with open(configpath, mode='w') as item: with open(configpath, mode='w') as item:
53 writer = csv.DictWriter(item, delimiter='=', lineterminator='\n', fieldnames=['title', 'value'])
71 writer = csv.DictWriter(item, delimiter='=', lineterminator='\n',
72 fieldnames=['title', 'value'])
73 try:
74 for row in data:
75 writer.writerow(data[row])
76 except Exception as err:
77 print("Error @ config write: error: {0}"
78 .format(err))
79
80
81 def config_check(path):
82 states = []
83 if(not(path)):
84 return [State.CONFIG_NOT_FOUND]
85
86 rows = config_open(path=path, option='r')
87
88 # Check if all required fields are present
89 for field in fields:
90 # DEBUG TEST NOT FINAL
91 if(field not in rows):
92 print("ERROR: field:{0} not found in {1}"
93 .format(field, rows))
94 return [State.CONFIG_BAD]
95
96 for row in rows:
97 # Check if a equal sign exists
98 if('=' not in row):
99 print("ERROR: config options have to be split by =, = not found")
100 return [State.CONFIG_BAD]
101
102 # Check if only one equal sign was used
103 elif(row.count('=') > 1):
104 print("ERROR: equal sign can only be used as delimiter!")
105 return [State.CONFIG_BAD]
106
107 # Add each working file/dir from the config to the state list
108 for index, field in enumerate(fields):
109 option = "".join(row[0]).split('=')
110 if(field == 'file_change_date' and option[1]):
111 states.append(index)
112 if(option[0].strip(' ') == field and option[1]):
113 if(field == 'attribute_file'):
114 if(os.path.isfile(option[1].strip(' '))):
115 states.append(index)
116 else:
117 if(os.path.exists(option[1].strip(' '))):
118 states.append(index)
119
120 return states
121
122
123 def get_path(message, path_type, initialdir):
124 path = ''
125 if(path_type == 'dir'):
126 path = tkinter.filedilag.askdirectory(title=message,
127 initialdir=initialdir)
128 elif(path_type == 'file'):
129 path = tkinter.filedialog.askopenfilename(title=message,
130 initialdir=initialdir)
131 return path
132
133
134 def get_options(configpath, initialdir):
135 options = {'uploadpath': '',
136 'datapath': '',
137 'attributefile': '',
138 'date': ''}
139
140 # Check the config for mistakes and correct them
141 config_state = []
142 config_state = config_check(path=configpath)
143
144 if(State.CONFIG_NOT_FOUND in config_state):
145 configpath = config_creation()
146
147 elif(State.CONFIG_BAD in config_state):
148 os.remove(configpath)
149 configpath = config_creation
150
151 if(State.CONFIG_UPLOAD_EXIST not in config_state or
152 State.CONFIG_DATA_EXIST not in config_state or
153 State.CONFIG_ATTR_EXIST not in config_state or
154 State.CONFIG_NOT_FOUND in config_state or
155 State.CONFIG_BAD in config_state):
156 options['uploadpath'] = get_path(message='Path for Upload files',
157 path_type='dir',
158 initialdir=initialdir)
159 options['datapath'] = get_path(message='Path for Input files',
160 path_type='dir',
161 initialdir=initialdir)
162 options['attributefile'] = get_path(message='Path for attribute file',
163 path_type='file',
164 initialdir=initialdir)
165
166 options['date'] = datetime.datetime.now().strftime("%d.%m.%Y-%H:%M")
54 167
55 for row in data:
56 writer.writerow(data[row])
168 config_write(configpath=configpath, data=options)
57 169
170 return options
File packages/item_upload.py changed (mode: 100644) (index 1d209c8..f0aa4d6)
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data, f
207 207 # Sort the dictionary to make sure that the parents are the first variant of each item # Sort the dictionary to make sure that the parents are the first variant of each item
208 208 sorted_Data = sort_Products(Data) sorted_Data = sort_Products(Data)
209 209
210 for index, row in enumerate( sorted_Data ):
211 print("DEBUG: sorted_Data index: {0} = {1}"
212 .format(index, row))
213
214 210 barcode.writeCSV(sorted_Data, "item", column_names, folder, filename) barcode.writeCSV(sorted_Data, "item", column_names, folder, filename)
215 211 except UnicodeDecodeError as err: except UnicodeDecodeError as err:
216 212 print("Decode Error at line: {0}, err: {1}".format(sys.exc_info()[2].tb_lineno, err)) print("Decode Error at line: {0}, err: {1}".format(sys.exc_info()[2].tb_lineno, err))
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/initBasti/Amazon2PlentySync

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/initBasti/Amazon2PlentySync

Clone this repository using git:
git clone git://git.rocketgit.com/user/initBasti/Amazon2PlentySync

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main