Subversion Repositories NedoOS

Rev

Rev 2236 | Rev 2271 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <oscalls.h>
  5. #include <osfs.h>
  6. #include <intrz80.h>
  7. #include <graphic.h>
  8. #include <../common/terminal.c>
  9. #include <tcp.h>
  10. //
  11. #define true 1
  12. #define false 0
  13.  
  14. unsigned int RBR_THR = 0xf8ef;
  15. unsigned int IER = 0xf9ef;
  16. unsigned int IIR_FCR = 0xfaef;
  17. unsigned int LCR = 0xfbef;
  18. unsigned int MCR = 0xfcef;
  19. unsigned int LSR = 0xfdef;
  20. unsigned int MSR = 0xfeef;
  21. unsigned int SR = 0xffef;
  22. unsigned int divider = 1;
  23. unsigned char comType = 0;
  24. unsigned int espType = 32;
  25.  
  26. unsigned char picture[15000];
  27. unsigned char netbuf[6912];
  28.  
  29. unsigned char minRating[] = "0000000000";
  30. struct fileStruct
  31. {
  32.   long picId;
  33.   unsigned int picYear;
  34.   unsigned long totalAmount;
  35.   unsigned int httpErr;
  36.   unsigned char picRating[8];
  37.   unsigned char picName[256];
  38.   unsigned char picType[64];
  39.   unsigned char authorIds[64];
  40.   unsigned char authorTitle[64];
  41.   unsigned char authorRealName[64];
  42.   unsigned char afn[128];
  43.   unsigned char pfn[128];
  44.   unsigned char fileName[128];
  45. } curFileStruct;
  46.  
  47. struct window
  48. {
  49.   unsigned char x;
  50.   unsigned char y;
  51.   unsigned char w;
  52.   unsigned char h;
  53.   unsigned char text;
  54.   unsigned char back;
  55.   unsigned char tittle[80];
  56. } curWin;
  57.  
  58. struct sockaddr_in dnsaddress;
  59. struct sockaddr_in targetadr;
  60. struct readstructure readStruct;
  61.  
  62. unsigned char ver[] = "3.9";
  63. const unsigned char sendOk[] = "SEND OK";
  64. const unsigned char gotWiFi[] = "WIFI GOT IP";
  65. unsigned char buffer[] = "0000000000";
  66. unsigned char userAgent[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; GetPic)\r\n\r\n\0";
  67. unsigned char zxart[] = "zxart.ee";
  68. unsigned char keypress, verbose, randomPic, slideShow, netDriver;
  69.  
  70. unsigned long contLen;
  71. unsigned long count = 0;
  72. unsigned int headlng;
  73. unsigned int slideShowTime = 0;
  74. unsigned int loaded;
  75.  
  76. unsigned char crlf[2] = {13, 10};
  77. unsigned char cmd[512];
  78. unsigned char link[512];
  79. unsigned char fileIdChar[10];
  80.  
  81. void clearStatus(void)
  82. {
  83. }
  84.  
  85. void emptyKeys(void)
  86. {
  87.   unsigned char loop = 0, key;
  88.   do
  89.   {
  90.     key = OS_GETKEY();
  91.     if (loop > 64)
  92.     {
  93.       break;
  94.     }
  95.     loop++;
  96.   } while (key != 0);
  97. }
  98.  
  99. void spaces(unsigned char number)
  100. {
  101.   while (number > 0)
  102.   {
  103.     putchar(' ');
  104.     number--;
  105.   }
  106. }
  107. void quit(void)
  108. {
  109.   OS_CLS(0);
  110.   OS_SETGFX(-1);
  111.   exit(0);
  112. }
  113.  
  114. void infoBox(struct window w, const char *message)
  115. {
  116.   unsigned char wcount, tempx, tittleStart;
  117.  
  118.   w.h++;
  119.   OS_SETXY(w.x, w.y - 1);
  120.   BDBOX(w.x, w.y, w.w + 1, w.h, w.back, 32);
  121.   OS_SETXY(w.x, w.y);
  122.   OS_SETCOLOR(w.text);
  123.   putchar(201);
  124.   for (wcount = 0; wcount < w.w; wcount++)
  125.   {
  126.     putchar(205);
  127.   }
  128.   putchar(187);
  129.   OS_SETXY(w.x, w.y + w.h);
  130.   putchar(200);
  131.   for (wcount = 0; wcount < w.w; wcount++)
  132.   {
  133.     putchar(205);
  134.   }
  135.   putchar(188);
  136.  
  137.   tempx = w.x + w.w + 1;
  138.   for (wcount = 1; wcount < w.h; wcount++)
  139.   {
  140.     OS_SETXY(w.x, w.y + wcount);
  141.     putchar(186);
  142.     OS_SETXY(tempx, w.y + wcount);
  143.     putchar(186);
  144.   }
  145.   tittleStart = w.x + (w.w / 2) - (strlen(w.tittle) / 2);
  146.   OS_SETXY(tittleStart, w.y);
  147.   printf("[%s]", w.tittle);
  148.  
  149.   OS_SETXY(w.x + 1, w.y + 1);
  150.   OS_SETCOLOR(w.back);
  151.   tittleStart = w.x + (w.w / 2) - (strlen(message) / 2);
  152.   OS_SETXY(tittleStart, w.y + 1);
  153.   printf("%s", message);
  154. }
  155.  
  156. void printHelp(void)
  157. {
  158.   OS_SETCOLOR(67);
  159.   printf("   GETPIC [%s] zxart.ee picture viewer for nedoNET\n\r", ver);
  160.   OS_SETCOLOR(6);
  161.   printf("-------------------------------------------------------\n\r");
  162.   printf(" Управление:\n\r");
  163.   printf(" 'ESC' - выход из программы;\n\r");
  164.   printf(" '<-' или 'B' к последним картинкам;\n\r");
  165.   printf(" '->' или 'Пробел' к более старым картинкам\n\r");
  166.   printf(" 'J' Прыжок на  указанную по счету картинку\n\r");
  167.   printf(" 'I' Просмотр экрана информации о картинках\n\r");
  168.   printf(" 'S' Сохранить картинку на диск в текущую папку\n\r");
  169.   printf(" 'V' не выводить информацию об авторах\n\r");
  170.   printf(" 'R' переход в режим  случайная картинка с рейтингом 4+\n\r");
  171.   printf(" 'A' переход в режим  слайд-шоу\n\r");
  172.   printf(" 'D' Переключение режима ZXNETUSB/ESP-COM\n\r");
  173.   printf(" 'T' Продолжительность одного слайда в int-ах \n\r");
  174.   printf(" 'M' Минимальный рейтинг для случайного воспроизведения. \n\r");
  175.   printf(" 'H' Данная справочная информация\n\r");
  176.   printf("-----------------Нажмите любую кнопку------------------\n\r");
  177.   OS_SETCOLOR(70);
  178.   keypress = getchar();
  179.   OS_CLS(0);
  180. }
  181.  
  182. void delay(unsigned long counter)
  183. {
  184.   unsigned long start, finish;
  185.   counter = counter / 20;
  186.   if (counter < 1)
  187.   {
  188.     counter = 1;
  189.   }
  190.   start = time();
  191.   finish = start + counter;
  192.  
  193.   while (start < finish)
  194.   {
  195.     start = time();
  196.   }
  197. }
  198.  
  199. ///////////////////////////
  200. #include <../common/esp-com.c>
  201. #include <../common/network.c>
  202. //////////////////////////
  203.  
  204. int testOperation2(const char *process, int socket)
  205. {
  206.   if (socket < 0)
  207.   {
  208.     printf("%s: [ERROR:", process);
  209.     errorPrint(-socket);
  210.     printf("]\r\n");
  211.     YIELD();
  212.     return -socket;
  213.   }
  214.   return 1;
  215. }
  216.  
  217. int cutHeader(unsigned int todo)
  218. {
  219.   unsigned char *count1;
  220.  
  221.   curFileStruct.httpErr = httpError();
  222.   if (curFileStruct.httpErr != 200)
  223.   {
  224.     clearStatus();
  225.     printf("HTTP response:[%u]", curFileStruct.httpErr);
  226.     return 0;
  227.   }
  228.   count1 = strstr(netbuf, "Content-Length:");
  229.   if (count1 == NULL)
  230.   {
  231.     clearStatus();
  232.     printf("contLen not found");
  233.     contLen = 0;
  234.     curFileStruct.httpErr = 999; // bad kostil
  235.     return 0;
  236.   }
  237.   contLen = atol(count1 + 15);
  238.   // printf("Content-Length: %lu \n\r", contLen);
  239.  
  240.   count1 = strstr(netbuf, "\r\n\r\n");
  241.   if (count1 == NULL)
  242.   {
  243.     clearStatus();
  244.     printf("end of header not found\r\n");
  245.   }
  246.   else
  247.   {
  248.     headlng = ((unsigned int)count1 - (unsigned int)netbuf + 4);
  249.     // printf("header %u bytes\r\n", headlng);
  250.   }
  251.   return todo - headlng;
  252. }
  253.  
  254. char *str_replace(char *dst, int num, const char *str, const char *orig, const char *rep)
  255. {
  256.   const char *ptr;
  257.   size_t len1 = strlen(orig);
  258.   size_t len2 = strlen(rep);
  259.   char *tmp = dst;
  260.  
  261.   num -= 1;
  262.   while ((ptr = strstr(str, orig)) != NULL)
  263.   {
  264.     num -= (ptr - str) + len2;
  265.     if (num < 1)
  266.       break;
  267.  
  268.     strncpy(dst, str, (size_t)(ptr - str));
  269.     dst += ptr - str;
  270.     strncpy(dst, rep, len2);
  271.     dst += len2;
  272.     str = ptr + len1;
  273.   }
  274.  
  275.   for (; (*dst = *str) && (num > 0); --num)
  276.   {
  277.     ++dst;
  278.     ++str;
  279.   }
  280.   return tmp;
  281. }
  282.  
  283. char fillPictureEsp(void)
  284. {
  285.   unsigned char sizeLink = 0;
  286.   unsigned long downloaded = 0;
  287.   unsigned char byte, countl = 0;
  288.   unsigned int todo = 0;
  289.   unsigned char *count1;
  290.   unsigned char firstPacket;
  291.   strcpy(link, netbuf);
  292.   sizeLink = strlen(link);
  293.   do
  294.   {
  295.     sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  296.     getAnswer2(); // CONNECT or ERROR or link is not valid
  297.     count1 = strstr(netbuf, "CONNECT");
  298.   } while (count1 == NULL);
  299.  
  300.   getAnswer2();                                   // OK
  301.   sprintf(netbuf, "AT+CIPSEND=%u", sizeLink + 2); // second CRLF in send command
  302.   sendcommand(netbuf);
  303.   getAnswer2();
  304.   do
  305.   {
  306.     byte = uart_readBlock();
  307.     // putchar(byte);
  308.   } while (byte != '>');
  309.   sendcommand(link);
  310.   countl = 0;
  311.   do
  312.   {
  313.     byte = uart_readBlock();
  314.     if (byte == sendOk[countl])
  315.     {
  316.       countl++;
  317.     }
  318.     else
  319.     {
  320.       countl = 0;
  321.     }
  322.   } while (countl < strlen(sendOk));
  323.   uart_readBlock(); // CR
  324.   uart_readBlock(); // LF
  325.   downloaded = 0;
  326.   firstPacket = true;
  327.   do
  328.   {
  329.     headlng = 0;
  330.     todo = recvHead();
  331.     getdataEsp(todo); // Requested size
  332.     if (firstPacket)
  333.     {
  334.       todo = cutHeader(todo);
  335.       firstPacket = false;
  336.       if (curFileStruct.httpErr != 200)
  337.       {
  338.         sendcommand("AT+CIPCLOSE");
  339.         getAnswer2(); // CLOSED
  340.         getAnswer2(); // OK
  341.         return false;
  342.       }
  343.     }
  344.  
  345.     if (downloaded + todo > sizeof(picture))
  346.     {
  347.       printf("dataBuffer overrun... %u reached \n\r", downloaded + todo);
  348.       return false;
  349.     }
  350.     memcpy(picture + downloaded, netbuf + headlng, todo);
  351.     downloaded = downloaded + todo;
  352.   } while (downloaded < contLen);
  353.   sendcommand("AT+CIPCLOSE");
  354.   getAnswer2(); // CLOSED or ERROR
  355.   count1 = strstr(netbuf, "CLOSED");
  356.   if (count1 != NULL)
  357.   {
  358.     getAnswer2(); // OK
  359.   }
  360.   return true;
  361. }
  362.  
  363. char fillPictureNet(void)
  364. {
  365.   int todo;
  366.   unsigned int downloaded = 0;
  367.   unsigned char firstPacket;
  368.   char socket, retry;
  369.   picture[0] = 0;
  370.   retry = 3;
  371.   socket = OpenSock(AF_INET, SOCK_STREAM);
  372.   if (testOperation2("OS_NETSOCKET", socket) != 1)
  373.   {
  374.     getchar();
  375.     quit();
  376.   }
  377.   todo = netConnect(socket, retry);
  378.   if (testOperation2("OS_NETCONNECT", todo) != 1)
  379.   {
  380.     getchar();
  381.     quit();
  382.   }
  383.   todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf), retry);
  384.   if (testOperation2("OS_WIZNETWRITE", todo) != 1)
  385.   {
  386.     getchar();
  387.     quit();
  388.   }
  389.   firstPacket = true;
  390.   do
  391.   {
  392.     headlng = 0;
  393.     todo = tcpRead(socket, retry);
  394.     testOperation("OS_WIZNETREAD", todo); // Quit if too many retries
  395.  
  396.     if (firstPacket)
  397.     {
  398.       todo = cutHeader(todo);
  399.       firstPacket = false;
  400.       if (curFileStruct.httpErr != 200)
  401.       {
  402.         netShutDown(socket, 0);
  403.         return false;
  404.       }
  405.     }
  406.  
  407.     if (downloaded + todo > sizeof(picture))
  408.     {
  409.       printf("dataBuffer overrun... %u reached \n\r", downloaded + todo);
  410.       return false;
  411.     }
  412.     memcpy(picture + downloaded, netbuf + headlng, todo);
  413.     downloaded = downloaded + todo;
  414.   } while (downloaded != contLen);
  415.  
  416.   netShutDown(socket, 0);
  417.   picture[downloaded + 1] = 0;
  418.   return true;
  419. }
  420.  
  421. void nameRepair(unsigned char *pfn, unsigned int tfnSize)
  422. {
  423.  
  424.   str_replace(pfn, tfnSize, pfn, "\\", "_");
  425.   str_replace(pfn, tfnSize, pfn, "/", "_");
  426.   str_replace(pfn, tfnSize, pfn, ":", "_");
  427.   str_replace(pfn, tfnSize, pfn, "*", "_");
  428.   str_replace(pfn, tfnSize, pfn, "?", "_");
  429.   str_replace(pfn, tfnSize, pfn, "<", "_");
  430.   str_replace(pfn, tfnSize, pfn, ">", "_");
  431.   str_replace(pfn, tfnSize, pfn, "|", "_");
  432.   str_replace(pfn, tfnSize, pfn, " ", "_");
  433.   str_replace(pfn, tfnSize, pfn, "&#039;", "'");
  434.   str_replace(pfn, tfnSize, pfn, "&amp;", "&");
  435.   str_replace(pfn, tfnSize, pfn, "&quot;", "'");
  436.   str_replace(pfn, tfnSize, pfn, "&gt;", ")");
  437.   str_replace(pfn, tfnSize, pfn, "&lt;", "(");
  438.   str_replace(pfn, tfnSize, pfn, "\"", "'");
  439. }
  440.  
  441. void stringRepair(unsigned char *pfn, unsigned int tSize)
  442. {
  443.   str_replace(pfn, tSize, pfn, "&#039;", "'");
  444.   str_replace(pfn, tSize, pfn, "&amp;", "&");
  445.   str_replace(pfn, tSize, pfn, "&gt;", ">");
  446.   str_replace(pfn, tSize, pfn, "&lt;", "<");
  447.   str_replace(pfn, tSize, pfn, "&quot;", "\"");
  448.   str_replace(pfn, tSize, pfn, "\\/", "/");
  449. }
  450.  
  451. void ncReplace(void)
  452. {
  453.   unsigned char len;
  454.   for (len = 0; len < strlen(curFileStruct.afn); len++)
  455.   {
  456.     if ((curFileStruct.afn[len] < ' ') || (curFileStruct.afn[len] > 0xef) || (curFileStruct.afn[len] > 0x7e && curFileStruct.afn[len] < 0xb0))
  457.     {
  458.       curFileStruct.afn[len] = '_';
  459.     }
  460.   }
  461.  
  462.   for (len = 0; len < strlen(curFileStruct.pfn); len++)
  463.   {
  464.     if ((curFileStruct.pfn[len] < ' ') || (curFileStruct.pfn[len] > 0xef) || (curFileStruct.pfn[len] > 0x7e && curFileStruct.pfn[len] < 0xb0))
  465.     {
  466.       curFileStruct.pfn[len] = '_';
  467.     }
  468.   }
  469. }
  470.  
  471. unsigned char savePic(unsigned long fileId)
  472. {
  473.   FILE *fp2;
  474.   unsigned char afnSize, tfnSize;
  475.  
  476.   afnSize = sizeof(curFileStruct.afn) - 1;
  477.   tfnSize = sizeof(curFileStruct.pfn) - 1;
  478.  
  479.   strcpy(curFileStruct.afn, curFileStruct.authorTitle);
  480.   nameRepair(curFileStruct.afn, afnSize);
  481.  
  482.   strcpy(curFileStruct.pfn, curFileStruct.picName);
  483.   nameRepair(curFileStruct.pfn, tfnSize);
  484.   ncReplace();
  485.  
  486.   sprintf(curFileStruct.fileName, "%s-%s-%ld.scr", curFileStruct.afn, curFileStruct.pfn, fileId);
  487.   if (strlen(curFileStruct.fileName) > 62)
  488.   {
  489.     sprintf(fileIdChar, "-%ld", fileId);
  490.     str_replace(curFileStruct.fileName, sizeof(curFileStruct.fileName) - 1, curFileStruct.fileName, fileIdChar, "");
  491.     curFileStruct.fileName[50] = '\0';
  492.     strcat(curFileStruct.fileName, fileIdChar);
  493.     strcat(curFileStruct.fileName, ".scr");
  494.   }
  495.   OS_SETSYSDRV();
  496.   OS_MKDIR("../downloads");        // Create if not exist
  497.   OS_MKDIR("../downloads/getpic"); // Create if not exist
  498.   OS_CHDIR("../downloads/getpic");
  499.   fp2 = OS_CREATEHANDLE(curFileStruct.fileName, 0x80);
  500.   if (((int)fp2) & 0xff)
  501.   {
  502.     printf("%s creating error\r\n", curFileStruct.fileName);
  503.     getchar();
  504.     quit();
  505.   }
  506.   OS_WRITEHANDLE(picture, fp2, 6912);
  507.   OS_CLOSEHANDLE(fp2);
  508.   return 0;
  509. }
  510.  
  511. int pos(unsigned char *s, unsigned char *c, unsigned int n, unsigned int startPos)
  512. {
  513.   unsigned int i, j;
  514.   unsigned int lenC, lenS;
  515.  
  516.   for (lenC = 0; c[lenC]; lenC++)
  517.     ;
  518.   for (lenS = 0; s[lenS]; lenS++)
  519.     ;
  520.  
  521.   for (i = startPos; i <= lenS - lenC; i++)
  522.   {
  523.     for (j = 0; s[i + j] == c[j]; j++)
  524.       ;
  525.  
  526.     if (j - lenC == 1 && i == lenS - lenC && !(n - 1))
  527.       return i;
  528.     if (j == lenC)
  529.       if (n - 1)
  530.         n--;
  531.       else
  532.         return i;
  533.   }
  534.   return -1;
  535. }
  536.  
  537. const char *parseJson(unsigned char *property)
  538. {
  539.   unsigned int w, lng, lngp1, findEnd, listPos;
  540.   unsigned char terminator;
  541.   int n;
  542.   n = -1;
  543.   // netbuf[0] = '\0';
  544.   n = pos(picture, property, 1, 0);
  545.   if (n == -1)
  546.   {
  547.     strcpy(netbuf, "-");
  548.     // printf("Property %s not found", property);
  549.     return netbuf;
  550.   }
  551.   lng = n - 1 + strlen(property);
  552.   if (picture[lng] == ':')
  553.   {
  554.     terminator = 0;
  555.   }
  556.   if (picture[lng] == '\"')
  557.   {
  558.     terminator = '\"';
  559.   }
  560.   if (picture[lng] == '[')
  561.   {
  562.     terminator = ']';
  563.   }
  564.  
  565.   findEnd = 1;
  566.   lngp1 = lng + 1;
  567.  
  568.   while (42)
  569.   {
  570.  
  571.     if ((picture[lngp1 + findEnd] == ','))
  572.     {
  573.       if (terminator == 0)
  574.       {
  575.         break;
  576.       }
  577.       if ((picture[lng + findEnd] == terminator))
  578.       {
  579.         findEnd--;
  580.         break;
  581.       }
  582.     }
  583.     findEnd++;
  584.   }
  585.   listPos = 0;
  586.   for (w = lngp1; w < findEnd + lngp1; w++)
  587.   {
  588.     netbuf[listPos] = picture[w];
  589.     listPos++;
  590.   }
  591.   netbuf[listPos] = 0;
  592.   return netbuf;
  593. }
  594.  
  595. void convert866(void)
  596. {
  597.   unsigned int lng, targetPos, w, q = 0;
  598.   unsigned char bufferl[8], one, two;
  599.   unsigned int decVal;
  600.   lng = strlen(netbuf);
  601.   targetPos = lng + 1;
  602.  
  603.   while (q < lng)
  604.   {
  605.     one = netbuf[q];
  606.     two = netbuf[q + 1];
  607.     if (one == 92 && two == 117)
  608.     {
  609.       q = q + 2;
  610.       for (w = 0; w < 4; w++)
  611.       {
  612.         bufferl[w] = netbuf[q + w];
  613.       }
  614.       q = q + 4;
  615.       bufferl[4] = '\0';
  616.       decVal = (unsigned int)strtol(bufferl, NULL, 16);
  617.  
  618.       if (decVal < 1088)
  619.       {
  620.         decVal = decVal - 912;
  621.       }
  622.       if (decVal > 1087)
  623.       {
  624.         decVal = decVal - 864;
  625.       }
  626.       if (decVal == 1025)
  627.       {
  628.         decVal = 240;
  629.       }
  630.       if (decVal == 1105)
  631.       {
  632.         decVal = 241;
  633.       }
  634.  
  635.       netbuf[targetPos] = decVal;
  636.     }
  637.     else
  638.     {
  639.       netbuf[targetPos] = netbuf[q];
  640.       q++;
  641.     }
  642.     targetPos++;
  643.   }
  644.   netbuf[targetPos] = 0;
  645.  
  646.   for (w = lng + 1; w < targetPos + 1; w++)
  647.   {
  648.     netbuf[w - lng - 1] = netbuf[w];
  649.   }
  650. }
  651.  
  652. long processJson(unsigned long startPos, unsigned char limit, unsigned char queryNum)
  653. {
  654.   unsigned int tSize;
  655.   unsigned char *count1, result;
  656.   switch (queryNum)
  657.   {
  658.   case 0:
  659.     sprintf(netbuf, "GET /api/export:zxPicture/filter:zxPictureType=standard/limit:%u/start:%lu/order:date,desc%s", limit, startPos, userAgent);
  660.     break;
  661.   case 1:
  662.     sprintf(netbuf, "GET /api/types:zxPicture/export:zxPicture/language:eng/start:0/limit:1/order:rand/filter:zxPictureMinRating=%s;zxPictureType=standard%s", minRating, userAgent);
  663.     break;
  664.   case 99: // GET /jsonElementData/elementId:182798
  665.     sprintf(netbuf, "GET /jsonElementData/elementId:%lu%s", startPos, userAgent);
  666.     break;
  667.   }
  668.  
  669.   switch (netDriver)
  670.   {
  671.   case 0:
  672.     result = fillPictureNet();
  673.     break;
  674.   case 1:
  675.     result = fillPictureEsp();
  676.     break;
  677.   }
  678.  
  679.   if (!result)
  680.   {
  681.     return -1;
  682.   }
  683.  
  684.   count1 = strstr(picture, "responseStatus\":\"success");
  685.   if (count1 == NULL)
  686.   {
  687.     OS_CLS(0);
  688.     OS_SETCOLOR(66);
  689.     puts("Picture[]:");
  690.     puts(picture);
  691.     puts("---------------");
  692.     printf("PROCESS JSON: [ERROR: Bad responseStatus.] [Query:%u][Pic:%lu]\r\n", queryNum, startPos);
  693.     YIELD();
  694.     getchar();
  695.     return -1;
  696.   }
  697.  
  698.   count1 = strstr(picture, "\"id\":");
  699.   if (count1 == NULL)
  700.   {
  701.     parseJson("\"totalAmount\":");
  702.  
  703.     if (atol(netbuf) == 0)
  704.     {
  705.       return -3;
  706.     }
  707.  
  708.     if (netbuf[0] != '-')
  709.     {
  710.       return -4;
  711.     }
  712.     OS_CLS(0);
  713.     OS_SETCOLOR(66);
  714.     puts("Picture[]:");
  715.     puts(picture);
  716.     puts("---------------");
  717.     printf("PROCESS JSON: [ERROR: ID not found.] [Query:%u][Pic:%lu]\r\n", queryNum, startPos);
  718.     YIELD();
  719.     return -2;
  720.   }
  721.   netbuf[0] = 0;
  722.  
  723.   switch (queryNum)
  724.   {
  725.   case 0:
  726.   case 1:
  727.     parseJson("\"id\":");
  728.     curFileStruct.picId = atol(netbuf);
  729.     parseJson(",\"title\":\"");
  730.     convert866();
  731.     strcpy(curFileStruct.picName, netbuf);
  732.     tSize = sizeof(curFileStruct.picName);
  733.     stringRepair(curFileStruct.picName, tSize);
  734.  
  735.     parseJson(",\"type\":\"");
  736.     strcpy(curFileStruct.picType, netbuf);
  737.     parseJson("\"rating\":\"");
  738.     strcpy(curFileStruct.picRating, netbuf);
  739.     parseJson("\"year\":\"");
  740.     curFileStruct.picYear = atoi(netbuf);
  741.     parseJson("\"totalAmount\":");
  742.     curFileStruct.totalAmount = atol(netbuf);
  743.     parseJson("\"authorIds\":[");
  744.     strcpy(curFileStruct.authorIds, netbuf);
  745.     break;
  746.   case 99:
  747.     parseJson(",\"title\":\"");
  748.     convert866();
  749.     strcpy(curFileStruct.authorTitle, netbuf);
  750.     parseJson(",\"realName\":\"");
  751.     convert866();
  752.     strcpy(curFileStruct.authorRealName, netbuf);
  753.     break;
  754.   }
  755.   return curFileStruct.picId;
  756. }
  757.  
  758. void printData(void)
  759. {
  760.   OS_SETCOLOR(70);
  761.   printf(" #: ");
  762.   OS_SETCOLOR(71);
  763.   printf("%lu", count);
  764.   OS_SETCOLOR(70);
  765.   printf(" ID: ");
  766.   OS_SETCOLOR(71);
  767.   printf("%lu ", curFileStruct.picId);
  768.   OS_SETCOLOR(70);
  769.   printf(" Total Pics: ");
  770.   OS_SETCOLOR(71);
  771.   printf("%lu\r\n", curFileStruct.totalAmount);
  772.   OS_SETCOLOR(70);
  773.   printf(" Author: ");
  774.   OS_SETCOLOR(69);
  775.   printf("%s\r\n", curFileStruct.authorTitle);
  776.   OS_SETCOLOR(70);
  777.   printf(" TITLE: ");
  778.   OS_SETCOLOR(67);
  779.   printf("%s\r\n", curFileStruct.picName);
  780.   OS_SETCOLOR(70);
  781.   printf(" RATING: ");
  782.   OS_SETCOLOR(71);
  783.   printf("%s", curFileStruct.picRating);
  784.   OS_SETCOLOR(70);
  785.   printf(" YEAR: ");
  786.   OS_SETCOLOR(71);
  787.   printf("%u\r\n", curFileStruct.picYear);
  788.   OS_SETCOLOR(70);
  789.   printf(" AuthorsIDs ");
  790.   OS_SETCOLOR(71);
  791.   printf("%s", curFileStruct.authorIds);
  792.   OS_SETCOLOR(70);
  793.   printf(" Real name: ");
  794.   OS_SETCOLOR(71);
  795.   printf("%s\r\n", curFileStruct.authorRealName);
  796.   OS_SETCOLOR(69);
  797.   printf("\r\n");
  798.   printf("\r\n");
  799.  
  800.   OS_SETCOLOR(70);
  801.  
  802.   OS_SETCOLOR(70);
  803.   printf(" Query: ");
  804.   OS_SETCOLOR(71);
  805.   if (randomPic)
  806.   {
  807.     printf("Random pic with %s+ rating\r\n", minRating);
  808.   }
  809.   else
  810.   {
  811.     puts("Sequental from newest");
  812.   }
  813.   OS_SETCOLOR(70);
  814.   printf(" Mode : ");
  815.   OS_SETCOLOR(71);
  816.  
  817.   if (slideShow)
  818.   {
  819.     printf("Slide-show, %u ints \r\n", slideShowTime);
  820.   }
  821.   else
  822.   {
  823.     puts("Manual show");
  824.   }
  825.  
  826.   // YIELD();
  827. }
  828.  
  829. unsigned char inputBox(struct window w, const char *prefilled)
  830. {
  831.   unsigned char wcount, tempx, tittleStart;
  832.   unsigned char byte, counter;
  833.   w.h++;
  834.   OS_SETXY(w.x, w.y - 1);
  835.   BDBOX(w.x, w.y, w.w + 1, w.h, w.back, 32);
  836.   OS_SETXY(w.x, w.y);
  837.   OS_SETCOLOR(w.text);
  838.   putchar(201);
  839.   for (wcount = 0; wcount < w.w; wcount++)
  840.   {
  841.     putchar(205);
  842.   }
  843.   putchar(187);
  844.   OS_SETXY(w.x, w.y + w.h);
  845.   putchar(200);
  846.   for (wcount = 0; wcount < w.w; wcount++)
  847.   {
  848.     putchar(205);
  849.   }
  850.   putchar(188);
  851.  
  852.   tempx = w.x + w.w + 1;
  853.   for (wcount = 1; wcount < w.h; wcount++)
  854.   {
  855.     OS_SETXY(w.x, w.y + wcount);
  856.     putchar(186);
  857.     OS_SETXY(tempx, w.y + wcount);
  858.     putchar(186);
  859.   }
  860.   tittleStart = w.x + (w.w / 2) - (strlen(w.tittle) / 2);
  861.   OS_SETXY(tittleStart, w.y);
  862.   printf("[%s]", w.tittle);
  863.   OS_SETXY(w.x + 1, w.y + 1);
  864.   OS_SETCOLOR(w.back);
  865.   putchar(219);
  866.  
  867.   cmd[0] = 0;
  868.  
  869.   counter = strlen(prefilled);
  870.   if (counter != 0)
  871.   {
  872.     strcpy(cmd, prefilled);
  873.     goto skipKeys;
  874.   }
  875.  
  876.   do
  877.   {
  878.     byte = OS_GETKEY();
  879.     if (byte != 0)
  880.     {
  881.       switch (byte)
  882.       {
  883.       case 0x08:
  884.         if (counter > 0)
  885.         {
  886.           counter--;
  887.           cmd[counter] = 0;
  888.         }
  889.         break;
  890.       case 0x0d:
  891.  
  892.         if (counter == 0)
  893.         {
  894.           return false;
  895.         }
  896.         else
  897.         {
  898.           return true;
  899.         }
  900.  
  901.       case 31:
  902.         break;
  903.       case 250:
  904.         break;
  905.       case 249:
  906.         break;
  907.       case 248:
  908.         break;
  909.       case 251: // Right
  910.         break;
  911.       case 252: // Del
  912.         OS_SETXY(w.x + 1, w.y + 1);
  913.         spaces(counter + 1);
  914.         cmd[0] = 0;
  915.         counter = 0;
  916.         break;
  917.       case 27:
  918.         cmd[0] = 0;
  919.         return false;
  920.       default:
  921.         if (counter < w.w - 1)
  922.         {
  923.           cmd[counter] = byte;
  924.           counter++;
  925.           cmd[counter] = 0;
  926.         }
  927.         break;
  928.       }
  929.     skipKeys:
  930.       OS_SETXY(w.x + 1, w.y + 1);
  931.       printf("%s", cmd);
  932.       putchar(219);
  933.       if (byte == 0x08)
  934.       {
  935.         putchar(' ');
  936.       }
  937.     }
  938.     YIELD();
  939.   } while (42);
  940.   return false;
  941. }
  942.  
  943. void safeKeys(unsigned char keypress)
  944. {
  945.   switch (keypress)
  946.   {
  947.   case 27:
  948.     OS_SETCOLOR(70);
  949.     printf("Good bye...\r\n");
  950.     delayLong(500);
  951.     quit();
  952.     break;
  953.   case 'j':
  954.   case 'J':
  955.     curWin.w = 13;
  956.     curWin.x = 80 / 2 - curWin.w / 2 - 2;
  957.     curWin.y = 11;
  958.     curWin.h = 1;
  959.     curWin.text = 103;
  960.     curWin.back = 103;
  961.     strcpy(curWin.tittle, "# of pic:");
  962.     if (inputBox(curWin, ""))
  963.     {
  964.       sscanf(cmd, "%lu", &count);
  965.       if (count > curFileStruct.totalAmount - 1)
  966.       {
  967.         count = curFileStruct.totalAmount - 1;
  968.       }
  969.     }
  970.     break;
  971.   case 't':
  972.   case 'T':
  973.     curWin.w = 20;
  974.     curWin.x = 80 / 2 - curWin.w / 2 - 2;
  975.     curWin.y = 11;
  976.     curWin.h = 1;
  977.     curWin.text = 103;
  978.     curWin.back = 103;
  979.     strcpy(curWin.tittle, "Slide time(ints)");
  980.     if (inputBox(curWin, ""))
  981.     {
  982.       sscanf(cmd, "%u", &slideShowTime);
  983.       OS_CLS(0);
  984.       OS_SETCOLOR(70);
  985.       printf("Slide duration set to %u ints.", slideShowTime);
  986.       delayLong(500);
  987.     }
  988.     break;
  989.   case 'v':
  990.   case 'V':
  991.     verbose = !verbose;
  992.  
  993.     if (verbose == 0)
  994.     {
  995.       BOX(1, 1, 80, 25, 40, ' ');
  996.       AT(1, 1);
  997.     }
  998.     break;
  999.   case 'h':
  1000.   case 'H':
  1001.     printHelp();
  1002.     break;
  1003.   case 'r':
  1004.   case 'R':
  1005.     randomPic = !randomPic;
  1006.     OS_SETCOLOR(70);
  1007.     if (verbose == 1)
  1008.     {
  1009.       if (randomPic == 1)
  1010.       {
  1011.         printf("    Random mode enabled...\r\n");
  1012.         count = 0;
  1013.         delayLong(500);
  1014.       }
  1015.       else
  1016.       {
  1017.         printf("    Sequental mode enabled...\r\n");
  1018.         count = 0;
  1019.         delayLong(500);
  1020.       }
  1021.     }
  1022.     break;
  1023.   case 'a':
  1024.   case 'A':
  1025.     slideShow = !slideShow;
  1026.     OS_SETCOLOR(70);
  1027.     if (slideShow == 1)
  1028.     {
  1029.       if (verbose == 1)
  1030.         printf("    SlideShow mode enabled...\r\n\r\n");
  1031.       slideShowTime = 150;
  1032.       delayLong(500);
  1033.     }
  1034.     else
  1035.     {
  1036.       if (verbose == 1)
  1037.         printf("    Manual mode enabled...\r\n\r\n");
  1038.       slideShowTime = 0;
  1039.       delayLong(500);
  1040.     }
  1041.     break;
  1042.   case 'd':
  1043.   case 'D':
  1044.     netDriver = !netDriver;
  1045.     OS_SETCOLOR(70);
  1046.     if (netDriver == 1)
  1047.     {
  1048.       printf("    ESP-COM mode enabled...\r\n");
  1049.       loadEspConfig();
  1050.       uart_init(divider);
  1051.       espReBoot();
  1052.       printf("    ESP-COM inited...\r\n");
  1053.       delayLong(500);
  1054.     }
  1055.     else
  1056.     {
  1057.       if (verbose == 1)
  1058.         printf("    NedoNET mode enabled...");
  1059.       delayLong(500);
  1060.     }
  1061.     break;
  1062.   case 'm':
  1063.   case 'M':
  1064.     curWin.w = 22;
  1065.     curWin.x = 80 / 2 - curWin.w / 2 - 2;
  1066.     curWin.y = 1;
  1067.     curWin.h = 1;
  1068.     curWin.text = 103;
  1069.     curWin.back = 103;
  1070.     strcpy(curWin.tittle, "Минимальная оценка:");
  1071.  
  1072.     if (inputBox(curWin, ""))
  1073.     {
  1074.       char counter;
  1075.       for (counter = 0; counter < strlen(cmd); counter++)
  1076.       {
  1077.         if ((((cmd[counter] < '0') || (cmd[counter] > '9'))) && cmd[counter] != '.')
  1078.         {
  1079.           counter = 0;
  1080.           break;
  1081.         }
  1082.       }
  1083.       if (counter != 0)
  1084.       {
  1085.         strncpy(minRating, cmd, 5);
  1086.         count = 0;
  1087.       }
  1088.     }
  1089.   default:
  1090.     break;
  1091.   }
  1092. }
  1093.  
  1094. void init(void)
  1095. {
  1096.   OS_SETSYSDRV();
  1097.   OS_MKDIR("../downloads");        // Create if not exist
  1098.   OS_MKDIR("../downloads/getpic"); // Create if not exist
  1099.   OS_CHDIR("../downloads/getpic");
  1100.  
  1101.   count = 0;
  1102.   verbose = 1;
  1103.   randomPic = 0;
  1104.   slideShow = 0;
  1105.   netDriver = 0;
  1106.   strcpy(minRating, "4.0");
  1107.  
  1108.   targetadr.family = AF_INET;
  1109.   targetadr.porth = 00;
  1110.   targetadr.portl = 80;
  1111.   targetadr.b1 = 217; // D9
  1112.   targetadr.b2 = 146; // 92
  1113.   targetadr.b3 = 69;  // 45
  1114.   targetadr.b4 = 13;  // 0D
  1115. }
  1116.  
  1117. C_task main(void)
  1118. {
  1119.   long iddqd, idkfa;
  1120.   char result;
  1121.  
  1122.   OS_HIDEFROMPARENT();
  1123.   OS_SETGFX(0x86);
  1124.   OS_CLS(0);
  1125.  
  1126.   init();
  1127.  
  1128.   printHelp();
  1129.   safeKeys(keypress);
  1130.  
  1131.   if (netDriver == 0)
  1132.   {
  1133.  
  1134.     get_dns();
  1135.     dnsResolve("zxart.ee");
  1136.     printf("\r\n");
  1137.   }
  1138.  
  1139. start:
  1140.   keypress = 0;
  1141.   switch (randomPic)
  1142.   {
  1143.   case 0:
  1144.  
  1145.     iddqd = processJson(count, 1, 0);
  1146.     break;
  1147.   case 1:
  1148.     iddqd = processJson(0, 1, 1);
  1149.     break;
  1150.   }
  1151.  
  1152.   OS_SETCOLOR(70);
  1153.  
  1154.   switch (iddqd)
  1155.   {
  1156.   case -3: // return 0 pictures
  1157.     strcpy(minRating, "1.0");
  1158.     printf("[%u]No picture is returned in query. Minimal rating is set to %s\r\n", curFileStruct.httpErr, minRating);
  1159.     delayLong(500);
  1160.     goto start;
  1161.   case -4: // return xxxx picture, but empty body.
  1162.     printf("[%u]Empty body is returned. Next picture, please.(%ld)...\r\n", curFileStruct.httpErr, iddqd);
  1163.     delayLong(500);
  1164.     count++;
  1165.     goto start;
  1166.   case -1: // return HTTP error != 200
  1167.     printf("[%u]Error getting pic info. Next picture, please(%ld)...\r\n", curFileStruct.httpErr, iddqd);
  1168.     count++;
  1169.     delayLong(500);
  1170.     goto start;
  1171.   }
  1172.  
  1173.   if (verbose == 1)
  1174.   {
  1175.     idkfa = processJson(atol(curFileStruct.authorIds), 0, 99);
  1176.     if (idkfa < 0)
  1177.     {
  1178.       printf("[%u]Error can't parse authorIds(%s). Next picture, please(%ld)...\r\n", curFileStruct.httpErr, curFileStruct.authorIds);
  1179.       count++;
  1180.       delayLong(500);
  1181.       goto start;
  1182.     }
  1183.   }
  1184.   if (strcmp(curFileStruct.picType, "standard") != 0)
  1185.   {
  1186.     printf("[%u]Error format '%s' not supported. Next picture, please.\n\r", curFileStruct.picType);
  1187.     delayLong(500);
  1188.     count++;
  1189.     goto start;
  1190.   }
  1191.   sprintf(netbuf, "GET /file/id:%lu%s", iddqd, userAgent);
  1192.   switch (netDriver)
  1193.   {
  1194.   case 0:
  1195.     result = fillPictureNet();
  1196.     break;
  1197.   case 1:
  1198.     result = fillPictureEsp();
  1199.     break;
  1200.   }
  1201.  
  1202.   if (result == -1) // return HTTP error != 200  case -3: // return 0 pictures
  1203.   {
  1204.     printf("[%u]Error getting pic. Next picture, please(%ld)...\r\n", curFileStruct.httpErr, result);
  1205.     count++;
  1206.     delayLong(500);
  1207.     goto start;
  1208.   }
  1209.  
  1210. review:
  1211.   OS_CLS(0);
  1212.   YIELD();
  1213.   keypress = viewScreen6912((unsigned int)&picture, slideShowTime);
  1214.   emptyKeys();
  1215.  
  1216.   ///// Keys only for pictures
  1217.   if (keypress == 's' || keypress == 'S')
  1218.   {
  1219.     savePic(iddqd);
  1220.     printf("%s saved.", curFileStruct.fileName);
  1221.     delayLong(500);
  1222.     count++;
  1223.   }
  1224.  
  1225.   if (keypress == 248 || keypress == 'b' || keypress == 'B')
  1226.   {
  1227.     if (count > 0)
  1228.     {
  1229.       count--;
  1230.     }
  1231.   }
  1232.   if (keypress == 251 || keypress == 32)
  1233.   {
  1234.     count++;
  1235.     goto start;
  1236.   }
  1237.   if (keypress == 'i' || keypress == 'I')
  1238.   {
  1239.     printData();
  1240.     getchar();
  1241.     goto review;
  1242.   }
  1243.   safeKeys(keypress);
  1244.   goto start;
  1245. }
  1246.