00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "precomp.h"
00028 #include "LicenseInfoLoader.h"
00029 #include "resource.h"
00030
00031 #include "CCPrintProgressDlg.h"
00032 #include "globals.h"
00033 #include "debug.h"
00034
00036 XDoc LicenseInfoLoader::m_xmlData[LLDT_Count];
00038 bool LicenseInfoLoader::m_bRetrievedFromWeb[LLDT_Count];
00039
00041 LPCTSTR CCINFO_URL[] =
00042 {
00043 _T("/rest/1.5/license/standard"),
00044 _T("/rest/1.5/license/recombo"),
00045 NULL
00046 };
00047
00049 LPCTSTR CCINFO_IMAGE_URL[] =
00050 {
00051 NULL,
00052 NULL,
00053 _T("http://i.creativecommons.org/l/by-nc/3.0/88x31.png"),
00054 _T("http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png"),
00055 _T("http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png"),
00056 _T("http://i.creativecommons.org/l/by/3.0/88x31.png"),
00057 _T("http://i.creativecommons.org/l/by-sa/3.0/88x31.png"),
00058 _T("http://i.creativecommons.org/l/by-nd/3.0/88x31.png"),
00059 _T("http://i.creativecommons.org/l/sampling/1.0/88x31.png"),
00060 _T("http://i.creativecommons.org/l/sampling+/1.0/88x31.png"),
00061 _T("http://i.creativecommons.org/l/nc-sampling+/1.0/88x31.png"),
00062 NULL
00063 };
00064
00069 inline TCHAR toHex(const BYTE &x)
00070 {
00071 return x > 9 ? x + 55: x + 48;
00072 }
00073
00080 std::tstring URLEncode(LPCTSTR pIn)
00081 {
00082
00083 std::tstring sOut;
00084
00085 const size_t nLen = _tcslen(pIn) + 1;
00086 register LPTSTR pOutTmp = NULL;
00087 LPTSTR pOutBuf = NULL;
00088 register LPCTSTR pInTmp = NULL;
00089 LPCTSTR pInBuf = pIn;
00090 TCHAR b = 0;
00091
00092
00093 pOutBuf = (LPTSTR)new TCHAR[nLen * 3];
00094 if (pOutBuf == NULL)
00095
00096 return sOut;
00097
00098
00099 pInTmp = pInBuf;
00100 pOutTmp = pOutBuf;
00101
00102
00103 while (*pInTmp)
00104 {
00105 if(_istalnum(*pInTmp))
00106 *pOutTmp++ = *pInTmp;
00107 else
00108 if(_istspace(*pInTmp))
00109 *pOutTmp++ = '+';
00110 else
00111 {
00112 *pOutTmp++ = '%';
00113 *pOutTmp++ = toHex((unsigned char)(*pInTmp)>>4);
00114 *pOutTmp++ = toHex((unsigned char)(*pInTmp)%16);
00115 }
00116 pInTmp++;
00117 }
00118
00119
00120 *pOutTmp = '\0';
00121 sOut = (LPCTSTR)pOutBuf;
00122 delete [] pOutBuf;
00123
00124 return sOut;
00125 }
00126
00130 UINT LicenseInfoLoader::GetLicenseImageID() const
00131 {
00132
00133 switch (m_eLicense)
00134 {
00135 case LTCC:
00136
00137 if (m_eModification != MTUnknown)
00138 {
00139
00140 UINT uBase = IDPNG_BY_NC + (int)m_eModification;
00141 if (m_bCommercialUse)
00142
00143 uBase += 3;
00144
00145 return uBase;
00146 }
00147 break;
00148 case LTSampling:
00149 if (m_eSampling == STUnknown)
00150 break;
00151
00152 return IDPNG_SAMPLING + (int)m_eSampling;
00153 case LTDevelopingNations:
00154 case LTPublicDomain:
00155
00156 return IDPNG_SOMERIGHTS;
00157 default:
00158 break;
00159 }
00160
00161
00162 return 0;
00163 }
00164
00169 LPCTSTR LicenseInfoLoader::GetLicenseURL(LoadedLicenseDataType eType)
00170 {
00171 if (eType > LLDTSampling)
00172
00173 return NULL;
00174 return CCINFO_URL[(int)eType];
00175 }
00176
00181 LPCTSTR LicenseInfoLoader::GetImageURL(LoadedLicenseDataType eType)
00182 {
00183 return CCINFO_IMAGE_URL[eType];
00184 }
00185
00189 std::tstring LicenseInfoLoader::GetLicenseName() const
00190 {
00191
00192 std::tstring sRet = m_cName;
00193 if (HasJurisdiction())
00194 {
00195
00196 sRet += _T(", ");
00197 sRet += m_cJurisdiction;
00198 }
00199
00200 return sRet;
00201 }
00202
00203
00208 bool LicenseInfoLoader::IsValidLicenseInfo(LoadedLicenseDataType eType)
00209 {
00210
00211 return IsValidLicenseInfo(eType, m_xmlData[eType]);
00212 }
00213
00219 bool LicenseInfoLoader::IsValidLicenseInfo(LoadedLicenseDataType eType, XDoc& doc)
00220 {
00221 switch (eType)
00222 {
00223 case LLDTCC:
00224 case LLDTSampling:
00225
00226 return (doc.GetRoot() != NULL) && (doc.GetRoot()->name == _T("licenseclass"));
00227 default:
00228
00229 return (doc.GetRoot() != NULL);
00230 }
00231 }
00232
00238 bool LicenseInfoLoader::LoadData(LoadedLicenseDataType eType, LPCTSTR pXML)
00239 {
00240
00241 return LoadAndValidateData(eType, m_xmlData[eType], pXML);
00242 }
00243
00250 bool LicenseInfoLoader::LoadAndValidateData(LoadedLicenseDataType eType, XDoc& doc, LPCTSTR pXML)
00251 {
00252
00253 PARSEINFO info;
00254 doc.Close();
00255 doc.Load(pXML, &info);
00256
00257 if (info.erorr_occur)
00258
00259 return false;
00260
00261
00262 return IsValidLicenseInfo(eType, doc);
00263 }
00264
00268 LicenseInfo::LoadedLicenseDataType LicenseInfoLoader::GetCCLicenseType() const
00269 {
00270
00271 if (m_eLicense == LTCC)
00272 {
00273
00274 switch (m_eModification)
00275 {
00276 case MTAllow:
00277
00278 return m_bCommercialUse ? LLDTCC_by : LLDTCC_by_nc;
00279 case MTShareAlike:
00280
00281 return m_bCommercialUse ? LLDTCC_by_nc_sa : LLDTCC_by_sa;
00282 case MTNo:
00283
00284 return m_bCommercialUse ? LLDTCC_by_nc_nd : LLDTCC_by_nd;
00285 default:
00286
00287 return LLDT_Count;
00288 }
00289 }
00290 else if (m_eLicense == LTSampling)
00291 {
00292
00293 switch (m_eSampling)
00294 {
00295 case STSampling:
00296
00297 return LLDTSampling_by;
00298 case STSamplingPlus:
00299
00300 return LLDTSampling_by_plus;
00301 case STSamplingNC:
00302
00303 return LLDTSampling_by_nc_plus;
00304 }
00305 }
00306
00307
00308 return LLDT_Count;
00309 }
00310
00314 void LicenseInfoLoader::InitLicenseRetrievedData()
00315 {
00316 for (int i=0;i<LLDT_Count;i++)
00317 m_bRetrievedFromWeb[i] = false;
00318 }
00319
00326 bool LicenseInfoLoader::RequestLicenseType(LoadedLicenseDataType eType, HWND hWnd, bool& bCancel)
00327 {
00328 bCancel = false;
00329 if (eType > LLDTSampling)
00330
00331 return false;
00332
00333 if (IsLicenseRetrievedData(eType))
00334
00335 return true;
00336
00337
00338
00339 CCPrintProgressDlg dlg;
00340
00341 InternetRequest request;
00342 std::tstring sURL = GetLicenseURL(eType);
00343 if (dlg.DoRequest(hWnd, request, sURL, _T("api.creativecommons.org")))
00344 {
00345
00346 unsigned int dwSize;
00347 const char* pBuffer = dlg.m_buffer.GetData(dwSize);
00348
00349 std::tstring sXML = MakeTStringFromUTF8(std::string(pBuffer, dwSize).c_str());
00350
00351
00352 if (!LoadData(eType, sXML.c_str()))
00353
00354 if (!LoadInternalLicenseInfo(eType))
00355 return false;
00356 }
00357 else
00358 {
00359
00360 if (dlg.GetCancel())
00361
00362 bCancel = true;
00363
00364 if (!LoadInternalLicenseInfo(eType))
00365 return false;
00366 }
00367
00368
00369 SetLicenseRetrieved(eType);
00370 return true;
00371 }
00372
00377 bool LicenseInfoLoader::LoadInternalLicenseInfo(LoadedLicenseDataType eType)
00378 {
00379
00380 if (IsValidLicenseInfo(eType))
00381
00382 return true;
00383
00384
00385 HRSRC hRes = FindResource(ghInstance, MAKEINTRESOURCE(IDX_STANDARD + (int)eType), _T("XML"));
00386 if (hRes == NULL)
00387
00388 return false;
00389
00390
00391 DWORD dwSize = SizeofResource(ghInstance, hRes);
00392 HGLOBAL hXML = LoadResource(ghInstance, hRes);
00393 if (hXML == NULL)
00394
00395 return false;
00396
00397
00398 LPVOID pXML = LockResource(hXML);
00399 std::tstring s = MakeTString(std::string((const char*)pXML, dwSize));
00400 UnlockResource(hXML);
00401
00402
00403 return LoadData(eType, s.c_str());
00404 }
00405
00412 bool LicenseInfoLoader::RequestLicense(HWND hParent, XDoc& doc, bool& bCancel)
00413 {
00414
00415 LoadedLicenseDataType eType = GetCCLicenseType();
00416 if (eType == LLDT_Count)
00417 {
00418
00419 #ifdef _DEBUG
00420 assert(false);
00421 #endif
00422 return false;
00423 }
00424
00425
00426 if (!HasJurisdiction() && IsLicenseRetrievedData(eType))
00427 {
00428
00429 doc = GetLicenseXML(eType);
00430 return true;
00431 }
00432
00433
00434
00435
00436 TCHAR cHeaders[1024];
00437 XDoc answers;
00438 std::tstring sJuri, sRequestURL;
00439
00440
00441
00442 LPXNode pAnswers = answers.AppendChild(_T("answers"));
00443 LoadedLicenseDataType eBaseType;
00444 LPXNode pClass;
00445 if (m_eLicense == LTCC)
00446 {
00447
00448 pClass = pAnswers->AppendChild(_T("license-standard"));
00449 pClass->AppendChild(_T("commercial"), m_bCommercialUse ? _T("y") : _T("n"));
00450 pClass->AppendChild(_T("derivatives"), (m_eModification == MTAllow) ? _T("y") : (m_eModification == MTShareAlike) ? _T("sa") : _T("n"));
00451 eBaseType = LLDTCC;
00452 sRequestURL = _T("/rest/1.5/license/standard/issue");
00453 }
00454 else
00455 {
00456
00457 pClass = pAnswers->AppendChild(_T("license-recombo"));
00458 pClass->AppendChild(_T("sampling"), (m_eSampling == STSampling) ? _T("sampling") : (m_eSampling == STSamplingPlus) ? _T("samplingplus") : _T("ncsamplingplus"));
00459 eBaseType = LLDTSampling;
00460 sRequestURL = _T("/rest/1.5/license/recombo/issue");
00461 }
00462
00463
00464 DISP_OPT opt;
00465 opt.newline = false;
00466 if (HasJurisdiction())
00467 {
00468
00469 const LPXNode pJuri = GetLicenseXML(eBaseType).Find(_T("field"), _T("jurisdiction"));
00470 if (pJuri != NULL)
00471 {
00472
00473 for (XNodes::const_iterator i = pJuri->childs.begin(); sJuri.empty() && (i != pJuri->childs.end()); i++)
00474 {
00475
00476 const LPXAttr pID = (*i)->GetAttr(_T("id"));
00477 if ((pID == NULL) || pID->value.empty())
00478
00479 continue;
00480 const LPXNode pLabel = (*i)->GetChild(_T("label"));
00481 if (pLabel != NULL)
00482 {
00483
00484 if (pLabel->GetText(&opt) == m_cJurisdiction)
00485
00486 sJuri = pID->value;
00487 }
00488 }
00489 }
00490 }
00491
00492
00493 pClass->AppendChild(_T("jurisdiction"), sJuri.c_str());
00494
00495
00496 opt.reference_value = true;
00497 opt.newline = false;
00498 std::tstring sOptional = answers.GetXML(&opt);
00499 sOptional = URLEncode(sOptional.c_str());
00500 if (sOptional.empty())
00501
00502 return false;
00503
00504
00505 sOptional = _T("answers=") + sOptional;
00506 _stprintf_s(cHeaders, _S(cHeaders), _T("Content-Type: application/x-www-form-urlencoded\r\nContent-Length: %d"), sOptional.size());
00507
00508
00509 CCPrintProgressDlg dlg;
00510 std::tstring sError;
00511 InternetRequest request;
00512 bool bSuccess = false;
00513 if (dlg.DoRequest(hParent, request, sRequestURL, _T("api.creativecommons.org"), MakeAnsiString(sOptional).c_str(), cHeaders))
00514 {
00515
00516 unsigned int dwSize;
00517 const char* pBuffer = dlg.m_buffer.GetData(dwSize);
00518 std::tstring sXML = MakeTString(std::string(pBuffer, dwSize));
00519
00520 bSuccess = LoadAndValidateData(eType, doc, sXML.c_str());
00521 if (bSuccess)
00522 {
00523 if (!HasJurisdiction())
00524
00525 LoadData(eType, sXML.c_str());
00526 }
00527 else
00528 {
00529 if (HasJurisdiction())
00530 sError = LoadResourceString(IDS_ERROR_RETRIEVEDATA_JURISDICTION);
00531 else
00532 sError = LoadResourceString(IDS_ERROR_RETRIEVEDATA);
00533 }
00534 }
00535 else
00536 {
00537 if (dlg.GetCancel())
00538 {
00539
00540 if (HasJurisdiction())
00541 sError = LoadResourceString(IDS_WARNING_USERCANCEL_JURISDICTION);
00542 else
00543 sError = LoadResourceString(IDS_WARNING_USERCANCEL);
00544 }
00545 else
00546 sError = LoadResourceString(IDS_ERROR_RETRIEVELICENSE);
00547 }
00548
00549 if (!bSuccess)
00550 {
00551
00552 bSuccess = LoadInternalLicenseInfo(eType);
00553 if (bSuccess)
00554 {
00555 doc = GetLicenseXML(eType);
00556 SetJurisdiction(_T(""));
00557 }
00558 else
00559 {
00560
00561 ASSERT(FALSE);
00562 MessageBox(hParent, LoadResourceString(IDS_ERROR_RETRIEVELICENSE).c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00563 return false;
00564 }
00565 }
00566
00567 if (bSuccess)
00568 {
00569
00570 if (!HasJurisdiction())
00571
00572 SetLicenseRetrieved(eType);
00573 }
00574
00575
00576 if (!sError.empty())
00577
00578 MessageBox(hParent, sError.c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00579
00580 return true;
00581 }
00582
00587 bool LicenseInfoLoader::LoadLicenseData(HWND hParent)
00588 {
00589 XDoc doc;
00590 bool bCancel = false, bError = false;
00591 LPXNode pResult = NULL;
00592 switch (m_eLicense)
00593 {
00594 case LicenseInfo::LTCC:
00595
00596
00597 if (!RequestLicense(hParent, doc, bCancel))
00598 {
00599
00600 MessageBox(hParent, LoadResourceString(IDS_ERROR_RETRIEVEDATA_SHORT).c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00601 return false;
00602 }
00603
00604
00605 pResult = doc.Find(_T("result"));
00606 if (pResult == NULL)
00607
00608 bError = true;
00609 else
00610 {
00611
00612 DISP_OPT opt;
00613 opt.reference_value = false;
00614 LPXNode pNode = pResult->GetChild(_T("license-uri"));
00615 if (pNode == NULL)
00616 bError = true;
00617 else
00618 SetURI(pNode->GetText(&opt).c_str());
00619 pNode = pResult->GetChild(_T("license-name"));
00620 if (pNode == NULL)
00621 bError = true;
00622 else
00623 SetName(pNode->GetText(&opt).c_str());
00624 }
00625 if (bError)
00626 {
00627
00628 MessageBox(hParent, LoadResourceString(IDS_ERROR_RETRIEVELICENSE).c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00629 return false;
00630 }
00631 break;
00632 case LicenseInfo::LTSampling:
00633
00634
00635 if (!RequestLicense(hParent, doc, bCancel))
00636 {
00637
00638 MessageBox(hParent, LoadResourceString(IDS_ERROR_RETRIEVEDATA_SHORT).c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00639 return false;
00640 }
00641
00642
00643 pResult = doc.Find(_T("result"));
00644 if (pResult == NULL)
00645
00646 bError = true;
00647 else
00648 {
00649
00650 DISP_OPT opt;
00651 opt.reference_value = false;
00652 LPXNode pNode = pResult->GetChild(_T("license-uri"));
00653 if (pNode == NULL)
00654 bError = true;
00655 else
00656 SetURI(pNode->GetText(&opt).c_str());
00657 pNode = pResult->GetChild(_T("license-name"));
00658 if (pNode == NULL)
00659 bError = true;
00660 else
00661 SetName(pNode->GetText(&opt).c_str());
00662 }
00663 if (bError)
00664 {
00665
00666 MessageBox(hParent, LoadResourceString(IDS_ERROR_RETRIEVELICENSE).c_str(), _T("CC PDF Printer"), MB_ICONWARNING|MB_OK);
00667 return false;
00668 }
00669 break;
00670 case LicenseInfo::LTDevelopingNations:
00671
00672 SetURI(_T("http://creativecommons.org/licenses/devnations/2.0/"));
00673 SetName(_T("Developing Nations"));
00674 SetJurisdiction(_T(""));
00675 break;
00676 case LicenseInfo::LTPublicDomain:
00677
00678 SetURI(_T("http://creativecommons.org/licenses/publicdomain/"));
00679 SetName(_T("Public Domain"));
00680 SetJurisdiction(_T(""));
00681 break;
00682 case LicenseInfo::LTUnknown:
00683 ASSERT(FALSE);
00684
00685 case LicenseInfo::LTNone:
00686
00687 SetURI(_T(""));
00688 SetName(_T(""));
00689 SetJurisdiction(_T(""));
00690 break;
00691 }
00692
00693 return true;
00694 }