##// END OF EJS Templates
merge from master
José Chávez -
r1054:10ce564971bb merge
parent child
Show More
@@ -0,0 +1,108
1 ## CHANGELOG:
2
3 ### 2.3
4 * Added high order function `multiSchain` for multiprocessing scripts.
5 * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc).
6 * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts.
7 * Added support for sending realtime graphic to web server.
8 * XML command `schain` is now `schain --xml`.
9 * Added a CLI tool named `schain`.
10 * Scripts templates can be now generated with `schain generate`.
11 * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters.
12 * Added suggestions when parameters are poorly written.
13 * `Controller.start()` now runs in a different process than the process calling it.
14 * Added `schainpy.utils.log` for log standarization.
15 * Running script on online mode no longer ignores date and hour. Issue #1109.
16 * Added support for receving voltage data directly from JARS (tcp, ipc).
17 * Updated README for compatibility with MAC OS GUI installation.
18 * Setup now installs numpy.
19
20 ### 2.2.6
21 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
22 * Added support for C extensions.
23 * Function `hildebrand_sehkon` optimized with a C wrapper.
24 * Numpy version updated.
25 * Migration to GIT.
26
27 ### 2.2.5:
28 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
29 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
30 * jroPlotter works directly with data objects instead of dictionaries
31 * script "schain" was added to Signal Chain installer
32
33 ### 2.2.4.1:
34 * jroIO_usrp.py is update to read Sandra's data
35 * decimation in Spectra and RTI plots is always enabled.
36 * time* window option added to GUI
37
38 ### 2.2.4:
39 * jroproc_spectra_lags.py added to schainpy
40 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
41 * Bug fixed in jroHeaderIO: Header size validation.
42
43 ### 2.2.3.1:
44 * Filtering block by time has been added.
45 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
46 properly but the next days did not.
47
48 ### 2.2.3:
49 * Bug fixed in GUI: Error getting(reading) Code value
50 * Bug fixed in GUI: Flip option always needs channelList field
51 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
52 was modified for every branch (because this was a reference). It was modified in data.copy()
53 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
54
55 ### 2.2.2:
56 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
57 * Rawdata and testRawdata.py added to Signal Chain project
58
59 ### 2.2.1:
60 * Bugs fixed in GUI
61 * Views were improved in GUI
62 * Support to MST* ISR experiments
63 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
64 * handleError added to jroplotter.py
65
66 ### 2.2.0:
67 * GUI: use of external plotter
68 * Compatible with matplotlib 1.5.0
69
70 ### 2.1.5:
71 * serializer module added to Signal Chain
72 * jroplotter.py added to Signal Chain
73
74 ### 2.1.4.2:
75 * A new Plotter Class was added
76 * Project.start() does not accept filename as a parameter anymore
77
78 ### 2.1.4.1:
79 * Send notifications when an error different to ValueError is detected
80
81 ### 2.1.4:
82 * Sending error notifications to signal chain administrator
83 * Login to email server added
84
85 ### 2.1.3.3:
86 * Colored Button Icons were added to GUI
87
88 ### 2.1.3.2:
89 * GUI: user interaction enhanced
90 * controller_api.py: Safe access to ControllerThead
91
92 ### 2.1.3.1:
93 * GUI: every icon were resized
94 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
95
96 ### 2.1.3:
97 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
98 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
99 Bug fixed selecting heights by block (selecting profiles instead heights)
100 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
101 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
102 * jroIO_heispectra.py: Channel index list does not exist.
103
104 ### 2.1.2:
105 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
106 Server thread opens and closes remote server each time file list is sent
107 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
108 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00] No newline at end of file
@@ -100,6 +100,7 ENV/
100 100 # eclipse
101 101 .project
102 102 .pydevproject
103 <<<<<<< HEAD
103 104
104 105 # vscode
105 106
@@ -107,3 +108,12 ENV/
107 108
108 109 schaingui/node_modules/
109 110 schainpy/scripts/
111 =======
112 .svn/
113 *.png
114 *.pyc
115 schainpy/scripts
116 .vscode
117 schaingui/node_modules
118 trash
119 >>>>>>> master
@@ -6,24 +6,40 Signal Chain (SCh) is a radar data processing library developed using [Python](w
6 6
7 7 ## Installation
8 8
9 Install system dependencies, download the latest stable release from [svn](http://jro-dev.igp.gob.pe/svn/jro_soft/schain/Releases/) e.g. schainpy-2.2.5.tar.gz. and install it as a normal python package.
9 Install system dependencies, clone the latest version from [git](http://jro-dev.igp.gob.pe/rhodecode/schain/) and install it as a normal python package.
10 10
11 ### Linux based system
11 12 ```
12 13 $ sudo apt-get install python-pip python-dev gfortran libpng-dev freetype* libblas-dev liblapack-dev libatlas-base-dev python-qt4 python-tk libssl-dev libhdf5-dev
13 $ tar xvzf schainpy-2.2.5.tar.gz
14 $ cd schainpy-2.2.5
14 $ sudo pip install numpy
15 $ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/
16 $ cd schain
15 17 $ sudo pip install ./
16 ```
17
18 **Its recommended to install schain in a virtual environment**
19 18
20 19 ```
20 **It is recommended to install schain in a virtual environment**
21 ```
21 22 $ sudo pip install virtualenv
22 23 $ virtualenv /path/to/virtual --system-site-packages
23 24 $ source /path/to/virtual/bin/activate
24 (virtual) $ cd schainpy-2.2.5
25 (virtual) $ cd schain
25 26 (virtual) $ pip install ./
27
28 ```
29
30 ### MAC Os
26 31 ```
32 $ brew install cartr/qt4/pyqt
33 $ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/
34 $ cd schain
35 $ pip install ./
36 ```
37
38 if ```pip install ./``` does not work, install a proper python enviroment, and repeat the steps.
39 ```
40 $ brew install python
41 ```
42
27 43
28 44 ## First Script
29 45
@@ -4,4 +4,5 Created on Feb 7, 2012
4 4 @author $Author$
5 5 @version $Id$
6 6 '''
7
7 8 __version__ = "2.3"
@@ -706,7 +706,7 class ProcUnitConf():
706 706 sts = self.procUnitObj.call(opType = opConfObj.type,
707 707 opName = opConfObj.name,
708 708 opId = opConfObj.id,
709 )
709 **kwargs)
710 710
711 711 # total_time = time.time() - ini
712 712 #
@@ -90,7 +90,7 class ControllerThread(threading.Thread, Project):
90 90 continue
91 91
92 92 if thisOpObj.name in plotterList:
93 thisOpObj.type = "plotter"
93 thisOpObj.type = "other"
94 94
95 95 def setPlotterQueue(self, plotter_queue):
96 96
@@ -292,11 +292,9 class JROData(GenericData):
292 292 return fmax
293 293
294 294 def getFmax(self):
295
296 295 PRF = 1./(self.ippSeconds * self.nCohInt)
297 296
298 297 fmax = PRF
299
300 298 return fmax
301 299
302 300 def getVmax(self):
@@ -24,8 +24,8 class SpectraPlot(Figure):
24 24 self.isConfig = False
25 25 self.__nsubplots = 1
26 26
27 self.WIDTH = 250
28 self.HEIGHT = 250
27 self.WIDTH = 1000
28 self.HEIGHT = 1000
29 29 self.WIDTHPROF = 120
30 30 self.HEIGHTPROF = 0
31 31 self.counter_imagwr = 0
1 NO CONTENT: modified file
@@ -1340,39 +1340,6 class JRODataReader(JRODataIO):
1340 1340 return
1341 1341
1342 1342 self.fileIndex = -1
1343 self.pathList = pathList
1344 self.filenameList = filenameList
1345 file_name = os.path.basename(filenameList[-1])
1346 basename, ext = os.path.splitext(file_name)
1347 last_set = int(basename[-3:])
1348
1349 self.online = online
1350 self.realtime = realtime
1351 self.delay = delay
1352 ext = ext.lower()
1353 self.ext = ext
1354 self.getByBlock = getblock
1355 self.nTxs = nTxs
1356 self.startTime = startTime
1357 self.endTime = endTime
1358
1359 #Added-----------------
1360 self.selBlocksize = blocksize
1361 self.selBlocktime = blocktime
1362
1363 # Verbose-----------
1364 self.verbose = verbose
1365 self.warnings = warnings
1366
1367 if not(self.setNextFile()):
1368 if (startDate!=None) and (endDate!=None):
1369 print "[Reading] No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
1370 elif startDate != None:
1371 print "[Reading] No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
1372 else:
1373 print "[Reading] No files"
1374
1375 self.fileIndex = -1
1376 1343 self.pathList = []
1377 1344 self.filenameList = []
1378 1345 return
@@ -55,6 +55,7 class DigitalRFReader(ProcessingUnit):
55 55 self.__nCode = None
56 56 self.__nBaud = None
57 57 self.__code = None
58 self.dtype = None
58 59
59 60 def close(self):
60 61 print 'Average of writing to digital rf format is ', self.oldAverage * 1000
@@ -74,10 +75,27 class DigitalRFReader(ProcessingUnit):
74 75
75 76 nProfiles = 1.0/ippSeconds # Number of profiles in one second
76 77
78 try:
77 79 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(self.__radarControllerHeader)
80 except:
81 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
82 txA=0,
83 txB=0,
84 nWindows=1,
85 nHeights=self.__nSamples,
86 firstHeight=self.__firstHeigth,
87 deltaHeight=self.__deltaHeigth,
88 codeType=self.__codeType,
89 nCode=self.__nCode, nBaud=self.__nBaud,
90 code = self.__code)
78 91
92 try:
79 93 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
80
94 except:
95 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
96 nProfiles=nProfiles,
97 nChannels=len(self.__channelList),
98 adcResolution=14)
81 99 self.dataOut.type = "Voltage"
82 100
83 101 self.dataOut.data = None
@@ -112,7 +130,8 class DigitalRFReader(ProcessingUnit):
112 130
113 131 self.dataOut.errorCount = 0
114 132
115 self.dataOut.nCohInt = self.fixed_metadata_dict['nCohInt']
133 try:
134 self.dataOut.nCohInt = self.fixed_metadata_dict.get('nCohInt', 1)
116 135
117 136 self.dataOut.flagDecodeData = self.fixed_metadata_dict['flagDecodeData'] # asumo que la data esta decodificada
118 137
@@ -121,6 +140,9 class DigitalRFReader(ProcessingUnit):
121 140 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
122 141
123 142 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
143 except:
144 pass
145
124 146
125 147 self.dataOut.ippSeconds = ippSeconds
126 148
@@ -237,35 +259,29 class DigitalRFReader(ProcessingUnit):
237 259 top_properties = self.digitalReadObj.get_properties(channelNameList[channelList[0]])
238 260
239 261
240
241
242
243
244 262 self.__num_subchannels = top_properties['num_subchannels']
245 263 self.__sample_rate = 1.0 * top_properties['sample_rate_numerator'] / top_properties['sample_rate_denominator']
246
247 264 # self.__samples_per_file = top_properties['samples_per_file'][0]
248 265 self.__deltaHeigth = 1e6*0.15/self.__sample_rate ## why 0.15?
249 266
250 267 this_metadata_file = self.digitalReadObj.get_digital_metadata(channelNameList[channelList[0]])
251 268 metadata_bounds = this_metadata_file.get_bounds()
252 269 self.fixed_metadata_dict = this_metadata_file.read(metadata_bounds[0])[metadata_bounds[0]] ## GET FIRST HEADER
270
271 try:
253 272 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
254 273 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
255 274 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
256 275 self.dtype = cPickle.loads(self.fixed_metadata_dict['dtype'])
276 except:
277 pass
257 278
258 self.__frequency = None
259 279
260 try:
261 self.__frequency = self.fixed_metadata_dict['frequency']
262 except:
263 280 self.__frequency = None
264 281
265 try:
266 self.__timezone = self.fixed_metadata_dict['timezone'] * 60
267 except:
268 self.__timezone = 0
282 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
283
284 self.__timezone = self.fixed_metadata_dict.get('timezone', 300)
269 285
270 286
271 287 try:
@@ -284,10 +300,14 class DigitalRFReader(ProcessingUnit):
284 300 nBaud = 1
285 301 code = numpy.ones((nCode, nBaud), dtype=numpy.int)
286 302
303 try:
287 304 if codeType:
288 305 nCode = self.__radarControllerHeader['nCode']
289 306 nBaud = self.__radarControllerHeader['nBaud']
290 307 code = self.__radarControllerHeader['code']
308 except:
309 pass
310
291 311
292 312 if not ippKm:
293 313 try:
@@ -296,6 +316,7 class DigitalRFReader(ProcessingUnit):
296 316 except:
297 317 ippKm = None
298 318 ####################################################
319 self.__ippKm = ippKm
299 320 startUTCSecond = None
300 321 endUTCSecond = None
301 322
@@ -336,7 +357,7 class DigitalRFReader(ProcessingUnit):
336 357 self.profileIndex = 0
337 358 self.i= 0
338 359 self.__delay = delay
339 self.__ippKm = ippKm
360
340 361 self.__codeType = codeType
341 362 self.__nCode = nCode
342 363 self.__nBaud = nBaud
@@ -587,6 +608,7 class DigitalRFWriter(Operation):
587 608 Operation.__init__(self, **kwargs)
588 609 self.metadata_dict = {}
589 610 self.dataOut = None
611 self.dtype = None
590 612
591 613 def setHeader(self):
592 614
@@ -878,7 +878,6 class IncohInt(Operation):
878 878 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
879 879
880 880 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
881
882 881 if n==1:
883 882 return
884 883
@@ -32,9 +32,7 class Remote(Thread):
32 32 None
33 33
34 34 Written by:
35
36 35 "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Jun. 03, 2015
37
38 36 """
39 37
40 38 server = None
@@ -638,18 +636,20 class SendToServer(ProcessingUnit):
638 636 return fullfilenameList
639 637
640 638 def run(self, **kwargs):
641
642 639 if not self.isConfig:
643 640 self.init = time.time()
644 641 self.setup(**kwargs)
645 642 self.isConfig = True
646 643
644 if not self.clientObj.is_alive():
645 print "[Remote Server]: Restarting connection "
646 self.setup(**kwargs)
647
647 648 if time.time() - self.init >= self.period:
648 649 fullfilenameList = self.findFiles()
649 650
650 651 if self.clientObj.updateFileList(fullfilenameList):
651 652 print "[Remote Server]: Sending the next files ", str(fullfilenameList)
652
653 653 self.init = time.time()
654 654
655 655 def close(self):
@@ -1,1 +1,1
1 <Project description="Testing USRP data reader" id="191" name="test01"><ReadUnit datatype="Voltage" id="1911" inputId="0" name="VoltageReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="Voltage" /><Parameter format="str" id="191112" name="path" value="/home/nanosat/data/John" /><Parameter format="date" id="191113" name="startDate" value="2000/07/03" /><Parameter format="date" id="191114" name="endDate" value="2017/07/03" /><Parameter format="time" id="191115" name="startTime" value="00:00:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:59" /><Parameter format="int" id="191118" name="blockTime" value="100" /><Parameter format="int" id="191119" name="walk" value="0" /><Parameter format="int" id="191120" name="online" value="0" /></Operation></ReadUnit><ProcUnit datatype="VoltageProc" id="1912" inputId="1911" name="VoltageProc"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="Decoder" priority="2" type="external"><Parameter format="intlist" id="191221" name="code" value="1,-1,-1,1,-1" /><Parameter format="int" id="191222" name="nCode" value="5" /><Parameter format="int" id="191223" name="nBaud" value="1" /></Operation></ProcUnit></Project> No newline at end of file
1 <Project description="Claire" id="002" name="script02"><ReadUnit datatype="VoltageReader" id="21" inputId="0" name="VoltageReader"><Operation id="211" name="run" priority="1" type="self"><Parameter format="str" id="2111" name="datatype" value="VoltageReader" /><Parameter format="str" id="2112" name="path" value="/media/nanosat/0BDE10E00BDE10E0/CLAIRE" /><Parameter format="date" id="2113" name="startDate" value="2017/07/26" /><Parameter format="date" id="2114" name="endDate" value="2017/07/26" /><Parameter format="time" id="2115" name="startTime" value="15:00:00" /><Parameter format="time" id="2116" name="endTime" value="16:00:00" /><Parameter format="int" id="2118" name="delay" value="30" /><Parameter format="int" id="2119" name="walk" value="1" /><Parameter format="int" id="2120" name="online" value="0" /></Operation><Operation id="212" name="printNumberOfBlock" priority="2" type="self" /></ReadUnit><ProcUnit datatype="VoltageProc" id="22" inputId="21" name="VoltageProc"><Operation id="221" name="run" priority="1" type="self" /></ProcUnit><ProcUnit datatype="SpectraProc" id="23" inputId="22" name="SpectraProc"><Operation id="231" name="run" priority="1" type="self"><Parameter format="int" id="2311" name="nFFTPoints" value="128" /><Parameter format="int" id="2312" name="nProfiles" value="128" /><Parameter format="pairslist" id="2313" name="pairsList" value="(0,1),(0,2),(1,2)" /></Operation><Operation id="232" name="setRadarFrequency" priority="2" type="self"><Parameter format="float" id="2321" name="frequency" value="445000000.0" /></Operation><Operation id="233" name="IncohInt" priority="3" type="other"><Parameter format="float" id="2331" name="timeInterval" value="128" /></Operation><Operation id="234" name="removeDC" priority="4" type="self"><Parameter format="int" id="2341" name="mode" value="2" /></Operation><Operation id="235" name="SpectraPlot" priority="5" type="external"><Parameter format="int" id="2351" name="id" value="235" /><Parameter format="str" id="2352" name="wintitle" value="SpectraPlot" /><Parameter format="str" id="2353" name="xaxis" value="frequency" /><Parameter format="float" id="2354" name="zmin" value="15.0" /><Parameter format="float" id="2355" name="zmax" value="50.0" /><Parameter format="int" id="2356" name="exp_code" value="21" /><Parameter format="int" id="2357" name="ftp_wei" value="0" /><Parameter format="int" id="2358" name="plot_pos" value="0" /></Operation></ProcUnit></Project> No newline at end of file
@@ -5,8 +5,18 Created on Jul 16, 2014
5 5 @author: Miguel Urco
6 6 """
7 7
8 from schainpy import __version__
9 8 from setuptools import setup, Extension
9 from setuptools.command.build_ext import build_ext as _build_ext
10 from schainpy import __version__
11
12 class build_ext(_build_ext):
13 def finalize_options(self):
14 _build_ext.finalize_options(self)
15 # Prevent numpy from thinking it is still in its setup process:
16 __builtins__.__NUMPY_SETUP__ = False
17 import numpy
18 self.include_dirs.append(numpy.get_include())
19
10 20
11 21 setup(name="schainpy",
12 22 version=__version__,
@@ -33,26 +43,19 setup(name="schainpy",
33 43 'schainpy.gui.figures': ['*.png', '*.jpg'],
34 44 },
35 45 include_package_data=False,
36 entry_points={
37 'console_scripts': [
38 'schain = schaincli.cli:main',
39 ],
40 },
41 scripts=['schainpy/gui/schainGUI'],
42 ext_modules=[Extension("cSchain", ["schainpy/model/proc/extensions.c"], include_dirs=[numpy.get_include()])],
46 scripts =['schainpy/gui/schainGUI',
47 'schainpy/scripts/schain'],
48 ext_modules=[
49 Extension("cSchain", ["schainpy/model/proc/extensions.c"]
50 )],
51 cmdclass={'build_ext':build_ext},
52 setup_requires=["numpy >= 1.11.2"],
43 53 install_requires=[
44 54 "scipy >= 0.14.0",
45 55 "h5py >= 2.2.1",
46 56 "matplotlib >= 1.4.2",
47 57 "pyfits >= 3.4",
48 "numpy >= 1.11.2",
49 "paramiko >= 2.1.2",
50 58 "paho-mqtt >= 1.2",
51 59 "zmq",
52 "fuzzywuzzy",
53 "click",
54 "colorama",
55 "python-Levenshtein"
56 60 ],
57 61 )
58
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now